aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore17
-rw-r--r--CMakeLists.txt25
-rw-r--r--Makefile14
-rw-r--r--config/CMakeLists.txt30
-rw-r--r--config/config.h.in214
-rw-r--r--config/pathdef.c.in7
-rw-r--r--src/CMakeLists.txt18
-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.c3618
-rw-r--r--src/ex_docmd.c9401
-rw-r--r--src/ex_eval.c2113
-rw-r--r--src/ex_getln.c5487
-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.c4279
-rw-r--r--src/globals.h1228
-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.c2343
-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.c4091
-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.c978
-rw-r--r--src/version.h40
-rw-r--r--src/vim.h1752
-rw-r--r--src/window.c5640
380 files changed, 501011 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..d87a317eea
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,17 @@
+build/
+*.rej
+*.orig
+*.mo
+*.swp
+*~
+*.pyc
+src/po/vim.pot
+
+src/po/*.ck
+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
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..4bdfaa39aa
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,14 @@
+CMAKE_FLAGS := -DCMAKE_BUILD_TYPE=Debug
+
+test: build/src/vim
+ cd src/testdir && make
+
+build/src/vim:
+ cd build && make
+
+cmake:
+ rm -rf build
+ mkdir build
+ cd build && cmake $(CMAKE_FLAGS) ../
+
+.PHONY: test cmake
diff --git a/config/CMakeLists.txt b/config/CMakeLists.txt
new file mode 100644
index 0000000000..3d9fd04c25
--- /dev/null
+++ b/config/CMakeLists.txt
@@ -0,0 +1,30 @@
+include(CheckTypeSize)
+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)
+
+# 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..6606c78c87
--- /dev/null
+++ b/config/config.h.in
@@ -0,0 +1,214 @@
+#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_BIND_TEXTDOMAIN_CODESET 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_GETTEXT 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
+#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
+#define HAVE_STROPTS_H 1
+#define HAVE_STRPBRK 1
+#define HAVE_STRTOL 1
+#define HAVE_SVR4_PTYS 1
+#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
+#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
+#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/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000000..65138a6d5d
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,18 @@
+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 termcap selinux)
+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..42ccf5a416
--- /dev/null
+++ b/src/ex_cmds2.c
@@ -0,0 +1,3618 @@
+/* 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. */
+#if (defined(FEAT_EVAL) && !((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
+ && defined(LC_MESSAGES))) \
+ || ((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
+ && (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE)) \
+ && !defined(LC_MESSAGES))
+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. */
+# if defined(HAVE_GET_LOCALE_VAL) && defined(LC_MESSAGES)
+ loc = (char_u *)get_locale_val(LC_MESSAGES);
+# else
+ loc = get_mess_env();
+# 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);
+}
+
+#if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
+ && (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
+/*
+ * ":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) {
+#ifndef LC_MESSAGES
+ 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..d3d9c256be
--- /dev/null
+++ b/src/ex_docmd.c
@@ -0,0 +1,9401 @@
+/* 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));
+#if !((defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
+ && (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE)))
+# 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;
+
+#if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
+ && (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
+ 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"},
+#if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
+ && (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
+ {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..ee9fc079fe
--- /dev/null
+++ b/src/ex_getln.c
@@ -0,0 +1,5487 @@
+/* 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},
+#if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
+ && (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
+ {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..134f6d175b
--- /dev/null
+++ b/src/getchar.c
@@ -0,0 +1,4279 @@
+/* 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;
+}
+
+
+/*
+ * Set up default mappings.
+ */
+void init_mappings() {
+}
+
+#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..bb60aa98c1
--- /dev/null
+++ b/src/globals.h
@@ -0,0 +1,1228 @@
+/* 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 */
+
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) \
+ || defined(FEAT_AUTOCMD)
+# 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. */
+#endif
+
+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(= '-');
+
+#if defined(FEAT_WINDOWS) || defined(FEAT_WILDMENU) || defined(FEAT_STL_OPT) \
+ || defined(FEAT_FOLDING)
+/* Characters from 'fillchars' option */
+EXTERN int fill_stl INIT(= ' ');
+EXTERN int fill_stlnc INIT(= ' ');
+#endif
+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"}
+
+#if (defined(FEAT_PRINTER) && defined(FEAT_STL_OPT)) \
+ || defined(FEAT_GUI_TABLINE)
+/* Page number used for %N in 'pageheader' and 'guitablabel'. */
+EXTERN linenr_T printer_page_num;
+#endif
+
+
+
+
+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"));
+#if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK) || defined(MACOS) \
+ || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MSWIN)
+EXTERN char_u e_font[] INIT(= N_("E235: Unknown font: %s"));
+#endif
+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
+#if defined(DYNAMIC_PERL) \
+ || defined(DYNAMIC_PYTHON) || defined(DYNAMIC_PYTHON3) \
+ || defined(DYNAMIC_RUBY) \
+ || defined(DYNAMIC_TCL) \
+ || defined(DYNAMIC_ICONV) \
+ || defined(DYNAMIC_GETTEXT) \
+ || defined(DYNAMIC_MZSCHEME) \
+ || defined(DYNAMIC_LUA)
+EXTERN char_u e_loadlib[] INIT(= N_("E370: Could not load library %s"));
+EXTERN char_u e_loadfunc[] INIT(= N_("E448: Could not load library function %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"));
+#if defined(FEAT_SYN_HL) || \
+ (defined(FEAT_INS_EXPAND) && defined(FEAT_COMPL_FUNC))
+EXTERN char_u e_notset[] INIT(= N_("E764: Option '%s' is not set"));
+#endif
+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..53f02a8b75
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,2343 @@
+/* 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"
+
+#ifdef SPAWNO
+# include <spawno.h> /* special MS-DOS swapping library */
+#endif
+
+
+/* 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 void early_arg_scan __ARGS((mparm_T *parmp));
+static void command_line_scan __ARGS((mparm_T *parmp));
+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
+
+
+/*
+ * 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
+# ifdef VIMDLL
+_export
+# endif
+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. */
+#ifdef STARTUPTIME
+ int i;
+#endif
+
+ /*
+ * 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. */
+ vim_memset(&params, 0, sizeof(params));
+ params.argc = argc;
+ params.argv = argv;
+ params.want_full_screen = TRUE;
+ params.use_debug_break_level = -1;
+ params.window_count = -1;
+
+
+
+#ifdef MEM_PROFILE
+ atexit(vim_mem_profile_dump);
+#endif
+
+#ifdef STARTUPTIME
+ for (i = 1; i < argc; ++i) {
+ if (STRICMP(argv[i], "--startuptime") == 0 && i + 1 < argc) {
+ time_fd = mch_fopen(argv[i + 1], "a");
+ TIME_MSG("--- VIM STARTING ---");
+ break;
+ }
+ }
+#endif
+ starttime = time(NULL);
+
+
+ (void)mb_init(); /* init mb_bytelen_tab[] to ones */
+ eval_init(); /* init global variables */
+
+#ifdef __QNXNTO__
+ qnx_init(); /* PhAttach() for clipboard, (and gui) */
+#endif
+
+#ifdef MAC_OS_CLASSIC
+ /* Prepare for possibly starting GUI sometime */
+ /* Macintosh needs this before any memory is allocated. */
+ gui_prepare(&params.argc, params.argv);
+ TIME_MSG("GUI prepared");
+#endif
+
+ /* Init the table of Normal mode commands. */
+ init_normal_cmds();
+
+
+ /*
+ * Allocate space for the generic buffers (needed for set_init_1() and
+ * EMSG2()).
+ */
+ if ((IObuff = alloc(IOSIZE)) == NULL
+ || (NameBuff = alloc(MAXPATHL)) == NULL)
+ mch_exit(0);
+ TIME_MSG("Allocated 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();
+ TIME_MSG("locale set");
+#endif
+
+
+ /*
+ * Do a first scan of the arguments in "argv[]":
+ * -display or --display
+ * --server...
+ * --socketid
+ * --windowid
+ */
+ early_arg_scan(&params);
+
+
+
+ /*
+ * 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.
+ */
+ params.stdout_isatty = (mch_check_win(params.argc, params.argv) != FAIL);
+ TIME_MSG("window checked");
+
+ /*
+ * 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);
+ TIME_MSG("parsing arguments");
+
+ /*
+ * 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) {
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
+ /*
+ * Expand wildcards in file names.
+ */
+ if (!params.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
+ fname = alist_name(&GARGLIST[0]);
+ }
+
+
+ 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_mappings(); /* set up initial mappings */
+
+ 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.
+ */
+if (p_lpl) {
+ source_runtime((char_u *)"plugin/**/*.vim", TRUE);
+ TIME_MSG("loading plugins");
+}
+
+/* Decide about window layout for diff mode after reading vimrc. */
+if (params.diff_mode && params.window_layout == 0) {
+ if (diffopt_horizontal())
+ params.window_layout = WIN_HOR; /* use horizontal split */
+ else
+ params.window_layout = WIN_VER; /* use vertical split */
+}
+
+/*
+ * 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 */
+}
+
+
+#ifdef SPAWNO /* special MSDOS swapping library */
+init_SPAWNO("", SWAP_ANY);
+#endif
+
+/*
+ * 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.
+ */
+if (params.edit_type == EDIT_QF) {
+ if (params.use_ef != NULL)
+ set_string_option_direct((char_u *)"ef", -1,
+ params.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");
+}
+
+/*
+ * 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.
+ */
+if (params.tagname != NULL) {
+#if defined(HAS_SWAP_EXISTS_ACTION)
+ swap_exists_did_quit = FALSE;
+#endif
+
+ vim_snprintf((char *)IObuff, IOSIZE, "ta %s", params.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
+}
+
+/* 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);
+ }
+}
+
+#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 (TOLOWER_ASC(initstr[0]) == 'r') {
+ restricted = TRUE;
+ ++initstr;
+ }
+
+ /* Use evim mode for "evim" and "egvim", not for "editor". */
+ if (TOLOWER_ASC(initstr[0]) == 'e'
+ && (TOLOWER_ASC(initstr[1]) == 'v'
+ || TOLOWER_ASC(initstr[1]) == 'g')) {
+ parmp->evim_mode = TRUE;
+ ++initstr;
+ }
+
+ /* "gvim" starts the GUI. Also accept "Gvim" for MS-Windows. */
+ if (TOLOWER_ASC(initstr[0]) == 'g') {
+ main_start_gui();
+ }
+
+ if (STRNICMP(initstr, "view", 4) == 0) {
+ readonlymode = TRUE;
+ curbuf->b_p_ro = TRUE;
+ p_uc = 10000; /* don't update very often */
+ initstr += 4;
+ } else if (STRNICMP(initstr, "vim", 3) == 0)
+ initstr += 3;
+
+ /* Catch "[r][g]vimdiff" and "[r][g]viewdiff". */
+ if (STRICMP(initstr, "diff") == 0) {
+ parmp->diff_mode = TRUE;
+ }
+
+ if (STRNICMP(initstr, "ex", 2) == 0) {
+ if (STRNICMP(initstr + 2, "im", 2) == 0)
+ exmode_active = EXMODE_VIM;
+ else
+ exmode_active = EXMODE_NORMAL;
+ change_compatible(TRUE); /* set 'compatible' */
+ }
+}
+
+/*
+ * Get the name of the display, before gui_prepare() removes it from
+ * argv[]. Used for the xterm-clipboard display.
+ *
+ * Also find the --server... arguments and --socketid and --windowid
+ */
+static void early_arg_scan(parmp)
+mparm_T *parmp UNUSED;
+{
+#if defined(FEAT_XCLIPBOARD) || defined(FEAT_CLIENTSERVER) \
+ || !defined(FEAT_NETBEANS_INTG)
+ int argc = parmp->argc;
+ char **argv = parmp->argv;
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ if (STRCMP(argv[i], "--") == 0)
+ break;
+
+ else if (strncmp(argv[i], "-nb", (size_t)3) == 0) {
+ mch_errmsg(_("'-nb' cannot be used: not enabled at compile time\n"));
+ mch_exit(2);
+ }
+
+ }
+#endif
+}
+
+/*
+ * 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);
+ }
+ }
+}
+
+/*
+ * 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..66f26826c4
--- /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);
+
+#if defined(HAVE_BIND_TEXTDOMAIN_CODESET) && defined(FEAT_GETTEXT)
+ /* 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..83a65cf9b5
--- /dev/null
+++ b/src/os_unix.c
@@ -0,0 +1,4091 @@
+/* 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
+#if defined(SIGALRM) && defined(FEAT_X11) \
+ && defined(FEAT_TITLE) && !defined(FEAT_GUI_GTK)
+# define SET_SIG_ALARM
+static RETSIGTYPE sig_alarm __ARGS(SIGPROTOARG);
+/* volatile because it is used in signal handler sig_alarm(). */
+static volatile int sig_alarm_called;
+#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) && !defined(FEAT_MZSCHEME)
+ /* 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) && !defined(FEAT_RUBY)
+ {SIGVTALRM, "VTALRM", TRUE},
+#endif
+#if defined(SIGPROF) && !defined(FEAT_MZSCHEME) && !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
+# if defined(__APPLE__) && (!defined(MAC_OS_X_VERSION_MAX_ALLOWED) \
+ || MAC_OS_X_VERSION_MAX_ALLOWED <= 1040)
+ /* missing prototype. Adding it to osdef?.h.in doesn't work, because
+ * "struct sigaltstack" needs to be declared. */
+ extern int sigaltstack __ARGS((const struct sigaltstack *ss,
+ struct sigaltstack *oss));
+# endif
+
+ 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
+
+#ifdef SET_SIG_ALARM
+/*
+ * signal function for alarm().
+ */
+static RETSIGTYPE
+sig_alarm SIGDEFARG(sigarg) {
+ /* doesn't do anything, just to break a system call */
+ sig_alarm_called = TRUE;
+ SIGRETURN;
+}
+
+#endif
+
+#if (defined(HAVE_SETJMP_H) \
+ && ((defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)) \
+ || 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);
+#if defined(FEAT_GUI_GTK) \
+ || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)
+ else
+ gui_mch_settitle(title, icon);
+#endif
+ 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;
+ }
+
+
+
+# ifdef FEAT_MOUSE_JSB
+ else {
+ if (on) {
+ /* D - Enable Mouse up/down messages
+ * L - Enable Left Button Reporting
+ * M - Enable Middle Button Reporting
+ * R - Enable Right Button Reporting
+ * K - Enable SHIFT and CTRL key Reporting
+ * + - Enable Advanced messaging of mouse moves and up/down messages
+ * Q - Quiet No Ack
+ * # - Numeric value of mouse pointer required
+ * 0 = Multiview 2000 cursor, used as standard
+ * 1 = Windows Arrow
+ * 2 = Windows I Beam
+ * 3 = Windows Hour Glass
+ * 4 = Windows Cross Hair
+ * 5 = Windows UP Arrow
+ */
+# ifdef JSBTERM_MOUSE_NONADVANCED
+ /* Disables full feedback of pointer movements */
+ out_str_nf((char_u *)IF_EB("\033[0~ZwLMRK1Q\033\\",
+ ESC_STR "[0~ZwLMRK1Q" ESC_STR "\\"));
+# else
+ out_str_nf((char_u *)IF_EB("\033[0~ZwLMRK+1Q\033\\",
+ ESC_STR "[0~ZwLMRK+1Q" ESC_STR "\\"));
+# endif
+ ison = TRUE;
+ } else {
+ out_str_nf((char_u *)IF_EB("\033[0~ZwQ\033\\",
+ ESC_STR "[0~ZwQ" ESC_STR "\\"));
+ ison = FALSE;
+ }
+ }
+# endif
+}
+
+/*
+ * 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);
+
+
+
+# ifdef FEAT_MOUSE_JSB
+ /* conflicts with xterm mouse: "\033[" and "\033[M" ??? */
+ if (!use_xterm_mouse()
+ )
+ set_mouse_termcode(KS_JSBTERM_MOUSE,
+ (char_u *)IF_EB("\033[0~zw", ESC_STR "[0~zw"));
+ else
+ del_mouse_termcode(KS_JSBTERM_MOUSE);
+# endif
+
+ /* 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
new file mode 100644
index 0000000000..62a7aa8bc8
--- /dev/null
+++ b/src/version.c
@@ -0,0 +1,978 @@
+/* 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"
+
+
+/*
+ * 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.
+ */
+
+#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",
+
+#if defined(UNIX) || defined(VMS)
+ "+mouse_dec",
+ "-mouse_gpm",
+# ifdef FEAT_MOUSE_JSB
+ "+mouse_jsbterm",
+# else
+ "-mouse_jsbterm",
+# endif
+ "+mouse_netterm",
+#endif
+
+
+#if defined(UNIX) || defined(VMS)
+ "+mouse_sgr",
+ "-mouse_sysmouse",
+ "+mouse_urxvt",
+ "+mouse_xterm",
+#endif
+
+ "+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
+ "-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();
+
+#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);
+
+ 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..3095dbf541
--- /dev/null
+++ b/src/vim.h
@@ -0,0 +1,1752 @@
+/* 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 */
+
+/* use fastcall for Borland, when compiling for Win32 (not for DOS16) */
+
+#if defined(MSDOS) || defined(WIN16) || defined(WIN32) || defined(_WIN64) \
+ || defined(__EMX__)
+# include "vimio.h"
+#endif
+
+/* ============ 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
+
+
+/*
+ * MACOS_CLASSIC compiling for MacOS prior to MacOS X
+ * MACOS_X_UNIX compiling for MacOS X (using os_unix.c)
+ * MACOS_X compiling for MacOS X (using os_unix.c)
+ * MACOS compiling for either one
+ */
+/* Unless made through the Makefile enforce GUI on Mac */
+
+#if defined(FEAT_GUI_MOTIF) \
+ || defined(FEAT_GUI_GTK) \
+ || defined(FEAT_GUI_ATHENA) \
+ || defined(FEAT_GUI_MAC) \
+ || defined(FEAT_GUI_W32) \
+ || defined(FEAT_GUI_W16) \
+ || defined(FEAT_GUI_PHOTON)
+# define FEAT_GUI_ENABLED /* also defined with NO_X11_INCLUDES */
+# if !defined(FEAT_GUI) && !defined(NO_X11_INCLUDES)
+# define FEAT_GUI
+# endif
+#endif
+
+/* Visual Studio 2005 has 'deprecated' many of the standard CRT functions */
+
+/* Practically everything is common to both Win32 and Win64 */
+
+/*
+ * SIZEOF_INT is used in feature.h, and the system-specific included files
+ * need items from feature.h. Therefore define SIZEOF_INT here.
+ */
+
+
+
+
+/* +x11 is only enabled when it's both available and wanted. */
+
+#ifdef NO_X11_INCLUDES
+/* In os_mac_conv.c and os_macosx.m NO_X11_INCLUDES is defined to avoid
+ * X11 headers. Disable all X11 related things to avoid conflicts. */
+#endif
+
+/* The Mac conversion stuff doesn't work under X11. */
+
+/* Can't use "PACKAGE" here, conflicts with a Perl include file. */
+#ifndef VIMPACKAGE
+# define VIMPACKAGE "vim"
+#endif
+
+/*
+ * Find out if function definitions should include argument types
+ */
+
+
+
+
+
+#if (defined(UNIX) || defined(__EMX__) || defined(VMS)) \
+ && (!defined(MACOS_X) || defined(HAVE_CONFIG_H))
+# include "os_unix.h" /* bring lots of system header files */
+#endif
+
+#ifndef __ARGS
+# if defined(__STDC__) || defined(__GNUC__) || defined(WIN3264)
+# define __ARGS(x) x
+# else
+# define __ARGS(x) ()
+# endif
+#endif
+
+/* __ARGS and __PARMS are the same thing. */
+#ifndef __PARMS
+# define __PARMS(x) __ARGS(x)
+#endif
+
+/* Mark unused function arguments with UNUSED, so that gcc -Wunused-parameter
+ * can be used to check for mistakes. */
+#ifdef HAVE_ATTRIBUTE_UNUSED
+# define UNUSED __attribute__((unused))
+#else
+# define UNUSED
+#endif
+
+/* if we're compiling in C++ (currently only KVim), the system
+ * headers must have the correct prototypes or nothing will build.
+ * conversely, our prototypes might clash due to throw() specifiers and
+ * cause compilation failures even though the headers are correct. For
+ * a concrete example, gcc-3.2 enforces exception specifications, and
+ * glibc-2.2.5 has them in their system headers.
+ */
+#if !defined(__cplusplus) && defined(UNIX) \
+ && !defined(MACOS_X) /* MACOS_X doesn't yet support osdef.h */
+#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
+
+#ifndef UNIX /* For Unix this is included in os_unix.h */
+# include <stdio.h>
+# include <ctype.h>
+#endif
+
+#include "ascii.h"
+#include "keymap.h"
+#include "term.h"
+#include "macros.h"
+
+#ifdef LATTICE
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif
+
+#if defined(HAVE_ERRNO_H) || defined(DJGPP) || defined(WIN16) \
+ || defined(WIN32) || defined(_WIN64) || defined(__EMX__)
+# include <errno.h>
+#endif
+
+/*
+ * Allow other (non-unix) systems to configure themselves now
+ * These are also in os_unix.h, because osdef.sh needs them there.
+ */
+#ifndef UNIX
+/* Note: Some systems need both string.h and strings.h (Savage). If the
+ * system can't handle this, define NO_STRINGS_WITH_STRING_H. */
+# ifdef HAVE_STRING_H
+# include <string.h>
+# endif
+# if defined(HAVE_STRINGS_H) && !defined(NO_STRINGS_WITH_STRING_H)
+# include <strings.h>
+# endif
+# ifdef HAVE_STAT_H
+# include <stat.h>
+# endif
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif /* NON-UNIX */
+
+#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
+
+#ifndef HAVE_SELECT
+# ifdef HAVE_SYS_POLL_H
+# include <sys/poll.h>
+# define HAVE_POLL
+# else
+# ifdef HAVE_POLL_H
+# include <poll.h>
+# define HAVE_POLL
+# endif
+# endif
+#endif
+
+/* ================ end of the header file puzzle =============== */
+
+/*
+ * For dynamically loaded imm library. Currently, only for Win32.
+ */
+#ifdef DYNAMIC_IME
+# define FEAT_MBYTE_IME
+#endif
+
+/*
+ * Check input method control.
+ */
+#if defined(FEAT_XIM) \
+ || (defined(FEAT_GUI) && (defined(FEAT_MBYTE_IME) || defined(GLOBAL_IME))) \
+ || (defined(FEAT_GUI_MAC) && defined(FEAT_MBYTE))
+# define USE_IM_CONTROL
+#endif
+
+/*
+ * For dynamically loaded gettext library. Currently, only for Win32.
+ */
+
+
+/*
+ * The _() stuff is for using gettext(). It is a no-op when libintl.h is not
+ * found or the +multilang feature is disabled.
+ */
+# include <libintl.h>
+# define _(x) gettext((char *)(x))
+# ifdef gettext_noop
+# define N_(x) gettext_noop(x)
+# else
+# define N_(x) x
+# 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;
+}
+