aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.asan-blacklist2
-rw-r--r--src/.valgrind.supp2
-rwxr-xr-xsrc/clint.py55
-rw-r--r--src/coverity-model.c70
-rw-r--r--src/nvim/CMakeLists.txt451
-rw-r--r--src/nvim/README.md92
-rw-r--r--src/nvim/api/buffer.c181
-rw-r--r--src/nvim/api/private/defs.h42
-rw-r--r--src/nvim/api/private/dispatch.c3
-rw-r--r--src/nvim/api/private/handle.c3
-rw-r--r--src/nvim/api/private/handle.h3
-rw-r--r--src/nvim/api/private/helpers.c375
-rw-r--r--src/nvim/api/private/helpers.h27
-rw-r--r--src/nvim/api/tabpage.c22
-rw-r--r--src/nvim/api/ui.c241
-rw-r--r--src/nvim/api/ui_events.in.h71
-rw-r--r--src/nvim/api/vim.c280
-rw-r--r--src/nvim/api/window.c51
-rw-r--r--src/nvim/arabic.c3
-rw-r--r--src/nvim/ascii.h17
-rw-r--r--src/nvim/auevents.lua3
-rw-r--r--src/nvim/buffer.c1113
-rw-r--r--src/nvim/buffer.h55
-rw-r--r--src/nvim/buffer_defs.h118
-rw-r--r--src/nvim/bufhl_defs.h23
-rw-r--r--src/nvim/charset.c215
-rw-r--r--src/nvim/charset.h14
-rw-r--r--src/nvim/cursor.c43
-rw-r--r--src/nvim/cursor_shape.c187
-rw-r--r--src/nvim/cursor_shape.h79
-rw-r--r--src/nvim/diff.c101
-rw-r--r--src/nvim/diff.h3
-rw-r--r--src/nvim/digraph.c29
-rw-r--r--src/nvim/digraph.h3
-rw-r--r--src/nvim/edit.c564
-rw-r--r--src/nvim/eval.c13226
-rw-r--r--src/nvim/eval.h46
-rw-r--r--src/nvim/eval.lua23
-rw-r--r--src/nvim/eval/decode.c304
-rw-r--r--src/nvim/eval/decode.h3
-rw-r--r--src/nvim/eval/encode.c90
-rw-r--r--src/nvim/eval/executor.c118
-rw-r--r--src/nvim/eval/executor.h11
-rw-r--r--src/nvim/eval/gc.c14
-rw-r--r--src/nvim/eval/gc.h12
-rw-r--r--src/nvim/eval/typval.c2627
-rw-r--r--src/nvim/eval/typval.h448
-rw-r--r--src/nvim/eval/typval_encode.c.h50
-rw-r--r--src/nvim/eval/typval_encode.h3
-rw-r--r--src/nvim/eval_defs.h198
-rw-r--r--src/nvim/event/defs.h8
-rw-r--r--src/nvim/event/libuv_process.c31
-rw-r--r--src/nvim/event/libuv_process.h5
-rw-r--r--src/nvim/event/loop.c27
-rw-r--r--src/nvim/event/multiqueue.c51
-rw-r--r--src/nvim/event/multiqueue.h2
-rw-r--r--src/nvim/event/process.c87
-rw-r--r--src/nvim/event/process.h5
-rw-r--r--src/nvim/event/rstream.c15
-rw-r--r--src/nvim/event/signal.c3
-rw-r--r--src/nvim/event/socket.c210
-rw-r--r--src/nvim/event/socket.h2
-rw-r--r--src/nvim/event/stream.c13
-rw-r--r--src/nvim/event/time.c3
-rw-r--r--src/nvim/event/wstream.c4
-rw-r--r--src/nvim/ex_cmds.c519
-rw-r--r--src/nvim/ex_cmds.h4
-rw-r--r--src/nvim/ex_cmds.lua65
-rw-r--r--src/nvim/ex_cmds2.c295
-rw-r--r--src/nvim/ex_cmds_defs.h30
-rw-r--r--src/nvim/ex_docmd.c1356
-rw-r--r--src/nvim/ex_docmd.h16
-rw-r--r--src/nvim/ex_eval.c95
-rw-r--r--src/nvim/ex_eval.h27
-rw-r--r--src/nvim/ex_getln.c1119
-rw-r--r--src/nvim/ex_getln.h5
-rw-r--r--src/nvim/farsi.c68
-rw-r--r--src/nvim/file_search.c110
-rw-r--r--src/nvim/file_search.h5
-rw-r--r--src/nvim/fileio.c846
-rw-r--r--src/nvim/fileio.h27
-rw-r--r--src/nvim/fold.c314
-rw-r--r--src/nvim/fold.h5
-rw-r--r--src/nvim/func_attr.h62
-rw-r--r--src/nvim/garray.c3
-rw-r--r--src/nvim/garray.h2
-rw-r--r--src/nvim/generators/c_grammar.lua50
-rw-r--r--src/nvim/generators/dump_bin_array.lua17
-rw-r--r--src/nvim/generators/gen_api_dispatch.lua458
-rw-r--r--src/nvim/generators/gen_api_ui_events.lua166
-rw-r--r--src/nvim/generators/gen_char_blob.lua48
-rwxr-xr-xsrc/nvim/generators/gen_declarations.lua287
-rw-r--r--src/nvim/generators/gen_eval.lua67
-rw-r--r--src/nvim/generators/gen_events.lua65
-rw-r--r--src/nvim/generators/gen_ex_cmds.lua88
-rw-r--r--src/nvim/generators/gen_options.lua190
-rw-r--r--src/nvim/generators/gen_unicode_tables.lua327
-rw-r--r--src/nvim/getchar.c573
-rw-r--r--src/nvim/getchar.h20
-rw-r--r--src/nvim/gettext.h21
-rw-r--r--src/nvim/globals.h207
-rw-r--r--src/nvim/hardcopy.c34
-rw-r--r--src/nvim/hardcopy.h4
-rw-r--r--src/nvim/hashtab.c81
-rw-r--r--src/nvim/hashtab.h19
-rw-r--r--src/nvim/highlight_defs.h126
-rw-r--r--src/nvim/iconv.h4
-rw-r--r--src/nvim/if_cscope.c357
-rw-r--r--src/nvim/if_cscope.h3
-rw-r--r--src/nvim/if_cscope_defs.h1
-rw-r--r--src/nvim/indent.c10
-rw-r--r--src/nvim/indent_c.c81
-rw-r--r--src/nvim/keymap.c66
-rw-r--r--src/nvim/keymap.h10
-rw-r--r--src/nvim/lib/kbtree.h451
-rw-r--r--src/nvim/log.c168
-rw-r--r--src/nvim/log.h79
-rw-r--r--src/nvim/lua/converter.c1189
-rw-r--r--src/nvim/lua/converter.h15
-rw-r--r--src/nvim/lua/executor.c662
-rw-r--r--src/nvim/lua/executor.h25
-rw-r--r--src/nvim/lua/vim.lua64
-rw-r--r--src/nvim/macros.h66
-rw-r--r--src/nvim/main.c306
-rw-r--r--src/nvim/map.c5
-rw-r--r--src/nvim/map.h2
-rw-r--r--src/nvim/mark.c67
-rw-r--r--src/nvim/mark.h44
-rw-r--r--src/nvim/mark_defs.h2
-rw-r--r--src/nvim/mbyte.c535
-rw-r--r--src/nvim/mbyte.h46
-rw-r--r--src/nvim/memfile.c35
-rw-r--r--src/nvim/memfile_defs.h2
-rw-r--r--src/nvim/memline.c87
-rw-r--r--src/nvim/memline.h2
-rw-r--r--src/nvim/memory.c119
-rw-r--r--src/nvim/menu.c311
-rw-r--r--src/nvim/menu.h52
-rw-r--r--src/nvim/message.c1569
-rw-r--r--src/nvim/message.h13
-rw-r--r--src/nvim/misc1.c108
-rw-r--r--src/nvim/mouse.c8
-rw-r--r--src/nvim/move.c26
-rw-r--r--src/nvim/move.h2
-rw-r--r--src/nvim/msgpack_rpc/channel.c314
-rw-r--r--src/nvim/msgpack_rpc/channel.h5
-rw-r--r--src/nvim/msgpack_rpc/helpers.c86
-rw-r--r--src/nvim/msgpack_rpc/helpers.h7
-rw-r--r--src/nvim/msgpack_rpc/server.c51
-rw-r--r--src/nvim/msgpack_rpc/server.h2
-rw-r--r--src/nvim/normal.c776
-rw-r--r--src/nvim/ops.c598
-rw-r--r--src/nvim/ops.h4
-rw-r--r--src/nvim/option.c754
-rw-r--r--src/nvim/option_defs.h98
-rw-r--r--src/nvim/options.lua75
-rw-r--r--src/nvim/os/dl.c3
-rw-r--r--src/nvim/os/env.c262
-rw-r--r--src/nvim/os/fileio.c135
-rw-r--r--src/nvim/os/fileio.h2
-rw-r--r--src/nvim/os/fs.c263
-rw-r--r--src/nvim/os/fs_defs.h2
-rw-r--r--src/nvim/os/input.c34
-rw-r--r--src/nvim/os/mem.c3
-rw-r--r--src/nvim/os/os_defs.h13
-rw-r--r--src/nvim/os/pty_process_unix.c64
-rw-r--r--src/nvim/os/pty_process_win.c410
-rw-r--r--src/nvim/os/pty_process_win.h27
-rw-r--r--src/nvim/os/shell.c60
-rw-r--r--src/nvim/os/shell.h2
-rw-r--r--src/nvim/os/signal.c3
-rw-r--r--src/nvim/os/stdpaths.c3
-rw-r--r--src/nvim/os/time.c3
-rw-r--r--src/nvim/os/unix_defs.h5
-rw-r--r--src/nvim/os/users.c3
-rw-r--r--src/nvim/os/win_defs.h28
-rw-r--r--src/nvim/os_unix.c430
-rw-r--r--src/nvim/path.c238
-rw-r--r--src/nvim/po/CMakeLists.txt10
-rw-r--r--src/nvim/po/check.vim76
-rw-r--r--src/nvim/po/eo.po6194
-rw-r--r--src/nvim/po/fi.po7517
-rw-r--r--src/nvim/po/fr.po6326
-rw-r--r--src/nvim/po/ga.po6199
-rw-r--r--src/nvim/po/it.po2
-rw-r--r--src/nvim/po/ja.euc-jp.po6119
-rw-r--r--src/nvim/po/ja.po6116
-rw-r--r--src/nvim/po/uk.po6
-rw-r--r--src/nvim/popupmnu.c51
-rw-r--r--src/nvim/popupmnu.h2
-rw-r--r--src/nvim/pos.h2
-rw-r--r--src/nvim/profile.c3
-rw-r--r--src/nvim/quickfix.c1696
-rw-r--r--src/nvim/quickfix.h3
-rw-r--r--src/nvim/rbuffer.c3
-rw-r--r--src/nvim/regexp.c1287
-rw-r--r--src/nvim/regexp.h4
-rw-r--r--src/nvim/regexp_nfa.c383
-rw-r--r--src/nvim/screen.c812
-rw-r--r--src/nvim/screen.h4
-rw-r--r--src/nvim/search.c110
-rw-r--r--src/nvim/search.h6
-rw-r--r--src/nvim/sha256.c17
-rw-r--r--src/nvim/sha256.h1
-rw-r--r--src/nvim/shada.c387
-rw-r--r--src/nvim/sign_defs.h2
-rw-r--r--src/nvim/spell.c6325
-rw-r--r--src/nvim/spell.h4
-rw-r--r--src/nvim/spell_defs.h287
-rw-r--r--src/nvim/spellfile.c5741
-rw-r--r--src/nvim/spellfile.h13
-rw-r--r--src/nvim/state.c53
-rw-r--r--src/nvim/strings.c1115
-rw-r--r--src/nvim/strings.h4
-rw-r--r--src/nvim/syntax.c932
-rw-r--r--src/nvim/syntax.h10
-rw-r--r--src/nvim/syntax_defs.h13
-rw-r--r--src/nvim/tag.c511
-rw-r--r--src/nvim/tag.h3
-rw-r--r--src/nvim/terminal.c334
-rw-r--r--src/nvim/testdir/Makefile63
-rw-r--r--src/nvim/testdir/runtest.vim153
-rw-r--r--src/nvim/testdir/samples/memfile_test.c146
-rw-r--r--src/nvim/testdir/setup.vim12
-rw-r--r--src/nvim/testdir/shared.vim214
-rw-r--r--src/nvim/testdir/test13.in63
-rw-r--r--src/nvim/testdir/test13.ok31
-rw-r--r--src/nvim/testdir/test17.in14
-rw-r--r--src/nvim/testdir/test49.vim4
-rw-r--r--src/nvim/testdir/test69.in191
-rw-r--r--src/nvim/testdir/test69.ok166
-rw-r--r--src/nvim/testdir/test73.in11
-rw-r--r--src/nvim/testdir/test8.in43
-rw-r--r--src/nvim/testdir/test8.ok7
-rw-r--r--src/nvim/testdir/test_alot.vim17
-rw-r--r--src/nvim/testdir/test_autocmd.vim329
-rw-r--r--src/nvim/testdir/test_breakindent.vim298
-rw-r--r--src/nvim/testdir/test_bufwintabinfo.vim13
-rw-r--r--src/nvim/testdir/test_charsearch.vim62
-rw-r--r--src/nvim/testdir/test_cmdline.vim76
-rw-r--r--src/nvim/testdir/test_command_count.vim191
-rw-r--r--src/nvim/testdir/test_cscope.vim266
-rw-r--r--src/nvim/testdir/test_cursor_func.vim8
-rw-r--r--src/nvim/testdir/test_diffmode.vim33
-rw-r--r--src/nvim/testdir/test_digraph.vim461
-rw-r--r--src/nvim/testdir/test_display.vim71
-rw-r--r--src/nvim/testdir/test_expr.vim407
-rw-r--r--src/nvim/testdir/test_expr_utf8.vim57
-rw-r--r--src/nvim/testdir/test_farsi.vim84
-rw-r--r--src/nvim/testdir/test_fileformat.vim17
-rw-r--r--src/nvim/testdir/test_filter_cmd.vim76
-rw-r--r--src/nvim/testdir/test_filter_map.vim81
-rw-r--r--src/nvim/testdir/test_float_func.vim332
-rw-r--r--src/nvim/testdir/test_fnameescape.vim21
-rw-r--r--src/nvim/testdir/test_fold.vim362
-rw-r--r--src/nvim/testdir/test_functions.vim194
-rw-r--r--src/nvim/testdir/test_gf.vim33
-rw-r--r--src/nvim/testdir/test_glob2regpat.vim30
-rw-r--r--src/nvim/testdir/test_gn.vim2
-rw-r--r--src/nvim/testdir/test_goto.vim294
-rw-r--r--src/nvim/testdir/test_help.vim16
-rw-r--r--src/nvim/testdir/test_help_tagjump.vim34
-rw-r--r--src/nvim/testdir/test_hide.vim97
-rw-r--r--src/nvim/testdir/test_history.vim41
-rw-r--r--src/nvim/testdir/test_hlsearch.vim34
-rw-r--r--src/nvim/testdir/test_increment.vim760
-rw-r--r--src/nvim/testdir/test_increment_dbcs.vim29
-rw-r--r--src/nvim/testdir/test_lambda.vim287
-rw-r--r--src/nvim/testdir/test_largefile.vim34
-rw-r--r--src/nvim/testdir/test_listlbr.vim235
-rw-r--r--src/nvim/testdir/test_listlbr_utf8.vim229
-rw-r--r--src/nvim/testdir/test_mapping.vim160
-rw-r--r--src/nvim/testdir/test_marks.vim26
-rw-r--r--src/nvim/testdir/test_match.vim12
-rw-r--r--src/nvim/testdir/test_matchadd_conceal.vim23
-rw-r--r--src/nvim/testdir/test_menu.vim2
-rw-r--r--src/nvim/testdir/test_nested_function.vim63
-rw-r--r--src/nvim/testdir/test_normal.vim2337
-rw-r--r--src/nvim/testdir/test_partial.vim21
-rw-r--r--src/nvim/testdir/test_popup.vim96
-rw-r--r--src/nvim/testdir/test_quickfix.vim469
-rw-r--r--src/nvim/testdir/test_regexp_utf8.vim83
-rw-r--r--src/nvim/testdir/test_search.vim300
-rw-r--r--src/nvim/testdir/test_smartindent.vim14
-rw-r--r--src/nvim/testdir/test_source_utf8.vim33
-rw-r--r--src/nvim/testdir/test_startup.vim242
-rw-r--r--src/nvim/testdir/test_startup_utf8.vim64
-rw-r--r--src/nvim/testdir/test_stat.vim64
-rw-r--r--src/nvim/testdir/test_substitute.vim41
-rw-r--r--src/nvim/testdir/test_syn_attr.vim2
-rw-r--r--src/nvim/testdir/test_tabpage.vim245
-rw-r--r--src/nvim/testdir/test_tagcase.vim73
-rw-r--r--src/nvim/testdir/test_tagjump.vim91
-rw-r--r--src/nvim/testdir/test_taglist.vim58
-rw-r--r--src/nvim/testdir/test_textobjects.vim43
-rw-r--r--src/nvim/testdir/test_timers.vim156
-rw-r--r--src/nvim/testdir/test_true_false.vim150
-rw-r--r--src/nvim/testdir/test_undo.vim267
-rw-r--r--src/nvim/testdir/test_utf8.vim65
-rw-r--r--src/nvim/testdir/test_vimscript.vim (renamed from src/nvim/testdir/test_viml.vim)151
-rw-r--r--src/nvim/testdir/test_window_cmd.vim358
-rw-r--r--src/nvim/testdir/test_window_id.vim9
-rw-r--r--src/nvim/testdir/test_writefile.vim16
-rw-r--r--src/nvim/testdir/view_util.vim30
-rw-r--r--src/nvim/tui/input.c21
-rw-r--r--src/nvim/tui/input.h3
-rw-r--r--src/nvim/tui/terminfo.c123
-rw-r--r--src/nvim/tui/terminfo.h10
-rw-r--r--src/nvim/tui/tui.c1260
-rw-r--r--src/nvim/tui/tui.h3
-rw-r--r--src/nvim/types.h1
-rw-r--r--src/nvim/ugrid.c3
-rw-r--r--src/nvim/ui.c273
-rw-r--r--src/nvim/ui.h41
-rw-r--r--src/nvim/ui_bridge.c269
-rw-r--r--src/nvim/undo.c140
-rw-r--r--src/nvim/version.c2994
-rw-r--r--src/nvim/version.h10
-rw-r--r--src/nvim/vim.h84
-rw-r--r--src/nvim/window.c433
-rw-r--r--src/nvim/window.h2
321 files changed, 67405 insertions, 50797 deletions
diff --git a/src/.asan-blacklist b/src/.asan-blacklist
index 7636f8fa82..928d81bd5a 100644
--- a/src/.asan-blacklist
+++ b/src/.asan-blacklist
@@ -1,3 +1,3 @@
# multiqueue.h pointer arithmetic is not accepted by asan
fun:multiqueue_node_data
-fun:dictwatcher_node_data
+fun:tv_dict_watcher_node_data
diff --git a/src/.valgrind.supp b/src/.valgrind.supp
index 8b630fcaaf..cce22bd632 100644
--- a/src/.valgrind.supp
+++ b/src/.valgrind.supp
@@ -10,7 +10,7 @@
Memcheck:Leak
fun:malloc
fun:uv_spawn
- fun:pipe_process_spawn
+ fun:libuv_process_spawn
fun:process_spawn
fun:job_start
}
diff --git a/src/clint.py b/src/clint.py
index e0f4d3eec5..4a41650ec4 100755
--- a/src/clint.py
+++ b/src/clint.py
@@ -182,6 +182,7 @@ _ERROR_CATEGORIES = [
'build/include_order',
'build/printf_format',
'build/storage_class',
+ 'build/useless_fattr',
'readability/alt_tokens',
'readability/bool',
'readability/braces',
@@ -571,7 +572,8 @@ class _CppLintState(object):
for category, count in self.errors_by_category.items():
sys.stderr.write('Category \'%s\' errors found: %d\n' %
(category, count))
- sys.stderr.write('Total errors found: %d\n' % self.error_count)
+ if self.error_count:
+ sys.stderr.write('Total errors found: %d\n' % self.error_count)
def SuppressErrorsFrom(self, fname):
"""Open file and read a list of suppressed errors from it"""
@@ -1224,6 +1226,10 @@ def CheckForHeaderGuard(filename, lines, error):
lines: An array of strings, each representing a line of the file.
error: The function to call with any errors found.
"""
+ if filename.endswith('.c.h') or FileInfo(filename).RelativePath() in set((
+ 'func_attr.h',
+ )):
+ return
cppvar = GetHeaderGuardCPPVariable(filename)
@@ -2268,11 +2274,14 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
# //!< Header comment
# or they begin with multiple slashes followed by a space:
# //////// Header comment
+ # or they are Vim {{{ fold markers
match = (Search(r'[=/-]{4,}\s*$', line[commentend:]) or
Search(r'^/$', line[commentend:]) or
Search(r'^!< ', line[commentend:]) or
Search(r'^/< ', line[commentend:]) or
- Search(r'^/+ ', line[commentend:]))
+ Search(r'^/+ ', line[commentend:]) or
+ Search(r'^(?:\{{3}|\}{3})\d*(?: |$)',
+ line[commentend:]))
if not match:
error(filename, linenum, 'whitespace/comments', 4,
'Should have a space between // and comment')
@@ -2520,6 +2529,8 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
r'(?<!\bklist_t)'
r'(?<!\bkliter_t)'
r'(?<!\bkhash_t)'
+ r'(?<!\bkbtree_t)'
+ r'(?<!\bkbitr_t)'
r'\((?:const )?(?:struct )?[a-zA-Z_]\w*(?: *\*(?:const)?)*\)'
r' +'
r'-?(?:\*+|&)?(?:\w+|\+\+|--|\()', cast_line)
@@ -2591,16 +2602,24 @@ def CheckBraces(filename, clean_lines, linenum, error):
else:
func_start_linenum = end_linenum + 1
while not clean_lines.lines[func_start_linenum] == '{':
- if not Match(r'^(?:\s*\b(?:FUNC_ATTR|REAL_FATTR)_\w+\b(?:\(\d+(, \d+)*\))?)+$',
- clean_lines.lines[func_start_linenum]):
- if clean_lines.lines[func_start_linenum].endswith('{'):
+ attrline = Match(r'^((?!# *define).*?)(?:FUNC_ATTR|FUNC_API|REAL_FATTR)_\w+(?:\(\d+(, \d+)*\))?',
+ clean_lines.lines[func_start_linenum])
+ if attrline:
+ if len(attrline.group(1)) != 2:
+ error(filename, func_start_linenum,
+ 'whitespace/indent', 5,
+ 'Function attribute line should have 2-space '
+ 'indent')
+
+ func_start_linenum += 1
+ else:
+ func_start = clean_lines.lines[func_start_linenum]
+ if not func_start.startswith('enum ') and func_start.endswith('{'):
error(filename, func_start_linenum,
'readability/braces', 5,
'Brace starting function body must be placed '
'after the function signature')
break
- else:
- func_start_linenum += 1
# An else clause should be on the same line as the preceding closing brace.
# If there is no preceding closing brace, there should be one.
@@ -3166,11 +3185,20 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
# Check if some verboten C functions are being used.
if Search(r'\bsprintf\b', line):
error(filename, linenum, 'runtime/printf', 5,
- 'Never use sprintf. Use snprintf instead.')
- match = Search(r'\b(strcpy|strcat)\b', line)
+ 'Use snprintf instead of sprintf.')
+ match = Search(r'\b(strncpy|STRNCPY)\b', line)
+ if match:
+ error(filename, linenum, 'runtime/printf', 4,
+ 'Use xstrlcpy or snprintf instead of %s (unless this is from Vim)'
+ % match.group(1))
+ match = Search(r'\b(strcpy)\b', line)
+ if match:
+ error(filename, linenum, 'runtime/printf', 4,
+ 'Use xstrlcpy or snprintf instead of %s' % match.group(1))
+ match = Search(r'\b(STRNCAT|strncat|strcat|vim_strcat)\b', line)
if match:
error(filename, linenum, 'runtime/printf', 4,
- 'Almost always, snprintf is better than %s' % match.group(1))
+ 'Use xstrlcat or snprintf instead of %s' % match.group(1))
# Check for suspicious usage of "if" like
# } if (a == b) {
@@ -3434,8 +3462,9 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
# When reading from stdin, the extension is unknown, so no cpplint tests
# should rely on the extension.
if filename != '-' and file_extension not in _valid_extensions:
- sys.stderr.write('Ignoring %s; not a valid file name '
- '(%s)\n' % (filename, ', '.join(_valid_extensions)))
+ sys.stderr.write('Ignoring {}; only linting {} files\n'.format(
+ filename,
+ ', '.join('.{}'.format(ext) for ext in _valid_extensions)))
else:
ProcessFileData(filename, file_extension, lines, Error,
extra_check_functions)
@@ -3565,7 +3594,7 @@ def main():
if __name__ == '__main__':
main()
-# vim: ts=4 sts=4 sw=4
+# vim: ts=4 sts=4 sw=4 foldmarker=â–¶,â–²
# Ignore "too complex" warnings when using pymode.
# pylama:ignore=C901
diff --git a/src/coverity-model.c b/src/coverity-model.c
new file mode 100644
index 0000000000..3c38e4ae4d
--- /dev/null
+++ b/src/coverity-model.c
@@ -0,0 +1,70 @@
+// Coverity Scan model
+//
+// This is a modeling file for Coverity Scan. Modeling helps to avoid false
+// positives.
+//
+// - A model file can't import any header files.
+// - Therefore only some built-in primitives like int, char and void are
+// available but not wchar_t, NULL etc.
+// - Modeling doesn't need full structs and typedefs. Rudimentary structs
+// and similar types are sufficient.
+// - An uninitialized local pointer is not an error. It signifies that the
+// variable could be either NULL or have some data.
+//
+// Coverity Scan doesn't pick up modifications automatically. The model file
+// must be uploaded by an admin in the analysis settings of
+// http://scan.coverity.com/projects/neovim-neovim
+//
+
+// Issue 105985
+//
+// Teach coverity that uv_pipe_open saves fd on success (0 return value)
+// and doesn't save it on failure (return value != 0).
+
+struct uv_pipe_s {
+ int something;
+};
+
+int uv_pipe_open(struct uv_pipe_s *handle, int fd)
+{
+ int result;
+ if (result == 0) {
+ __coverity_escape__(fd);
+ }
+ return result;
+}
+
+// Issue 2422
+//
+// Teach coverity about jemalloc functions, so that it understands
+// they are equivalent to malloc ones.
+
+void *je_malloc(size_t size)
+{
+ return __coverity_alloc__(size);
+}
+
+void je_free(void *ptr)
+{
+ __coverity_free__(ptr);
+}
+
+void *je_calloc(size_t count, size_t size)
+{
+ return je_malloc(count * size);
+}
+
+void *je_realloc(void *ptr, size_t size)
+{
+ je_free(ptr);
+ return je_malloc(size);
+}
+
+// Hint Coverity that adding item to d avoids losing track
+// of the memory allocated for item.
+typedef struct {} dictitem_T;
+typedef struct {} dict_T;
+int tv_dict_add(dict_T *const d, dictitem_T *const item)
+{
+ __coverity_escape__(item);
+}
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index f2b75dca2a..e2f1f16635 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -10,44 +10,72 @@ if(USE_GCOV)
endif()
endif()
+if(WIN32)
+ # tell MinGW compiler to enable wmain
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -municode")
+endif()
+
+set(TOUCHES_DIR ${PROJECT_BINARY_DIR}/touches)
+set(GENERATOR_DIR ${CMAKE_CURRENT_LIST_DIR}/generators)
set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/nvim/auto)
-set(DISPATCH_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gendispatch.lua)
-file(GLOB API_HEADERS api/*.h)
-file(GLOB MSGPACK_RPC_HEADERS msgpack_rpc/*.h)
+set(API_DISPATCH_GENERATOR ${GENERATOR_DIR}/gen_api_dispatch.lua)
+set(API_UI_EVENTS_GENERATOR ${GENERATOR_DIR}/gen_api_ui_events.lua)
set(API_METADATA ${PROJECT_BINARY_DIR}/api_metadata.mpack)
set(FUNCS_DATA ${PROJECT_BINARY_DIR}/funcs_data.mpack)
-set(HEADER_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gendeclarations.lua)
+set(MSGPACK_LUA_C_BINDINGS ${GENERATED_DIR}/msgpack_lua_c_bindings.generated.c)
+set(HEADER_GENERATOR ${GENERATOR_DIR}/gen_declarations.lua)
set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include)
set(GENERATED_API_DISPATCH ${GENERATED_DIR}/api/private/dispatch_wrappers.generated.h)
set(GENERATED_FUNCS_METADATA ${GENERATED_DIR}/api/private/funcs_metadata.generated.h)
+set(GENERATED_UI_EVENTS ${GENERATED_DIR}/ui_events.generated.h)
+set(GENERATED_UI_EVENTS_CALL ${GENERATED_DIR}/ui_events_call.generated.h)
+set(GENERATED_UI_EVENTS_REMOTE ${GENERATED_DIR}/ui_events_remote.generated.h)
+set(GENERATED_UI_EVENTS_BRIDGE ${GENERATED_DIR}/ui_events_bridge.generated.h)
+set(GENERATED_UI_EVENTS_METADATA ${GENERATED_DIR}/api/private/ui_events_metadata.generated.h)
set(GENERATED_EX_CMDS_ENUM ${GENERATED_INCLUDES_DIR}/ex_cmds_enum.generated.h)
set(GENERATED_EX_CMDS_DEFS ${GENERATED_DIR}/ex_cmds_defs.generated.h)
-set(GENERATED_FUNCS_HASH_INPUT ${GENERATED_DIR}/funcs.generated.h.gperf)
set(GENERATED_FUNCS ${GENERATED_DIR}/funcs.generated.h)
set(GENERATED_EVENTS_ENUM ${GENERATED_INCLUDES_DIR}/auevents_enum.generated.h)
set(GENERATED_EVENTS_NAMES_MAP ${GENERATED_DIR}/auevents_name_map.generated.h)
set(GENERATED_OPTIONS ${GENERATED_DIR}/options.generated.h)
-set(EX_CMDS_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/genex_cmds.lua)
-set(FUNCS_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/geneval.lua)
-set(EVENTS_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gen_events.lua)
-set(OPTIONS_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/genoptions.lua)
-set(EVENTS_LIST_FILE ${PROJECT_SOURCE_DIR}/src/nvim/auevents.lua)
-set(EX_CMDS_DEFS_FILE ${PROJECT_SOURCE_DIR}/src/nvim/ex_cmds.lua)
-set(EVAL_DEFS_FILE ${PROJECT_SOURCE_DIR}/src/nvim/eval.lua)
-set(OPTIONS_LIST_FILE ${PROJECT_SOURCE_DIR}/src/nvim/options.lua)
-set(UNICODE_TABLES_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/genunicodetables.lua)
+set(EX_CMDS_GENERATOR ${GENERATOR_DIR}/gen_ex_cmds.lua)
+set(FUNCS_GENERATOR ${GENERATOR_DIR}/gen_eval.lua)
+set(EVENTS_GENERATOR ${GENERATOR_DIR}/gen_events.lua)
+set(OPTIONS_GENERATOR ${GENERATOR_DIR}/gen_options.lua)
+set(UNICODE_TABLES_GENERATOR ${GENERATOR_DIR}/gen_unicode_tables.lua)
set(UNICODE_DIR ${PROJECT_SOURCE_DIR}/unicode)
-file(GLOB UNICODE_FILES ${UNICODE_DIR}/*.txt)
set(GENERATED_UNICODE_TABLES ${GENERATED_DIR}/unicode_tables.generated.h)
+set(VIM_MODULE_FILE ${GENERATED_DIR}/lua/vim_module.generated.h)
+set(VIM_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/src/nvim/lua/vim.lua)
+set(CHAR_BLOB_GENERATOR ${GENERATOR_DIR}/gen_char_blob.lua)
+set(LINT_SUPPRESS_FILE ${PROJECT_BINARY_DIR}/errors.json)
+set(LINT_SUPPRESS_URL_BASE "https://raw.githubusercontent.com/neovim/doc/gh-pages/reports/clint")
+set(LINT_SUPPRESS_URL "${LINT_SUPPRESS_URL_BASE}/errors.json")
+set(LINT_PRG ${PROJECT_SOURCE_DIR}/src/clint.py)
+set(DOWNLOAD_SCRIPT ${PROJECT_SOURCE_DIR}/cmake/Download.cmake)
+set(LINT_SUPPRESSES_ROOT ${PROJECT_BINARY_DIR}/errors)
+set(LINT_SUPPRESSES_URL "${LINT_SUPPRESS_URL_BASE}/errors.tar.gz")
+set(LINT_SUPPRESSES_ARCHIVE ${LINT_SUPPRESSES_ROOT}/errors.tar.gz)
+set(LINT_SUPPRESSES_TOUCH_FILE "${TOUCHES_DIR}/unpacked-clint-errors-archive")
+set(LINT_SUPPRESSES_INSTALL_SCRIPT "${PROJECT_SOURCE_DIR}/cmake/InstallClintErrors.cmake")
+
+file(GLOB UNICODE_FILES ${UNICODE_DIR}/*.txt)
+file(GLOB API_HEADERS api/*.h)
+list(REMOVE_ITEM API_HEADERS ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h)
+file(GLOB MSGPACK_RPC_HEADERS msgpack_rpc/*.h)
include_directories(${GENERATED_DIR})
include_directories(${CACHED_GENERATED_DIR})
include_directories(${GENERATED_INCLUDES_DIR})
+file(MAKE_DIRECTORY ${TOUCHES_DIR})
file(MAKE_DIRECTORY ${GENERATED_DIR})
file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR})
+file(MAKE_DIRECTORY ${LINT_SUPPRESSES_ROOT})
+file(MAKE_DIRECTORY ${LINT_SUPPRESSES_ROOT}/src)
-file(GLOB NEOVIM_SOURCES *.c)
+file(GLOB NVIM_SOURCES *.c)
+file(GLOB NVIM_HEADERS *.h)
foreach(subdir
os
@@ -57,6 +85,7 @@ foreach(subdir
tui
event
eval
+ lua
)
if(${subdir} MATCHES "tui" AND NOT FEAT_TUI)
continue()
@@ -65,18 +94,21 @@ foreach(subdir
file(MAKE_DIRECTORY ${GENERATED_DIR}/${subdir})
file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/${subdir})
file(GLOB sources ${subdir}/*.c)
- list(APPEND NEOVIM_SOURCES ${sources})
+ file(GLOB headers ${subdir}/*.h)
+ list(APPEND NVIM_SOURCES ${sources})
+ list(APPEND NVIM_HEADERS ${headers})
endforeach()
-file(GLOB_RECURSE NEOVIM_HEADERS *.h)
file(GLOB UNIT_TEST_FIXTURES ${PROJECT_SOURCE_DIR}/test/unit/fixtures/*.c)
# Sort file lists to ensure generated files are created in the same order from
# build to build.
-list(SORT NEOVIM_SOURCES)
-list(SORT NEOVIM_HEADERS)
+list(SORT NVIM_SOURCES)
+list(SORT NVIM_HEADERS)
+
+list(APPEND LINT_NVIM_SOURCES ${NVIM_SOURCES} ${NVIM_HEADERS})
-foreach(sfile ${NEOVIM_SOURCES})
+foreach(sfile ${NVIM_SOURCES})
get_filename_component(f ${sfile} NAME)
if(${f} MATCHES "^(regexp_nfa.c)$")
list(APPEND to_remove ${sfile})
@@ -84,13 +116,15 @@ foreach(sfile ${NEOVIM_SOURCES})
if(WIN32 AND ${f} MATCHES "^(pty_process_unix.c)$")
list(APPEND to_remove ${sfile})
endif()
+ if(NOT WIN32 AND ${f} MATCHES "^(pty_process_win.c)$")
+ list(APPEND to_remove ${sfile})
+ endif()
endforeach()
-list(REMOVE_ITEM NEOVIM_SOURCES ${to_remove})
+list(REMOVE_ITEM NVIM_SOURCES ${to_remove})
# Legacy files that do not yet pass -Wconversion.
set(CONV_SOURCES
- buffer.c
diff.c
edit.c
eval.c
@@ -105,12 +139,13 @@ set(CONV_SOURCES
screen.c
search.c
spell.c
+ spellfile.c
syntax.c
tag.c
window.c)
foreach(sfile ${CONV_SOURCES})
- if(NOT EXISTS "${PROJECT_SOURCE_DIR}/src/nvim/${sfile}")
+ if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/${sfile}")
message(FATAL_ERROR "${sfile} doesn't exist (it was added to CONV_SOURCES)")
endif()
endforeach()
@@ -144,7 +179,7 @@ if(CLANG_ASAN_UBSAN OR CLANG_MSAN OR CLANG_TSAN)
endif()
get_directory_property(gen_includes INCLUDE_DIRECTORIES)
-foreach(gen_include ${gen_includes})
+foreach(gen_include ${gen_includes} ${LUA_PREFERRED_INCLUDE_DIRS})
list(APPEND gen_cflags "-I${gen_include}")
endforeach()
string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
@@ -152,12 +187,28 @@ separate_arguments(C_FLAGS_ARRAY UNIX_COMMAND ${CMAKE_C_FLAGS})
separate_arguments(C_FLAGS_${build_type}_ARRAY UNIX_COMMAND ${CMAKE_C_FLAGS_${build_type}})
set(gen_cflags ${gen_cflags} ${C_FLAGS_${build_type}_ARRAY} ${C_FLAGS_ARRAY})
-foreach(sfile ${NEOVIM_SOURCES}
- "${PROJECT_SOURCE_DIR}/src/nvim/regexp_nfa.c"
- ${GENERATED_API_DISPATCH})
+function(get_preproc_output varname iname)
+ if(MSVC)
+ set(${varname} /P /Fi${iname} PARENT_SCOPE)
+ else()
+ set(${varname} -E -o ${iname} PARENT_SCOPE)
+ endif()
+endfunction()
+
+# NVIM_GENERATED_FOR_HEADERS: generated headers to be included in headers
+# NVIM_GENERATED_FOR_SOURCES: generated headers to be included in sources
+# NVIM_GENERATED_SOURCES: generated source files
+# These lists must be mutually exclusive.
+foreach(sfile ${NVIM_SOURCES}
+ "${CMAKE_CURRENT_LIST_DIR}/regexp_nfa.c"
+ ${GENERATED_API_DISPATCH}
+ "${GENERATED_UI_EVENTS_CALL}"
+ "${GENERATED_UI_EVENTS_REMOTE}"
+ "${GENERATED_UI_EVENTS_BRIDGE}"
+ )
get_filename_component(full_d ${sfile} PATH)
- file(RELATIVE_PATH d "${PROJECT_SOURCE_DIR}/src/nvim" "${full_d}")
- if(${d} MATCHES "^([.][.]|auto/)")
+ file(RELATIVE_PATH d "${CMAKE_CURRENT_LIST_DIR}" "${full_d}")
+ if(${d} MATCHES "^[.][.]|auto/")
file(RELATIVE_PATH d "${GENERATED_DIR}" "${full_d}")
endif()
get_filename_component(f ${sfile} NAME)
@@ -166,26 +217,22 @@ foreach(sfile ${NEOVIM_SOURCES}
set(f "${d}/${f}")
set(r "${d}/${r}")
endif()
- set(gf1 "${GENERATED_DIR}/${r}.c.generated.h")
- set(gf2 "${GENERATED_INCLUDES_DIR}/${r}.h.generated.h")
- set(gf3 "${GENERATED_DIR}/${r}.i")
+ set(gf_c_h "${GENERATED_DIR}/${r}.c.generated.h")
+ set(gf_h_h "${GENERATED_INCLUDES_DIR}/${r}.h.generated.h")
+ set(gf_i "${GENERATED_DIR}/${r}.i")
- if(MSVC)
- set(PREPROC_OUTPUT /P /Fi${gf3})
- else()
- set(PREPROC_OUTPUT -E -o ${gf3})
- endif()
+ get_preproc_output(PREPROC_OUTPUT ${gf_i})
add_custom_command(
- OUTPUT "${gf1}" "${gf2}"
+ OUTPUT "${gf_c_h}" "${gf_h_h}"
COMMAND ${CMAKE_C_COMPILER} ${sfile} ${PREPROC_OUTPUT} ${gen_cflags} ${C_FLAGS_ARRAY}
- COMMAND "${LUA_PRG}" "${HEADER_GENERATOR}" "${sfile}" "${gf1}" "${gf2}" "${gf3}"
+ COMMAND "${LUA_PRG}" "${HEADER_GENERATOR}" "${sfile}" "${gf_c_h}" "${gf_h_h}" "${gf_i}"
DEPENDS "${HEADER_GENERATOR}" "${sfile}"
)
- list(APPEND NEOVIM_GENERATED_SOURCES "${gf1}")
- list(APPEND NEOVIM_GENERATED_SOURCES "${gf2}")
+ list(APPEND NVIM_GENERATED_FOR_SOURCES "${gf_c_h}")
+ list(APPEND NVIM_GENERATED_FOR_HEADERS "${gf_h_h}")
if(${d} MATCHES "^api$" AND NOT ${f} MATCHES "^api/helpers.c$")
- list(APPEND API_HEADERS ${gf2})
+ list(APPEND API_HEADERS ${gf_h_h})
endif()
endforeach()
@@ -198,33 +245,74 @@ add_custom_command(OUTPUT ${GENERATED_UNICODE_TABLES}
${UNICODE_FILES}
)
-add_custom_command(OUTPUT ${GENERATED_API_DISPATCH} ${GENERATED_FUNCS_METADATA}
- ${API_METADATA}
- COMMAND ${LUA_PRG} ${DISPATCH_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}
- ${API_HEADERS} ${GENERATED_API_DISPATCH}
+add_custom_command(
+ OUTPUT ${GENERATED_API_DISPATCH} ${GENERATED_FUNCS_METADATA}
+ ${API_METADATA} ${MSGPACK_LUA_C_BINDINGS}
+ COMMAND ${LUA_PRG} ${API_DISPATCH_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}
+ ${GENERATED_API_DISPATCH}
${GENERATED_FUNCS_METADATA} ${API_METADATA}
+ ${MSGPACK_LUA_C_BINDINGS}
+ ${API_HEADERS}
DEPENDS
${API_HEADERS}
${MSGPACK_RPC_HEADERS}
- ${DISPATCH_GENERATOR}
+ ${API_DISPATCH_GENERATOR}
${CMAKE_CURRENT_LIST_DIR}/api/dispatch_deprecated.lua
)
-list(APPEND NEOVIM_GENERATED_SOURCES
- "${PROJECT_BINARY_DIR}/config/auto/pathdef.c"
- "${GENERATED_API_DISPATCH}"
+add_custom_command(
+ OUTPUT ${VIM_MODULE_FILE}
+ COMMAND ${LUA_PRG} ${CHAR_BLOB_GENERATOR} ${VIM_MODULE_SOURCE}
+ ${VIM_MODULE_FILE} vim_module
+ DEPENDS
+ ${CHAR_BLOB_GENERATOR}
+ ${VIM_MODULE_SOURCE}
+)
+
+list(APPEND NVIM_GENERATED_SOURCES
+ "${MSGPACK_LUA_C_BINDINGS}"
+)
+
+add_custom_command(
+ OUTPUT ${GENERATED_UI_EVENTS}
+ ${GENERATED_UI_EVENTS_CALL}
+ ${GENERATED_UI_EVENTS_REMOTE}
+ ${GENERATED_UI_EVENTS_BRIDGE}
+ ${GENERATED_UI_EVENTS_METADATA}
+ COMMAND ${LUA_PRG} ${API_UI_EVENTS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}
+ ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h
+ ${GENERATED_UI_EVENTS}
+ ${GENERATED_UI_EVENTS_CALL}
+ ${GENERATED_UI_EVENTS_REMOTE}
+ ${GENERATED_UI_EVENTS_BRIDGE}
+ ${GENERATED_UI_EVENTS_METADATA}
+ DEPENDS
+ ${API_UI_EVENTS_GENERATOR}
+ ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h
+)
+
+list(APPEND NVIM_GENERATED_FOR_HEADERS
"${GENERATED_EX_CMDS_ENUM}"
- "${GENERATED_EX_CMDS_DEFS}"
"${GENERATED_EVENTS_ENUM}"
+)
+
+list(APPEND NVIM_GENERATED_FOR_SOURCES
+ "${GENERATED_API_DISPATCH}"
+ "${GENERATED_EX_CMDS_DEFS}"
"${GENERATED_EVENTS_NAMES_MAP}"
"${GENERATED_OPTIONS}"
"${GENERATED_UNICODE_TABLES}"
+ "${VIM_MODULE_FILE}"
+)
+
+list(APPEND NVIM_GENERATED_SOURCES
+ "${PROJECT_BINARY_DIR}/config/auto/pathdef.c"
)
add_custom_command(OUTPUT ${GENERATED_EX_CMDS_ENUM} ${GENERATED_EX_CMDS_DEFS}
COMMAND ${LUA_PRG} ${EX_CMDS_GENERATOR}
- ${PROJECT_SOURCE_DIR}/src/nvim ${GENERATED_INCLUDES_DIR} ${GENERATED_DIR}
- DEPENDS ${EX_CMDS_GENERATOR} ${EX_CMDS_DEFS_FILE}
+ ${CMAKE_CURRENT_LIST_DIR} ${GENERATED_INCLUDES_DIR} ${GENERATED_DIR}
+ DEPENDS ${EX_CMDS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/ex_cmds.lua
)
if(NOT GPERF_PRG)
@@ -232,26 +320,34 @@ if(NOT GPERF_PRG)
endif()
add_custom_command(OUTPUT ${GENERATED_FUNCS} ${FUNCS_DATA}
COMMAND ${LUA_PRG} ${FUNCS_GENERATOR}
- ${PROJECT_SOURCE_DIR}/src/nvim ${GENERATED_DIR} ${API_METADATA} ${FUNCS_DATA}
+ ${CMAKE_CURRENT_LIST_DIR} ${GENERATED_DIR} ${API_METADATA} ${FUNCS_DATA}
COMMAND ${GPERF_PRG}
- ${GENERATED_FUNCS_HASH_INPUT} --output-file=${GENERATED_FUNCS}
- DEPENDS ${FUNCS_GENERATOR} ${EVAL_DEFS_FILE} ${API_METADATA}
+ ${GENERATED_DIR}/funcs.generated.h.gperf --output-file=${GENERATED_FUNCS}
+ DEPENDS ${FUNCS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/eval.lua ${API_METADATA}
)
-list(APPEND NEOVIM_GENERATED_SOURCES
+list(APPEND NVIM_GENERATED_FOR_SOURCES
"${GENERATED_FUNCS}")
add_custom_command(OUTPUT ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP}
COMMAND ${LUA_PRG} ${EVENTS_GENERATOR}
- ${PROJECT_SOURCE_DIR}/src/nvim ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP}
- DEPENDS ${EVENTS_GENERATOR} ${EVENTS_LIST_FILE}
+ ${CMAKE_CURRENT_LIST_DIR} ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP}
+ DEPENDS ${EVENTS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/auevents.lua
)
add_custom_command(OUTPUT ${GENERATED_OPTIONS}
COMMAND ${LUA_PRG} ${OPTIONS_GENERATOR}
- ${PROJECT_SOURCE_DIR}/src/nvim ${GENERATED_OPTIONS}
- DEPENDS ${OPTIONS_GENERATOR} ${OPTIONS_LIST_FILE}
+ ${CMAKE_CURRENT_LIST_DIR} ${GENERATED_OPTIONS}
+ DEPENDS ${OPTIONS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/options.lua
)
+# NVIM_GENERATED_FOR_SOURCES and NVIM_GENERATED_FOR_HEADERS must be mutually exclusive.
+foreach(hfile ${NVIM_GENERATED_FOR_HEADERS})
+ list(FIND NVIM_GENERATED_FOR_SOURCES ${hfile} hfile_idx)
+ if(NOT ${hfile_idx} EQUAL -1)
+ message(FATAL_ERROR "File included in both NVIM_GENERATED_FOR_HEADERS and NVIM_GENERATED_FOR_SOURCES")
+ endif()
+endforeach()
+
# Our dependencies come first.
if (LibIntl_FOUND)
@@ -262,6 +358,10 @@ if(Iconv_LIBRARIES)
list(APPEND NVIM_LINK_LIBRARIES ${Iconv_LIBRARIES})
endif()
+if(WIN32)
+ list(APPEND NVIM_LINK_LIBRARIES ${WINPTY_LIBRARIES})
+endif()
+
# Put these last on the link line, since multiple things may depend on them.
list(APPEND NVIM_LINK_LIBRARIES
${LIBUV_LIBRARIES}
@@ -279,31 +379,120 @@ if(UNIX)
)
endif()
-set(NVIM_EXEC_LINK_LIBRARIES ${NVIM_LINK_LIBRARIES})
+set(NVIM_EXEC_LINK_LIBRARIES ${NVIM_LINK_LIBRARIES} ${LUA_PREFERRED_LIBRARIES})
+
+if(CMAKE_VERSION VERSION_LESS "2.8.8")
+ # Use include_directories() because INCLUDE_DIRECTORIES target property
+ # is not supported
+ include_directories(${LUA_PREFERRED_INCLUDE_DIRS})
+endif()
# Don't use jemalloc in the unit test library.
if(JEMALLOC_FOUND)
list(APPEND NVIM_EXEC_LINK_LIBRARIES ${JEMALLOC_LIBRARIES})
endif()
-add_executable(nvim ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES}
- ${NEOVIM_HEADERS})
+add_executable(nvim ${NVIM_GENERATED_FOR_SOURCES} ${NVIM_GENERATED_FOR_HEADERS}
+ ${NVIM_GENERATED_SOURCES} ${NVIM_SOURCES} ${NVIM_HEADERS})
target_link_libraries(nvim ${NVIM_EXEC_LINK_LIBRARIES})
install_helper(TARGETS nvim)
+set_property(TARGET nvim APPEND PROPERTY
+ INCLUDE_DIRECTORIES ${LUA_PREFERRED_INCLUDE_DIRS})
+
if(WIN32)
- # Copy DLLs to bin/ and install them along with nvim
- add_custom_target(nvim_dll_deps ALL DEPENDS nvim
+ # Copy DLLs and third-party tools to bin/ and install them along with nvim
+ add_custom_target(nvim_runtime_deps ALL
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+ install(DIRECTORY ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+ add_custom_target(nvim_dll_deps DEPENDS nvim
COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/windows_runtime_deps
COMMAND ${CMAKE_COMMAND}
"-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}"
-DBINARY="${PROJECT_BINARY_DIR}/bin/nvim${CMAKE_EXECUTABLE_SUFFIX}"
-DDST=${PROJECT_BINARY_DIR}/windows_runtime_deps
- -P ${PROJECT_SOURCE_DIR}/cmake/WindowsDllCopy.cmake
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_BINARY_DIR}/windows_runtime_deps/
- ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
- install(DIRECTORY ${PROJECT_BINARY_DIR}/windows_runtime_deps/
- DESTINATION ${CMAKE_INSTALL_BINDIR})
+ -P ${PROJECT_SOURCE_DIR}/cmake/WindowsDllCopy.cmake)
+ add_dependencies(nvim_runtime_deps nvim_dll_deps)
+
+ add_custom_target(external_blobs
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/windows_runtime_deps/platforms
+
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/ca-bundle.crt" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/cat.exe" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/curl.exe" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/diff.exe" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/tee.exe" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/tidy.exe" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/win32yank.exe" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/winpty-agent.exe" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/D3Dcompiler_47.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/libEGL.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/libgcc_s_dw2-1.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/libGLESV2.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/libstdc++-6.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/libwinpthread-1.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/nvim-qt.exe" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/Qt5Core.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/Qt5Gui.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/Qt5Network.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/Qt5Svg.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/Qt5Widgets.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/winpty.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+
+ COMMAND ${CMAKE_COMMAND} -E copy "${DEPS_PREFIX}/bin/platforms/qwindows.dll" ${PROJECT_BINARY_DIR}/windows_runtime_deps/platforms/
+ )
+ add_dependencies(nvim_runtime_deps external_blobs)
+endif()
+
+add_library(
+ libnvim
+ STATIC
+ EXCLUDE_FROM_ALL
+ ${NVIM_SOURCES} ${NVIM_GENERATED_SOURCES}
+ ${NVIM_HEADERS} ${NVIM_GENERATED_FOR_SOURCES} ${NVIM_GENERATED_FOR_HEADERS}
+)
+set_property(TARGET libnvim APPEND PROPERTY
+ INCLUDE_DIRECTORIES ${LUA_PREFERRED_INCLUDE_DIRS})
+set_target_properties(
+ libnvim
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON
+ OUTPUT_NAME nvim
+)
+set_property(
+ TARGET libnvim
+ APPEND_STRING PROPERTY COMPILE_FLAGS " -DMAKE_LIB "
+)
+
+if(LUAJIT_FOUND)
+ set(NVIM_TEST_LINK_LIBRARIES ${NVIM_LINK_LIBRARIES} ${LUAJIT_LIBRARIES})
+ add_library(
+ nvim-test
+ MODULE
+ EXCLUDE_FROM_ALL
+ ${NVIM_SOURCES} ${NVIM_GENERATED_SOURCES}
+ ${NVIM_HEADERS} ${NVIM_GENERATED_FOR_SOURCES} ${NVIM_GENERATED_FOR_HEADERS}
+ ${UNIT_TEST_FIXTURES}
+ )
+ target_link_libraries(nvim-test ${NVIM_TEST_LINK_LIBRARIES})
+ target_link_libraries(libnvim ${NVIM_TEST_LINK_LIBRARIES})
+ set_property(
+ TARGET nvim-test
+ APPEND PROPERTY INCLUDE_DIRECTORIES ${LUAJIT_INCLUDE_DIRS}
+ )
+ set_target_properties(
+ nvim-test
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON
+ )
+ set_property(
+ TARGET nvim-test
+ APPEND_STRING PROPERTY COMPILE_FLAGS " -DUNIT_TESTING "
+ )
endif()
if(CLANG_ASAN_UBSAN)
@@ -330,17 +519,111 @@ elseif(CLANG_TSAN)
set_property(TARGET nvim APPEND_STRING PROPERTY LINK_FLAGS "-fsanitize=thread ")
endif()
-add_library(libnvim STATIC EXCLUDE_FROM_ALL ${NEOVIM_GENERATED_SOURCES}
- ${NEOVIM_SOURCES} ${NEOVIM_HEADERS})
-target_link_libraries(libnvim ${NVIM_LINK_LIBRARIES})
-set_target_properties(libnvim PROPERTIES
- POSITION_INDEPENDENT_CODE ON
- OUTPUT_NAME nvim)
-set_property(TARGET libnvim APPEND_STRING PROPERTY COMPILE_FLAGS " -DMAKE_LIB ")
-
-add_library(nvim-test MODULE EXCLUDE_FROM_ALL ${NEOVIM_GENERATED_SOURCES}
- ${NEOVIM_SOURCES} ${UNIT_TEST_FIXTURES} ${NEOVIM_HEADERS})
-target_link_libraries(nvim-test ${NVIM_LINK_LIBRARIES})
-set_property(TARGET nvim-test APPEND_STRING PROPERTY COMPILE_FLAGS -DUNIT_TESTING)
+function(get_test_target prefix sfile relative_path_var target_var)
+ get_filename_component(full_d "${sfile}" PATH)
+ file(RELATIVE_PATH d "${PROJECT_SOURCE_DIR}/src/nvim" "${full_d}")
+ if(d MATCHES "^[.][.]")
+ file(RELATIVE_PATH d "${GENERATED_DIR}" "${full_d}")
+ endif()
+ get_filename_component(r "${sfile}" NAME)
+ if(NOT d MATCHES "^[.]?$")
+ set(r "${d}/${r}")
+ endif()
+ string(REGEX REPLACE "[/.]" "-" suffix "${r}")
+ set(${relative_path_var} ${r} PARENT_SCOPE)
+ if(prefix STREQUAL "")
+ set(${target_var} "${suffix}" PARENT_SCOPE)
+ else()
+ set(${target_var} "${prefix}-${suffix}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+set(NO_SINGLE_CHECK_HEADERS
+ os/win_defs.h
+ os/pty_process_win.h
+ regexp_defs.h
+ syntax_defs.h
+ terminal.h
+ undo.h
+ undo_defs.h
+)
+foreach(hfile ${NVIM_HEADERS})
+ get_test_target(test-includes "${hfile}" relative_path texe)
+
+ if(NOT ${hfile} MATCHES "[.](c|in)[.]h$")
+ set(tsource "${GENERATED_DIR}/${relative_path}.test-include.c")
+ write_file("${tsource}" "#include \"${hfile}\"\nint main(int argc, char **argv) { return 0; }")
+ add_executable(
+ ${texe}
+ EXCLUDE_FROM_ALL
+ ${tsource} ${NVIM_HEADERS} ${NVIM_GENERATED_FOR_HEADERS})
+ set_property(
+ TARGET ${texe}
+ APPEND PROPERTY INCLUDE_DIRECTORIES ${LUA_PREFERRED_INCLUDE_DIRS}
+ )
+
+ list(FIND NO_SINGLE_CHECK_HEADERS "${relative_path}" hfile_exclude_idx)
+ if(${hfile_exclude_idx} EQUAL -1)
+ list(APPEND HEADER_CHECK_TARGETS ${texe})
+ endif()
+ endif()
+endforeach()
+add_custom_target(check-single-includes DEPENDS ${HEADER_CHECK_TARGETS})
+
+function(add_download output url allow_failure)
+ add_custom_command(
+ OUTPUT "${output}"
+ COMMAND
+ ${CMAKE_COMMAND}
+ -DURL=${url} -DFILE=${output}
+ -DALLOW_FAILURE=${allow_failure}
+ -P ${DOWNLOAD_SCRIPT}
+ DEPENDS ${DOWNLOAD_SCRIPT}
+ )
+endfunction()
+
+add_download(${LINT_SUPPRESSES_ARCHIVE} ${LINT_SUPPRESSES_URL} off)
+
+add_custom_command(
+ OUTPUT ${LINT_SUPPRESSES_TOUCH_FILE}
+ WORKING_DIRECTORY ${LINT_SUPPRESSES_ROOT}/src
+ COMMAND ${CMAKE_COMMAND} -E tar xfz ${LINT_SUPPRESSES_ARCHIVE}
+ COMMAND
+ ${CMAKE_COMMAND}
+ -DTARGET=${LINT_SUPPRESSES_ROOT}
+ -P ${LINT_SUPPRESSES_INSTALL_SCRIPT}
+ COMMAND ${CMAKE_COMMAND} -E touch ${LINT_SUPPRESSES_TOUCH_FILE}
+ DEPENDS
+ ${LINT_SUPPRESSES_ARCHIVE} ${LINT_SUPPRESSES_INSTALL_SCRIPT}
+)
+
+add_download(${LINT_SUPPRESS_FILE} ${LINT_SUPPRESS_URL} off)
+
+set(LINT_NVIM_REL_SOURCES)
+foreach(sfile ${LINT_NVIM_SOURCES})
+ get_test_target("" "${sfile}" r suffix)
+ set(suppress_file ${LINT_SUPPRESSES_ROOT}/${suffix}.json)
+ set(suppress_url "${LINT_SUPPRESS_URL_BASE}/${suffix}.json")
+ set(rsfile src/nvim/${r})
+ set(touch_file "${TOUCHES_DIR}/ran-clint-${suffix}")
+ add_custom_command(
+ OUTPUT ${touch_file}
+ COMMAND ${LINT_PRG} --suppress-errors=${suppress_file} ${rsfile}
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ COMMAND ${CMAKE_COMMAND} -E touch ${touch_file}
+ DEPENDS ${LINT_PRG} ${sfile} ${LINT_SUPPRESSES_TOUCH_FILE}
+ )
+ list(APPEND LINT_TARGETS ${touch_file})
+ list(APPEND LINT_NVIM_REL_SOURCES ${rsfile})
+endforeach()
+add_custom_target(clint DEPENDS ${LINT_TARGETS})
+
+add_custom_target(
+ clint-full
+ COMMAND
+ ${LINT_PRG} --suppress-errors=${LINT_SUPPRESS_FILE} ${LINT_NVIM_REL_SOURCES}
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ DEPENDS ${LINT_PRG} ${LINT_NVIM_SOURCES} ${LINT_SUPPRESS_FILE}
+)
add_subdirectory(po)
diff --git a/src/nvim/README.md b/src/nvim/README.md
index f16c6de12f..0caf71e2c5 100644
--- a/src/nvim/README.md
+++ b/src/nvim/README.md
@@ -1,23 +1,43 @@
-## Source code overview
+Nvim core source
+================
-Since Neovim has inherited most code from Vim, some information in [its
-README](https://raw.githubusercontent.com/vim/vim/master/src/README.txt) still
-applies.
+Module-specific details are documented at the top of each module (`terminal.c`,
+`screen.c`, ...).
-This document aims to give a high level overview of how Neovim works internally,
-focusing on parts that are different from Vim. Currently this is still a work in
-progress, especially because I have avoided adding too many details about parts
-that are constantly changing. As the code becomes more organized and stable,
-this document will be updated to reflect the changes.
+See `:help development` for more guidelines.
-If you are looking for module-specific details, it is best to read the source
-code. Some files are extensively commented at the top (e.g. terminal.c,
-screen.c).
+Logs
+----
-### Top-level program loops
+Low-level log messages sink to `$NVIM_LOG_FILE`.
-First let's understand what a Vim-like program does by analyzing the workflow of
-a typical editing session:
+You can use `LOG_CALLSTACK();` anywhere in the source to log the current
+stacktrace. To log in an alternate file, e.g. stderr, use
+`LOG_CALLSTACK_TO_FILE(FILE*)`. (Currently Linux-only.)
+
+UI events are logged at level 0 (`DEBUG_LOG_LEVEL`).
+
+ rm -rf build/
+ make CMAKE_EXTRA_FLAGS="-DMIN_LOG_LEVEL=0"
+
+Filename conventions
+--------------------
+
+The source files use extensions to hint about their purpose.
+
+- `*.c`, `*.generated.c` - full C files, with all includes, etc.
+- `*.c.h` - parametrized C files, contain all necessary includes, but require
+ defining macros before actually using. Example: `typval_encode.c.h`
+- `*.h` - full headers, with all includes. Does *not* apply to `*.generated.h`.
+- `*.h.generated.h` - exported functions’ declarations.
+- `*.c.generated.h` - static functions’ declarations.
+
+Nvim lifecycle
+--------------
+
+Following describes how Nvim processes input.
+
+Consider a typical Vim-like editing session:
01. Vim dispays the welcome screen
02. User types: `:`
@@ -41,16 +61,14 @@ a typical editing session:
21. User types: `word<ESC>`
22. Vim inserts "word" at the beginning and returns to normal mode
-Note that we have split user actions into sequences of inputs that change the
-state of the editor. While there's no documentation about a "g command
-mode" (step 16), internally it is implemented similarly to "operator-pending
-mode".
+Note that we split user actions into sequences of inputs that change the state
+of the editor. While there's no documentation about a "g command mode" (step
+16), internally it is implemented similarly to "operator-pending mode".
-From this we can see that Vim has the behavior of a input-driven state
-machine (more specifically, a pushdown automaton since it requires a stack for
+From this we can see that Vim has the behavior of an input-driven state machine
+(more specifically, a pushdown automaton since it requires a stack for
transitioning back from states). Assuming each state has a callback responsible
-for handling keys, this pseudocode (a python-like language) shows a good
-representation of the main program loop:
+for handling keys, this pseudocode represents the main program loop:
```py
def state_enter(state_callback, data):
@@ -126,12 +144,11 @@ def insert_state(data, key):
return true
```
-While the actual code is much more complicated, the above gives an idea of how
-Neovim is organized internally. Some states like the `g_command_state` or
-`get_operator_count_state` do not have a dedicated `state_enter` callback, but
-are implicitly embedded into other states (this will change later as we continue
-the refactoring effort). To start reading the actual code, here's the
-recommended order:
+The above gives an idea of how Nvim is organized internally. Some states like
+the `g_command_state` or `get_operator_count_state` do not have a dedicated
+`state_enter` callback, but are implicitly embedded into other states (this
+will change later as we continue the refactoring effort). To start reading the
+actual code, here's the recommended order:
1. `state_enter()` function (state.c). This is the actual program loop,
note that a `VimState` structure is used, which contains function pointers
@@ -152,16 +169,17 @@ modes managed by the `state_enter` loop:
- insert mode: `insert_{enter,check,execute}()`(`edit.c`)
- terminal mode: `terminal_{enter,execute}()`(`terminal.c`)
-### Async event support
+Async event support
+-------------------
-One of the features Neovim added is the support for handling arbitrary
+One of the features Nvim added is the support for handling arbitrary
asynchronous events, which can include:
-- msgpack-rpc requests
+- RPC requests
- job control callbacks
-- timers (not implemented yet but the support code is already there)
+- timers
-Neovim implements this functionality by entering another event loop while
+Nvim implements this functionality by entering another event loop while
waiting for characters, so instead of:
```py
@@ -171,7 +189,7 @@ def state_enter(state_callback, data):
while state_callback(data, key) # invoke the callback for the current state
```
-Neovim program loop is more like:
+Nvim program loop is more like:
```py
def state_enter(state_callback, data):
@@ -182,9 +200,9 @@ def state_enter(state_callback, data):
where `event` is something the operating system delivers to us, including (but
not limited to) user input. The `read_next_event()` part is internally
-implemented by libuv, the platform layer used by Neovim.
+implemented by libuv, the platform layer used by Nvim.
-Since Neovim inherited its code from Vim, the states are not prepared to receive
+Since Nvim inherited its code from Vim, the states are not prepared to receive
"arbitrary events", so we use a special key to represent those (When a state
receives an "arbitrary event", it normally doesn't do anything other update the
screen).
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index eaaae943d2..82de8fd4a2 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
// Much of this code was adapted from 'if_py_both.h' from the original
// vim source
#include <stdbool.h>
@@ -32,6 +35,7 @@
/// @param[out] err Error details, if any
/// @return Line count
Integer nvim_buf_line_count(Buffer buffer, Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -61,7 +65,7 @@ String buffer_get_line(Buffer buffer, Integer index, Error *err)
index = convert_index(index);
Array slice = nvim_buf_get_lines(0, buffer, index, index+1, true, err);
- if (!err->set && slice.size) {
+ if (!ERROR_SET(err) && slice.size) {
rv = slice.items[0].data.string;
}
@@ -132,7 +136,6 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer,
return nvim_buf_get_lines(0, buffer, start , end, false, err);
}
-
/// Retrieves a line range from the buffer
///
/// Indexing is zero-based, end-exclusive. Negative indices are interpreted
@@ -154,6 +157,7 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id,
Integer end,
Boolean strict_indexing,
Error *err)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -167,7 +171,7 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id,
end = normalize_index(buf, end, &oob);
if (strict_indexing && oob) {
- api_set_error(err, Validation, _("Index out of bounds"));
+ api_set_error(err, kErrorTypeValidation, "Index out of bounds");
return rv;
}
@@ -183,7 +187,7 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id,
int64_t lnum = start + (int64_t)i;
if (lnum > LONG_MAX) {
- api_set_error(err, Validation, _("Line index is too high"));
+ api_set_error(err, kErrorTypeValidation, "Line index is too high");
goto end;
}
@@ -191,7 +195,7 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id,
Object str = STRING_OBJ(cstr_to_string(bufstr));
// Vim represents NULs as NLs, but this may confuse clients.
- if (channel_id != INTERNAL_CALL) {
+ if (channel_id != VIML_INTERNAL_CALL) {
strchrsub(str.data.string.data, '\n', '\0');
}
@@ -199,7 +203,7 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id,
}
end:
- if (err->set) {
+ if (ERROR_SET(err)) {
for (size_t i = 0; i < rv.size; i++) {
xfree(rv.items[i].data.string.data);
}
@@ -266,6 +270,7 @@ void nvim_buf_set_lines(uint64_t channel_id,
Boolean strict_indexing,
ArrayOf(String) replacement, // NOLINT
Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -278,54 +283,58 @@ void nvim_buf_set_lines(uint64_t channel_id,
end = normalize_index(buf, end, &oob);
if (strict_indexing && oob) {
- api_set_error(err, Validation, _("Index out of bounds"));
+ api_set_error(err, kErrorTypeValidation, "Index out of bounds");
return;
}
if (start > end) {
api_set_error(err,
- Validation,
- _("Argument \"start\" is higher than \"end\""));
+ kErrorTypeValidation,
+ "Argument \"start\" is higher than \"end\"");
return;
}
- buf_T *save_curbuf = NULL;
+ for (size_t i = 0; i < replacement.size; i++) {
+ if (replacement.items[i].type != kObjectTypeString) {
+ api_set_error(err,
+ kErrorTypeValidation,
+ "All items in the replacement array must be strings");
+ return;
+ }
+ // Disallow newlines in the middle of the line.
+ if (channel_id != VIML_INTERNAL_CALL) {
+ const String l = replacement.items[i].data.string;
+ if (memchr(l.data, NL, l.size)) {
+ api_set_error(err, kErrorTypeValidation,
+ "String cannot contain newlines");
+ return;
+ }
+ }
+ }
+
win_T *save_curwin = NULL;
tabpage_T *save_curtab = NULL;
size_t new_len = replacement.size;
size_t old_len = (size_t)(end - start);
- ssize_t extra = 0; // lines added to text, can be negative
+ ptrdiff_t extra = 0; // lines added to text, can be negative
char **lines = (new_len != 0) ? xcalloc(new_len, sizeof(char *)) : NULL;
for (size_t i = 0; i < new_len; i++) {
- if (replacement.items[i].type != kObjectTypeString) {
- api_set_error(err,
- Validation,
- _("All items in the replacement array must be strings"));
- goto end;
- }
-
- String l = replacement.items[i].data.string;
+ const String l = replacement.items[i].data.string;
- // Fill lines[i] with l's contents. Disallow newlines in the middle of a
- // line and convert NULs to newlines to avoid truncation.
- lines[i] = xmallocz(l.size);
- for (size_t j = 0; j < l.size; j++) {
- if (l.data[j] == '\n' && channel_id != INTERNAL_CALL) {
- api_set_error(err, Exception, _("string cannot contain newlines"));
- new_len = i + 1;
- goto end;
- }
- lines[i][j] = (char) (l.data[j] == '\0' ? '\n' : l.data[j]);
- }
+ // Fill lines[i] with l's contents. Convert NULs to newlines as required by
+ // NL-used-for-NUL.
+ lines[i] = xmemdupz(l.data, l.size);
+ memchrsub(lines[i], NUL, NL, l.size);
}
try_start();
+ bufref_T save_curbuf = { NULL, 0, 0 };
switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
if (u_save((linenr_T)(start - 1), (linenr_T)end) == FAIL) {
- api_set_error(err, Exception, _("Failed to save undo information"));
+ api_set_error(err, kErrorTypeException, "Failed to save undo information");
goto end;
}
@@ -335,13 +344,13 @@ void nvim_buf_set_lines(uint64_t channel_id,
size_t to_delete = (new_len < old_len) ? (size_t)(old_len - new_len) : 0;
for (size_t i = 0; i < to_delete; i++) {
if (ml_delete((linenr_T)start, false) == FAIL) {
- api_set_error(err, Exception, _("Failed to delete line"));
+ api_set_error(err, kErrorTypeException, "Failed to delete line");
goto end;
}
}
- if ((ssize_t)to_delete > 0) {
- extra -= (ssize_t)to_delete;
+ if (to_delete > 0) {
+ extra -= (ptrdiff_t)to_delete;
}
// For as long as possible, replace the existing old_len with the
@@ -352,12 +361,12 @@ void nvim_buf_set_lines(uint64_t channel_id,
int64_t lnum = start + (int64_t)i;
if (lnum > LONG_MAX) {
- api_set_error(err, Validation, _("Index value is too high"));
+ api_set_error(err, kErrorTypeValidation, "Index value is too high");
goto end;
}
if (ml_replace((linenr_T)lnum, (char_u *)lines[i], false) == FAIL) {
- api_set_error(err, Exception, _("Failed to replace line"));
+ api_set_error(err, kErrorTypeException, "Failed to replace line");
goto end;
}
// Mark lines that haven't been passed to the buffer as they need
@@ -370,12 +379,12 @@ void nvim_buf_set_lines(uint64_t channel_id,
int64_t lnum = start + (int64_t)i - 1;
if (lnum > LONG_MAX) {
- api_set_error(err, Validation, _("Index value is too high"));
+ api_set_error(err, kErrorTypeValidation, "Index value is too high");
goto end;
}
if (ml_append((linenr_T)lnum, (char_u *)lines[i], 0, false) == FAIL) {
- api_set_error(err, Exception, _("Failed to insert line"));
+ api_set_error(err, kErrorTypeException, "Failed to insert line");
goto end;
}
@@ -389,14 +398,14 @@ void nvim_buf_set_lines(uint64_t channel_id,
// changed range, and move any in the remainder of the buffer.
// Only adjust marks if we managed to switch to a window that holds
// the buffer, otherwise line numbers will be invalid.
- if (save_curbuf == NULL) {
- mark_adjust((linenr_T)start, (linenr_T)(end - 1), MAXLNUM, extra);
+ if (save_curbuf.br_buf == NULL) {
+ mark_adjust((linenr_T)start, (linenr_T)(end - 1), MAXLNUM, extra, false);
}
- changed_lines((linenr_T)start, 0, (linenr_T)end, extra);
+ changed_lines((linenr_T)start, 0, (linenr_T)end, (long)extra);
- if (buf == curbuf) {
- fix_cursor((linenr_T)start, (linenr_T)end, extra);
+ if (save_curbuf.br_buf == NULL) {
+ fix_cursor((linenr_T)start, (linenr_T)end, (linenr_T)extra);
}
end:
@@ -405,7 +414,7 @@ end:
}
xfree(lines);
- restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
+ restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
try_end(err);
}
@@ -416,6 +425,7 @@ end:
/// @param[out] err Error details, if any
/// @return Variable value
Object nvim_buf_get_var(Buffer buffer, String name, Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -426,6 +436,43 @@ Object nvim_buf_get_var(Buffer buffer, String name, Error *err)
return dict_get_value(buf->b_vars, name, err);
}
+/// Gets a changed tick of a buffer
+///
+/// @param[in] buffer Buffer handle.
+///
+/// @return `b:changedtick` value.
+Integer nvim_buf_get_changedtick(Buffer buffer, Error *err)
+ FUNC_API_SINCE(2)
+{
+ const buf_T *const buf = find_buffer_by_handle(buffer, err);
+
+ if (!buf) {
+ return -1;
+ }
+
+ return buf->b_changedtick;
+}
+
+/// Get a list of dictionaries describing buffer-local mappings
+/// Note that the buffer key in the dictionary will represent the buffer
+/// handle where the mapping is present
+///
+/// @param mode The abbreviation for the mode
+/// @param buffer_id Buffer handle
+/// @param[out] err Error details, if any
+/// @returns An array of maparg() like dictionaries describing mappings
+ArrayOf(Dictionary) nvim_buf_get_keymap(Buffer buffer, String mode, Error *err)
+ FUNC_API_SINCE(3)
+{
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+
+ if (!buf) {
+ return (Array)ARRAY_DICT_INIT;
+ }
+
+ return keymap_array(mode, buf);
+}
+
/// Sets a buffer-scoped (b:) variable
///
/// @param buffer Buffer handle
@@ -433,6 +480,7 @@ Object nvim_buf_get_var(Buffer buffer, String name, Error *err)
/// @param value Variable value
/// @param[out] err Error details, if any
void nvim_buf_set_var(Buffer buffer, String name, Object value, Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -440,7 +488,7 @@ void nvim_buf_set_var(Buffer buffer, String name, Object value, Error *err)
return;
}
- dict_set_value(buf->b_vars, name, value, false, false, err);
+ dict_set_var(buf->b_vars, name, value, false, false, err);
}
/// Removes a buffer-scoped (b:) variable
@@ -449,6 +497,7 @@ void nvim_buf_set_var(Buffer buffer, String name, Object value, Error *err)
/// @param name Variable name
/// @param[out] err Error details, if any
void nvim_buf_del_var(Buffer buffer, String name, Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -456,7 +505,7 @@ void nvim_buf_del_var(Buffer buffer, String name, Error *err)
return;
}
- dict_set_value(buf->b_vars, name, NIL, true, false, err);
+ dict_set_var(buf->b_vars, name, NIL, true, false, err);
}
/// Sets a buffer-scoped (b:) variable
@@ -479,7 +528,7 @@ Object buffer_set_var(Buffer buffer, String name, Object value, Error *err)
return (Object) OBJECT_INIT;
}
- return dict_set_value(buf->b_vars, name, value, false, true, err);
+ return dict_set_var(buf->b_vars, name, value, false, true, err);
}
/// Removes a buffer-scoped (b:) variable
@@ -498,7 +547,7 @@ Object buffer_del_var(Buffer buffer, String name, Error *err)
return (Object) OBJECT_INIT;
}
- return dict_set_value(buf->b_vars, name, NIL, true, true, err);
+ return dict_set_var(buf->b_vars, name, NIL, true, true, err);
}
@@ -509,6 +558,7 @@ Object buffer_del_var(Buffer buffer, String name, Error *err)
/// @param[out] err Error details, if any
/// @return Option value
Object nvim_buf_get_option(Buffer buffer, String name, Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -527,6 +577,7 @@ Object nvim_buf_get_option(Buffer buffer, String name, Error *err)
/// @param value Option value
/// @param[out] err Error details, if any
void nvim_buf_set_option(Buffer buffer, String name, Object value, Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -539,10 +590,15 @@ void nvim_buf_set_option(Buffer buffer, String name, Object value, Error *err)
/// Gets the buffer number
///
+/// @deprecated The buffer number now is equal to the object id,
+/// so there is no need to use this function.
+///
/// @param buffer Buffer handle
/// @param[out] err Error details, if any
/// @return Buffer number
Integer nvim_buf_get_number(Buffer buffer, Error *err)
+ FUNC_API_SINCE(1)
+ FUNC_API_DEPRECATED_SINCE(2)
{
Integer rv = 0;
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -560,6 +616,7 @@ Integer nvim_buf_get_number(Buffer buffer, Error *err)
/// @param[out] err Error details, if any
/// @return Buffer name
String nvim_buf_get_name(Buffer buffer, Error *err)
+ FUNC_API_SINCE(1)
{
String rv = STRING_INIT;
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -577,6 +634,7 @@ String nvim_buf_get_name(Buffer buffer, Error *err)
/// @param name Buffer name
/// @param[out] err Error details, if any
void nvim_buf_set_name(Buffer buffer, String name, Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -597,7 +655,7 @@ void nvim_buf_set_name(Buffer buffer, String name, Error *err)
}
if (ren_ret == FAIL) {
- api_set_error(err, Exception, _("Failed to rename buffer"));
+ api_set_error(err, kErrorTypeException, "Failed to rename buffer");
}
}
@@ -606,9 +664,12 @@ void nvim_buf_set_name(Buffer buffer, String name, Error *err)
/// @param buffer Buffer handle
/// @return true if the buffer is valid, false otherwise
Boolean nvim_buf_is_valid(Buffer buffer)
+ FUNC_API_SINCE(1)
{
Error stub = ERROR_INIT;
- return find_buffer_by_handle(buffer, &stub) != NULL;
+ Boolean ret = find_buffer_by_handle(buffer, &stub) != NULL;
+ api_clear_error(&stub);
+ return ret;
}
/// Inserts a sequence of lines to a buffer at a certain index
@@ -637,6 +698,7 @@ void buffer_insert(Buffer buffer,
/// @param[out] err Error details, if any
/// @return (row, col) tuple
ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -646,25 +708,26 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err)
}
if (name.size != 1) {
- api_set_error(err, Validation, _("Mark name must be a single character"));
+ api_set_error(err, kErrorTypeValidation,
+ "Mark name must be a single character");
return rv;
}
pos_T *posp;
- buf_T *savebuf;
char mark = *name.data;
try_start();
- switch_buffer(&savebuf, buf);
+ bufref_T save_buf;
+ switch_buffer(&save_buf, buf);
posp = getmark(mark, false);
- restore_buffer(savebuf);
+ restore_buffer(&save_buf);
if (try_end(err)) {
return rv;
}
if (posp == NULL) {
- api_set_error(err, Validation, _("Invalid mark name"));
+ api_set_error(err, kErrorTypeValidation, "Invalid mark name");
return rv;
}
@@ -711,6 +774,7 @@ Integer nvim_buf_add_highlight(Buffer buffer,
Integer col_start,
Integer col_end,
Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
if (!buf) {
@@ -718,11 +782,11 @@ Integer nvim_buf_add_highlight(Buffer buffer,
}
if (line < 0 || line >= MAXLNUM) {
- api_set_error(err, Validation, _("Line number outside range"));
+ api_set_error(err, kErrorTypeValidation, "Line number outside range");
return 0;
}
if (col_start < 0 || col_start > MAXCOL) {
- api_set_error(err, Validation, _("Column value outside range"));
+ api_set_error(err, kErrorTypeValidation, "Column value outside range");
return 0;
}
if (col_end < 0 || col_end > MAXCOL) {
@@ -751,6 +815,7 @@ void nvim_buf_clear_highlight(Buffer buffer,
Integer line_start,
Integer line_end,
Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
if (!buf) {
@@ -758,7 +823,7 @@ void nvim_buf_clear_highlight(Buffer buffer,
}
if (line_start < 0 || line_start >= MAXLNUM) {
- api_set_error(err, Validation, _("Line number outside range"));
+ api_set_error(err, kErrorTypeValidation, "Line number outside range");
return;
}
if (line_end < 0 || line_end > MAXLNUM) {
diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h
index 223aab09dc..2144c80d6a 100644
--- a/src/nvim/api/private/defs.h
+++ b/src/nvim/api/private/defs.h
@@ -5,12 +5,16 @@
#include <stdbool.h>
#include <string.h>
+#include "nvim/func_attr.h"
+
#define ARRAY_DICT_INIT {.size = 0, .capacity = 0, .items = NULL}
#define STRING_INIT {.data = NULL, .size = 0}
#define OBJECT_INIT { .type = kObjectTypeNil }
-#define ERROR_INIT { .set = false }
+#define ERROR_INIT { .type = kErrorTypeNone, .msg = NULL }
#define REMOTE_TYPE(type) typedef handle_T type
+#define ERROR_SET(e) ((e)->type != kErrorTypeNone)
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# define ArrayOf(...) Array
# define DictionaryOf(...) Dictionary
@@ -20,6 +24,7 @@ typedef int handle_T;
// Basic types
typedef enum {
+ kErrorTypeNone = -1,
kErrorTypeException,
kErrorTypeValidation
} ErrorType;
@@ -33,13 +38,31 @@ typedef enum {
/// Used as the message ID of notifications.
#define NO_RESPONSE UINT64_MAX
-/// Used as channel_id when the call is local.
-#define INTERNAL_CALL UINT64_MAX
+/// Mask for all internal calls
+#define INTERNAL_CALL_MASK (((uint64_t)1) << (sizeof(uint64_t) * 8 - 1))
+
+/// Internal call from VimL code
+#define VIML_INTERNAL_CALL INTERNAL_CALL_MASK
+
+/// Internal call from lua code
+#define LUA_INTERNAL_CALL (VIML_INTERNAL_CALL + 1)
+
+static inline bool is_internal_call(uint64_t channel_id)
+ REAL_FATTR_ALWAYS_INLINE REAL_FATTR_CONST;
+
+/// Check whether call is internal
+///
+/// @param[in] channel_id Channel id.
+///
+/// @return true if channel_id refers to internal channel.
+static inline bool is_internal_call(const uint64_t channel_id)
+{
+ return !!(channel_id & INTERNAL_CALL_MASK);
+}
typedef struct {
ErrorType type;
- char msg[1024];
- bool set;
+ char *msg;
} Error;
typedef bool Boolean;
@@ -76,16 +99,17 @@ typedef struct {
} Dictionary;
typedef enum {
- kObjectTypeBuffer,
- kObjectTypeWindow,
- kObjectTypeTabpage,
- kObjectTypeNil,
+ kObjectTypeNil = 0,
kObjectTypeBoolean,
kObjectTypeInteger,
kObjectTypeFloat,
kObjectTypeString,
kObjectTypeArray,
kObjectTypeDictionary,
+ // EXT types, cannot be split or reordered, see #EXT_OBJECT_TYPE_SHIFT
+ kObjectTypeBuffer,
+ kObjectTypeWindow,
+ kObjectTypeTabpage,
} ObjectType;
struct object {
diff --git a/src/nvim/api/private/dispatch.c b/src/nvim/api/private/dispatch.c
index 9b3bcc380a..f8eebcdb10 100644
--- a/src/nvim/api/private/dispatch.c
+++ b/src/nvim/api/private/dispatch.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <inttypes.h>
#include <stdbool.h>
#include <stdint.h>
diff --git a/src/nvim/api/private/handle.c b/src/nvim/api/private/handle.c
index acb0fb332a..eb96192af2 100644
--- a/src/nvim/api/private/handle.c
+++ b/src/nvim/api/private/handle.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <stdint.h>
diff --git a/src/nvim/api/private/handle.h b/src/nvim/api/private/handle.h
index 30bbfbee1b..26e9dc3314 100644
--- a/src/nvim/api/private/handle.h
+++ b/src/nvim/api/private/handle.h
@@ -10,8 +10,11 @@
void handle_register_##name(type *name); \
void handle_unregister_##name(type *name);
+// handle_get_buffer handle_register_buffer, handle_unregister_buffer
HANDLE_DECLS(buf_T, buffer)
+// handle_get_window handle_register_window, handle_unregister_window
HANDLE_DECLS(win_T, window)
+// handle_get_tabpage handle_register_tabpage, handle_unregister_tabpage
HANDLE_DECLS(tabpage_T, tabpage)
void handle_init(void);
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 7daa4d7207..e736e29e2d 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
@@ -14,12 +17,14 @@
#include "nvim/window.h"
#include "nvim/memory.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval.h"
#include "nvim/map_defs.h"
#include "nvim/map.h"
#include "nvim/option.h"
#include "nvim/option_defs.h"
#include "nvim/version.h"
#include "nvim/lib/kvec.h"
+#include "nvim/getchar.h"
/// Helper structure for vim_to_object
typedef struct {
@@ -29,9 +34,75 @@ typedef struct {
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "api/private/helpers.c.generated.h"
# include "api/private/funcs_metadata.generated.h"
+# include "api/private/ui_events_metadata.generated.h"
#endif
+/// Start block that may cause VimL exceptions while evaluating another code
+///
+/// Used when caller is supposed to be operating when other VimL code is being
+/// processed and that “other VimL code†must not be affected.
+///
+/// @param[out] tstate Location where try state should be saved.
+void try_enter(TryState *const tstate)
+{
+ *tstate = (TryState) {
+ .current_exception = current_exception,
+ .msg_list = (const struct msglist *const *)msg_list,
+ .private_msg_list = NULL,
+ .trylevel = trylevel,
+ .got_int = got_int,
+ .did_throw = did_throw,
+ .need_rethrow = need_rethrow,
+ .did_emsg = did_emsg,
+ };
+ msg_list = &tstate->private_msg_list;
+ current_exception = NULL;
+ trylevel = 1;
+ got_int = false;
+ did_throw = false;
+ need_rethrow = false;
+ did_emsg = false;
+}
+
+/// End try block, set the error message if any and restore previous state
+///
+/// @warning Return is consistent with most functions (false on error), not with
+/// try_end (true on error).
+///
+/// @param[in] tstate Previous state to restore.
+/// @param[out] err Location where error should be saved.
+///
+/// @return false if error occurred, true otherwise.
+bool try_leave(const TryState *const tstate, Error *const err)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const bool ret = !try_end(err);
+ assert(trylevel == 0);
+ assert(!need_rethrow);
+ assert(!got_int);
+ assert(!did_throw);
+ assert(!did_emsg);
+ assert(msg_list == &tstate->private_msg_list);
+ assert(*msg_list == NULL);
+ assert(current_exception == NULL);
+ msg_list = (struct msglist **)tstate->msg_list;
+ current_exception = tstate->current_exception;
+ trylevel = tstate->trylevel;
+ got_int = tstate->got_int;
+ did_throw = tstate->did_throw;
+ need_rethrow = tstate->need_rethrow;
+ did_emsg = tstate->did_emsg;
+ return ret;
+}
+
/// Start block that may cause vimscript exceptions
+///
+/// Each try_start() call should be mirrored by try_end() call.
+///
+/// To be used as a replacement of `:try … catch … endtry` in C code, in cases
+/// when error flag could not already be set. If there may be pending error
+/// state at the time try_start() is executed which needs to be preserved,
+/// try_enter()/try_leave() pair should be used instead.
void try_start(void)
{
++trylevel;
@@ -44,7 +115,9 @@ void try_start(void)
/// @return true if an error occurred
bool try_end(Error *err)
{
- --trylevel;
+ // Note: all globals manipulated here should be saved/restored in
+ // try_enter/try_leave.
+ trylevel--;
// Without this it stops processing all subsequent VimL commands and
// generates strange error messages if I e.g. try calling Test() in a
@@ -57,7 +130,7 @@ bool try_end(Error *err)
discard_current_exception();
}
- api_set_error(err, Exception, _("Keyboard interrupt"));
+ api_set_error(err, kErrorTypeException, "Keyboard interrupt");
got_int = false;
} else if (msg_list != NULL && *msg_list != NULL) {
int should_free;
@@ -65,19 +138,18 @@ bool try_end(Error *err)
ET_ERROR,
NULL,
&should_free);
- xstrlcpy(err->msg, msg, sizeof(err->msg));
- err->set = true;
+ api_set_error(err, kErrorTypeException, "%s", msg);
free_global_msglist();
if (should_free) {
xfree(msg);
}
} else if (did_throw) {
- api_set_error(err, Exception, "%s", current_exception->value);
+ api_set_error(err, kErrorTypeException, "%s", current_exception->value);
discard_current_exception();
}
- return err->set;
+ return ERROR_SET(err);
}
/// Recursively expands a vimscript value in a dict
@@ -87,18 +159,17 @@ bool try_end(Error *err)
/// @param[out] err Details of an error that may have occurred
Object dict_get_value(dict_T *dict, String key, Error *err)
{
- hashitem_T *hi = hash_find(&dict->dv_hashtab, (uint8_t *) key.data);
+ dictitem_T *const di = tv_dict_find(dict, key.data, (ptrdiff_t)key.size);
- if (HASHITEM_EMPTY(hi)) {
- api_set_error(err, Validation, _("Key not found"));
- return (Object) OBJECT_INIT;
+ if (di == NULL) {
+ api_set_error(err, kErrorTypeValidation, "Key '%s' not found", key.data);
+ return (Object)OBJECT_INIT;
}
- dictitem_T *di = dict_lookup(hi);
return vim_to_object(&di->di_tv);
}
-/// Set a value in a dict. Objects are recursively expanded into their
+/// Set a value in a scope dict. Objects are recursively expanded into their
/// vimscript equivalents.
///
/// @param dict The vimscript dict
@@ -109,42 +180,55 @@ Object dict_get_value(dict_T *dict, String key, Error *err)
/// @param retval If true the old value will be converted and returned.
/// @param[out] err Details of an error that may have occurred
/// @return The old value if `retval` is true and the key was present, else NIL
-Object dict_set_value(dict_T *dict, String key, Object value, bool del,
- bool retval, Error *err)
+Object dict_set_var(dict_T *dict, String key, Object value, bool del,
+ bool retval, Error *err)
{
Object rv = OBJECT_INIT;
if (dict->dv_lock) {
- api_set_error(err, Exception, _("Dictionary is locked"));
+ api_set_error(err, kErrorTypeException, "Dictionary is locked");
return rv;
}
if (key.size == 0) {
- api_set_error(err, Validation, _("Empty dictionary keys aren't allowed"));
+ api_set_error(err, kErrorTypeValidation,
+ "Empty variable names aren't allowed");
return rv;
}
if (key.size > INT_MAX) {
- api_set_error(err, Validation, _("Key length is too high"));
+ api_set_error(err, kErrorTypeValidation, "Key length is too high");
return rv;
}
- dictitem_T *di = dict_find(dict, (uint8_t *)key.data, (int)key.size);
+ dictitem_T *di = tv_dict_find(dict, key.data, (ptrdiff_t)key.size);
+
+ if (di != NULL) {
+ if (di->di_flags & DI_FLAGS_RO) {
+ api_set_error(err, kErrorTypeException, "Key is read-only: %s", key.data);
+ return rv;
+ } else if (di->di_flags & DI_FLAGS_FIX) {
+ api_set_error(err, kErrorTypeException, "Key is fixed: %s", key.data);
+ return rv;
+ } else if (di->di_flags & DI_FLAGS_LOCK) {
+ api_set_error(err, kErrorTypeException, "Key is locked: %s", key.data);
+ return rv;
+ }
+ }
if (del) {
// Delete the key
if (di == NULL) {
// Doesn't exist, fail
- api_set_error(err, Validation, _("Key \"%s\" doesn't exist"), key.data);
+ api_set_error(err, kErrorTypeValidation, "Key does not exist: %s",
+ key.data);
} else {
// Return the old value
if (retval) {
rv = vim_to_object(&di->di_tv);
}
// Delete the entry
- hashitem_T *hi = hash_find(&dict->dv_hashtab, di->di_key);
- hash_remove(&dict->dv_hashtab, hi);
- dictitem_free(di);
+ tv_dict_item_remove(dict, di);
}
} else {
// Update the key
@@ -157,20 +241,20 @@ Object dict_set_value(dict_T *dict, String key, Object value, bool del,
if (di == NULL) {
// Need to create an entry
- di = dictitem_alloc((uint8_t *) key.data);
- dict_add(dict, di);
+ di = tv_dict_item_alloc_len(key.data, key.size);
+ tv_dict_add(dict, di);
} else {
// Return the old value
if (retval) {
rv = vim_to_object(&di->di_tv);
}
- clear_tv(&di->di_tv);
+ tv_clear(&di->di_tv);
}
// Update the value
- copy_tv(&tv, &di->di_tv);
+ tv_copy(&tv, &di->di_tv);
// Clear the temporary variable
- clear_tv(&tv);
+ tv_clear(&tv);
}
return rv;
@@ -189,7 +273,7 @@ Object get_option_from(void *from, int type, String name, Error *err)
Object rv = OBJECT_INIT;
if (name.size == 0) {
- api_set_error(err, Validation, _("Empty option name"));
+ api_set_error(err, kErrorTypeValidation, "Empty option name");
return rv;
}
@@ -201,8 +285,8 @@ Object get_option_from(void *from, int type, String name, Error *err)
if (!flags) {
api_set_error(err,
- Validation,
- _("Invalid option name \"%s\""),
+ kErrorTypeValidation,
+ "Invalid option name \"%s\"",
name.data);
return rv;
}
@@ -220,14 +304,14 @@ Object get_option_from(void *from, int type, String name, Error *err)
rv.data.string.size = strlen(stringval);
} else {
api_set_error(err,
- Exception,
- _("Unable to get value for option \"%s\""),
+ kErrorTypeException,
+ "Unable to get value for option \"%s\"",
name.data);
}
} else {
api_set_error(err,
- Exception,
- _("Unknown type for option \"%s\""),
+ kErrorTypeException,
+ "Unknown type for option \"%s\"",
name.data);
}
@@ -244,7 +328,7 @@ Object get_option_from(void *from, int type, String name, Error *err)
void set_option_to(void *to, int type, String name, Object value, Error *err)
{
if (name.size == 0) {
- api_set_error(err, Validation, _("Empty option name"));
+ api_set_error(err, kErrorTypeValidation, "Empty option name");
return;
}
@@ -252,8 +336,8 @@ void set_option_to(void *to, int type, String name, Object value, Error *err)
if (flags == 0) {
api_set_error(err,
- Validation,
- _("Invalid option name \"%s\""),
+ kErrorTypeValidation,
+ "Invalid option name \"%s\"",
name.data);
return;
}
@@ -261,15 +345,15 @@ void set_option_to(void *to, int type, String name, Object value, Error *err)
if (value.type == kObjectTypeNil) {
if (type == SREQ_GLOBAL) {
api_set_error(err,
- Exception,
- _("Unable to unset option \"%s\""),
+ kErrorTypeException,
+ "Unable to unset option \"%s\"",
name.data);
return;
} else if (!(flags & SOPT_GLOBAL)) {
api_set_error(err,
- Exception,
- _("Cannot unset option \"%s\" "
- "because it doesn't have a global value"),
+ kErrorTypeException,
+ "Cannot unset option \"%s\" "
+ "because it doesn't have a global value",
name.data);
return;
} else {
@@ -278,13 +362,13 @@ void set_option_to(void *to, int type, String name, Object value, Error *err)
}
}
- int opt_flags = (type ? OPT_LOCAL : OPT_GLOBAL);
+ int opt_flags = (type == SREQ_GLOBAL) ? OPT_GLOBAL : OPT_LOCAL;
if (flags & SOPT_BOOL) {
if (value.type != kObjectTypeBoolean) {
api_set_error(err,
- Validation,
- _("Option \"%s\" requires a boolean value"),
+ kErrorTypeValidation,
+ "Option \"%s\" requires a boolean value",
name.data);
return;
}
@@ -294,16 +378,16 @@ void set_option_to(void *to, int type, String name, Object value, Error *err)
} else if (flags & SOPT_NUM) {
if (value.type != kObjectTypeInteger) {
api_set_error(err,
- Validation,
- _("Option \"%s\" requires an integer value"),
+ kErrorTypeValidation,
+ "Option \"%s\" requires an integer value",
name.data);
return;
}
if (value.data.integer > INT_MAX || value.data.integer < INT_MIN) {
api_set_error(err,
- Validation,
- _("Value for option \"%s\" is outside range"),
+ kErrorTypeValidation,
+ "Value for option \"%s\" is outside range",
name.data);
return;
}
@@ -313,8 +397,8 @@ void set_option_to(void *to, int type, String name, Object value, Error *err)
} else {
if (value.type != kObjectTypeString) {
api_set_error(err,
- Validation,
- _("Option \"%s\" requires a string value"),
+ kErrorTypeValidation,
+ "Option \"%s\" requires a string value",
name.data);
return;
}
@@ -338,7 +422,7 @@ void set_option_to(void *to, int type, String name, Object value, Error *err)
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER TYPVAL_ENCODE_CONV_NUMBER
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
- kv_push(edata->stack, FLOATING_OBJ((Float)(flt)))
+ kv_push(edata->stack, FLOAT_OBJ((Float)(flt)))
#define TYPVAL_ENCODE_CONV_STRING(tv, str, len) \
do { \
@@ -380,7 +464,7 @@ static inline void typval_encode_list_start(EncodedData *const edata,
kv_push(edata->stack, ARRAY_OBJ(((Array) {
.capacity = len,
.size = 0,
- .items = xmalloc(len * sizeof(*((Object *)NULL)->data.array.items)),
+ .items = xmalloc(len * sizeof(*((Object)OBJECT_INIT).data.array.items)),
})));
}
@@ -422,7 +506,8 @@ static inline void typval_encode_dict_start(EncodedData *const edata,
kv_push(edata->stack, DICTIONARY_OBJ(((Dictionary) {
.capacity = len,
.size = 0,
- .items = xmalloc(len * sizeof(*((Object *)NULL)->data.dictionary.items)),
+ .items = xmalloc(len * sizeof(
+ *((Object)OBJECT_INIT).data.dictionary.items)),
})));
}
@@ -546,13 +631,13 @@ buf_T *find_buffer_by_handle(Buffer buffer, Error *err)
buf_T *rv = handle_get_buffer(buffer);
if (!rv) {
- api_set_error(err, Validation, _("Invalid buffer id"));
+ api_set_error(err, kErrorTypeValidation, "Invalid buffer id");
}
return rv;
}
-win_T * find_window_by_handle(Window window, Error *err)
+win_T *find_window_by_handle(Window window, Error *err)
{
if (window == 0) {
return curwin;
@@ -561,13 +646,13 @@ win_T * find_window_by_handle(Window window, Error *err)
win_T *rv = handle_get_window(window);
if (!rv) {
- api_set_error(err, Validation, _("Invalid window id"));
+ api_set_error(err, kErrorTypeValidation, "Invalid window id");
}
return rv;
}
-tabpage_T * find_tab_by_handle(Tabpage tabpage, Error *err)
+tabpage_T *find_tab_by_handle(Tabpage tabpage, Error *err)
{
if (tabpage == 0) {
return curtab;
@@ -576,7 +661,7 @@ tabpage_T * find_tab_by_handle(Tabpage tabpage, Error *err)
tabpage_T *rv = handle_get_tabpage(tabpage);
if (!rv) {
- api_set_error(err, Validation, _("Invalid tabpage id"));
+ api_set_error(err, kErrorTypeValidation, "Invalid tabpage id");
}
return rv;
@@ -613,7 +698,7 @@ String cstr_as_string(char *str) FUNC_ATTR_PURE
if (str == NULL) {
return (String) STRING_INIT;
}
- return (String) {.data = str, .size = strlen(str)};
+ return (String) { .data = str, .size = strlen(str) };
}
/// Converts from type Object to a VimL value.
@@ -644,7 +729,7 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err)
case kObjectTypeInteger:
if (obj.data.integer > VARNUMBER_MAX
|| obj.data.integer < VARNUMBER_MIN) {
- api_set_error(err, Validation, _("Integer value outside range"));
+ api_set_error(err, kErrorTypeValidation, "Integer value outside range");
return false;
}
@@ -668,20 +753,20 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err)
break;
case kObjectTypeArray: {
- list_T *list = list_alloc();
+ list_T *const list = tv_list_alloc();
for (uint32_t i = 0; i < obj.data.array.size; i++) {
Object item = obj.data.array.items[i];
- listitem_T *li = listitem_alloc();
+ listitem_T *li = tv_list_item_alloc();
if (!object_to_vim(item, &li->li_tv, err)) {
// cleanup
- listitem_free(li);
- list_free(list);
+ tv_list_item_free(li);
+ tv_list_free(list);
return false;
}
- list_append(list, li);
+ tv_list_append(list, li);
}
list->lv_refcount++;
@@ -691,30 +776,30 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err)
}
case kObjectTypeDictionary: {
- dict_T *dict = dict_alloc();
+ dict_T *const dict = tv_dict_alloc();
for (uint32_t i = 0; i < obj.data.dictionary.size; i++) {
KeyValuePair item = obj.data.dictionary.items[i];
String key = item.key;
if (key.size == 0) {
- api_set_error(err, Validation,
- _("Empty dictionary keys aren't allowed"));
+ api_set_error(err, kErrorTypeValidation,
+ "Empty dictionary keys aren't allowed");
// cleanup
- dict_free(dict);
+ tv_dict_free(dict);
return false;
}
- dictitem_T *di = dictitem_alloc((uint8_t *)key.data);
+ dictitem_T *const di = tv_dict_item_alloc(key.data);
if (!object_to_vim(item.value, &di->di_tv, err)) {
// cleanup
- dictitem_free(di);
- dict_free(dict);
+ tv_dict_item_free(di);
+ tv_dict_free(dict);
return false;
}
- dict_add(dict, di);
+ tv_dict_add(dict, di);
}
dict->dv_refcount++;
@@ -786,6 +871,17 @@ void api_free_dictionary(Dictionary value)
xfree(value.items);
}
+void api_clear_error(Error *value)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (!ERROR_SET(value)) {
+ return;
+ }
+ xfree(value->msg);
+ value->msg = NULL;
+ value->type = kErrorTypeNone;
+}
+
Dictionary api_metadata(void)
{
static Dictionary metadata = ARRAY_DICT_INIT;
@@ -793,6 +889,7 @@ Dictionary api_metadata(void)
if (!metadata.size) {
PUT(metadata, "version", DICTIONARY_OBJ(version_dict()));
init_function_metadata(&metadata);
+ init_ui_event_metadata(&metadata);
init_error_type_metadata(&metadata);
init_type_metadata(&metadata);
}
@@ -816,6 +913,22 @@ static void init_function_metadata(Dictionary *metadata)
PUT(*metadata, "functions", functions);
}
+static void init_ui_event_metadata(Dictionary *metadata)
+{
+ msgpack_unpacked unpacked;
+ msgpack_unpacked_init(&unpacked);
+ if (msgpack_unpack_next(&unpacked,
+ (const char *)ui_events_metadata,
+ sizeof(ui_events_metadata),
+ NULL) != MSGPACK_UNPACK_SUCCESS) {
+ abort();
+ }
+ Object ui_events;
+ msgpack_rpc_to_object(&unpacked.data, &ui_events);
+ msgpack_unpacked_destroy(&unpacked);
+ PUT(*metadata, "ui_events", ui_events);
+}
+
static void init_error_type_metadata(Dictionary *metadata)
{
Dictionary types = ARRAY_DICT_INIT;
@@ -837,15 +950,18 @@ static void init_type_metadata(Dictionary *metadata)
Dictionary types = ARRAY_DICT_INIT;
Dictionary buffer_metadata = ARRAY_DICT_INIT;
- PUT(buffer_metadata, "id", INTEGER_OBJ(kObjectTypeBuffer));
+ PUT(buffer_metadata, "id",
+ INTEGER_OBJ(kObjectTypeBuffer - EXT_OBJECT_TYPE_SHIFT));
PUT(buffer_metadata, "prefix", STRING_OBJ(cstr_to_string("nvim_buf_")));
Dictionary window_metadata = ARRAY_DICT_INIT;
- PUT(window_metadata, "id", INTEGER_OBJ(kObjectTypeWindow));
+ PUT(window_metadata, "id",
+ INTEGER_OBJ(kObjectTypeWindow - EXT_OBJECT_TYPE_SHIFT));
PUT(window_metadata, "prefix", STRING_OBJ(cstr_to_string("nvim_win_")));
Dictionary tabpage_metadata = ARRAY_DICT_INIT;
- PUT(tabpage_metadata, "id", INTEGER_OBJ(kObjectTypeTabpage));
+ PUT(tabpage_metadata, "id",
+ INTEGER_OBJ(kObjectTypeTabpage - EXT_OBJECT_TYPE_SHIFT));
PUT(tabpage_metadata, "prefix", STRING_OBJ(cstr_to_string("nvim_tabpage_")));
PUT(types, "Buffer", DICTIONARY_OBJ(buffer_metadata));
@@ -855,6 +971,24 @@ static void init_type_metadata(Dictionary *metadata)
PUT(*metadata, "types", DICTIONARY_OBJ(types));
}
+String copy_string(String str)
+{
+ if (str.data != NULL) {
+ return (String){ .data = xmemdupz(str.data, str.size), .size = str.size };
+ } else {
+ return (String)STRING_INIT;
+ }
+}
+
+Array copy_array(Array array)
+{
+ Array rv = ARRAY_DICT_INIT;
+ for (size_t i = 0; i < array.size; i++) {
+ ADD(rv, copy_object(array.items[i]));
+ }
+ return rv;
+}
+
/// Creates a deep clone of an object
Object copy_object(Object obj)
{
@@ -866,15 +1000,10 @@ Object copy_object(Object obj)
return obj;
case kObjectTypeString:
- return STRING_OBJ(cstr_to_string(obj.data.string.data));
+ return STRING_OBJ(copy_string(obj.data.string));
- case kObjectTypeArray: {
- Array rv = ARRAY_DICT_INIT;
- for (size_t i = 0; i < obj.data.array.size; i++) {
- ADD(rv, copy_object(obj.data.array.items[i]));
- }
- return ARRAY_OBJ(rv);
- }
+ case kObjectTypeArray:
+ return ARRAY_OBJ(copy_array(obj.data.array));
case kObjectTypeDictionary: {
Dictionary rv = ARRAY_DICT_INIT;
@@ -899,7 +1028,7 @@ static void set_option_value_for(char *key,
{
win_T *save_curwin = NULL;
tabpage_T *save_curtab = NULL;
- buf_T *save_curbuf = NULL;
+ bufref_T save_curbuf = { NULL, 0, 0 };
try_start();
switch (opt_type)
@@ -912,8 +1041,8 @@ static void set_option_value_for(char *key,
return;
}
api_set_error(err,
- Exception,
- _("Problem while switching windows"));
+ kErrorTypeException,
+ "Problem while switching windows");
return;
}
set_option_value_err(key, numval, stringval, opt_flags, err);
@@ -922,14 +1051,14 @@ static void set_option_value_for(char *key,
case SREQ_BUF:
switch_buffer(&save_curbuf, (buf_T *)from);
set_option_value_err(key, numval, stringval, opt_flags, err);
- restore_buffer(save_curbuf);
+ restore_buffer(&save_curbuf);
break;
case SREQ_GLOBAL:
set_option_value_err(key, numval, stringval, opt_flags, err);
break;
}
- if (err->set) {
+ if (ERROR_SET(err)) {
return;
}
@@ -945,15 +1074,69 @@ static void set_option_value_err(char *key,
{
char *errmsg;
- if ((errmsg = (char *)set_option_value((uint8_t *)key,
- numval,
- (uint8_t *)stringval,
- opt_flags)))
- {
+ if ((errmsg = set_option_value(key, numval, stringval, opt_flags))) {
if (try_end(err)) {
return;
}
- api_set_error(err, Exception, "%s", errmsg);
+ api_set_error(err, kErrorTypeException, "%s", errmsg);
}
}
+
+void api_set_error(Error *err, ErrorType errType, const char *format, ...)
+ FUNC_ATTR_NONNULL_ALL
+{
+ assert(kErrorTypeNone != errType);
+ va_list args1;
+ va_list args2;
+ va_start(args1, format);
+ va_copy(args2, args1);
+ int len = vsnprintf(NULL, 0, format, args1);
+ va_end(args1);
+ assert(len >= 0);
+ // Limit error message to 1 MB.
+ size_t bufsize = MIN((size_t)len + 1, 1024 * 1024);
+ err->msg = xmalloc(bufsize);
+ vsnprintf(err->msg, bufsize, format, args2);
+ va_end(args2);
+
+ err->type = errType;
+}
+
+/// Get an array containing dictionaries describing mappings
+/// based on mode and buffer id
+///
+/// @param mode The abbreviation for the mode
+/// @param buf The buffer to get the mapping array. NULL for global
+/// @returns An array of maparg() like dictionaries describing mappings
+ArrayOf(Dictionary) keymap_array(String mode, buf_T *buf)
+{
+ Array mappings = ARRAY_DICT_INIT;
+ dict_T *const dict = tv_dict_alloc();
+
+ // Convert the string mode to the integer mode
+ // that is stored within each mapblock
+ char_u *p = (char_u *)mode.data;
+ int int_mode = get_map_mode(&p, 0);
+
+ // Determine the desired buffer value
+ long buffer_value = (buf == NULL) ? 0 : buf->handle;
+
+ for (int i = 0; i < MAX_MAPHASH; i++) {
+ for (const mapblock_T *current_maphash = get_maphash(i, buf);
+ current_maphash;
+ current_maphash = current_maphash->m_next) {
+ // Check for correct mode
+ if (int_mode & current_maphash->m_mode) {
+ mapblock_fill_dict(dict, current_maphash, buffer_value, false);
+ ADD(mappings, vim_to_object(
+ (typval_T[]) { { .v_type = VAR_DICT, .vval.v_dict = dict } }));
+
+ tv_dict_clear(dict);
+ }
+ }
+ }
+ tv_dict_free(dict);
+
+ return mappings;
+}
diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h
index 9fe8c351cf..87f334ac30 100644
--- a/src/nvim/api/private/helpers.h
+++ b/src/nvim/api/private/helpers.h
@@ -6,17 +6,9 @@
#include "nvim/api/private/defs.h"
#include "nvim/vim.h"
#include "nvim/memory.h"
+#include "nvim/ex_eval.h"
#include "nvim/lib/kvec.h"
-#define api_set_error(err, errtype, ...) \
- do { \
- snprintf((err)->msg, \
- sizeof((err)->msg), \
- __VA_ARGS__); \
- (err)->set = true; \
- (err)->type = kErrorType##errtype; \
- } while (0)
-
#define OBJECT_OBJ(o) o
#define BOOLEAN_OBJ(b) ((Object) { \
@@ -27,7 +19,7 @@
.type = kObjectTypeInteger, \
.data.integer = i })
-#define FLOATING_OBJ(f) ((Object) { \
+#define FLOAT_OBJ(f) ((Object) { \
.type = kObjectTypeFloat, \
.data.floating = f })
@@ -91,6 +83,21 @@
#define api_free_window(value)
#define api_free_tabpage(value)
+/// Structure used for saving state for :try
+///
+/// Used when caller is supposed to be operating when other VimL code is being
+/// processed and that “other VimL code†must not be affected.
+typedef struct {
+ except_T *current_exception;
+ struct msglist *private_msg_list;
+ const struct msglist *const *msg_list;
+ int trylevel;
+ int got_int;
+ int did_throw;
+ int need_rethrow;
+ int did_emsg;
+} TryState;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "api/private/helpers.h.generated.h"
#endif
diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c
index 9e61ec1871..b6830d9fcf 100644
--- a/src/nvim/api/tabpage.c
+++ b/src/nvim/api/tabpage.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
@@ -15,6 +18,7 @@
/// @param[out] err Error details, if any
/// @return List of windows in `tabpage`
ArrayOf(Window) nvim_tabpage_list_wins(Tabpage tabpage, Error *err)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
tabpage_T *tab = find_tab_by_handle(tabpage, err);
@@ -44,6 +48,7 @@ ArrayOf(Window) nvim_tabpage_list_wins(Tabpage tabpage, Error *err)
/// @param[out] err Error details, if any
/// @return Variable value
Object nvim_tabpage_get_var(Tabpage tabpage, String name, Error *err)
+ FUNC_API_SINCE(1)
{
tabpage_T *tab = find_tab_by_handle(tabpage, err);
@@ -64,6 +69,7 @@ void nvim_tabpage_set_var(Tabpage tabpage,
String name,
Object value,
Error *err)
+ FUNC_API_SINCE(1)
{
tabpage_T *tab = find_tab_by_handle(tabpage, err);
@@ -71,7 +77,7 @@ void nvim_tabpage_set_var(Tabpage tabpage,
return;
}
- dict_set_value(tab->tp_vars, name, value, false, false, err);
+ dict_set_var(tab->tp_vars, name, value, false, false, err);
}
/// Removes a tab-scoped (t:) variable
@@ -80,6 +86,7 @@ void nvim_tabpage_set_var(Tabpage tabpage,
/// @param name Variable name
/// @param[out] err Error details, if any
void nvim_tabpage_del_var(Tabpage tabpage, String name, Error *err)
+ FUNC_API_SINCE(1)
{
tabpage_T *tab = find_tab_by_handle(tabpage, err);
@@ -87,7 +94,7 @@ void nvim_tabpage_del_var(Tabpage tabpage, String name, Error *err)
return;
}
- dict_set_value(tab->tp_vars, name, NIL, true, false, err);
+ dict_set_var(tab->tp_vars, name, NIL, true, false, err);
}
/// Sets a tab-scoped (t:) variable
@@ -110,7 +117,7 @@ Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err)
return (Object) OBJECT_INIT;
}
- return dict_set_value(tab->tp_vars, name, value, false, true, err);
+ return dict_set_var(tab->tp_vars, name, value, false, true, err);
}
/// Removes a tab-scoped (t:) variable
@@ -129,7 +136,7 @@ Object tabpage_del_var(Tabpage tabpage, String name, Error *err)
return (Object) OBJECT_INIT;
}
- return dict_set_value(tab->tp_vars, name, NIL, true, true, err);
+ return dict_set_var(tab->tp_vars, name, NIL, true, true, err);
}
/// Gets the current window in a tabpage
@@ -138,6 +145,7 @@ Object tabpage_del_var(Tabpage tabpage, String name, Error *err)
/// @param[out] err Error details, if any
/// @return Window handle
Window nvim_tabpage_get_win(Tabpage tabpage, Error *err)
+ FUNC_API_SINCE(1)
{
Window rv = 0;
tabpage_T *tab = find_tab_by_handle(tabpage, err);
@@ -165,6 +173,7 @@ Window nvim_tabpage_get_win(Tabpage tabpage, Error *err)
/// @param[out] err Error details, if any
/// @return Tabpage number
Integer nvim_tabpage_get_number(Tabpage tabpage, Error *err)
+ FUNC_API_SINCE(1)
{
Integer rv = 0;
tabpage_T *tab = find_tab_by_handle(tabpage, err);
@@ -181,8 +190,11 @@ Integer nvim_tabpage_get_number(Tabpage tabpage, Error *err)
/// @param tabpage Tabpage handle
/// @return true if the tabpage is valid, false otherwise
Boolean nvim_tabpage_is_valid(Tabpage tabpage)
+ FUNC_API_SINCE(1)
{
Error stub = ERROR_INIT;
- return find_tab_by_handle(tabpage, &stub) != NULL;
+ Boolean ret = find_tab_by_handle(tabpage, &stub) != NULL;
+ api_clear_error(&stub);
+ return ret;
}
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index 9178538110..573be23d8e 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
@@ -12,9 +15,11 @@
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
#include "nvim/popupmnu.h"
+#include "nvim/cursor_shape.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "api/ui.c.generated.h"
+# include "ui_events_remote.generated.h"
#endif
typedef struct {
@@ -25,13 +30,13 @@ typedef struct {
static PMap(uint64_t) *connected_uis = NULL;
void remote_ui_init(void)
- FUNC_API_NOEXPORT
+ FUNC_API_NOEXPORT
{
connected_uis = pmap_new(uint64_t)();
}
void remote_ui_disconnect(uint64_t channel_id)
- FUNC_API_NOEXPORT
+ FUNC_API_NOEXPORT
{
UI *ui = pmap_get(uint64_t)(connected_uis, channel_id);
if (!ui) {
@@ -48,27 +53,27 @@ void remote_ui_disconnect(uint64_t channel_id)
void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
Dictionary options, Error *err)
- FUNC_API_NOEVAL
+ FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
if (pmap_has(uint64_t)(connected_uis, channel_id)) {
- api_set_error(err, Exception, _("UI already attached for channel"));
+ api_set_error(err, kErrorTypeException, "UI already attached for channel");
return;
}
if (width <= 0 || height <= 0) {
- api_set_error(err, Validation,
- _("Expected width > 0 and height > 0"));
+ api_set_error(err, kErrorTypeValidation,
+ "Expected width > 0 and height > 0");
return;
}
UI *ui = xcalloc(1, sizeof(UI));
ui->width = (int)width;
ui->height = (int)height;
ui->rgb = true;
- ui->pum_external = false;
ui->resize = remote_ui_resize;
ui->clear = remote_ui_clear;
ui->eol_clear = remote_ui_eol_clear;
ui->cursor_goto = remote_ui_cursor_goto;
+ ui->mode_info_set = remote_ui_mode_info_set;
ui->update_menu = remote_ui_update_menu;
ui->busy_start = remote_ui_busy_start;
ui->busy_stop = remote_ui_busy_stop;
@@ -90,9 +95,11 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
ui->set_icon = remote_ui_set_icon;
ui->event = remote_ui_event;
+ memset(ui->ui_ext, 0, sizeof(ui->ui_ext));
+
for (size_t i = 0; i < options.size; i++) {
ui_set_option(ui, options.items[i].key, options.items[i].value, err);
- if (err->set) {
+ if (ERROR_SET(err)) {
xfree(ui);
return;
}
@@ -118,10 +125,10 @@ void ui_attach(uint64_t channel_id, Integer width, Integer height,
}
void nvim_ui_detach(uint64_t channel_id, Error *err)
- FUNC_API_NOEVAL
+ FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
- api_set_error(err, Exception, _("UI is not attached for channel"));
+ api_set_error(err, kErrorTypeException, "UI is not attached for channel");
return;
}
remote_ui_disconnect(channel_id);
@@ -130,16 +137,16 @@ void nvim_ui_detach(uint64_t channel_id, Error *err)
void nvim_ui_try_resize(uint64_t channel_id, Integer width,
Integer height, Error *err)
- FUNC_API_NOEVAL
+ FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
- api_set_error(err, Exception, _("UI is not attached for channel"));
+ api_set_error(err, kErrorTypeException, "UI is not attached for channel");
return;
}
if (width <= 0 || height <= 0) {
- api_set_error(err, Validation,
- _("Expected width > 0 and height > 0"));
+ api_set_error(err, kErrorTypeValidation,
+ "Expected width > 0 and height > 0");
return;
}
@@ -151,37 +158,61 @@ void nvim_ui_try_resize(uint64_t channel_id, Integer width,
void nvim_ui_set_option(uint64_t channel_id, String name,
Object value, Error *error)
- FUNC_API_NOEVAL
+ FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
- api_set_error(error, Exception, _("UI is not attached for channel"));
+ api_set_error(error, kErrorTypeException, "UI is not attached for channel");
return;
}
UI *ui = pmap_get(uint64_t)(connected_uis, channel_id);
ui_set_option(ui, name, value, error);
- if (!error->set) {
+ if (!ERROR_SET(error)) {
ui_refresh();
}
}
-static void ui_set_option(UI *ui, String name, Object value, Error *error) {
- if (strcmp(name.data, "rgb") == 0) {
+static void ui_set_option(UI *ui, String name, Object value, Error *error)
+{
+#define UI_EXT_OPTION(o, e) \
+ do { \
+ if (strequal(name.data, #o)) { \
+ if (value.type != kObjectTypeBoolean) { \
+ api_set_error(error, kErrorTypeValidation, #o " must be a Boolean"); \
+ return; \
+ } \
+ ui->ui_ext[(e)] = value.data.boolean; \
+ return; \
+ } \
+ } while (0)
+
+ if (strequal(name.data, "rgb")) {
if (value.type != kObjectTypeBoolean) {
- api_set_error(error, Validation, _("rgb must be a Boolean"));
+ api_set_error(error, kErrorTypeValidation, "rgb must be a Boolean");
return;
}
ui->rgb = value.data.boolean;
- } else if (strcmp(name.data, "popupmenu_external") == 0) {
+ return;
+ }
+
+ UI_EXT_OPTION(ext_cmdline, kUICmdline);
+ UI_EXT_OPTION(ext_popupmenu, kUIPopupmenu);
+ UI_EXT_OPTION(ext_tabline, kUITabline);
+ UI_EXT_OPTION(ext_wildmenu, kUIWildmenu);
+
+ if (strequal(name.data, "popupmenu_external")) {
+ // LEGACY: Deprecated option, use `ui_ext` instead.
if (value.type != kObjectTypeBoolean) {
- api_set_error(error, Validation,
- _("popupmenu_external must be a Boolean"));
+ api_set_error(error, kErrorTypeValidation,
+ "popupmenu_external must be a Boolean");
return;
}
- ui->pum_external = value.data.boolean;
- } else {
- api_set_error(error, Validation, _("No such ui option"));
+ ui->ui_ext[kUIPopupmenu] = value.data.boolean;
+ return;
}
+
+ api_set_error(error, kErrorTypeValidation, "No such ui option");
+#undef UI_EXT_OPTION
}
static void push_call(UI *ui, char *name, Array args)
@@ -206,97 +237,6 @@ static void push_call(UI *ui, char *name, Array args)
kv_A(data->buffer, kv_size(data->buffer) - 1).data.array = call;
}
-static void remote_ui_resize(UI *ui, int width, int height)
-{
- Array args = ARRAY_DICT_INIT;
- ADD(args, INTEGER_OBJ(width));
- ADD(args, INTEGER_OBJ(height));
- push_call(ui, "resize", args);
-}
-
-static void remote_ui_clear(UI *ui)
-{
- Array args = ARRAY_DICT_INIT;
- push_call(ui, "clear", args);
-}
-
-static void remote_ui_eol_clear(UI *ui)
-{
- Array args = ARRAY_DICT_INIT;
- push_call(ui, "eol_clear", args);
-}
-
-static void remote_ui_cursor_goto(UI *ui, int row, int col)
-{
- Array args = ARRAY_DICT_INIT;
- ADD(args, INTEGER_OBJ(row));
- ADD(args, INTEGER_OBJ(col));
- push_call(ui, "cursor_goto", args);
-}
-
-static void remote_ui_update_menu(UI *ui)
-{
- Array args = ARRAY_DICT_INIT;
- push_call(ui, "update_menu", args);
-}
-
-static void remote_ui_busy_start(UI *ui)
-{
- Array args = ARRAY_DICT_INIT;
- push_call(ui, "busy_start", args);
-}
-
-static void remote_ui_busy_stop(UI *ui)
-{
- Array args = ARRAY_DICT_INIT;
- push_call(ui, "busy_stop", args);
-}
-
-static void remote_ui_mouse_on(UI *ui)
-{
- Array args = ARRAY_DICT_INIT;
- push_call(ui, "mouse_on", args);
-}
-
-static void remote_ui_mouse_off(UI *ui)
-{
- Array args = ARRAY_DICT_INIT;
- push_call(ui, "mouse_off", args);
-}
-
-static void remote_ui_mode_change(UI *ui, int mode)
-{
- Array args = ARRAY_DICT_INIT;
- if (mode == INSERT) {
- ADD(args, STRING_OBJ(cstr_to_string("insert")));
- } else if (mode == REPLACE) {
- ADD(args, STRING_OBJ(cstr_to_string("replace")));
- } else if (mode == CMDLINE) {
- ADD(args, STRING_OBJ(cstr_to_string("cmdline")));
- } else {
- assert(mode == NORMAL);
- ADD(args, STRING_OBJ(cstr_to_string("normal")));
- }
- push_call(ui, "mode_change", args);
-}
-
-static void remote_ui_set_scroll_region(UI *ui, int top, int bot, int left,
- int right)
-{
- Array args = ARRAY_DICT_INIT;
- ADD(args, INTEGER_OBJ(top));
- ADD(args, INTEGER_OBJ(bot));
- ADD(args, INTEGER_OBJ(left));
- ADD(args, INTEGER_OBJ(right));
- push_call(ui, "set_scroll_region", args);
-}
-
-static void remote_ui_scroll(UI *ui, int count)
-{
- Array args = ARRAY_DICT_INIT;
- ADD(args, INTEGER_OBJ(count));
- push_call(ui, "scroll", args);
-}
static void remote_ui_highlight_set(UI *ui, HlAttrs attrs)
{
@@ -339,72 +279,13 @@ static void remote_ui_highlight_set(UI *ui, HlAttrs attrs)
push_call(ui, "highlight_set", args);
}
-static void remote_ui_put(UI *ui, uint8_t *data, size_t size)
-{
- Array args = ARRAY_DICT_INIT;
- String str = { .data = xmemdupz(data, size), .size = size };
- ADD(args, STRING_OBJ(str));
- push_call(ui, "put", args);
-}
-
-static void remote_ui_bell(UI *ui)
-{
- Array args = ARRAY_DICT_INIT;
- push_call(ui, "bell", args);
-}
-
-static void remote_ui_visual_bell(UI *ui)
-{
- Array args = ARRAY_DICT_INIT;
- push_call(ui, "visual_bell", args);
-}
-
-static void remote_ui_update_fg(UI *ui, int fg)
-{
- Array args = ARRAY_DICT_INIT;
- ADD(args, INTEGER_OBJ(fg));
- push_call(ui, "update_fg", args);
-}
-
-static void remote_ui_update_bg(UI *ui, int bg)
-{
- Array args = ARRAY_DICT_INIT;
- ADD(args, INTEGER_OBJ(bg));
- push_call(ui, "update_bg", args);
-}
-
-static void remote_ui_update_sp(UI *ui, int sp)
-{
- Array args = ARRAY_DICT_INIT;
- ADD(args, INTEGER_OBJ(sp));
- push_call(ui, "update_sp", args);
-}
-
static void remote_ui_flush(UI *ui)
{
UIData *data = ui->data;
- channel_send_event(data->channel_id, "redraw", data->buffer);
- data->buffer = (Array)ARRAY_DICT_INIT;
-}
-
-static void remote_ui_suspend(UI *ui)
-{
- Array args = ARRAY_DICT_INIT;
- push_call(ui, "suspend", args);
-}
-
-static void remote_ui_set_title(UI *ui, char *title)
-{
- Array args = ARRAY_DICT_INIT;
- ADD(args, STRING_OBJ(cstr_to_string(title)));
- push_call(ui, "set_title", args);
-}
-
-static void remote_ui_set_icon(UI *ui, char *icon)
-{
- Array args = ARRAY_DICT_INIT;
- ADD(args, STRING_OBJ(cstr_to_string(icon)));
- push_call(ui, "set_icon", args);
+ if (data->buffer.size > 0) {
+ channel_send_event(data->channel_id, "redraw", data->buffer);
+ data->buffer = (Array)ARRAY_DICT_INIT;
+ }
}
static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed)
diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h
new file mode 100644
index 0000000000..1b5d17584f
--- /dev/null
+++ b/src/nvim/api/ui_events.in.h
@@ -0,0 +1,71 @@
+#ifndef NVIM_API_UI_EVENTS_IN_H
+#define NVIM_API_UI_EVENTS_IN_H
+
+// This file is not compiled, just parsed for definitons
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# error "don't include this file, include nvim/ui.h"
+#endif
+
+#include "nvim/api/private/defs.h"
+#include "nvim/func_attr.h"
+#include "nvim/ui.h"
+
+void resize(Integer rows, Integer columns)
+ FUNC_API_SINCE(3);
+void clear(void)
+ FUNC_API_SINCE(3);
+void eol_clear(void)
+ FUNC_API_SINCE(3);
+void cursor_goto(Integer row, Integer col)
+ FUNC_API_SINCE(3);
+void mode_info_set(Boolean enabled, Array cursor_styles)
+ FUNC_API_SINCE(3);
+void update_menu(void)
+ FUNC_API_SINCE(3);
+void busy_start(void)
+ FUNC_API_SINCE(3);
+void busy_stop(void)
+ FUNC_API_SINCE(3);
+void mouse_on(void)
+ FUNC_API_SINCE(3);
+void mouse_off(void)
+ FUNC_API_SINCE(3);
+void mode_change(String mode, Integer mode_idx)
+ FUNC_API_SINCE(3);
+void set_scroll_region(Integer top, Integer bot, Integer left, Integer right)
+ FUNC_API_SINCE(3);
+void scroll(Integer count)
+ FUNC_API_SINCE(3);
+void highlight_set(HlAttrs attrs)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_IMPL FUNC_API_BRIDGE_IMPL;
+void put(String str)
+ FUNC_API_SINCE(3);
+void bell(void)
+ FUNC_API_SINCE(3);
+void visual_bell(void)
+ FUNC_API_SINCE(3);
+void flush(void)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_IMPL;
+void update_fg(Integer fg)
+ FUNC_API_SINCE(3);
+void update_bg(Integer bg)
+ FUNC_API_SINCE(3);
+void update_sp(Integer sp)
+ FUNC_API_SINCE(3);
+void suspend(void)
+ FUNC_API_SINCE(3) FUNC_API_BRIDGE_IMPL;
+void set_title(String title)
+ FUNC_API_SINCE(3);
+void set_icon(String icon)
+ FUNC_API_SINCE(3);
+
+void popupmenu_show(Array items, Integer selected, Integer row, Integer col)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void popupmenu_hide(void)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void popupmenu_select(Integer selected)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void tabline_update(Tabpage current, Array tabs)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+
+#endif // NVIM_API_UI_EVENTS_IN_H
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index b17b59f7a6..cfbe34b848 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <stdint.h>
#include <inttypes.h>
@@ -10,8 +13,10 @@
#include "nvim/ascii.h"
#include "nvim/api/private/helpers.h"
#include "nvim/api/private/defs.h"
+#include "nvim/api/private/dispatch.h"
#include "nvim/api/buffer.h"
#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/lua/executor.h"
#include "nvim/vim.h"
#include "nvim/buffer.h"
#include "nvim/file_search.h"
@@ -22,7 +27,9 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval.h"
#include "nvim/option.h"
+#include "nvim/state.h"
#include "nvim/syntax.h"
#include "nvim/getchar.h"
#include "nvim/os/input.h"
@@ -39,6 +46,7 @@
/// @param command Ex-command string
/// @param[out] err Error details (including actual VimL error), if any
void nvim_command(String command, Error *err)
+ FUNC_API_SINCE(1)
{
// Run the command
try_start();
@@ -56,6 +64,7 @@ void nvim_command(String command, Error *err)
/// @see feedkeys()
/// @see vim_strsave_escape_csi
void nvim_feedkeys(String keys, String mode, Boolean escape_csi)
+ FUNC_API_SINCE(1)
{
bool remap = true;
bool insert = false;
@@ -122,43 +131,44 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_csi)
/// @return Number of bytes actually written (can be fewer than
/// requested if the buffer becomes full).
Integer nvim_input(String keys)
- FUNC_API_ASYNC
+ FUNC_API_SINCE(1) FUNC_API_ASYNC
{
return (Integer)input_enqueue(keys);
}
-/// Replaces any terminal codes with the internal representation
+/// Replaces terminal codes and |keycodes| (<CR>, <Esc>, ...) in a string with
+/// the internal representation.
///
+/// @param str String to be converted.
+/// @param from_part Legacy Vim parameter. Usually true.
+/// @param do_lt Also translate <lt>. Ignored if `special` is false.
+/// @param special Replace |keycodes|, e.g. <CR> becomes a "\n" char.
/// @see replace_termcodes
/// @see cpoptions
String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt,
Boolean special)
+ FUNC_API_SINCE(1)
{
if (str.size == 0) {
// Empty string
- return str;
+ return (String) { .data = NULL, .size = 0 };
}
char *ptr = NULL;
- // Set 'cpoptions' the way we want it.
- // FLAG_CPO_BSLASH set - backslashes are *not* treated specially
- // FLAG_CPO_KEYCODE set - keycodes are *not* reverse-engineered
- // FLAG_CPO_SPECI unset - <Key> sequences *are* interpreted
- // The third from end parameter of replace_termcodes() is true so that the
- // <lt> sequence is recognised - needed for a real backslash.
replace_termcodes((char_u *)str.data, str.size, (char_u **)&ptr,
from_part, do_lt, special, CPO_TO_CPO_FLAGS);
return cstr_as_string(ptr);
}
String nvim_command_output(String str, Error *err)
+ FUNC_API_SINCE(1)
{
do_cmdline_cmd("redir => v:command_output");
nvim_command(str, err);
do_cmdline_cmd("redir END");
- if (err->set) {
- return (String) STRING_INIT;
+ if (ERROR_SET(err)) {
+ return (String)STRING_INIT;
}
return cstr_to_string((char *)get_vim_var_str(VV_COMMAND_OUTPUT));
@@ -172,27 +182,30 @@ String nvim_command_output(String str, Error *err)
/// @param[out] err Error details, if any
/// @return Evaluation result or expanded object
Object nvim_eval(String expr, Error *err)
+ FUNC_API_SINCE(1)
{
Object rv = OBJECT_INIT;
// Evaluate the expression
try_start();
- typval_T *expr_result = eval_expr((char_u *)expr.data, NULL);
- if (!expr_result) {
- api_set_error(err, Exception, _("Failed to evaluate expression"));
+ typval_T rettv;
+ if (eval0((char_u *)expr.data, &rettv, NULL, true) == FAIL) {
+ api_set_error(err, kErrorTypeException, "Failed to evaluate expression");
}
if (!try_end(err)) {
// No errors, convert the result
- rv = vim_to_object(expr_result);
+ rv = vim_to_object(&rettv);
}
- // Free the vim object
- free_tv(expr_result);
+ // Free the Vim object
+ tv_clear(&rettv);
+
return rv;
}
-/// Calls a VimL function with the given arguments.
+/// Calls a VimL function with the given arguments
+///
/// On VimL error: Returns a generic error; v:errmsg is not updated.
///
/// @param fname Function to call
@@ -200,11 +213,12 @@ Object nvim_eval(String expr, Error *err)
/// @param[out] err Error details, if any
/// @return Result of the function call
Object nvim_call_function(String fname, Array args, Error *err)
+ FUNC_API_SINCE(1)
{
Object rv = OBJECT_INIT;
if (args.size > MAX_FUNC_ARGS) {
- api_set_error(err, Validation,
- _("Function called with too many arguments."));
+ api_set_error(err, kErrorTypeValidation,
+ "Function called with too many arguments.");
return rv;
}
@@ -221,27 +235,45 @@ Object nvim_call_function(String fname, Array args, Error *err)
// Call the function
typval_T rettv;
int dummy;
- int r = call_func((char_u *) fname.data, (int) fname.size,
- &rettv, (int) args.size, vim_args,
+ int r = call_func((char_u *)fname.data, (int)fname.size,
+ &rettv, (int)args.size, vim_args, NULL,
curwin->w_cursor.lnum, curwin->w_cursor.lnum, &dummy,
- true,
- NULL, NULL);
+ true, NULL, NULL);
if (r == FAIL) {
- api_set_error(err, Exception, _("Error calling function."));
+ api_set_error(err, kErrorTypeException, "Error calling function.");
}
if (!try_end(err)) {
rv = vim_to_object(&rettv);
}
- clear_tv(&rettv);
+ tv_clear(&rettv);
free_vim_args:
while (i > 0) {
- clear_tv(&vim_args[--i]);
+ tv_clear(&vim_args[--i]);
}
return rv;
}
+/// Execute lua code. Parameters might be passed, they are available inside
+/// the chunk as `...`. The chunk can return a value.
+///
+/// To evaluate an expression, it must be prefixed with "return ". For
+/// instance, to call a lua function with arguments sent in and get its
+/// return value back, use the code "return my_function(...)".
+///
+/// @param code lua code to execute
+/// @param args Arguments to the code
+/// @param[out] err Details of an error encountered while parsing
+/// or executing the lua code.
+///
+/// @return Return value of lua code if present or NIL.
+Object nvim_execute_lua(String code, Array args, Error *err)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY
+{
+ return executor_exec_lua_api(code, args, err);
+}
+
/// Calculates the number of display cells occupied by `text`.
/// <Tab> counts as one cell.
///
@@ -249,9 +281,10 @@ free_vim_args:
/// @param[out] err Error details, if any
/// @return Number of cells
Integer nvim_strwidth(String str, Error *err)
+ FUNC_API_SINCE(1)
{
if (str.size > INT_MAX) {
- api_set_error(err, Validation, _("String length is too high"));
+ api_set_error(err, kErrorTypeValidation, "String length is too high");
return 0;
}
@@ -262,9 +295,10 @@ Integer nvim_strwidth(String str, Error *err)
///
/// @return List of paths
ArrayOf(String) nvim_list_runtime_paths(void)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
- uint8_t *rtp = p_rtp;
+ char_u *rtp = p_rtp;
if (*rtp == NUL) {
// No paths
@@ -278,13 +312,14 @@ ArrayOf(String) nvim_list_runtime_paths(void)
}
rtp++;
}
+ rv.size++;
// Allocate memory for the copies
- rv.items = xmalloc(sizeof(Object) * rv.size);
+ rv.items = xmalloc(sizeof(*rv.items) * rv.size);
// Reset the position
rtp = p_rtp;
// Start copying
- for (size_t i = 0; i < rv.size && *rtp != NUL; i++) {
+ for (size_t i = 0; i < rv.size; i++) {
rv.items[i].type = kObjectTypeString;
rv.items[i].data.string.data = xmalloc(MAXPATHL);
// Copy the path from 'runtimepath' to rv.items[i]
@@ -303,21 +338,22 @@ ArrayOf(String) nvim_list_runtime_paths(void)
/// @param dir Directory path
/// @param[out] err Error details, if any
void nvim_set_current_dir(String dir, Error *err)
+ FUNC_API_SINCE(1)
{
if (dir.size >= MAXPATHL) {
- api_set_error(err, Validation, _("Directory string is too long"));
+ api_set_error(err, kErrorTypeValidation, "Directory string is too long");
return;
}
char string[MAXPATHL];
- strncpy(string, dir.data, dir.size);
+ memcpy(string, dir.data, dir.size);
string[dir.size] = NUL;
try_start();
- if (vim_chdir((char_u *)string)) {
+ if (vim_chdir((char_u *)string, kCdScopeGlobal)) {
if (!try_end(err)) {
- api_set_error(err, Exception, _("Failed to change directory"));
+ api_set_error(err, kErrorTypeException, "Failed to change directory");
}
return;
}
@@ -331,6 +367,7 @@ void nvim_set_current_dir(String dir, Error *err)
/// @param[out] err Error details, if any
/// @return Current line string
String nvim_get_current_line(Error *err)
+ FUNC_API_SINCE(1)
{
return buffer_get_line(curbuf->handle, curwin->w_cursor.lnum - 1, err);
}
@@ -340,6 +377,7 @@ String nvim_get_current_line(Error *err)
/// @param line Line contents
/// @param[out] err Error details, if any
void nvim_set_current_line(String line, Error *err)
+ FUNC_API_SINCE(1)
{
buffer_set_line(curbuf->handle, curwin->w_cursor.lnum - 1, line, err);
}
@@ -348,6 +386,7 @@ void nvim_set_current_line(String line, Error *err)
///
/// @param[out] err Error details, if any
void nvim_del_current_line(Error *err)
+ FUNC_API_SINCE(1)
{
buffer_del_line(curbuf->handle, curwin->w_cursor.lnum - 1, err);
}
@@ -358,6 +397,7 @@ void nvim_del_current_line(Error *err)
/// @param[out] err Error details, if any
/// @return Variable value
Object nvim_get_var(String name, Error *err)
+ FUNC_API_SINCE(1)
{
return dict_get_value(&globvardict, name, err);
}
@@ -368,8 +408,9 @@ Object nvim_get_var(String name, Error *err)
/// @param value Variable value
/// @param[out] err Error details, if any
void nvim_set_var(String name, Object value, Error *err)
+ FUNC_API_SINCE(1)
{
- dict_set_value(&globvardict, name, value, false, false, err);
+ dict_set_var(&globvardict, name, value, false, false, err);
}
/// Removes a global (g:) variable
@@ -377,8 +418,9 @@ void nvim_set_var(String name, Object value, Error *err)
/// @param name Variable name
/// @param[out] err Error details, if any
void nvim_del_var(String name, Error *err)
+ FUNC_API_SINCE(1)
{
- dict_set_value(&globvardict, name, NIL, true, false, err);
+ dict_set_var(&globvardict, name, NIL, true, false, err);
}
/// Sets a global variable
@@ -394,7 +436,7 @@ void nvim_del_var(String name, Error *err)
/// or if previous value was `v:null`.
Object vim_set_var(String name, Object value, Error *err)
{
- return dict_set_value(&globvardict, name, value, false, true, err);
+ return dict_set_var(&globvardict, name, value, false, true, err);
}
/// Removes a global variable
@@ -406,7 +448,7 @@ Object vim_set_var(String name, Object value, Error *err)
/// @return Old value
Object vim_del_var(String name, Error *err)
{
- return dict_set_value(&globvardict, name, NIL, true, true, err);
+ return dict_set_var(&globvardict, name, NIL, true, true, err);
}
/// Gets a v: variable
@@ -415,6 +457,7 @@ Object vim_del_var(String name, Error *err)
/// @param[out] err Error details, if any
/// @return Variable value
Object nvim_get_vvar(String name, Error *err)
+ FUNC_API_SINCE(1)
{
return dict_get_value(&vimvardict, name, err);
}
@@ -423,8 +466,9 @@ Object nvim_get_vvar(String name, Error *err)
///
/// @param name Option name
/// @param[out] err Error details, if any
-/// @return Option value
+/// @return Option value (global)
Object nvim_get_option(String name, Error *err)
+ FUNC_API_SINCE(1)
{
return get_option_from(NULL, SREQ_GLOBAL, name, err);
}
@@ -435,32 +479,38 @@ Object nvim_get_option(String name, Error *err)
/// @param value New option value
/// @param[out] err Error details, if any
void nvim_set_option(String name, Object value, Error *err)
+ FUNC_API_SINCE(1)
{
set_option_to(NULL, SREQ_GLOBAL, name, value, err);
}
-/// Writes a message to vim output buffer
+/// Writes a message to the Vim output buffer. Does not append "\n", the
+/// message is buffered (won't display) until a linefeed is written.
///
/// @param str Message
void nvim_out_write(String str)
+ FUNC_API_SINCE(1)
{
write_msg(str, false);
}
-/// Writes a message to vim error buffer
+/// Writes a message to the Vim error buffer. Does not append "\n", the
+/// message is buffered (won't display) until a linefeed is written.
///
/// @param str Message
void nvim_err_write(String str)
+ FUNC_API_SINCE(1)
{
write_msg(str, true);
}
-/// Writes a message to vim error buffer. Appends a linefeed to ensure all
-/// contents are written.
+/// Writes a message to the Vim error buffer. Appends "\n", so the buffer is
+/// flushed (and displayed).
///
/// @param str Message
/// @see nvim_err_write()
void nvim_err_writeln(String str)
+ FUNC_API_SINCE(1)
{
nvim_err_write(str);
nvim_err_write((String) { .data = "\n", .size = 1 });
@@ -470,6 +520,7 @@ void nvim_err_writeln(String str)
///
/// @return List of buffer handles
ArrayOf(Buffer) nvim_list_bufs(void)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
@@ -491,6 +542,7 @@ ArrayOf(Buffer) nvim_list_bufs(void)
///
/// @return Buffer handle
Buffer nvim_get_current_buf(void)
+ FUNC_API_SINCE(1)
{
return curbuf->handle;
}
@@ -500,6 +552,7 @@ Buffer nvim_get_current_buf(void)
/// @param id Buffer handle
/// @param[out] err Error details, if any
void nvim_set_current_buf(Buffer buffer, Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -511,8 +564,8 @@ void nvim_set_current_buf(Buffer buffer, Error *err)
int result = do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, buf->b_fnum, 0);
if (!try_end(err) && result == FAIL) {
api_set_error(err,
- Exception,
- _("Failed to switch to buffer %d"),
+ kErrorTypeException,
+ "Failed to switch to buffer %d",
buffer);
}
}
@@ -521,6 +574,7 @@ void nvim_set_current_buf(Buffer buffer, Error *err)
///
/// @return List of window handles
ArrayOf(Window) nvim_list_wins(void)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
@@ -542,6 +596,7 @@ ArrayOf(Window) nvim_list_wins(void)
///
/// @return Window handle
Window nvim_get_current_win(void)
+ FUNC_API_SINCE(1)
{
return curwin->handle;
}
@@ -550,6 +605,7 @@ Window nvim_get_current_win(void)
///
/// @param handle Window handle
void nvim_set_current_win(Window window, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -561,8 +617,8 @@ void nvim_set_current_win(Window window, Error *err)
goto_tabpage_win(win_find_tabpage(win), win);
if (!try_end(err) && win != curwin) {
api_set_error(err,
- Exception,
- _("Failed to switch to window %d"),
+ kErrorTypeException,
+ "Failed to switch to window %d",
window);
}
}
@@ -571,6 +627,7 @@ void nvim_set_current_win(Window window, Error *err)
///
/// @return List of tabpage handles
ArrayOf(Tabpage) nvim_list_tabpages(void)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
@@ -592,6 +649,7 @@ ArrayOf(Tabpage) nvim_list_tabpages(void)
///
/// @return Tabpage handle
Tabpage nvim_get_current_tabpage(void)
+ FUNC_API_SINCE(1)
{
return curtab->handle;
}
@@ -601,6 +659,7 @@ Tabpage nvim_get_current_tabpage(void)
/// @param handle Tabpage handle
/// @param[out] err Error details, if any
void nvim_set_current_tabpage(Tabpage tabpage, Error *err)
+ FUNC_API_SINCE(1)
{
tabpage_T *tp = find_tab_by_handle(tabpage, err);
@@ -612,8 +671,8 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err)
goto_tabpage_tp(tp, true, true);
if (!try_end(err) && tp != curtab) {
api_set_error(err,
- Exception,
- _("Failed to switch to tabpage %d"),
+ kErrorTypeException,
+ "Failed to switch to tabpage %d",
tabpage);
}
}
@@ -623,7 +682,7 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err)
/// @param channel_id Channel id (passed automatically by the dispatcher)
/// @param event Event type string
void nvim_subscribe(uint64_t channel_id, String event)
- FUNC_API_NOEVAL
+ FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
size_t length = (event.size < METHOD_MAXLEN ? event.size : METHOD_MAXLEN);
char e[METHOD_MAXLEN + 1];
@@ -637,7 +696,7 @@ void nvim_subscribe(uint64_t channel_id, String event)
/// @param channel_id Channel id (passed automatically by the dispatcher)
/// @param event Event type string
void nvim_unsubscribe(uint64_t channel_id, String event)
- FUNC_API_NOEVAL
+ FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
size_t length = (event.size < METHOD_MAXLEN ?
event.size :
@@ -649,11 +708,13 @@ void nvim_unsubscribe(uint64_t channel_id, String event)
}
Integer nvim_get_color_by_name(String name)
+ FUNC_API_SINCE(1)
{
- return name_to_color((uint8_t *)name.data);
+ return name_to_color((char_u *)name.data);
}
Dictionary nvim_get_color_map(void)
+ FUNC_API_SINCE(1)
{
Dictionary colors = ARRAY_DICT_INIT;
@@ -665,8 +726,37 @@ Dictionary nvim_get_color_map(void)
}
+/// Gets the current mode.
+/// mode: Mode string. |mode()|
+/// blocking: true if Nvim is waiting for input.
+///
+/// @returns Dictionary { "mode": String, "blocking": Boolean }
+Dictionary nvim_get_mode(void)
+ FUNC_API_SINCE(2) FUNC_API_ASYNC
+{
+ Dictionary rv = ARRAY_DICT_INIT;
+ char *modestr = get_mode();
+ bool blocked = input_blocking();
+
+ PUT(rv, "mode", STRING_OBJ(cstr_as_string(modestr)));
+ PUT(rv, "blocking", BOOLEAN_OBJ(blocked));
+
+ return rv;
+}
+
+/// Get a list of dictionaries describing global (i.e. non-buffer) mappings
+/// Note that the "buffer" key will be 0 to represent false.
+///
+/// @param mode The abbreviation for the mode
+/// @returns An array of maparg() like dictionaries describing mappings
+ArrayOf(Dictionary) nvim_get_keymap(String mode)
+ FUNC_API_SINCE(3)
+{
+ return keymap_array(mode, NULL);
+}
+
Array nvim_get_api_info(uint64_t channel_id)
- FUNC_API_ASYNC FUNC_API_NOEVAL
+ FUNC_API_SINCE(1) FUNC_API_ASYNC FUNC_API_REMOTE_ONLY
{
Array rv = ARRAY_DICT_INIT;
@@ -699,7 +789,7 @@ Array nvim_get_api_info(uint64_t channel_id)
/// which resulted in an error, the error type and the error message. If an
/// error ocurred, the values from all preceding calls will still be returned.
Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err)
- FUNC_API_NOEVAL
+ FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
Array rv = ARRAY_DICT_INIT;
Array results = ARRAY_DICT_INIT;
@@ -709,30 +799,30 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err)
for (i = 0; i < calls.size; i++) {
if (calls.items[i].type != kObjectTypeArray) {
api_set_error(err,
- Validation,
- _("All items in calls array must be arrays"));
+ kErrorTypeValidation,
+ "All items in calls array must be arrays");
goto validation_error;
}
Array call = calls.items[i].data.array;
if (call.size != 2) {
api_set_error(err,
- Validation,
- _("All items in calls array must be arrays of size 2"));
+ kErrorTypeValidation,
+ "All items in calls array must be arrays of size 2");
goto validation_error;
}
if (call.items[0].type != kObjectTypeString) {
api_set_error(err,
- Validation,
- _("name must be String"));
+ kErrorTypeValidation,
+ "Name must be String");
goto validation_error;
}
String name = call.items[0].data.string;
if (call.items[1].type != kObjectTypeArray) {
api_set_error(err,
- Validation,
- _("args must be Array"));
+ kErrorTypeValidation,
+ "Args must be Array");
goto validation_error;
}
Array args = call.items[1].data.array;
@@ -740,7 +830,7 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err)
MsgpackRpcRequestHandler handler = msgpack_rpc_get_handler_for(name.data,
name.size);
Object result = handler.fn(channel_id, args, &nested_error);
- if (nested_error.set) {
+ if (ERROR_SET(&nested_error)) {
// error handled after loop
break;
}
@@ -749,7 +839,7 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err)
}
ADD(rv, ARRAY_OBJ(results));
- if (nested_error.set) {
+ if (ERROR_SET(&nested_error)) {
Array errval = ARRAY_DICT_INIT;
ADD(errval, INTEGER_OBJ((Integer)i));
ADD(errval, INTEGER_OBJ(nested_error.type));
@@ -758,10 +848,12 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err)
} else {
ADD(rv, NIL);
}
- return rv;
+ goto theend;
validation_error:
api_free_array(results);
+theend:
+ api_clear_error(&nested_error);
return rv;
}
@@ -780,7 +872,7 @@ static void write_msg(String message, bool to_err)
#define PUSH_CHAR(i, pos, line_buf, msg) \
if (message.data[i] == NL || pos == LINE_BUFFER_SIZE - 1) { \
line_buf[pos] = NUL; \
- msg((uint8_t *)line_buf); \
+ msg((char_u *)line_buf); \
pos = 0; \
continue; \
} \
@@ -798,3 +890,57 @@ static void write_msg(String message, bool to_err)
--no_wait_return;
msg_end();
}
+
+// Functions used for testing purposes
+
+/// Returns object given as argument
+///
+/// This API function is used for testing. One should not rely on its presence
+/// in plugins.
+///
+/// @param[in] obj Object to return.
+///
+/// @return its argument.
+Object nvim__id(Object obj)
+{
+ return copy_object(obj);
+}
+
+/// Returns array given as argument
+///
+/// This API function is used for testing. One should not rely on its presence
+/// in plugins.
+///
+/// @param[in] arr Array to return.
+///
+/// @return its argument.
+Array nvim__id_array(Array arr)
+{
+ return copy_object(ARRAY_OBJ(arr)).data.array;
+}
+
+/// Returns dictionary given as argument
+///
+/// This API function is used for testing. One should not rely on its presence
+/// in plugins.
+///
+/// @param[in] dct Dictionary to return.
+///
+/// @return its argument.
+Dictionary nvim__id_dictionary(Dictionary dct)
+{
+ return copy_object(DICTIONARY_OBJ(dct)).data.dictionary;
+}
+
+/// Returns floating-point value given as argument
+///
+/// This API function is used for testing. One should not rely on its presence
+/// in plugins.
+///
+/// @param[in] flt Value to return.
+///
+/// @return its argument.
+Float nvim__id_float(Float flt)
+{
+ return flt;
+}
diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c
index 1f555a6a05..9bc91ef8fb 100644
--- a/src/nvim/api/window.c
+++ b/src/nvim/api/window.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
@@ -19,6 +22,7 @@
/// @param[out] err Error details, if any
/// @return Buffer handle
Buffer nvim_win_get_buf(Window window, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -35,6 +39,7 @@ Buffer nvim_win_get_buf(Window window, Error *err)
/// @param[out] err Error details, if any
/// @return (row, col) tuple
ArrayOf(Integer, 2) nvim_win_get_cursor(Window window, Error *err)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
win_T *win = find_window_by_handle(window, err);
@@ -53,18 +58,19 @@ ArrayOf(Integer, 2) nvim_win_get_cursor(Window window, Error *err)
/// @param pos (row, col) tuple representing the new position
/// @param[out] err Error details, if any
void nvim_win_set_cursor(Window window, ArrayOf(Integer, 2) pos, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
- if (pos.size != 2 || pos.items[0].type != kObjectTypeInteger
- || pos.items[1].type != kObjectTypeInteger) {
- api_set_error(err,
- Validation,
- _("Argument \"pos\" must be a [row, col] array"));
+ if (!win) {
return;
}
- if (!win) {
+ if (pos.size != 2 || pos.items[0].type != kObjectTypeInteger
+ || pos.items[1].type != kObjectTypeInteger) {
+ api_set_error(err,
+ kErrorTypeValidation,
+ "Argument \"pos\" must be a [row, col] array");
return;
}
@@ -72,12 +78,12 @@ void nvim_win_set_cursor(Window window, ArrayOf(Integer, 2) pos, Error *err)
int64_t col = pos.items[1].data.integer;
if (row <= 0 || row > win->w_buffer->b_ml.ml_line_count) {
- api_set_error(err, Validation, _("Cursor position outside buffer"));
+ api_set_error(err, kErrorTypeValidation, "Cursor position outside buffer");
return;
}
if (col > MAXCOL || col < 0) {
- api_set_error(err, Validation, _("Column value outside range"));
+ api_set_error(err, kErrorTypeValidation, "Column value outside range");
return;
}
@@ -99,6 +105,7 @@ void nvim_win_set_cursor(Window window, ArrayOf(Integer, 2) pos, Error *err)
/// @param[out] err Error details, if any
/// @return Height as a count of rows
Integer nvim_win_get_height(Window window, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -116,6 +123,7 @@ Integer nvim_win_get_height(Window window, Error *err)
/// @param height Height as a count of rows
/// @param[out] err Error details, if any
void nvim_win_set_height(Window window, Integer height, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -124,7 +132,7 @@ void nvim_win_set_height(Window window, Integer height, Error *err)
}
if (height > INT_MAX || height < INT_MIN) {
- api_set_error(err, Validation, _("Height value outside range"));
+ api_set_error(err, kErrorTypeValidation, "Height value outside range");
return;
}
@@ -142,6 +150,7 @@ void nvim_win_set_height(Window window, Integer height, Error *err)
/// @param[out] err Error details, if any
/// @return Width as a count of columns
Integer nvim_win_get_width(Window window, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -159,6 +168,7 @@ Integer nvim_win_get_width(Window window, Error *err)
/// @param width Width as a count of columns
/// @param[out] err Error details, if any
void nvim_win_set_width(Window window, Integer width, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -167,7 +177,7 @@ void nvim_win_set_width(Window window, Integer width, Error *err)
}
if (width > INT_MAX || width < INT_MIN) {
- api_set_error(err, Validation, _("Width value outside range"));
+ api_set_error(err, kErrorTypeValidation, "Width value outside range");
return;
}
@@ -186,6 +196,7 @@ void nvim_win_set_width(Window window, Integer width, Error *err)
/// @param[out] err Error details, if any
/// @return Variable value
Object nvim_win_get_var(Window window, String name, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -203,6 +214,7 @@ Object nvim_win_get_var(Window window, String name, Error *err)
/// @param value Variable value
/// @param[out] err Error details, if any
void nvim_win_set_var(Window window, String name, Object value, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -210,7 +222,7 @@ void nvim_win_set_var(Window window, String name, Object value, Error *err)
return;
}
- dict_set_value(win->w_vars, name, value, false, false, err);
+ dict_set_var(win->w_vars, name, value, false, false, err);
}
/// Removes a window-scoped (w:) variable
@@ -219,6 +231,7 @@ void nvim_win_set_var(Window window, String name, Object value, Error *err)
/// @param name Variable name
/// @param[out] err Error details, if any
void nvim_win_del_var(Window window, String name, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -226,7 +239,7 @@ void nvim_win_del_var(Window window, String name, Error *err)
return;
}
- dict_set_value(win->w_vars, name, NIL, true, false, err);
+ dict_set_var(win->w_vars, name, NIL, true, false, err);
}
/// Sets a window-scoped (w:) variable
@@ -249,7 +262,7 @@ Object window_set_var(Window window, String name, Object value, Error *err)
return (Object) OBJECT_INIT;
}
- return dict_set_value(win->w_vars, name, value, false, true, err);
+ return dict_set_var(win->w_vars, name, value, false, true, err);
}
/// Removes a window-scoped (w:) variable
@@ -268,7 +281,7 @@ Object window_del_var(Window window, String name, Error *err)
return (Object) OBJECT_INIT;
}
- return dict_set_value(win->w_vars, name, NIL, true, true, err);
+ return dict_set_var(win->w_vars, name, NIL, true, true, err);
}
/// Gets a window option value
@@ -278,6 +291,7 @@ Object window_del_var(Window window, String name, Error *err)
/// @param[out] err Error details, if any
/// @return Option value
Object nvim_win_get_option(Window window, String name, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -296,6 +310,7 @@ Object nvim_win_get_option(Window window, String name, Error *err)
/// @param value Option value
/// @param[out] err Error details, if any
void nvim_win_set_option(Window window, String name, Object value, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -312,6 +327,7 @@ void nvim_win_set_option(Window window, String name, Object value, Error *err)
/// @param[out] err Error details, if any
/// @return (row, col) tuple with the window position
ArrayOf(Integer, 2) nvim_win_get_position(Window window, Error *err)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
win_T *win = find_window_by_handle(window, err);
@@ -330,6 +346,7 @@ ArrayOf(Integer, 2) nvim_win_get_position(Window window, Error *err)
/// @param[out] err Error details, if any
/// @return Tabpage that contains the window
Tabpage nvim_win_get_tabpage(Window window, Error *err)
+ FUNC_API_SINCE(1)
{
Tabpage rv = 0;
win_T *win = find_window_by_handle(window, err);
@@ -347,6 +364,7 @@ Tabpage nvim_win_get_tabpage(Window window, Error *err)
/// @param[out] err Error details, if any
/// @return Window number
Integer nvim_win_get_number(Window window, Error *err)
+ FUNC_API_SINCE(1)
{
int rv = 0;
win_T *win = find_window_by_handle(window, err);
@@ -366,8 +384,11 @@ Integer nvim_win_get_number(Window window, Error *err)
/// @param window Window handle
/// @return true if the window is valid, false otherwise
Boolean nvim_win_is_valid(Window window)
+ FUNC_API_SINCE(1)
{
Error stub = ERROR_INIT;
- return find_window_by_handle(window, &stub) != NULL;
+ Boolean ret = find_window_by_handle(window, &stub) != NULL;
+ api_clear_error(&stub);
+ return ret;
}
diff --git a/src/nvim/arabic.c b/src/nvim/arabic.c
index db97bd9dc4..1ef51d2a2a 100644
--- a/src/nvim/arabic.c
+++ b/src/nvim/arabic.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// @file arabic.c
///
/// Functions for Arabic language.
diff --git a/src/nvim/ascii.h b/src/nvim/ascii.h
index 44ff540b40..adde91f9ec 100644
--- a/src/nvim/ascii.h
+++ b/src/nvim/ascii.h
@@ -8,9 +8,11 @@
// Definitions of various common control characters.
-#define CharOrd(x) ((x) < 'a' ? (x) - 'A' : (x) - 'a')
-#define CharOrdLow(x) ((x) - 'a')
-#define CharOrdUp(x) ((x) - 'A')
+#define CharOrd(x) ((uint8_t)(x) < 'a' \
+ ? (uint8_t)(x) - 'A'\
+ : (uint8_t)(x) - 'a')
+#define CharOrdLow(x) ((uint8_t)(x) - 'a')
+#define CharOrdUp(x) ((uint8_t)(x) - 'A')
#define ROT13(c, a) (((((c) - (a)) + 13) % 26) + (a))
#define NUL '\000'
@@ -18,15 +20,14 @@
#define BS '\010'
#define TAB '\011'
#define NL '\012'
-#define NL_STR (char_u *)"\012"
+#define NL_STR "\012"
#define FF '\014'
#define CAR '\015' /* CR is used by Mac OS X */
#define ESC '\033'
-#define ESC_STR (char_u *)"\033"
-#define ESC_STR_nc "\033"
+#define ESC_STR "\033"
#define DEL 0x7f
-#define DEL_STR (char_u *)"\177"
-#define CSI 0x9b /* Control Sequence Introducer */
+#define DEL_STR "\177"
+#define CSI 0x9b // Control Sequence Introducer
#define CSI_STR "\233"
#define DCS 0x90 /* Device Control String */
#define STERM 0x9c /* String Terminator */
diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua
index 8d891effae..68a47c244f 100644
--- a/src/nvim/auevents.lua
+++ b/src/nvim/auevents.lua
@@ -28,6 +28,7 @@ return {
'CursorHoldI', -- idem, in Insert mode
'CursorMoved', -- cursor was moved
'CursorMovedI', -- cursor was moved in Insert mode
+ 'DirChanged', -- directory changed
'EncodingChanged', -- after changing the 'encoding' option
'FileAppendCmd', -- append to a file using command
'FileAppendPost', -- after appending to a file
@@ -89,6 +90,7 @@ return {
'VimLeave', -- before exiting Vim
'VimLeavePre', -- before exiting Vim and writing ShaDa file
'VimResized', -- after Vim window was resized
+ 'WinNew', -- when entering a new window
'WinEnter', -- after entering a window
'WinLeave', -- before leaving a window
},
@@ -101,6 +103,7 @@ return {
-- List of neovim-specific events or aliases for the purpose of generating
-- syntax file
neovim_specific = {
+ DirChanged=true,
TabClosed=true,
TabNew=true,
TabNewEntered=true,
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index d9fdc80c60..724a8578ac 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* buffer.c: functions for dealing with the buffer structure
*/
@@ -21,6 +24,7 @@
#include <inttypes.h>
#include "nvim/api/private/handle.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
#include "nvim/assert.h"
#include "nvim/vim.h"
@@ -70,6 +74,12 @@
#include "nvim/os/time.h"
#include "nvim/os/input.h"
+typedef enum {
+ kBLSUnchanged = 0,
+ kBLSChanged = 1,
+ kBLSDeleted = 2,
+} BufhlLineStatus;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "buffer.c.generated.h"
#endif
@@ -78,6 +88,60 @@ static char *msg_loclist = N_("[Location List]");
static char *msg_qflist = N_("[Quickfix List]");
static char *e_auabort = N_("E855: Autocommands caused command to abort");
+// Number of times free_buffer() was called.
+static int buf_free_count = 0;
+
+// Read data from buffer for retrying.
+static int
+read_buffer(
+ int read_stdin, // read file from stdin, otherwise fifo
+ exarg_T *eap, // for forced 'ff' and 'fenc' or NULL
+ int flags) // extra flags for readfile()
+{
+ int retval = OK;
+ linenr_T line_count;
+
+ //
+ // Read from the buffer which the text is already filled in and append at
+ // the end. This makes it possible to retry when 'fileformat' or
+ // 'fileencoding' was guessed wrong.
+ //
+ line_count = curbuf->b_ml.ml_line_count;
+ retval = readfile(
+ read_stdin ? NULL : curbuf->b_ffname,
+ read_stdin ? NULL : curbuf->b_fname,
+ (linenr_T)line_count, (linenr_T)0, (linenr_T)MAXLNUM, eap,
+ flags | READ_BUFFER);
+ if (retval == OK) {
+ // Delete the binary lines.
+ while (--line_count >= 0) {
+ ml_delete((linenr_T)1, false);
+ }
+ } else {
+ // Delete the converted lines.
+ while (curbuf->b_ml.ml_line_count > line_count) {
+ ml_delete(line_count, false);
+ }
+ }
+ // Put the cursor on the first line.
+ curwin->w_cursor.lnum = 1;
+ curwin->w_cursor.col = 0;
+
+ if (read_stdin) {
+ // Set or reset 'modified' before executing autocommands, so that
+ // it can be changed there.
+ if (!readonlymode && !bufempty()) {
+ changed();
+ } else if (retval != FAIL) {
+ unchanged(curbuf, false);
+ }
+
+ apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, false,
+ curbuf, &retval);
+ }
+ return retval;
+}
+
/*
* Open current buffer, that is: open the memfile and read the file into
* memory.
@@ -91,8 +155,9 @@ open_buffer (
)
{
int retval = OK;
- buf_T *old_curbuf;
+ bufref_T old_curbuf;
long old_tw = curbuf->b_p_tw;
+ int read_fifo = false;
/*
* The 'readonly' flag is only set when BF_NEVERLOADED is being reset.
@@ -133,23 +198,55 @@ open_buffer (
return FAIL;
}
- /* The autocommands in readfile() may change the buffer, but only AFTER
- * reading the file. */
- old_curbuf = curbuf;
- modified_was_set = FALSE;
+ // The autocommands in readfile() may change the buffer, but only AFTER
+ // reading the file.
+ set_bufref(&old_curbuf, curbuf);
+ modified_was_set = false;
/* mark cursor position as being invalid */
curwin->w_valid = 0;
if (curbuf->b_ffname != NULL) {
int old_msg_silent = msg_silent;
+#ifdef UNIX
+ int save_bin = curbuf->b_p_bin;
+ int perm;
+
+ perm = os_getperm((const char *)curbuf->b_ffname);
+ if (perm >= 0 && (0
+# ifdef S_ISFIFO
+ || S_ISFIFO(perm)
+# endif
+# ifdef S_ISSOCK
+ || S_ISSOCK(perm)
+# endif
+# ifdef OPEN_CHR_FILES
+ || (S_ISCHR(perm)
+ && is_dev_fd_file(curbuf->b_ffname))
+# endif
+ )
+ ) {
+ read_fifo = true;
+ }
+ if (read_fifo) {
+ curbuf->b_p_bin = true;
+ }
+#endif
if (shortmess(SHM_FILEINFO)) {
msg_silent = 1;
}
retval = readfile(curbuf->b_ffname, curbuf->b_fname,
(linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap,
- flags | READ_NEW);
+ flags | READ_NEW | (read_fifo ? READ_FIFO : 0));
+#ifdef UNIX
+ if (read_fifo) {
+ curbuf->b_p_bin = save_bin;
+ if (retval == OK) {
+ retval = read_buffer(false, eap, flags);
+ }
+ }
+#endif
msg_silent = old_msg_silent;
// Help buffer is filtered.
@@ -158,7 +255,6 @@ open_buffer (
}
} else if (read_stdin) {
int save_bin = curbuf->b_p_bin;
- linenr_T line_count;
/*
* First read the text in binary mode into the buffer.
@@ -172,56 +268,31 @@ open_buffer (
flags | (READ_NEW + READ_STDIN));
curbuf->b_p_bin = save_bin;
if (retval == OK) {
- line_count = curbuf->b_ml.ml_line_count;
- retval = readfile(NULL, NULL, (linenr_T)line_count,
- (linenr_T)0, (linenr_T)MAXLNUM, eap,
- flags | READ_BUFFER);
- if (retval == OK) {
- /* Delete the binary lines. */
- while (--line_count >= 0)
- ml_delete((linenr_T)1, FALSE);
- } else {
- /* Delete the converted lines. */
- while (curbuf->b_ml.ml_line_count > line_count)
- ml_delete(line_count, FALSE);
- }
- /* Put the cursor on the first line. */
- curwin->w_cursor.lnum = 1;
- curwin->w_cursor.col = 0;
-
- /* Set or reset 'modified' before executing autocommands, so that
- * it can be changed there. */
- if (!readonlymode && !bufempty())
- changed();
- else if (retval != FAIL)
- unchanged(curbuf, FALSE);
- apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, FALSE,
- curbuf, &retval);
+ retval = read_buffer(true, eap, flags);
}
}
/* if first time loading this buffer, init b_chartab[] */
if (curbuf->b_flags & BF_NEVERLOADED) {
- (void)buf_init_chartab(curbuf, FALSE);
+ (void)buf_init_chartab(curbuf, false);
parse_cino(curbuf);
}
- /*
- * Set/reset the Changed flag first, autocmds may change the buffer.
- * Apply the automatic commands, before processing the modelines.
- * So the modelines have priority over auto commands.
- */
- /* When reading stdin, the buffer contents always needs writing, so set
- * the changed flag. Unless in readonly mode: "ls | nvim -R -".
- * When interrupted and 'cpoptions' contains 'i' set changed flag. */
+ // Set/reset the Changed flag first, autocmds may change the buffer.
+ // Apply the automatic commands, before processing the modelines.
+ // So the modelines have priority over auto commands.
+
+ // When reading stdin, the buffer contents always needs writing, so set
+ // the changed flag. Unless in readonly mode: "ls | nvim -R -".
+ // When interrupted and 'cpoptions' contains 'i' set changed flag.
if ((got_int && vim_strchr(p_cpo, CPO_INTMOD) != NULL)
- || modified_was_set /* ":set modified" used in autocmd */
- || (aborting() && vim_strchr(p_cpo, CPO_INTMOD) != NULL)
- )
+ || modified_was_set // ":set modified" used in autocmd
+ || (aborting() && vim_strchr(p_cpo, CPO_INTMOD) != NULL)) {
changed();
- else if (retval != FAIL && !read_stdin)
- unchanged(curbuf, FALSE);
- save_file_ff(curbuf); /* keep this fileformat */
+ } else if (retval != FAIL && !read_stdin && !read_fifo) {
+ unchanged(curbuf, false);
+ }
+ save_file_ff(curbuf); // keep this fileformat
/* require "!" to overwrite the file, because it wasn't read completely */
if (aborting())
@@ -246,11 +317,11 @@ open_buffer (
* The autocommands may have changed the current buffer. Apply the
* modelines to the correct buffer, if it still exists and is loaded.
*/
- if (buf_valid(old_curbuf) && old_curbuf->b_ml.ml_mfp != NULL) {
+ if (bufref_valid(&old_curbuf) && old_curbuf.br_buf->b_ml.ml_mfp != NULL) {
aco_save_T aco;
- /* Go to the buffer that was opened. */
- aucmd_prepbuf(&aco, old_curbuf);
+ // Go to the buffer that was opened.
+ aucmd_prepbuf(&aco, old_curbuf.br_buf);
do_modelines(0);
curbuf->b_flags &= ~(BF_CHECK_RO | BF_NEVERLOADED);
@@ -264,14 +335,45 @@ open_buffer (
return retval;
}
-/// Check that "buf" points to a valid buffer (in the buffer list).
+/// Store "buf" in "bufref" and set the free count.
+///
+/// @param bufref Reference to be used for the buffer.
+/// @param buf The buffer to reference.
+void set_bufref(bufref_T *bufref, buf_T *buf)
+{
+ bufref->br_buf = buf;
+ bufref->br_fnum = buf->b_fnum;
+ bufref->br_buf_free_count = buf_free_count;
+}
+
+/// Return true if "bufref->br_buf" points to the same buffer as when
+/// set_bufref() was called and it is a valid buffer.
+/// Only goes through the buffer list if buf_free_count changed.
+/// Also checks if b_fnum is still the same, a :bwipe followed by :new might get
+/// the same allocated memory, but it's a different buffer.
+///
+/// @param bufref Buffer reference to check for.
+bool bufref_valid(bufref_T *bufref)
+{
+ return bufref->br_buf_free_count == buf_free_count
+ ? true
+ : buf_valid(bufref->br_buf) && bufref->br_fnum == bufref->br_buf->b_fnum;
+}
+
+/// Check that "buf" points to a valid buffer in the buffer list.
+///
+/// Can be slow if there are many buffers, prefer using bufref_valid().
+///
+/// @param buf The buffer to check for.
bool buf_valid(buf_T *buf)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (buf == NULL) {
return false;
}
- FOR_ALL_BUFFERS(bp) {
+ // Assume that we more often have a recent buffer,
+ // start with the last one.
+ for (buf_T *bp = lastbuf; bp != NULL; bp = bp->b_prev) {
if (bp == buf) {
return true;
}
@@ -303,6 +405,10 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last)
bool del_buf = (action == DOBUF_DEL || action == DOBUF_WIPE);
bool wipe_buf = (action == DOBUF_WIPE);
+ bool is_curwin = (curwin != NULL && curwin->w_buffer == buf);
+ win_T *the_curwin = curwin;
+ tabpage_T *the_curtab = curtab;
+
// Force unloading or deleting when 'bufhidden' says so, but not for terminal
// buffers.
// The caller must take care of NOT deleting/freeing when 'bufhidden' is
@@ -326,6 +432,13 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last)
wipe_buf = true;
}
+ // Disallow deleting the buffer when it is locked (already being closed or
+ // halfway a command that relies on it). Unloading is allowed.
+ if (buf->b_locked > 0 && (del_buf || wipe_buf)) {
+ EMSG(_("E937: Attempt to delete a buffer that is in use"));
+ return;
+ }
+
if (win_valid_any_tab(win)) {
// Set b_last_cursor when closing the last window for the buffer.
// Remember the last cursor position and window options of the buffer.
@@ -339,35 +452,36 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last)
win->w_cursor.col, TRUE);
}
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+
/* When the buffer is no longer in a window, trigger BufWinLeave */
if (buf->b_nwindows == 1) {
- buf->b_closing = true;
- apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
- FALSE, buf);
- if (!buf_valid(buf)) {
- /* Autocommands deleted the buffer. */
+ buf->b_locked++;
+ if (apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname, false,
+ buf) && !bufref_valid(&bufref)) {
+ // Autocommands deleted the buffer.
EMSG(_(e_auabort));
return;
}
- buf->b_closing = false;
+ buf->b_locked--;
if (abort_if_last && one_window()) {
/* Autocommands made this the only window. */
EMSG(_(e_auabort));
return;
}
- /* When the buffer becomes hidden, but is not unloaded, trigger
- * BufHidden */
+ // When the buffer becomes hidden, but is not unloaded, trigger
+ // BufHidden
if (!unload_buf) {
- buf->b_closing = true;
- apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname,
- FALSE, buf);
- if (!buf_valid(buf)) {
- /* Autocommands deleted the buffer. */
+ buf->b_locked++;
+ if (apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname, false,
+ buf) && !bufref_valid(&bufref)) {
+ // Autocommands deleted the buffer.
EMSG(_(e_auabort));
return;
}
- buf->b_closing = false;
+ buf->b_locked--;
if (abort_if_last && one_window()) {
/* Autocommands made this the only window. */
EMSG(_(e_auabort));
@@ -377,6 +491,16 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last)
if (aborting()) /* autocmds may abort script processing */
return;
}
+
+ // If the buffer was in curwin and the window has changed, go back to that
+ // window, if it still exists. This avoids that ":edit x" triggering a
+ // "tabnext" BufUnload autocmd leaves a window behind without a buffer.
+ if (is_curwin && curwin != the_curwin && win_valid_any_tab(the_curwin)) {
+ block_autocmds();
+ goto_tabpage_win(the_curtab, the_curwin);
+ unblock_autocmds();
+ }
+
int nwindows = buf->b_nwindows;
/* decrease the link count from windows (unless not in any window) */
@@ -390,7 +514,7 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last)
if (buf->terminal) {
terminal_close(buf->terminal, NULL);
- }
+ }
/* Always remove the buffer when there is no file name. */
if (buf->b_ffname == NULL)
@@ -403,23 +527,29 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last)
/* Remember if we are closing the current buffer. Restore the number of
* windows, so that autocommands in buf_freeall() don't get confused. */
bool is_curbuf = (buf == curbuf);
+
+ // When closing the current buffer stop Visual mode before freeing
+ // anything.
+ if (is_curbuf && VIsual_active
+#if defined(EXITFREE)
+ && !entered_free_all_mem
+#endif
+ ) {
+ end_visual_mode();
+ }
+
buf->b_nwindows = nwindows;
buf_freeall(buf, (del_buf ? BFA_DEL : 0) + (wipe_buf ? BFA_WIPE : 0));
- if (win_valid_any_tab(win) && win->w_buffer == buf) {
- win->w_buffer = NULL; // make sure we don't use the buffer now
- }
- /* Autocommands may have deleted the buffer. */
- if (!buf_valid(buf))
+ if (!bufref_valid(&bufref)) {
+ // Autocommands may have deleted the buffer.
return;
- if (aborting()) /* autocmds may abort script processing */
+ }
+ if (aborting()) {
+ // Autocmds may abort script processing.
return;
-
- /* Autocommands may have opened or closed windows for this buffer.
- * Decrement the count for the close we do here. */
- if (buf->b_nwindows > 0)
- --buf->b_nwindows;
+ }
/*
* It's possible that autocommands change curbuf to the one being deleted.
@@ -431,6 +561,16 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last)
if (buf == curbuf && !is_curbuf)
return;
+ if (win_valid_any_tab(win) && win->w_buffer == buf) {
+ win->w_buffer = NULL; // make sure we don't use the buffer now
+ }
+
+ // Autocommands may have opened or closed windows for this buffer.
+ // Decrement the count for the close we do here.
+ if (buf->b_nwindows > 0) {
+ buf->b_nwindows--;
+ }
+
/* Change directories when the 'acd' option is set. */
do_autochdir();
@@ -508,25 +648,32 @@ void buf_freeall(buf_T *buf, int flags)
tabpage_T *the_curtab = curtab;
// Make sure the buffer isn't closed by autocommands.
- buf->b_closing = true;
- if (buf->b_ml.ml_mfp != NULL) {
- apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, false, buf);
- if (!buf_valid(buf)) { // autocommands may delete the buffer
- return;
- }
+ buf->b_locked++;
+
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+
+ if ((buf->b_ml.ml_mfp != NULL)
+ && apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, false, buf)
+ && !bufref_valid(&bufref)) {
+ // Autocommands deleted the buffer.
+ return;
}
- if ((flags & BFA_DEL) && buf->b_p_bl) {
- apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname, FALSE, buf);
- if (!buf_valid(buf)) /* autocommands may delete the buffer */
- return;
+ if ((flags & BFA_DEL)
+ && buf->b_p_bl
+ && apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname, false, buf)
+ && !bufref_valid(&bufref)) {
+ // Autocommands may delete the buffer.
+ return;
}
- if (flags & BFA_WIPE) {
- apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname,
- FALSE, buf);
- if (!buf_valid(buf)) /* autocommands may delete the buffer */
- return;
+ if ((flags & BFA_WIPE)
+ && apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname, false,
+ buf)
+ && !bufref_valid(&bufref)) {
+ // Autocommands may delete the buffer.
+ return;
}
- buf->b_closing = false;
+ buf->b_locked--;
// If the buffer was in curwin and the window has changed, go back to that
// window, if it still exists. This avoids that ":edit x" triggering a
@@ -548,10 +695,11 @@ void buf_freeall(buf_T *buf, int flags)
*/
if (buf == curbuf && !is_curbuf)
return;
- diff_buf_delete(buf); /* Can't use 'diff' for unloaded buffer. */
- /* Remove any ownsyntax, unless exiting. */
- if (firstwin != NULL && curwin->w_buffer == buf)
+ diff_buf_delete(buf); // Can't use 'diff' for unloaded buffer.
+ // Remove any ownsyntax, unless exiting.
+ if (curwin != NULL && curwin->w_buffer == buf) {
reset_synblock(curwin);
+ }
/* No folds in an empty buffer. */
FOR_ALL_TAB_WINDOWS(tp, win) {
@@ -577,10 +725,11 @@ void buf_freeall(buf_T *buf, int flags)
static void free_buffer(buf_T *buf)
{
handle_unregister_buffer(buf);
- free_buffer_stuff(buf, TRUE);
+ buf_free_count++;
+ free_buffer_stuff(buf, true);
unref_var_dict(buf->b_vars);
aubuflocal_remove(buf);
- dict_unref(buf->additional_data);
+ tv_dict_unref(buf->additional_data);
clear_fmark(&buf->b_last_cursor);
clear_fmark(&buf->b_last_insert);
clear_fmark(&buf->b_last_change);
@@ -616,8 +765,18 @@ free_buffer_stuff (
free_buf_options(buf, true);
ga_clear(&buf->b_s.b_langp);
}
+ {
+ // Avoid loosing b:changedtick when deleting buffer: clearing variables
+ // implies using clear_tv() on b:changedtick and that sets changedtick to
+ // zero.
+ hashitem_T *const changedtick_hi = hash_find(
+ &buf->b_vars->dv_hashtab, (const char_u *)"changedtick");
+ assert(changedtick_hi != NULL);
+ hash_remove(&buf->b_vars->dv_hashtab, changedtick_hi);
+ }
vars_clear(&buf->b_vars->dv_hashtab); // free all internal variables
hash_init(&buf->b_vars->dv_hashtab);
+ buf_init_changedtick(buf);
uc_clear(&buf->b_ucmds); // clear local user commands
buf_delete_signs(buf); // delete any signs
bufhl_clear_all(buf); // delete any highligts
@@ -650,11 +809,13 @@ static void clear_wininfo(buf_T *buf)
*/
void goto_buffer(exarg_T *eap, int start, int dir, int count)
{
- (void)do_buffer(*eap->cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
- start, dir, count, eap->forceit);
- buf_T *old_curbuf = curbuf;
+ bufref_T old_curbuf;
+ set_bufref(&old_curbuf, curbuf);
swap_exists_action = SEA_DIALOG;
+ (void)do_buffer(*eap->cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
+ start, dir, count, eap->forceit);
+
if (swap_exists_action == SEA_QUIT && *eap->cmd == 's') {
cleanup_T cs;
@@ -671,18 +832,20 @@ void goto_buffer(exarg_T *eap, int start, int dir, int count)
* new aborting error, interrupt, or uncaught exception. */
leave_cleanup(&cs);
} else {
- handle_swap_exists(old_curbuf);
+ handle_swap_exists(&old_curbuf);
}
}
-/*
- * Handle the situation of swap_exists_action being set.
- * It is allowed for "old_curbuf" to be NULL or invalid.
- */
-void handle_swap_exists(buf_T *old_curbuf)
+/// Handle the situation of swap_exists_action being set.
+///
+/// It is allowed for "old_curbuf" to be NULL or invalid.
+///
+/// @param old_curbuf The buffer to check for.
+void handle_swap_exists(bufref_T *old_curbuf)
{
cleanup_T cs;
long old_tw = curbuf->b_p_tw;
+ buf_T *buf;
if (swap_exists_action == SEA_QUIT) {
/* Reset the error/interrupt/exception state here so that
@@ -695,13 +858,18 @@ void handle_swap_exists(buf_T *old_curbuf)
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
+ || !bufref_valid(old_curbuf)
+ || old_curbuf->br_buf == curbuf) {
+ buf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED);
+ } else {
+ buf = old_curbuf->br_buf;
}
- if (old_curbuf != NULL) {
- enter_buffer(old_curbuf);
- if (old_tw != curbuf->b_p_tw)
+ if (buf != NULL) {
+ enter_buffer(buf);
+ if (old_tw != curbuf->b_p_tw) {
check_colorcolumn(curwin);
+ }
}
/* If "old_curbuf" is NULL we are in big trouble here... */
@@ -724,7 +892,7 @@ void handle_swap_exists(buf_T *old_curbuf)
* new aborting error, interrupt, or uncaught exception. */
leave_cleanup(&cs);
}
- swap_exists_action = SEA_NONE;
+ swap_exists_action = SEA_NONE; // -V519
}
/*
@@ -852,6 +1020,9 @@ static int empty_curbuf(int close_others, int forceit, int action)
return FAIL;
}
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+
if (close_others) {
/* Close any other windows on this buffer, then make it empty. */
close_windows(buf, TRUE);
@@ -861,15 +1032,17 @@ static int empty_curbuf(int close_others, int forceit, int action)
retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE,
forceit ? ECMD_FORCEIT : 0, curwin);
- /*
- * do_ecmd() may create a new buffer, then we have to delete
- * the old one. But do_ecmd() may have done that already, check
- * if the buffer still exists.
- */
- if (buf != curbuf && buf_valid(buf) && buf->b_nwindows == 0)
- close_buffer(NULL, buf, action, FALSE);
- if (!close_others)
- need_fileinfo = FALSE;
+ // do_ecmd() may create a new buffer, then we have to delete
+ // the old one. But do_ecmd() may have done that already, check
+ // if the buffer still exists.
+ if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows == 0) {
+ close_buffer(NULL, buf, action, false);
+ }
+
+ if (!close_others) {
+ need_fileinfo = false;
+ }
+
return retval;
}
/*
@@ -971,6 +1144,8 @@ do_buffer (
*/
if (unload) {
int forward;
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
/* When unloading or deleting a buffer that's already unloaded and
* unlisted: fail silently. */
@@ -979,15 +1154,16 @@ do_buffer (
if (!forceit && (buf->terminal || bufIsChanged(buf))) {
if ((p_confirm || cmdmod.confirm) && p_write && !buf->terminal) {
- dialog_changed(buf, FALSE);
- if (!buf_valid(buf))
- /* Autocommand deleted buffer, oops! It's not changed
- * now. */
+ dialog_changed(buf, false);
+ if (!bufref_valid(&bufref)) {
+ // Autocommand deleted buffer, oops! It's not changed now.
return FAIL;
- /* If it's still changed fail silently, the dialog already
- * mentioned why it fails. */
- if (bufIsChanged(buf))
+ }
+ // If it's still changed fail silently, the dialog already
+ // mentioned why it fails.
+ if (bufIsChanged(buf)) {
return FAIL;
+ }
} else {
if (buf->terminal) {
EMSG2(_("E89: %s will be killed(add ! to override)"),
@@ -1001,6 +1177,11 @@ do_buffer (
}
}
+ // When closing the current buffer stop Visual mode.
+ if (buf == curbuf && VIsual_active) {
+ end_visual_mode();
+ }
+
/*
* If deleting the last (listed) buffer, make it empty.
* The last (listed) buffer cannot be unloaded.
@@ -1021,9 +1202,9 @@ do_buffer (
* a window with this buffer.
*/
while (buf == curbuf
- && !(curwin->w_closing || curwin->w_buffer->b_closing)
- && (firstwin != lastwin || first_tabpage->tp_next != NULL)) {
- if (win_close(curwin, FALSE) == FAIL)
+ && !(curwin->w_closing || curwin->w_buffer->b_locked > 0)
+ && (!ONE_WINDOW || first_tabpage->tp_next != NULL)) {
+ if (win_close(curwin, false) == FAIL)
break;
}
@@ -1031,27 +1212,26 @@ do_buffer (
* If the buffer to be deleted is not the current one, delete it here.
*/
if (buf != curbuf) {
- close_windows(buf, FALSE);
- if (buf != curbuf && buf_valid(buf) && buf->b_nwindows <= 0)
- close_buffer(NULL, buf, action, FALSE);
+ close_windows(buf, false);
+ if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows <= 0) {
+ close_buffer(NULL, buf, action, false);
+ }
return OK;
}
- /*
- * Deleting the current buffer: Need to find another buffer to go to.
- * There should be another, otherwise it would have been handled
- * above. However, autocommands may have deleted all buffers.
- * First use au_new_curbuf, if it is valid.
- * Then prefer the buffer we most recently visited.
- * Else try to find one that is loaded, after the current buffer,
- * then before the current buffer.
- * Finally use any buffer.
- */
- buf = NULL; /* selected buffer */
- bp = NULL; /* used when no loaded buffer found */
- if (au_new_curbuf != NULL && buf_valid(au_new_curbuf))
- buf = au_new_curbuf;
- else if (curwin->w_jumplistlen > 0) {
+ // Deleting the current buffer: Need to find another buffer to go to.
+ // There should be another, otherwise it would have been handled
+ // above. However, autocommands may have deleted all buffers.
+ // First use au_new_curbuf.br_buf, if it is valid.
+ // Then prefer the buffer we most recently visited.
+ // Else try to find one that is loaded, after the current buffer,
+ // then before the current buffer.
+ // Finally use any buffer.
+ buf = NULL; // Selected buffer.
+ bp = NULL; // Used when no loaded buffer found.
+ if (au_new_curbuf.br_buf != NULL && bufref_valid(&au_new_curbuf)) {
+ buf = au_new_curbuf.br_buf;
+ } else if (curwin->w_jumplistlen > 0) {
int jumpidx;
jumpidx = curwin->w_jumplistidx - 1;
@@ -1156,10 +1336,13 @@ do_buffer (
*/
if (action == DOBUF_GOTO && !can_abandon(curbuf, forceit)) {
if ((p_confirm || cmdmod.confirm) && p_write) {
- dialog_changed(curbuf, FALSE);
- if (!buf_valid(buf))
- /* Autocommand deleted buffer, oops! */
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ dialog_changed(curbuf, false);
+ if (!bufref_valid(&bufref)) {
+ // Autocommand deleted buffer, oops!
return FAIL;
+ }
}
if (bufIsChanged(curbuf)) {
EMSG(_(e_nowrtmsg));
@@ -1207,14 +1390,18 @@ void set_curbuf(buf_T *buf, int action)
/* close_windows() or apply_autocmds() may change curbuf */
prevbuf = curbuf;
+ bufref_T bufref;
+ set_bufref(&bufref, prevbuf);
- apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
- if (buf_valid(prevbuf) && !aborting()) {
- if (prevbuf == curwin->w_buffer)
+ if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf)
+ || (bufref_valid(&bufref) && !aborting())) {
+ if (prevbuf == curwin->w_buffer) {
reset_synblock(curwin);
- if (unload)
- close_windows(prevbuf, FALSE);
- if (buf_valid(prevbuf) && !aborting()) {
+ }
+ if (unload) {
+ close_windows(prevbuf, false);
+ }
+ if (bufref_valid(&bufref) && !aborting()) {
win_T *previouswin = curwin;
if (prevbuf == curbuf)
u_sync(FALSE);
@@ -1278,7 +1465,9 @@ void enter_buffer(buf_T *buf)
curwin->w_valid = 0;
if (buf->terminal) {
- terminal_resize(buf->terminal, curwin->w_width, curwin->w_height);
+ terminal_resize(buf->terminal,
+ (uint16_t)curwin->w_width,
+ (uint16_t)curwin->w_height);
}
/* Make sure the buffer is loaded. */
@@ -1344,6 +1533,26 @@ void do_autochdir(void)
static int top_file_num = 1; ///< highest file number
+/// Initialize b:changedtick and changedtick_val attribute
+///
+/// @param[out] buf Buffer to intialize for.
+static inline void buf_init_changedtick(buf_T *const buf)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
+{
+ STATIC_ASSERT(sizeof("changedtick") <= sizeof(buf->changedtick_di.di_key),
+ "buf->changedtick_di cannot hold large enough keys");
+ buf->changedtick_di = (ChangedtickDictItem) {
+ .di_flags = DI_FLAGS_RO|DI_FLAGS_FIX, // Must not include DI_FLAGS_ALLOC.
+ .di_tv = (typval_T) {
+ .v_type = VAR_NUMBER,
+ .v_lock = VAR_FIXED,
+ .vval.v_number = buf->b_changedtick,
+ },
+ .di_key = "changedtick",
+ };
+ tv_dict_add(buf->b_vars, (dictitem_T *)&buf->changedtick_di);
+}
+
/// Add a file name to the buffer list.
/// If the same file name already exists return a pointer to that buffer.
/// If it does not exist, or if fname == NULL, a new entry is created.
@@ -1351,6 +1560,8 @@ static int top_file_num = 1; ///< highest file number
/// If (flags & BLN_LISTED) is TRUE, add new buffer to buffer list.
/// If (flags & BLN_DUMMY) is TRUE, don't count it as a real buffer.
/// If (flags & BLN_NEW) is TRUE, don't use an existing buffer.
+/// If (flags & BLN_NOOPT) is TRUE, don't copy options from the current buffer
+/// if the buffer already exists.
/// This is the ONLY way to create a new buffer.
///
/// @param ffname full path of fname or relative
@@ -1364,7 +1575,7 @@ buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags)
{
buf_T *buf;
- fname_expand(curbuf, &ffname, &sfname); /* will allocate ffname */
+ fname_expand(curbuf, &ffname, &sfname); // will allocate ffname
/*
* If file name already exists in the list, update the entry.
@@ -1378,16 +1589,20 @@ buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags)
&& (buf = buflist_findname_file_id(ffname, &file_id,
file_id_valid)) != NULL) {
xfree(ffname);
- if (lnum != 0)
- buflist_setfpos(buf, curwin, lnum, (colnr_T)0, FALSE);
- /* copy the options now, if 'cpo' doesn't have 's' and not done
- * already */
- buf_copy_options(buf, 0);
+ if (lnum != 0) {
+ buflist_setfpos(buf, curwin, lnum, (colnr_T)0, false);
+ }
+ if ((flags & BLN_NOOPT) == 0) {
+ // Copy the options now, if 'cpo' doesn't have 's' and not done already.
+ buf_copy_options(buf, 0);
+ }
if ((flags & BLN_LISTED) && !buf->b_p_bl) {
- buf->b_p_bl = TRUE;
+ buf->b_p_bl = true;
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
if (!(flags & BLN_DUMMY)) {
- apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
- if (!buf_valid(buf)) {
+ if (apply_autocmds(EVENT_BUFADD, NULL, NULL, false, buf)
+ && !bufref_valid(&bufref)) {
return NULL;
}
}
@@ -1427,8 +1642,9 @@ buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags)
if (buf != curbuf || curbuf == NULL) {
buf = xcalloc(1, sizeof(buf_T));
// init b: variables
- buf->b_vars = dict_alloc();
+ buf->b_vars = tv_dict_alloc();
init_var_dict(buf->b_vars, &buf->b_bufvar, VAR_SCOPE);
+ buf_init_changedtick(buf);
}
if (ffname != NULL) {
@@ -1520,18 +1736,21 @@ buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags)
// Tricky: these autocommands may change the buffer list. They could also
// split the window with re-using the one empty buffer. This may result in
// unexpectedly losing the empty buffer.
- apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf);
- if (!buf_valid(buf)) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ if (apply_autocmds(EVENT_BUFNEW, NULL, NULL, false, buf)
+ && !bufref_valid(&bufref)) {
return NULL;
}
- if (flags & BLN_LISTED) {
- apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
- if (!buf_valid(buf)) {
- return NULL;
- }
+ if ((flags & BLN_LISTED)
+ && apply_autocmds(EVENT_BUFADD, NULL, NULL, false, buf)
+ && !bufref_valid(&bufref)) {
+ return NULL;
}
- if (aborting()) /* autocmds may abort script processing */
+ if (aborting()) {
+ // Autocmds may abort script processing.
return NULL;
+ }
}
return buf;
@@ -1555,6 +1774,7 @@ void free_buf_options(buf_T *buf, int free_p_ff)
clear_string_option(&buf->b_p_inex);
clear_string_option(&buf->b_p_inde);
clear_string_option(&buf->b_p_indk);
+ clear_string_option(&buf->b_p_fp);
clear_string_option(&buf->b_p_fex);
clear_string_option(&buf->b_p_kp);
clear_string_option(&buf->b_p_mps);
@@ -1597,16 +1817,15 @@ void free_buf_options(buf_T *buf, int free_p_ff)
clear_string_option(&buf->b_p_bkc);
}
-/*
- * get alternate file n
- * set linenr to lnum or altfpos.lnum if lnum == 0
- * also set cursor column to altfpos.col if 'startofline' is not set.
- * if (options & GETF_SETMARK) call setpcmark()
- * if (options & GETF_ALT) we are jumping to an alternate file.
- * if (options & GETF_SWITCH) respect 'switchbuf' settings when jumping
- *
- * return FAIL for failure, OK for success
- */
+
+/// Get alternate file "n".
+/// Set linenr to "lnum" or altfpos.lnum if "lnum" == 0.
+/// Also set cursor column to altfpos.col if 'startofline' is not set.
+/// if (options & GETF_SETMARK) call setpcmark()
+/// if (options & GETF_ALT) we are jumping to an alternate file.
+/// if (options & GETF_SWITCH) respect 'switchbuf' settings when jumping
+///
+/// Return FAIL for failure, OK for success.
int buflist_getfile(int n, linenr_T lnum, int options, int forceit)
{
buf_T *buf;
@@ -1687,9 +1906,7 @@ int buflist_getfile(int n, linenr_T lnum, int options, int forceit)
return FAIL;
}
-/*
- * go to the last know line number for the current buffer
- */
+// Go to the last known line number for the current buffer.
void buflist_getfpos(void)
{
pos_T *fpos;
@@ -1754,7 +1971,8 @@ buf_T *buflist_findname(char_u *ffname)
static buf_T *buflist_findname_file_id(char_u *ffname, FileID *file_id,
bool file_id_valid)
{
- FOR_ALL_BUFFERS(buf) {
+ // Start at the last buffer, expect to find a match sooner.
+ FOR_ALL_BUFFERS_BACKWARDS(buf) {
if ((buf->b_flags & BF_DUMMY) == 0
&& !otherfile_buf(buf, ffname, file_id, file_id_valid)) {
return buf;
@@ -1828,7 +2046,7 @@ int buflist_findpat(
return -1;
}
- FOR_ALL_BUFFERS(buf) {
+ FOR_ALL_BUFFERS_BACKWARDS(buf) {
if (buf->b_p_bl == find_listed
&& (!diffmode || diff_mode_buf(buf))
&& buflist_match(&regmatch, buf, false) != NULL) {
@@ -1942,7 +2160,7 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options)
if (count == 0) /* no match found, break here */
break;
if (round == 1) {
- *file = xmalloc(count * sizeof(**file));
+ *file = xmalloc((size_t)count * sizeof(**file));
}
}
vim_regfree(regmatch.regprog);
@@ -1997,21 +2215,14 @@ static char_u *fname_match(regmatch_T *rmp, char_u *name, bool ignore_case)
return match;
}
-/*
- * find file in buffer list by number
- */
+/// Find a file in the buffer list by buffer number.
buf_T *buflist_findnr(int nr)
{
if (nr == 0) {
nr = curwin->w_alt_fnum;
}
- FOR_ALL_BUFFERS(buf) {
- if (buf->b_fnum == nr) {
- return buf;
- }
- }
- return NULL;
+ return handle_get_buffer((handle_T)nr);
}
/*
@@ -2169,7 +2380,7 @@ void get_winopts(buf_T *buf)
/* Set 'foldlevel' to 'foldlevelstart' if it's not negative. */
if (p_fdls >= 0)
curwin->w_p_fdl = p_fdls;
- check_colorcolumn(curwin);
+ didset_window_options(curwin);
}
/*
@@ -2193,9 +2404,7 @@ linenr_T buflist_findlnum(buf_T *buf)
return buflist_findfpos(buf)->lnum;
}
-/*
- * List all know file names (for :files and :buffers command).
- */
+// List all known file names (for :files and :buffers command).
void buflist_list(exarg_T *eap)
{
buf_T *buf;
@@ -2220,12 +2429,17 @@ void buflist_list(exarg_T *eap)
&& (buf == curbuf || curwin->w_alt_fnum != buf->b_fnum))) {
continue;
}
- msg_putchar('\n');
- if (buf_spname(buf) != NULL)
+ if (buf_spname(buf) != NULL) {
STRLCPY(NameBuff, buf_spname(buf), MAXPATHL);
- else
- home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, TRUE);
+ } else {
+ home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, true);
+ }
+ if (message_filtered(NameBuff)) {
+ continue;
+ }
+
+ msg_putchar('\n');
len = vim_snprintf((char *)IObuff, IOSIZE - 20, "%3d%c%c%c%c%c \"%s\"",
buf->b_fnum,
buf->b_p_bl ? ' ' : 'u',
@@ -2579,7 +2793,7 @@ fileinfo (
else
name = curbuf->b_ffname;
home_replace(shorthelp ? curbuf : NULL, name, p,
- (int)(IOSIZE - (p - buffer)), TRUE);
+ (size_t)(IOSIZE - (p - buffer)), true);
}
vim_snprintf_add((char *)buffer, IOSIZE, "\"%s%s%s%s%s%s",
@@ -2689,9 +2903,10 @@ void maketitle(void)
if (p_title) {
if (p_titlelen > 0) {
- maxlen = p_titlelen * Columns / 100;
- if (maxlen < 10)
+ maxlen = (int)(p_titlelen * Columns / 100);
+ if (maxlen < 10) {
maxlen = 10;
+ }
}
t_str = buf;
@@ -2743,7 +2958,7 @@ void maketitle(void)
buf[off++] = ' ';
buf[off++] = '(';
home_replace(curbuf, curbuf->b_ffname,
- buf + off, SPACE_FOR_DIR - off, TRUE);
+ buf + off, (size_t)(SPACE_FOR_DIR - off), true);
#ifdef BACKSLASH_IN_FILENAME
/* avoid "c:/name" to be reduced to "c" */
if (isalpha(buf[off]) && buf[off + 1] == ':')
@@ -2850,13 +3065,13 @@ static bool ti_change(char_u *str, char_u **last)
return false;
}
-/*
- * Put current window title back (used after calling a shell)
- */
+
+/// Set current window title
void resettitle(void)
{
- ui_set_title((char *)lasttitle);
- ui_set_icon((char *)lasticon);
+ ui_call_set_title(cstr_as_string((char *)lasttitle));
+ ui_call_set_icon(cstr_as_string((char *)lasticon));
+ ui_flush();
}
# if defined(EXITFREE)
@@ -2908,13 +3123,13 @@ int build_stl_str_hl(
size_t outlen,
char_u *fmt,
int use_sandbox,
- int fillchar,
+ char_u fillchar,
int maxwidth,
struct stl_hlrec *hltab,
StlClickRecord *tabtab
)
{
- int groupitem[STL_MAX_ITEM];
+ int groupitems[STL_MAX_ITEM];
struct stl_item {
// Where the item starts in the status line output buffer
char_u *start;
@@ -2934,7 +3149,7 @@ int build_stl_str_hl(
ClickFunc,
Trunc
} type;
- } item[STL_MAX_ITEM];
+ } items[STL_MAX_ITEM];
#define TMPLEN 70
char_u tmp[TMPLEN];
char_u *usefmt = fmt;
@@ -3036,16 +3251,16 @@ int build_stl_str_hl(
if (groupdepth > 0) {
continue;
}
- item[curitem].type = Separate;
- item[curitem++].start = out_p;
+ items[curitem].type = Separate;
+ items[curitem++].start = out_p;
continue;
}
// STL_TRUNCMARK: Where to begin truncating if the statusline is too long.
if (*fmt_p == STL_TRUNCMARK) {
fmt_p++;
- item[curitem].type = Trunc;
- item[curitem++].start = out_p;
+ items[curitem].type = Trunc;
+ items[curitem++].start = out_p;
continue;
}
@@ -3061,7 +3276,7 @@ int build_stl_str_hl(
// Determine how long the group is.
// Note: We set the current output position to null
// so `vim_strsize` will work.
- char_u *t = item[groupitem[groupdepth]].start;
+ char_u *t = items[groupitems[groupdepth]].start;
*out_p = NUL;
long group_len = vim_strsize(t);
@@ -3071,11 +3286,11 @@ int build_stl_str_hl(
// move the output pointer back to where the group started.
// Note: This erases any non-item characters that were in the group.
// Otherwise there would be no reason to do this step.
- if (curitem > groupitem[groupdepth] + 1
- && item[groupitem[groupdepth]].minwid == 0) {
+ if (curitem > groupitems[groupdepth] + 1
+ && items[groupitems[groupdepth]].minwid == 0) {
bool has_normal_items = false;
- for (long n = groupitem[groupdepth] + 1; n < curitem; n++) {
- if (item[n].type == Normal || item[n].type == Highlight) {
+ for (long n = groupitems[groupdepth] + 1; n < curitem; n++) {
+ if (items[n].type == Normal || items[n].type == Highlight) {
has_normal_items = true;
break;
}
@@ -3089,18 +3304,18 @@ int build_stl_str_hl(
// If the group is longer than it is allowed to be
// truncate by removing bytes from the start of the group text.
- if (group_len > item[groupitem[groupdepth]].maxwid) {
+ if (group_len > items[groupitems[groupdepth]].maxwid) {
// { Determine the number of bytes to remove
long n;
if (has_mbyte) {
/* Find the first character that should be included. */
n = 0;
- while (group_len >= item[groupitem[groupdepth]].maxwid) {
+ while (group_len >= items[groupitems[groupdepth]].maxwid) {
group_len -= ptr2cells(t + n);
n += (*mb_ptr2len)(t + n);
}
} else {
- n = (long)(out_p - t) - item[groupitem[groupdepth]].maxwid + 1;
+ n = (long)(out_p - t) - items[groupitems[groupdepth]].maxwid + 1;
}
// }
@@ -3110,25 +3325,26 @@ int build_stl_str_hl(
// { Move the truncated output
memmove(t + 1, t + n, (size_t)(out_p - (t + n)));
out_p = out_p - n + 1;
- /* Fill up space left over by half a double-wide char. */
- while (++group_len < item[groupitem[groupdepth]].minwid)
+ // Fill up space left over by half a double-wide char.
+ while (++group_len < items[groupitems[groupdepth]].minwid) {
*out_p++ = fillchar;
+ }
// }
- /* correct the start of the items for the truncation */
- for (int idx = groupitem[groupdepth] + 1; idx < curitem; idx++) {
+ // correct the start of the items for the truncation
+ for (int idx = groupitems[groupdepth] + 1; idx < curitem; idx++) {
// Shift everything back by the number of removed bytes
- item[idx].start -= n;
+ items[idx].start -= n;
// If the item was partially or completely truncated, set its
// start to the start of the group
- if (item[idx].start < t) {
- item[idx].start = t;
+ if (items[idx].start < t) {
+ items[idx].start = t;
}
}
// If the group is shorter than the minimum width, add padding characters.
- } else if (abs(item[groupitem[groupdepth]].minwid) > group_len) {
- long min_group_width = item[groupitem[groupdepth]].minwid;
+ } else if (abs(items[groupitems[groupdepth]].minwid) > group_len) {
+ long min_group_width = items[groupitems[groupdepth]].minwid;
// If the group is left-aligned, add characters to the right.
if (min_group_width < 0) {
min_group_width = 0 - min_group_width;
@@ -3147,8 +3363,8 @@ int build_stl_str_hl(
// }
// Adjust item start positions
- for (int n = groupitem[groupdepth] + 1; n < curitem; n++) {
- item[n].start += group_len;
+ for (int n = groupitems[groupdepth] + 1; n < curitem; n++) {
+ items[n].start += group_len;
}
// Prepend the fill characters
@@ -3186,9 +3402,9 @@ int build_stl_str_hl(
// User highlight groups override the min width field
// to denote the styling to use.
if (*fmt_p == STL_USER_HL) {
- item[curitem].type = Highlight;
- item[curitem].start = out_p;
- item[curitem].minwid = minwid > 9 ? 1 : minwid;
+ items[curitem].type = Highlight;
+ items[curitem].start = out_p;
+ items[curitem].minwid = minwid > 9 ? 1 : minwid;
fmt_p++;
curitem++;
continue;
@@ -3220,20 +3436,21 @@ int build_stl_str_hl(
if (*fmt_p == STL_TABPAGENR || *fmt_p == STL_TABCLOSENR) {
if (*fmt_p == STL_TABCLOSENR) {
if (minwid == 0) {
- /* %X ends the close label, go back to the previously
- * define tab label nr. */
- for (long n = curitem - 1; n >= 0; --n)
- if (item[n].type == TabPage && item[n].minwid >= 0) {
- minwid = item[n].minwid;
+ // %X ends the close label, go back to the previous tab label nr.
+ for (long n = curitem - 1; n >= 0; n--) {
+ if (items[n].type == TabPage && items[n].minwid >= 0) {
+ minwid = items[n].minwid;
break;
}
- } else
- /* close nrs are stored as negative values */
+ }
+ } else {
+ // close nrs are stored as negative values
minwid = -minwid;
+ }
}
- item[curitem].type = TabPage;
- item[curitem].start = out_p;
- item[curitem].minwid = minwid;
+ items[curitem].type = TabPage;
+ items[curitem].start = out_p;
+ items[curitem].minwid = minwid;
fmt_p++;
curitem++;
continue;
@@ -3248,10 +3465,10 @@ int build_stl_str_hl(
if (*fmt_p != STL_CLICK_FUNC) {
break;
}
- item[curitem].type = ClickFunc;
- item[curitem].start = out_p;
- item[curitem].cmd = xmemdupz(t, (size_t) (((char *) fmt_p - t)));
- item[curitem].minwid = minwid;
+ items[curitem].type = ClickFunc;
+ items[curitem].start = out_p;
+ items[curitem].cmd = xmemdupz(t, (size_t)(((char *)fmt_p - t)));
+ items[curitem].minwid = minwid;
fmt_p++;
curitem++;
continue;
@@ -3274,11 +3491,11 @@ int build_stl_str_hl(
// Denotes the start of a new group
if (*fmt_p == '(') {
- groupitem[groupdepth++] = curitem;
- item[curitem].type = Group;
- item[curitem].start = out_p;
- item[curitem].minwid = minwid;
- item[curitem].maxwid = maxwid;
+ groupitems[groupdepth++] = curitem;
+ items[curitem].type = Group;
+ items[curitem].start = out_p;
+ items[curitem].minwid = minwid;
+ items[curitem].maxwid = maxwid;
fmt_p++;
curitem++;
continue;
@@ -3305,7 +3522,7 @@ int build_stl_str_hl(
case STL_FULLPATH:
case STL_FILENAME:
{
- // Set fillable to false to that ' ' in the filename will not
+ // Set fillable to false so that ' ' in the filename will not
// get replaced with the fillchar
fillable = false;
if (buf_spname(wp->w_buffer) != NULL) {
@@ -3358,7 +3575,7 @@ int build_stl_str_hl(
curbuf = o_curbuf;
// Remove the variable we just stored
- do_unlet((char_u *)"g:actual_curbuf", true);
+ do_unlet(S_LEN("g:actual_curbuf"), true);
// }
@@ -3440,7 +3657,7 @@ int build_stl_str_hl(
case STL_KEYMAP:
fillable = false;
- if (get_keymap_str(wp, tmp, TMPLEN))
+ if (get_keymap_str(wp, (char_u *)"<%s>", tmp, TMPLEN))
str = tmp;
break;
case STL_PAGENUM:
@@ -3453,6 +3670,7 @@ int build_stl_str_hl(
case STL_OFFSET_X:
base = kNumBaseHexadecimal;
+ // fallthrough
case STL_OFFSET:
{
long l = ml_find_line_or_offset(wp->w_buffer, wp->w_cursor.lnum, NULL);
@@ -3463,6 +3681,7 @@ int build_stl_str_hl(
}
case STL_BYTEVAL_X:
base = kNumBaseHexadecimal;
+ // fallthrough
case STL_BYTEVAL:
num = byteval;
if (num == NL)
@@ -3510,7 +3729,7 @@ int build_stl_str_hl(
wp->w_buffer->b_p_ft);
// Uppercase the file extension
for (char_u *t = tmp; *t != 0; t++) {
- *t = TOUPPER_LOC(*t);
+ *t = (char_u)TOUPPER_LOC(*t);
}
str = tmp;
}
@@ -3557,9 +3776,9 @@ int build_stl_str_hl(
// Create a highlight item based on the name
if (*fmt_p == '#') {
- item[curitem].type = Highlight;
- item[curitem].start = out_p;
- item[curitem].minwid = -syn_namen2id(t, (int)(fmt_p - t));
+ items[curitem].type = Highlight;
+ items[curitem].start = out_p;
+ items[curitem].minwid = -syn_namen2id(t, (int)(fmt_p - t));
curitem++;
fmt_p++;
}
@@ -3570,8 +3789,8 @@ int build_stl_str_hl(
// If we made it this far, the item is normal and starts at
// our current position in the output buffer.
// Non-normal items would have `continued`.
- item[curitem].start = out_p;
- item[curitem].type = Normal;
+ items[curitem].start = out_p;
+ items[curitem].type = Normal;
// Copy the item string into the output buffer
if (str != NULL && *str) {
@@ -3687,7 +3906,8 @@ int build_stl_str_hl(
}
// }
- size_t remaining_buf_len = (out_end_p - out_p) + 1;
+ assert(out_end_p >= out_p);
+ size_t remaining_buf_len = (size_t)(out_end_p - out_p) + 1;
// If the number is going to take up too much room
// Figure out the approximate number in "scientific" type notation.
@@ -3702,7 +3922,7 @@ int build_stl_str_hl(
// { Reduce the number by base^n
while (num_chars-- > maxwid) {
- num /= base;
+ num /= (long)base;
}
// }
@@ -3727,7 +3947,7 @@ int build_stl_str_hl(
// Otherwise, there was nothing to print so mark the item as empty
} else {
- item[curitem].type = Empty;
+ items[curitem].type = Empty;
}
// Only free the string buffer if we allocated it.
@@ -3752,8 +3972,7 @@ int build_stl_str_hl(
}
// We have now processed the entire statusline format string.
- // What follows is post-processing to handle alignment and
- // highlighting factors.
+ // What follows is post-processing to handle alignment and highlighting.
int width = vim_strsize(out);
if (maxwidth > 0 && width > maxwidth) {
@@ -3768,16 +3987,17 @@ int build_stl_str_hl(
// Otherwise, look for the truncation item
} else {
// Default to truncating at the first item
- trunc_p = item[0].start;
+ trunc_p = items[0].start;
item_idx = 0;
- for (int i = 0; i < itemcnt; i++)
- if (item[i].type == Trunc) {
- // Truncate at %< item.
- trunc_p = item[i].start;
+ for (int i = 0; i < itemcnt; i++) {
+ if (items[i].type == Trunc) {
+ // Truncate at %< items.
+ trunc_p = items[i].start;
item_idx = i;
break;
}
+ }
}
// If the truncation point we found is beyond the maximum
@@ -3807,7 +4027,7 @@ int build_stl_str_hl(
// Ignore any items in the statusline that occur after
// the truncation point
for (int i = 0; i < itemcnt; i++) {
- if (item[i].start > trunc_p) {
+ if (items[i].start > trunc_p) {
itemcnt = i;
break;
}
@@ -3862,12 +4082,12 @@ int build_stl_str_hl(
for (int i = item_idx; i < itemcnt; i++) {
// Items starting at or after the end of the truncated section need
// to be moved backwards.
- if (item[i].start >= trunc_end_p) {
- item[i].start -= item_offset;
+ if (items[i].start >= trunc_end_p) {
+ items[i].start -= item_offset;
// Anything inside the truncated area is set to start
// at the `<` truncation character.
} else {
- item[i].start = trunc_p;
+ items[i].start = trunc_p;
}
}
// }
@@ -3878,12 +4098,12 @@ int build_stl_str_hl(
// add characters at the separate marker (if there is one) to
// fill up the available space.
} else if (width < maxwidth
- && STRLEN(out) + maxwidth - width + 1 < outlen) {
+ && STRLEN(out) + (size_t)(maxwidth - width) + 1 < outlen) {
// Find how many separators there are, which we will use when
// figuring out how many groups there are.
int num_separators = 0;
for (int i = 0; i < itemcnt; i++) {
- if (item[i].type == Separate) {
+ if (items[i].type == Separate) {
num_separators++;
}
}
@@ -3895,7 +4115,7 @@ int build_stl_str_hl(
int separator_locations[STL_MAX_ITEM];
int index = 0;
for (int i = 0; i < itemcnt; i++) {
- if (item[i].type == Separate) {
+ if (items[i].type == Separate) {
separator_locations[index] = i;
index++;
}
@@ -3906,18 +4126,18 @@ int build_stl_str_hl(
standard_spaces * (num_separators - 1);
for (int i = 0; i < num_separators; i++) {
- int dislocation = (i == (num_separators - 1)) ?
- final_spaces : standard_spaces;
- char_u *sep_loc = item[separator_locations[i]].start + dislocation;
- STRMOVE(sep_loc, item[separator_locations[i]].start);
- for (char_u *s = item[separator_locations[i]].start; s < sep_loc; s++) {
+ int dislocation = (i == (num_separators - 1))
+ ? final_spaces : standard_spaces;
+ char_u *seploc = items[separator_locations[i]].start + dislocation;
+ STRMOVE(seploc, items[separator_locations[i]].start);
+ for (char_u *s = items[separator_locations[i]].start; s < seploc; s++) {
*s = fillchar;
}
for (int item_idx = separator_locations[i] + 1;
item_idx < itemcnt;
item_idx++) {
- item[item_idx].start += dislocation;
+ items[item_idx].start += dislocation;
}
}
@@ -3929,9 +4149,9 @@ int build_stl_str_hl(
if (hltab != NULL) {
struct stl_hlrec *sp = hltab;
for (long l = 0; l < itemcnt; l++) {
- if (item[l].type == Highlight) {
- sp->start = item[l].start;
- sp->userhl = item[l].minwid;
+ if (items[l].type == Highlight) {
+ sp->start = items[l].start;
+ sp->userhl = items[l].minwid;
sp++;
}
}
@@ -3943,14 +4163,14 @@ int build_stl_str_hl(
if (tabtab != NULL) {
StlClickRecord *cur_tab_rec = tabtab;
for (long l = 0; l < itemcnt; l++) {
- if (item[l].type == TabPage) {
- cur_tab_rec->start = (char *) item[l].start;
- if (item[l].minwid == 0) {
+ if (items[l].type == TabPage) {
+ cur_tab_rec->start = (char *)items[l].start;
+ if (items[l].minwid == 0) {
cur_tab_rec->def.type = kStlClickDisabled;
cur_tab_rec->def.tabnr = 0;
} else {
- int tabnr = item[l].minwid;
- if (item[l].minwid > 0) {
+ int tabnr = items[l].minwid;
+ if (items[l].minwid > 0) {
cur_tab_rec->def.type = kStlClickTabSwitch;
} else {
cur_tab_rec->def.type = kStlClickTabClose;
@@ -3960,11 +4180,11 @@ int build_stl_str_hl(
}
cur_tab_rec->def.func = NULL;
cur_tab_rec++;
- } else if (item[l].type == ClickFunc) {
- cur_tab_rec->start = (char *) item[l].start;
+ } else if (items[l].type == ClickFunc) {
+ cur_tab_rec->start = (char *)items[l].start;
cur_tab_rec->def.type = kStlClickFuncRun;
- cur_tab_rec->def.tabnr = item[l].minwid;
- cur_tab_rec->def.func = item[l].cmd;
+ cur_tab_rec->def.tabnr = items[l].minwid;
+ cur_tab_rec->def.func = items[l].cmd;
cur_tab_rec++;
}
}
@@ -4059,14 +4279,12 @@ void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname)
#ifdef WIN32
if (!buf->b_p_bin) {
- char_u *rfname;
-
// If the file name is a shortcut file, use the file it links to.
- rfname = os_resolve_shortcut(*ffname);
+ char *rfname = os_resolve_shortcut((const char *)(*ffname));
if (rfname != NULL) {
xfree(*ffname);
- *ffname = rfname;
- *sfname = rfname;
+ *ffname = (char_u *)rfname;
+ *sfname = (char_u *)rfname;
}
}
#endif
@@ -4116,6 +4334,8 @@ do_arg_all (
win_T *new_curwin = NULL;
tabpage_T *new_curtab = NULL;
+ assert(firstwin != NULL); // satisfy coverity
+
if (ARGCOUNT <= 0) {
/* Don't give an error message. We don't want it when the ":all"
* command is in the .vimrc. */
@@ -4124,7 +4344,7 @@ do_arg_all (
setpcmark();
opened_len = ARGCOUNT;
- opened = xcalloc(opened_len, 1);
+ opened = xcalloc((size_t)opened_len, 1);
/* Autocommands may do anything to the argument list. Make sure it's not
* freed while we are working here by "locking" it. We still have to
@@ -4198,24 +4418,27 @@ do_arg_all (
|| !bufIsChanged(buf)) {
/* If the buffer was changed, and we would like to hide it,
* try autowriting. */
- if (!P_HID(buf) && buf->b_nwindows <= 1
- && bufIsChanged(buf)) {
- (void)autowrite(buf, FALSE);
- /* check if autocommands removed the window */
- if (!win_valid(wp) || !buf_valid(buf)) {
- wpnext = firstwin; /* start all over... */
+ if (!P_HID(buf) && buf->b_nwindows <= 1 && bufIsChanged(buf)) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ (void)autowrite(buf, false);
+ // Check if autocommands removed the window.
+ if (!win_valid(wp) || !bufref_valid(&bufref)) {
+ wpnext = firstwin; // Start all over...
continue;
}
}
- /* don't close last window */
- if (firstwin == lastwin
- && (first_tabpage->tp_next == NULL || !had_tab))
- use_firstwin = TRUE;
- else {
+ // don't close last window
+ if (ONE_WINDOW
+ && (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... */
+ // check if autocommands removed the next window
+ if (!win_valid(wpnext)) {
+ // start all over...
+ wpnext = firstwin;
+ }
}
}
}
@@ -4306,19 +4529,23 @@ do_arg_all (
/* Remove the "lock" on the argument list. */
alist_unlink(alist);
- --autocmd_no_enter;
- /* restore last referenced tabpage's curwin */
+ autocmd_no_enter--;
+ // restore last referenced tabpage's curwin
if (last_curtab != new_curtab) {
- if (valid_tabpage(last_curtab))
- goto_tabpage_tp(last_curtab, TRUE, TRUE);
- if (win_valid(last_curwin))
+ if (valid_tabpage(last_curtab)) {
+ goto_tabpage_tp(last_curtab, true, true);
+ }
+ if (win_valid(last_curwin)) {
win_enter(last_curwin, false);
+ }
+ }
+ // to window with first arg
+ if (valid_tabpage(new_curtab)) {
+ goto_tabpage_tp(new_curtab, true, true);
}
- /* to window with first arg */
- if (valid_tabpage(new_curtab))
- goto_tabpage_tp(new_curtab, TRUE, TRUE);
- if (win_valid(new_curwin))
+ if (win_valid(new_curwin)) {
win_enter(new_curwin, false);
+ }
--autocmd_no_leave;
xfree(opened);
@@ -4335,8 +4562,8 @@ void ex_buffer_all(exarg_T *eap)
bool p_ea_save;
int open_wins = 0;
int r;
- int count; /* Maximum number of windows to open. */
- int all; /* When TRUE also load inactive buffers. */
+ long count; // Maximum number of windows to open.
+ int all; // When TRUE also load inactive buffers.
int had_tab = cmdmod.tab;
tabpage_T *tpnext;
@@ -4367,9 +4594,9 @@ void ex_buffer_all(exarg_T *eap)
? wp->w_height + wp->w_status_height < Rows - p_ch
- tabline_height()
: wp->w_width != Columns)
- || (had_tab > 0 && wp != firstwin)
- ) && firstwin != lastwin
- && !(wp->w_closing || wp->w_buffer->b_closing)
+ || (had_tab > 0 && wp != firstwin))
+ && !ONE_WINDOW
+ && !(wp->w_closing || wp->w_buffer->b_locked > 0)
) {
win_close(wp, FALSE);
wpnext = firstwin; /* just in case an autocommand does
@@ -4417,7 +4644,9 @@ void ex_buffer_all(exarg_T *eap)
}
if (wp == NULL && split_ret == OK) {
- /* Split the window and put the buffer in it */
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ // Split the window and put the buffer in it.
p_ea_save = p_ea;
p_ea = true; /* use space from all windows */
split_ret = win_split(0, WSP_ROOM | WSP_BELOW);
@@ -4429,7 +4658,8 @@ void ex_buffer_all(exarg_T *eap)
/* Open the buffer in this window. */
swap_exists_action = SEA_DIALOG;
set_curbuf(buf, DOBUF_GOTO);
- if (!buf_valid(buf)) { /* autocommands deleted the buffer!!! */
+ if (!bufref_valid(&bufref)) {
+ // Autocommands deleted the buffer.
swap_exists_action = SEA_NONE;
break;
}
@@ -4857,7 +5087,7 @@ int buf_findsign(
for (sign = buf->b_signlist; sign != NULL; sign = sign->next) {
if (sign->id == id) {
- return sign->lnum;
+ return (int)sign->lnum;
}
}
@@ -4971,6 +5201,30 @@ void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_a
// bufhl: plugin highlights associated with a buffer
+/// Get reference to line in kbtree_t
+///
+/// @param b the three
+/// @param line the linenumber to lookup
+/// @param put if true, put a new line when not found
+/// if false, return NULL when not found
+BufhlLine *bufhl_tree_ref(BufhlInfo *b, linenr_T line, bool put)
+{
+ BufhlLine t = BUFHLLINE_INIT(line);
+
+ // kp_put() only works if key is absent, try get first
+ BufhlLine **pp = kb_get(bufhl, b, &t);
+ if (pp) {
+ return *pp;
+ } else if (!put) {
+ return NULL;
+ }
+
+ BufhlLine *p = xmalloc(sizeof(*p));
+ *p = (BufhlLine)BUFHLLINE_INIT(line);
+ kb_put(bufhl, b, p);
+ return p;
+}
+
/// Adds a highlight to buffer.
///
/// Unlike matchaddpos() highlights follow changes to line numbering (as lines
@@ -5008,13 +5262,10 @@ int bufhl_add_hl(buf_T *buf,
// no highlight group or invalid line, just return src_id
return src_id;
}
- if (!buf->b_bufhl_info) {
- buf->b_bufhl_info = map_new(linenr_T, bufhl_vec_T)();
- }
- bufhl_vec_T* lineinfo = map_ref(linenr_T, bufhl_vec_T)(buf->b_bufhl_info,
- lnum, true);
- bufhl_hl_item_T *hlentry = kv_pushp(*lineinfo);
+ BufhlLine *lineinfo = bufhl_tree_ref(&buf->b_bufhl_info, lnum, true);
+
+ BufhlItem *hlentry = kv_pushp(lineinfo->items);
hlentry->src_id = src_id;
hlentry->hl_id = hl_id;
hlentry->start = col_start;
@@ -5036,20 +5287,24 @@ int bufhl_add_hl(buf_T *buf,
void bufhl_clear_line_range(buf_T *buf,
int src_id,
linenr_T line_start,
- linenr_T line_end) {
- if (!buf->b_bufhl_info) {
- return;
- }
- linenr_T line;
+ linenr_T line_end)
+{
linenr_T first_changed = MAXLNUM, last_changed = -1;
- // In the case line_start - line_end << bufhl_info->size
- // it might be better to reverse this, i e loop over the lines
- // to clear on.
- bufhl_vec_T unused;
- map_foreach(buf->b_bufhl_info, line, unused, {
- (void)unused;
+
+ kbitr_t(bufhl) itr;
+ BufhlLine *l, t = BUFHLLINE_INIT(line_start);
+ if (!kb_itr_get(bufhl, &buf->b_bufhl_info, &t, &itr)) {
+ kb_itr_next(bufhl, &buf->b_bufhl_info, &itr);
+ }
+ for (; kb_itr_valid(&itr); kb_itr_next(bufhl, &buf->b_bufhl_info, &itr)) {
+ l = kb_itr_key(&itr);
+ linenr_T line = l->line;
+ if (line > line_end) {
+ break;
+ }
if (line_start <= line && line <= line_end) {
- if (bufhl_clear_line(buf->b_bufhl_info, src_id, line)) {
+ BufhlLineStatus status = bufhl_clear_line(l, src_id, line);
+ if (status != kBLSUnchanged) {
if (line > last_changed) {
last_changed = line;
}
@@ -5057,8 +5312,12 @@ void bufhl_clear_line_range(buf_T *buf,
first_changed = line;
}
}
+ if (status == kBLSDeleted) {
+ kb_del_itr(bufhl, &buf->b_bufhl_info, &itr);
+ xfree(l);
+ }
}
- })
+ }
if (last_changed != -1) {
changed_lines_buf(buf, first_changed, last_changed+1, 0);
@@ -5071,40 +5330,40 @@ void bufhl_clear_line_range(buf_T *buf,
/// @param bufhl_info The highlight info for the buffer
/// @param src_id Highlight source group to clear, or -1 to clear all groups.
/// @param lnum Linenr where the highlight should be cleared
-static bool bufhl_clear_line(bufhl_info_T *bufhl_info, int src_id, int lnum) {
- bufhl_vec_T* lineinfo = map_ref(linenr_T, bufhl_vec_T)(bufhl_info,
- lnum, false);
- size_t oldsize = kv_size(*lineinfo);
+static BufhlLineStatus bufhl_clear_line(BufhlLine *lineinfo, int src_id,
+ linenr_T lnum)
+{
+ size_t oldsize = kv_size(lineinfo->items);
if (src_id < 0) {
- kv_size(*lineinfo) = 0;
+ kv_size(lineinfo->items) = 0;
} else {
- size_t newind = 0;
- for (size_t i = 0; i < kv_size(*lineinfo); i++) {
- if (kv_A(*lineinfo, i).src_id != src_id) {
- if (i != newind) {
- kv_A(*lineinfo, newind) = kv_A(*lineinfo, i);
+ size_t newidx = 0;
+ for (size_t i = 0; i < kv_size(lineinfo->items); i++) {
+ if (kv_A(lineinfo->items, i).src_id != src_id) {
+ if (i != newidx) {
+ kv_A(lineinfo->items, newidx) = kv_A(lineinfo->items, i);
}
- newind++;
+ newidx++;
}
}
- kv_size(*lineinfo) = newind;
+ kv_size(lineinfo->items) = newidx;
}
- if (kv_size(*lineinfo) == 0) {
- kv_destroy(*lineinfo);
- map_del(linenr_T, bufhl_vec_T)(bufhl_info, lnum);
+ if (kv_size(lineinfo->items) == 0) {
+ kv_destroy(lineinfo->items);
+ return kBLSDeleted;
}
- return kv_size(*lineinfo) != oldsize;
+ return kv_size(lineinfo->items) != oldsize ? kBLSChanged : kBLSUnchanged;
}
/// Remove all highlights and free the highlight data
-void bufhl_clear_all(buf_T* buf) {
- if (!buf->b_bufhl_info) {
- return;
- }
+void bufhl_clear_all(buf_T *buf)
+{
bufhl_clear_line_range(buf, -1, 1, MAXLNUM);
- map_free(linenr_T, bufhl_vec_T)(buf->b_bufhl_info);
- buf->b_bufhl_info = NULL;
+ kb_destroy(bufhl, (&buf->b_bufhl_info));
+ kb_init(&buf->b_bufhl_info);
+ kv_destroy(buf->b_bufhl_move_space);
+ kv_init(buf->b_bufhl_move_space);
}
/// Adjust a placed highlight for inserted/deleted lines.
@@ -5112,29 +5371,49 @@ void bufhl_mark_adjust(buf_T* buf,
linenr_T line1,
linenr_T line2,
long amount,
- long amount_after) {
- if (!buf->b_bufhl_info) {
+ long amount_after,
+ bool end_temp)
+{
+ kbitr_t(bufhl) itr;
+ BufhlLine *l, t = BUFHLLINE_INIT(line1);
+ if (end_temp && amount < 0) {
+ // Move all items from b_bufhl_move_space to the btree.
+ for (size_t i = 0; i < kv_size(buf->b_bufhl_move_space); i++) {
+ l = kv_A(buf->b_bufhl_move_space, i);
+ l->line += amount;
+ kb_put(bufhl, &buf->b_bufhl_info, l);
+ }
+ kv_size(buf->b_bufhl_move_space) = 0;
return;
}
- bufhl_info_T *newmap = map_new(linenr_T, bufhl_vec_T)();
- linenr_T line;
- bufhl_vec_T lineinfo;
- map_foreach(buf->b_bufhl_info, line, lineinfo, {
- if (line >= line1 && line <= line2) {
+ if (!kb_itr_get(bufhl, &buf->b_bufhl_info, &t, &itr)) {
+ kb_itr_next(bufhl, &buf->b_bufhl_info, &itr);
+ }
+ for (; kb_itr_valid(&itr); kb_itr_next(bufhl, &buf->b_bufhl_info, &itr)) {
+ l = kb_itr_key(&itr);
+ if (l->line >= line1 && l->line <= line2) {
+ if (end_temp && amount > 0) {
+ kb_del_itr(bufhl, &buf->b_bufhl_info, &itr);
+ kv_push(buf->b_bufhl_move_space, l);
+ }
if (amount == MAXLNUM) {
- bufhl_clear_line(buf->b_bufhl_info, -1, line);
- continue;
+ if (bufhl_clear_line(l, -1, l->line) == kBLSDeleted) {
+ kb_del_itr(bufhl, &buf->b_bufhl_info, &itr);
+ xfree(l);
+ } else {
+ assert(false);
+ }
} else {
- line += amount;
+ l->line += amount;
}
- } else if (line > line2) {
- line += amount_after;
+ } else if (l->line > line2) {
+ if (amount_after == 0) {
+ break;
+ }
+ l->line += amount_after;
}
- map_put(linenr_T, bufhl_vec_T)(newmap, line, lineinfo);
- });
- map_free(linenr_T, bufhl_vec_T)(buf->b_bufhl_info);
- buf->b_bufhl_info = newmap;
+ }
}
@@ -5144,13 +5423,14 @@ void bufhl_mark_adjust(buf_T* buf,
/// @param lnum The line number
/// @param[out] info The highligts for the line
/// @return true if there was highlights to display
-bool bufhl_start_line(buf_T *buf, linenr_T lnum, bufhl_lineinfo_T *info) {
- if (!buf->b_bufhl_info) {
+bool bufhl_start_line(buf_T *buf, linenr_T lnum, BufhlLineInfo *info)
+{
+ BufhlLine *lineinfo = bufhl_tree_ref(&buf->b_bufhl_info, lnum, false);
+ if (!lineinfo) {
return false;
}
-
info->valid_to = -1;
- info->entries = map_get(linenr_T, bufhl_vec_T)(buf->b_bufhl_info, lnum);
+ info->entries = lineinfo->items;
return kv_size(info->entries) > 0;
}
@@ -5164,14 +5444,15 @@ bool bufhl_start_line(buf_T *buf, linenr_T lnum, bufhl_lineinfo_T *info) {
/// @param info The info returned by bufhl_start_line
/// @param col The column to get the attr for
/// @return The highilight attr to display at the column
-int bufhl_get_attr(bufhl_lineinfo_T *info, colnr_T col) {
+int bufhl_get_attr(BufhlLineInfo *info, colnr_T col)
+{
if (col <= info->valid_to) {
return info->current;
}
int attr = 0;
info->valid_to = MAXCOL;
for (size_t i = 0; i < kv_size(info->entries); i++) {
- bufhl_hl_item_T entry = kv_A(info->entries, i);
+ BufhlItem entry = kv_A(info->entries, i);
if (entry.start <= col && col <= entry.stop) {
int entry_attr = syn_id2attr(entry.hl_id);
attr = hl_combine_attr(attr, entry_attr);
@@ -5286,8 +5567,8 @@ void buf_open_scratch(handle_T bufnr, char *bufname)
{
(void)do_ecmd((int)bufnr, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
(void)setfname(curbuf, (char_u *)bufname, NULL, true);
- set_option_value((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL);
- set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
- set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
+ set_option_value("bh", 0L, "hide", OPT_LOCAL);
+ set_option_value("bt", 0L, "nofile", OPT_LOCAL);
+ set_option_value("swf", 0L, NULL, OPT_LOCAL);
RESET_BINDING(curwin);
}
diff --git a/src/nvim/buffer.h b/src/nvim/buffer.h
index 36cbec7e60..faeeed121c 100644
--- a/src/nvim/buffer.h
+++ b/src/nvim/buffer.h
@@ -1,10 +1,14 @@
#ifndef NVIM_BUFFER_H
#define NVIM_BUFFER_H
+#include "nvim/vim.h"
#include "nvim/window.h"
#include "nvim/pos.h" // for linenr_T
#include "nvim/ex_cmds_defs.h" // for exarg_T
#include "nvim/screen.h" // for StlClickRecord
+#include "nvim/func_attr.h"
+#include "nvim/eval.h"
+#include "nvim/macros.h"
// Values for buflist_getfile()
enum getf_values {
@@ -15,9 +19,11 @@ enum getf_values {
// Values for buflist_new() flags
enum bln_values {
- BLN_CURBUF = 1, // May re-use curbuf for new buffer
- BLN_LISTED = 2, // Put new buffer in buffer list
- BLN_DUMMY = 4, // Allocating dummy buffer
+ BLN_CURBUF = 1, // May re-use curbuf for new buffer
+ BLN_LISTED = 2, // Put new buffer in buffer list
+ BLN_DUMMY = 4, // Allocating dummy buffer
+ // TODO(mhinz): merge patch that introduces BLN_NEW
+ BLN_NOOPT = 16, // Don't copy options to existing buffer
};
// Values for action argument for do_buffer()
@@ -55,35 +61,64 @@ enum bfa_values {
static inline void switch_to_win_for_buf(buf_T *buf,
win_T **save_curwinp,
tabpage_T **save_curtabp,
- buf_T **save_curbufp)
+ bufref_T *save_curbuf)
{
win_T *wp;
tabpage_T *tp;
if (!find_win_for_buf(buf, &wp, &tp)
- || switch_win(save_curwinp, save_curtabp, wp, tp, true) == FAIL)
- switch_buffer(save_curbufp, buf);
+ || switch_win(save_curwinp, save_curtabp, wp, tp, true) == FAIL) {
+ switch_buffer(save_curbuf, buf);
+ }
}
static inline void restore_win_for_buf(win_T *save_curwin,
tabpage_T *save_curtab,
- buf_T *save_curbuf)
+ bufref_T *save_curbuf)
{
- if (save_curbuf == NULL) {
+ if (save_curbuf->br_buf == NULL) {
restore_win(save_curwin, save_curtab, true);
} else {
restore_buffer(save_curbuf);
}
}
+static inline void buf_set_changedtick(buf_T *const buf,
+ const varnumber_T changedtick)
+ REAL_FATTR_NONNULL_ALL REAL_FATTR_ALWAYS_INLINE;
+
+/// Set b_changedtick and corresponding variable
+///
+/// @param[out] buf Buffer to set changedtick in.
+/// @param[in] changedtick New value.
+static inline void buf_set_changedtick(buf_T *const buf,
+ const varnumber_T changedtick)
+{
+#ifndef NDEBUG
+ dictitem_T *const changedtick_di = tv_dict_find(
+ buf->b_vars, S_LEN("changedtick"));
+ assert(changedtick_di != NULL);
+ assert(changedtick_di->di_tv.v_type == VAR_NUMBER);
+ assert(changedtick_di->di_tv.v_lock == VAR_FIXED);
+ // For some reason formatc does not like the below.
+# ifndef UNIT_TESTING_LUA_PREPROCESSING
+ assert(changedtick_di->di_flags == (DI_FLAGS_RO|DI_FLAGS_FIX));
+# endif
+ assert(changedtick_di == (dictitem_T *)&buf->changedtick_di);
+ assert(&buf->b_changedtick // -V501
+ == &buf->changedtick_di.di_tv.vval.v_number);
+#endif
+ buf->b_changedtick = changedtick;
+}
+
#define WITH_BUFFER(b, code) \
do { \
- buf_T *save_curbuf = NULL; \
win_T *save_curwin = NULL; \
tabpage_T *save_curtab = NULL; \
+ bufref_T save_curbuf = { NULL, 0, 0 }; \
switch_to_win_for_buf(b, &save_curwin, &save_curtab, &save_curbuf); \
code; \
- restore_win_for_buf(save_curwin, save_curtab, save_curbuf); \
+ restore_win_for_buf(save_curwin, save_curtab, &save_curbuf); \
} while (0)
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 2b66a07f48..559dffb945 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -8,14 +8,22 @@
typedef struct file_buffer buf_T; // Forward declaration
+// Reference to a buffer that stores the value of buf_free_count.
+// bufref_valid() only needs to check "buf" when the count differs.
+typedef struct {
+ buf_T *br_buf;
+ int br_fnum;
+ int br_buf_free_count;
+} bufref_T;
+
// for garray_T
#include "nvim/garray.h"
+// for HLF_COUNT
+#include "nvim/highlight_defs.h"
// for pos_T, lpos_T and linenr_T
#include "nvim/pos.h"
// for the number window-local and buffer-local options
#include "nvim/option_defs.h"
-// for optional iconv support
-#include "nvim/iconv.h"
// for jump list and tag stack sizes in a buffer and mark types
#include "nvim/mark_defs.h"
// for u_header_T; needs buf_T.
@@ -23,7 +31,7 @@ typedef struct file_buffer buf_T; // Forward declaration
// for hashtab_T
#include "nvim/hashtab.h"
// for dict_T
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
// for proftime_T
#include "nvim/profile.h"
// for String
@@ -31,7 +39,7 @@ typedef struct file_buffer buf_T; // Forward declaration
// for Map(K, V)
#include "nvim/map.h"
-#define MODIFIABLE(buf) (!buf->terminal && buf->b_p_ma)
+#define MODIFIABLE(buf) (buf->b_p_ma)
/*
* Flags for w_valid.
@@ -83,36 +91,23 @@ typedef struct file_buffer buf_T; // Forward declaration
typedef struct window_S win_T;
typedef struct wininfo_S wininfo_T;
typedef struct frame_S frame_T;
-typedef int scid_T; /* script ID */
// for struct memline (it needs memfile_T)
#include "nvim/memline_defs.h"
-
// for struct memfile, bhdr_T, blocknr_T... (it needs buf_T)
#include "nvim/memfile_defs.h"
-/*
- * This is here because regexp_defs.h needs win_T and buf_T. regprog_T is
- * used below.
- */
+// for regprog_T. Needs win_T and buf_T.
#include "nvim/regexp_defs.h"
-
-// for synstate_T (needs reg_extmatch_T, win_T and buf_T)
+// for synstate_T (needs reg_extmatch_T, win_T, buf_T)
#include "nvim/syntax_defs.h"
-
// for signlist_T
#include "nvim/sign_defs.h"
-
// for bufhl_*_T
#include "nvim/bufhl_defs.h"
-typedef Map(linenr_T, bufhl_vec_T) bufhl_info_T;
-
-// for FileID
-#include "nvim/os/fs_defs.h"
-
-// for Terminal
-#include "nvim/terminal.h"
+#include "nvim/os/fs_defs.h" // for FileID
+#include "nvim/terminal.h" // for Terminal
/*
* The taggy struct is used to store the information about a :tag command.
@@ -239,6 +234,8 @@ typedef struct {
# define w_p_crb_save w_onebuf_opt.wo_crb_save
char_u *wo_scl;
# define w_p_scl w_onebuf_opt.wo_scl // 'signcolumn'
+ char_u *wo_winhl;
+# define w_p_winhl w_onebuf_opt.wo_winhl // 'winhighlight'
int wo_scriptID[WV_COUNT]; /* SIDs for window-local options */
# define w_p_scriptID w_onebuf_opt.wo_scriptID
@@ -325,25 +322,6 @@ typedef struct {
} tasave_T;
/*
- * Used for conversion of terminal I/O and script files.
- */
-typedef struct {
- int vc_type; /* zero or one of the CONV_ values */
- int vc_factor; /* max. expansion factor */
-# ifdef USE_ICONV
- iconv_t vc_fd; /* for CONV_ICONV */
-# endif
- bool vc_fail; /* fail for invalid char, don't use '?' */
-} vimconv_T;
-
-#define CONV_NONE 0
-#define CONV_TO_UTF8 1
-#define CONV_9_TO_UTF8 2
-#define CONV_TO_LATIN1 3
-#define CONV_TO_LATIN9 4
-#define CONV_ICONV 5
-
-/*
* Structure used for mappings and abbreviations.
*/
typedef struct mapblock mapblock_T;
@@ -453,6 +431,16 @@ typedef struct {
char_u *b_syn_isk; // iskeyword option
} synblock_T;
+/// Type used for changedtick_di member in buf_T
+///
+/// Primary exists so that literals of relevant type can be made.
+typedef TV_DICTITEM_STRUCT(sizeof("changedtick")) ChangedtickDictItem;
+
+#define BUF_HAS_QF_ENTRY 1
+#define BUF_HAS_LL_ENTRY 2
+
+// Maximum number of maphash blocks we will have
+#define MAX_MAPHASH 256
/*
* buffer: structure that holds information about one file
@@ -473,9 +461,9 @@ struct file_buffer {
int b_nwindows; /* nr of windows open on this buffer */
- int b_flags; /* various BF_ flags */
- bool b_closing; /* buffer is being closed, don't let
- autocommands close it too. */
+ int b_flags; // various BF_ flags
+ int b_locked; // Buffer is being closed or referenced, don't
+ // let autocommands wipe it out.
/*
* b_ffname has the full path of the file (NULL for no name).
@@ -492,7 +480,9 @@ struct file_buffer {
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
+/// Change identifier incremented for each change, including undo
+#define b_changedtick changedtick_di.di_tv.vval.v_number
+ ChangedtickDictItem changedtick_di; // b:changedtick dictionary item.
bool b_saving; /* Set to true if we are in the middle of
saving the buffer. */
@@ -540,8 +530,8 @@ struct file_buffer {
*/
uint64_t b_chartab[4];
- /* Table used for mappings local to a buffer. */
- mapblock_T *(b_maphash[256]);
+ // Table used for mappings local to a buffer.
+ mapblock_T *(b_maphash[MAX_MAPHASH]);
/* First abbreviation local to a buffer. */
mapblock_T *b_first_abbr;
@@ -611,7 +601,7 @@ struct file_buffer {
int b_p_bomb; ///< 'bomb'
char_u *b_p_bh; ///< 'bufhidden'
char_u *b_p_bt; ///< 'buftype'
- bool b_has_qf_entry; ///< quickfix exists for buffer
+ int b_has_qf_entry; ///< quickfix exists for buffer
int b_p_bl; ///< 'buflisted'
int b_p_cin; ///< 'cindent'
char_u *b_p_cino; ///< 'cinoptions'
@@ -641,6 +631,7 @@ struct file_buffer {
char_u *b_p_inde; ///< 'indentexpr'
uint32_t b_p_inde_flags; ///< flags for 'indentexpr'
char_u *b_p_indk; ///< 'indentkeys'
+ char_u *b_p_fp; ///< 'formatprg'
char_u *b_p_fex; ///< 'formatexpr'
uint32_t b_p_fex_flags; ///< flags for 'formatexpr'
char_u *b_p_kp; ///< 'keywordprg'
@@ -654,6 +645,7 @@ struct file_buffer {
char_u *b_p_qe; ///< 'quoteescape'
int b_p_ro; ///< 'readonly'
long b_p_sw; ///< 'shiftwidth'
+ long b_p_scbk; ///< 'scrollback'
int b_p_si; ///< 'smartindent'
long b_p_sts; ///< 'softtabstop'
long b_p_sts_nopaste; ///< b_p_sts saved for paste mode
@@ -734,8 +726,8 @@ struct file_buffer {
int b_bad_char; /* "++bad=" argument when edit started or 0 */
int b_start_bomb; /* 'bomb' when it was read */
- dictitem_T b_bufvar; /* variable for "b:" Dictionary */
- dict_T *b_vars; /* internal variables, local to buffer */
+ ScopeDictDictItem b_bufvar; ///< Variable for "b:" Dictionary.
+ dict_T *b_vars; ///< b: scope dictionary.
/* When a buffer is created, it starts without a swap file. b_may_swap is
* then set to indicate that a swap file may be opened later. It is reset
@@ -768,7 +760,9 @@ struct file_buffer {
int b_mapped_ctrl_c; // modes where CTRL-C is mapped
- bufhl_info_T *b_bufhl_info; // buffer stored highlights
+ BufhlInfo b_bufhl_info; // buffer stored highlights
+
+ kvec_t(BufhlLine *) b_bufhl_move_space; // temporary space for highlights
};
/*
@@ -823,10 +817,9 @@ struct tabpage_S {
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
- char_u *localdir; ///< Absolute path of local directory or
- ///< NULL
+ ScopeDictDictItem tp_winvar; ///< Variable for "t:" Dictionary.
+ dict_T *tp_vars; ///< Internal variables, local to tab page.
+ char_u *tp_localdir; ///< Absolute path of local cwd or NULL.
};
/*
@@ -945,6 +938,14 @@ struct window_S {
synblock_T *w_s; /* for :ownsyntax */
+ int w_hl_id_normal; ///< 'winhighlight' normal id
+ int w_hl_attr_normal; ///< 'winhighlight' normal final attrs
+
+ int w_hl_ids[HLF_COUNT]; ///< 'winhighlight' id
+ int w_hl_attrs[HLF_COUNT]; ///< 'winhighlight' final attrs
+
+ int w_hl_needs_update; ///< attrs need to be recalculated
+
win_T *w_prev; /* link to previous window */
win_T *w_next; /* link to next window */
bool w_closing; /* window is being closed, don't let
@@ -1118,8 +1119,8 @@ struct window_S {
long w_scbind_pos;
- dictitem_T w_winvar; /* variable for "w:" Dictionary */
- dict_T *w_vars; /* internal variables, local to window */
+ ScopeDictDictItem w_winvar; ///< Variable for "w:" dictionary.
+ dict_T *w_vars; ///< Dictionary with w: variables.
int w_farsi; /* for the window dependent Farsi functions */
@@ -1174,4 +1175,9 @@ struct window_S {
qf_info_T *w_llist_ref;
};
+static inline int win_hl_attr(win_T *wp, int hlf)
+{
+ return wp->w_hl_attrs[hlf];
+}
+
#endif // NVIM_BUFFER_DEFS_H
diff --git a/src/nvim/bufhl_defs.h b/src/nvim/bufhl_defs.h
index e47bb2a238..14b1afa7d9 100644
--- a/src/nvim/bufhl_defs.h
+++ b/src/nvim/bufhl_defs.h
@@ -3,23 +3,32 @@
#include "nvim/pos.h"
#include "nvim/lib/kvec.h"
+#include "nvim/lib/kbtree.h"
+
// bufhl: buffer specific highlighting
-struct bufhl_hl_item
-{
+typedef struct {
int src_id;
int hl_id; // highlight group
colnr_T start; // first column to highlight
colnr_T stop; // last column to highlight
-};
-typedef struct bufhl_hl_item bufhl_hl_item_T;
+} BufhlItem;
-typedef kvec_t(struct bufhl_hl_item) bufhl_vec_T;
+typedef kvec_t(BufhlItem) BufhlItemVec;
+
+typedef struct {
+ linenr_T line;
+ BufhlItemVec items;
+} BufhlLine;
+#define BUFHLLINE_INIT(l) { l, KV_INITIAL_VALUE }
typedef struct {
- bufhl_vec_T entries;
+ BufhlItemVec entries;
int current;
colnr_T valid_to;
-} bufhl_lineinfo_T;
+} BufhlLineInfo;
+#define BUFHL_CMP(a, b) ((int)(((a)->line - (b)->line)))
+KBTREE_INIT(bufhl, BufhlLine *, BUFHL_CMP, 10) // -V512
+typedef kbtree_t(bufhl) BufhlInfo;
#endif // NVIM_BUFHL_DEFS_H
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 4d150c3230..403ef65c4f 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// @file charset.c
///
/// Code related to character sets.
@@ -15,6 +18,7 @@
#include "nvim/func_attr.h"
#include "nvim/indent.h"
#include "nvim/main.h"
+#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
@@ -41,8 +45,10 @@ static bool chartab_initialized = false;
(buf)->b_chartab[(unsigned)(c) >> 6] |= (1ull << ((c) & 0x3f))
#define RESET_CHARTAB(buf, c) \
(buf)->b_chartab[(unsigned)(c) >> 6] &= ~(1ull << ((c) & 0x3f))
+#define GET_CHARTAB_TAB(chartab, c) \
+ ((chartab)[(unsigned)(c) >> 6] & (1ull << ((c) & 0x3f)))
#define GET_CHARTAB(buf, c) \
- ((buf)->b_chartab[(unsigned)(c) >> 6] & (1ull << ((c) & 0x3f)))
+ GET_CHARTAB_TAB((buf)->b_chartab, c)
// Table used below, see init_chartab() for an explanation
static char_u g_chartab[256];
@@ -88,7 +94,6 @@ int buf_init_chartab(buf_T *buf, int global)
{
int c;
int c2;
- char_u *p;
int i;
bool tilde;
bool do_isalpha;
@@ -142,7 +147,8 @@ int buf_init_chartab(buf_T *buf, int global)
// Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint'
// options Each option is a list of characters, character numbers or
// ranges, separated by commas, e.g.: "200-210,x,#-178,-"
- for (i = global ? 0 : 3; i <= 3; ++i) {
+ for (i = global ? 0 : 3; i <= 3; i++) {
+ const char_u *p;
if (i == 0) {
// first round: 'isident'
p = p_isi;
@@ -167,7 +173,7 @@ int buf_init_chartab(buf_T *buf, int global)
}
if (ascii_isdigit(*p)) {
- c = getdigits_int(&p);
+ c = getdigits_int((char_u **)&p);
} else {
c = mb_ptr2char_adv(&p);
}
@@ -177,7 +183,7 @@ int buf_init_chartab(buf_T *buf, int global)
++p;
if (ascii_isdigit(*p)) {
- c2 = getdigits_int(&p);
+ c2 = getdigits_int((char_u **)&p);
} else {
c2 = mb_ptr2char_adv(&p);
}
@@ -210,8 +216,8 @@ int buf_init_chartab(buf_T *buf, int global)
// work properly when 'encoding' is "latin1" and the locale is
// "C".
if (!do_isalpha
- || vim_islower(c)
- || vim_isupper(c)
+ || mb_islower(c)
+ || mb_isupper(c)
|| (p_altkeymap && (F_isalpha(c) || F_isdigit(c)))) {
if (i == 0) {
// (re)set ID flag
@@ -415,11 +421,11 @@ char_u* str_foldcase(char_u *str, int orglen, char_u *buf, int buflen)
while (STR_CHAR(i) != NUL) {
int c = utf_ptr2char(STR_PTR(i));
int olen = utf_ptr2len(STR_PTR(i));
- int lc = utf_tolower(c);
+ int lc = mb_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.
+ // mb_tolower() doesn't return the original character.
if (((c < 0x80) || (olen > 1)) && (c != lc)) {
int nlen = utf_char2len(lc);
@@ -486,7 +492,8 @@ char_u* transchar(int c)
c = K_SECOND(c);
}
- if ((!chartab_initialized && (((c >= ' ') && (c <= '~')) || F_ischar(c)))
+ if ((!chartab_initialized && (((c >= ' ') && (c <= '~'))
+ || (p_altkeymap && F_ischar(c))))
|| ((c < 256) && vim_isprintc_strict(c))) {
// printable character
transchar_buf[i] = (char_u)c;
@@ -538,18 +545,8 @@ void transchar_nonprint(char_u *buf, int c)
buf[1] = (char_u)(c ^ 0x40);
buf[2] = NUL;
- } else if (c >= 0x80) {
- transchar_hex(buf, c);
- } else if ((c >= ' ' + 0x80) && (c <= '~' + 0x80)) {
- // 0xa0 - 0xfe
- buf[0] = '|';
- buf[1] = (char_u)(c - 0x80);
- buf[2] = NUL;
} else {
- // 0x80 - 0x9f and 0xff
- buf[0] = '~';
- buf[1] = (char_u)((c - 0x80) ^ 0x40);
- buf[2] = NUL;
+ transchar_hex(buf, c);
}
}
@@ -633,7 +630,7 @@ int char2cells(int c)
/// @param p
///
/// @return number of display cells.
-int ptr2cells(char_u *p)
+int ptr2cells(const char_u *p)
{
// For UTF-8 we need to look at more bytes if the first byte is >= 0x80.
if (*p >= 0x80) {
@@ -775,6 +772,20 @@ bool vim_iswordc(int c)
return vim_iswordc_buf(c, curbuf);
}
+/// Check that "c" is a keyword character
+/// Letters and characters from 'iskeyword' option for given buffer.
+/// For multi-byte characters mb_get_class() is used (builtin rules).
+///
+/// @param[in] c Character to check.
+/// @param[in] chartab Buffer chartab.
+bool vim_iswordc_tab(const int c, const uint64_t *const chartab)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+{
+ return (c >= 0x100
+ ? (utf_class(c) >= 2)
+ : (c > 0 && GET_CHARTAB_TAB(chartab, c) != 0));
+}
+
/// Check that "c" is a keyword character:
/// Letters and characters from 'iskeyword' option for given buffer.
/// For multi-byte characters mb_get_class() is used (builtin rules).
@@ -784,10 +795,7 @@ bool vim_iswordc(int c)
bool vim_iswordc_buf(int c, buf_T *buf)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(2)
{
- if (c >= 0x100) {
- return utf_class(c) >= 2;
- }
- return c > 0 && c < 0x100 && GET_CHARTAB(buf, c) != 0;
+ return vim_iswordc_tab(c, buf->b_chartab);
}
/// Just like vim_iswordc() but uses a pointer to the (multi-byte) character.
@@ -973,10 +981,8 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he
mb_ptr_adv(s);
c = *s;
- if (!((c != NUL)
- && (vim_isbreak(c)
- || (!vim_isbreak(c)
- && ((col2 == col) || !vim_isbreak(*ps)))))) {
+ if (!(c != NUL
+ && (vim_isbreak(c) || col2 == col || !vim_isbreak(*ps)))) {
break;
}
@@ -1159,7 +1165,13 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
// continue until the NUL
posptr = NULL;
} else {
+ // Special check for an empty line, which can happen on exit, when
+ // ml_get_buf() always returns an empty string.
+ if (*ptr == NUL) {
+ pos->col = 0;
+ }
posptr = ptr + pos->col;
+ posptr -= utf_head_off(line, posptr);
}
// This function is used very often, do some speed optimizations.
@@ -1346,7 +1358,7 @@ void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left,
colnr_T to1;
colnr_T to2;
- if (ltp(pos1, pos2)) {
+ if (lt(*pos1, *pos2)) {
getvvcol(wp, pos1, &from1, NULL, &to1);
getvvcol(wp, pos2, &from2, NULL, &to2);
} else {
@@ -1373,32 +1385,35 @@ void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left,
/// skipwhite: skip over ' ' and '\t'.
///
-/// @param q
+/// @param[in] q String to skip in.
///
/// @return Pointer to character after the skipped whitespace.
-char_u* skipwhite(char_u *q)
+char_u *skipwhite(const char_u *q)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_RET
{
- char_u *p = q;
+ const char_u *p = q;
while (ascii_iswhite(*p)) {
- // skip to next non-white
p++;
}
- return p;
+ return (char_u *)p;
}
-/// skip over digits
+/// Skip over digits
///
-/// @param q
+/// @param[in] q String to skip digits in.
///
/// @return Pointer to the character after the skipped digits.
-char_u* skipdigits(char_u *q)
+char_u *skipdigits(const char_u *q)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_RET
{
- char_u *p = q;
+ const char_u *p = q;
while (ascii_isdigit(*p)) {
// skip to next non-digit
p++;
}
- return p;
+ return (char_u *)p;
}
/// skip over binary digits
@@ -1483,78 +1498,17 @@ char_u* skiptohex(char_u *q)
return p;
}
-// Vim's own character class functions. These exist because many library
-// islower()/toupper() etc. do not work properly: they crash when used with
-// invalid values or can't handle latin1 when the locale is C.
-// Speed is most important here.
-
-/// Check that the character is lower-case
-///
-/// @param c character to check
-bool vim_islower(int c)
- FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
-{
- if (c <= '@') {
- return false;
- }
-
- if (c >= 0x80) {
- return utf_islower(c);
- }
- return islower(c);
-}
-
-/// Check that the character is upper-case
+/// Skip over text until ' ' or '\t' or NUL
///
-/// @param c character to check
-bool vim_isupper(int c)
- FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
-{
- if (c <= '@') {
- return false;
- }
-
- if (c >= 0x80) {
- return utf_isupper(c);
- }
- return isupper(c);
-}
-
-int vim_toupper(int c)
-{
- if (c <= '@') {
- return c;
- }
-
- if (c >= 0x80) {
- return utf_toupper(c);
- }
- return TOUPPER_LOC(c);
-}
-
-int vim_tolower(int c)
-{
- if (c <= '@') {
- return c;
- }
-
- if (c >= 0x80) {
- return utf_tolower(c);
- }
- return TOLOWER_LOC(c);
-}
-
-/// skiptowhite: skip over text until ' ' or '\t' or NUL.
-///
-/// @param p
+/// @param[in] p Text to skip over.
///
/// @return Pointer to the next whitespace or NUL character.
-char_u* skiptowhite(char_u *p)
+char_u *skiptowhite(const char_u *p)
{
while (*p != ' ' && *p != '\t' && *p != NUL) {
p++;
}
- return p;
+ return (char_u *)p;
}
/// skiptowhite_esc: Like skiptowhite(), but also skip escaped chars
@@ -1665,13 +1619,13 @@ bool vim_isblankline(char_u *lbuf)
/// @param unptr Returns the unsigned result.
/// @param maxlen Max length of string to check.
void vim_str2nr(const char_u *const start, int *const prep, int *const len,
- const int what, long *const nptr, unsigned long *const unptr,
- const int maxlen)
+ const int what, varnumber_T *const nptr,
+ uvarnumber_T *const unptr, const int maxlen)
{
const char_u *ptr = start;
int pre = 0; // default is decimal
bool negative = false;
- unsigned long un = 0;
+ uvarnumber_T un = 0;
if (ptr[0] == '-') {
negative = true;
@@ -1727,7 +1681,12 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
n += 2; // skip over "0b"
}
while ('0' <= *ptr && *ptr <= '1') {
- un = 2 * un + (unsigned long)(*ptr - '0');
+ // avoid ubsan error for overflow
+ if (un < UVARNUMBER_MAX / 2) {
+ un = 2 * un + (uvarnumber_T)(*ptr - '0');
+ } else {
+ un = UVARNUMBER_MAX;
+ }
ptr++;
if (n++ == maxlen) {
break;
@@ -1736,7 +1695,12 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
} else if ((pre == '0') || what == STR2NR_OCT + STR2NR_FORCE) {
// octal
while ('0' <= *ptr && *ptr <= '7') {
- un = 8 * un + (unsigned long)(*ptr - '0');
+ // avoid ubsan error for overflow
+ if (un < UVARNUMBER_MAX / 8) {
+ un = 8 * un + (uvarnumber_T)(*ptr - '0');
+ } else {
+ un = UVARNUMBER_MAX;
+ }
ptr++;
if (n++ == maxlen) {
break;
@@ -1749,7 +1713,12 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
n += 2; // skip over "0x"
}
while (ascii_isxdigit(*ptr)) {
- un = 16 * un + (unsigned long)hex2nr(*ptr);
+ // avoid ubsan error for overflow
+ if (un < UVARNUMBER_MAX / 16) {
+ un = 16 * un + (uvarnumber_T)hex2nr(*ptr);
+ } else {
+ un = UVARNUMBER_MAX;
+ }
ptr++;
if (n++ == maxlen) {
break;
@@ -1758,7 +1727,12 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
} else {
// decimal
while (ascii_isdigit(*ptr)) {
- un = 10 * un + (unsigned long)(*ptr - '0');
+ // avoid ubsan error for overflow
+ if (un < UVARNUMBER_MAX / 10) {
+ un = 10 * un + (uvarnumber_T)(*ptr - '0');
+ } else {
+ un = UVARNUMBER_MAX;
+ }
ptr++;
if (n++ == maxlen) {
break;
@@ -1775,11 +1749,18 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
}
if (nptr != NULL) {
- if (negative) {
- // account for leading '-' for decimal numbers
- *nptr = -(long)un;
+ if (negative) { // account for leading '-' for decimal numbers
+ // avoid ubsan error for overflow
+ if (un > VARNUMBER_MAX) {
+ *nptr = VARNUMBER_MIN;
+ } else {
+ *nptr = -(varnumber_T)un;
+ }
} else {
- *nptr = (long)un;
+ if (un > VARNUMBER_MAX) {
+ un = VARNUMBER_MAX;
+ }
+ *nptr = (varnumber_T)un;
}
}
diff --git a/src/nvim/charset.h b/src/nvim/charset.h
index 78d6f2a76c..c69582c4c6 100644
--- a/src/nvim/charset.h
+++ b/src/nvim/charset.h
@@ -1,6 +1,20 @@
#ifndef NVIM_CHARSET_H
#define NVIM_CHARSET_H
+#include "nvim/types.h"
+#include "nvim/pos.h"
+#include "nvim/buffer_defs.h"
+
+/// Return the folded-case equivalent of the given character
+///
+/// @param[in] c Character to transform.
+///
+/// @return Folded variant.
+#define CH_FOLD(c) \
+ utf_fold((sizeof(c) == sizeof(char)) \
+ ?((int)(uint8_t)(c)) \
+ :((int)(c)))
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "charset.h.generated.h"
#endif
diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c
index 3ba9da34f2..60002f3cea 100644
--- a/src/nvim/cursor.c
+++ b/src/nvim/cursor.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <stdbool.h>
#include <inttypes.h>
@@ -12,6 +15,7 @@
#include "nvim/state.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
+#include "nvim/mark.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "cursor.c.generated.h"
@@ -227,9 +231,10 @@ static int coladvance2(
}
}
- /* prevent from moving onto a trail byte */
- if (has_mbyte)
- mb_adjustpos(curbuf, pos);
+ // Prevent from moving onto a trail byte.
+ if (has_mbyte) {
+ mark_mb_adjustpos(curbuf, pos);
+ }
if (col < wcol)
return FAIL;
@@ -294,6 +299,26 @@ linenr_T get_cursor_rel_lnum(win_T *wp, linenr_T lnum)
return (lnum < cursor) ? -retval : retval;
}
+// Make sure "pos.lnum" and "pos.col" are valid in "buf".
+// This allows for the col to be on the NUL byte.
+void check_pos(buf_T *buf, pos_T *pos)
+{
+ char_u *line;
+ colnr_T len;
+
+ if (pos->lnum > buf->b_ml.ml_line_count) {
+ pos->lnum = buf->b_ml.ml_line_count;
+ }
+
+ if (pos->col > 0) {
+ line = ml_get_buf(buf, pos->lnum, false);
+ len = (colnr_T)STRLEN(line);
+ if (pos->col > len) {
+ pos->col = len;
+ }
+ }
+}
+
/*
* Make sure curwin->w_cursor.lnum is valid.
*/
@@ -318,9 +343,8 @@ void check_cursor_col(void)
check_cursor_col_win(curwin);
}
-/*
- * Make sure win->w_cursor.col is valid.
- */
+/// Make sure win->w_cursor.col is valid. Special handling of insert-mode.
+/// @see mb_check_adjust_col
void check_cursor_col_win(win_T *win)
{
colnr_T len;
@@ -342,9 +366,10 @@ void check_cursor_col_win(win_T *win)
win->w_cursor.col = len;
} else {
win->w_cursor.col = len - 1;
- /* Move the cursor to the head byte. */
- if (has_mbyte)
- mb_adjustpos(win->w_buffer, &win->w_cursor);
+ // Move the cursor to the head byte.
+ if (has_mbyte) {
+ mark_mb_adjustpos(win->w_buffer, &win->w_cursor);
+ }
}
} else if (win->w_cursor.col < 0) {
win->w_cursor.col = 0;
diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c
index b50462664c..97fc3a3ca3 100644
--- a/src/nvim/cursor_shape.c
+++ b/src/nvim/cursor_shape.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <stdint.h>
#include "nvim/vim.h"
@@ -7,40 +10,75 @@
#include "nvim/charset.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/ui.h"
-/*
- * Handling of cursor and mouse pointer shapes in various modes.
- */
-
-static cursorentry_T shape_table[SHAPE_IDX_COUNT] =
+/// Handling of cursor and mouse pointer shapes in various modes.
+cursorentry_T shape_table[SHAPE_IDX_COUNT] =
{
- /* The values will be filled in from the 'guicursor' and 'mouseshape'
- * defaults when Vim starts.
- * Adjust the SHAPE_IDX_ defines when making changes! */
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "n", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "v", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "i", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "r", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "c", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "ci", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "cr", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "o", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "ve", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 0L, 0L, 0L, 0, 0, "e", SHAPE_MOUSE},
- {0, 0, 0, 0L, 0L, 0L, 0, 0, "s", SHAPE_MOUSE},
- {0, 0, 0, 0L, 0L, 0L, 0, 0, "sd", SHAPE_MOUSE},
- {0, 0, 0, 0L, 0L, 0L, 0, 0, "vs", SHAPE_MOUSE},
- {0, 0, 0, 0L, 0L, 0L, 0, 0, "vd", SHAPE_MOUSE},
- {0, 0, 0, 0L, 0L, 0L, 0, 0, "m", SHAPE_MOUSE},
- {0, 0, 0, 0L, 0L, 0L, 0, 0, "ml", SHAPE_MOUSE},
- {0, 0, 0, 100L, 100L, 100L, 0, 0, "sm", SHAPE_CURSOR},
+ // Values are set by 'guicursor' and 'mouseshape'.
+ // Adjust the SHAPE_IDX_ defines when changing this!
+ { "normal", 0, 0, 0, 700L, 400L, 250L, 0, 0, "n", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "visual", 0, 0, 0, 700L, 400L, 250L, 0, 0, "v", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "insert", 0, 0, 0, 700L, 400L, 250L, 0, 0, "i", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "replace", 0, 0, 0, 700L, 400L, 250L, 0, 0, "r", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "cmdline_normal", 0, 0, 0, 700L, 400L, 250L, 0, 0, "c", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "cmdline_insert", 0, 0, 0, 700L, 400L, 250L, 0, 0, "ci", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "cmdline_replace", 0, 0, 0, 700L, 400L, 250L, 0, 0, "cr", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "operator", 0, 0, 0, 700L, 400L, 250L, 0, 0, "o", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "visual_select", 0, 0, 0, 700L, 400L, 250L, 0, 0, "ve", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "cmdline_hover", 0, 0, 0, 0L, 0L, 0L, 0, 0, "e", SHAPE_MOUSE },
+ { "statusline_hover", 0, 0, 0, 0L, 0L, 0L, 0, 0, "s", SHAPE_MOUSE },
+ { "statusline_drag", 0, 0, 0, 0L, 0L, 0L, 0, 0, "sd", SHAPE_MOUSE },
+ { "vsep_hover", 0, 0, 0, 0L, 0L, 0L, 0, 0, "vs", SHAPE_MOUSE },
+ { "vsep_drag", 0, 0, 0, 0L, 0L, 0L, 0, 0, "vd", SHAPE_MOUSE },
+ { "more", 0, 0, 0, 0L, 0L, 0L, 0, 0, "m", SHAPE_MOUSE },
+ { "more_lastline", 0, 0, 0, 0L, 0L, 0L, 0, 0, "ml", SHAPE_MOUSE },
+ { "showmatch", 0, 0, 0, 100L, 100L, 100L, 0, 0, "sm", SHAPE_CURSOR },
};
-/*
- * Parse the 'guicursor' option ("what" is SHAPE_CURSOR) or 'mouseshape'
- * ("what" is SHAPE_MOUSE).
- * Returns error message for an illegal option, NULL otherwise.
- */
+/// Converts cursor_shapes into an Array of Dictionaries
+/// @return Array of the form {[ "cursor_shape": ... ], ...}
+Array mode_style_array(void)
+{
+ Array all = ARRAY_DICT_INIT;
+
+ for (int i = 0; i < SHAPE_IDX_COUNT; i++) {
+ Dictionary dic = ARRAY_DICT_INIT;
+ cursorentry_T *cur = &shape_table[i];
+ if (cur->used_for & SHAPE_MOUSE) {
+ PUT(dic, "mouse_shape", INTEGER_OBJ(cur->mshape));
+ }
+ if (cur->used_for & SHAPE_CURSOR) {
+ String shape_str;
+ switch (cur->shape) {
+ case SHAPE_BLOCK: shape_str = cstr_to_string("block"); break;
+ case SHAPE_VER: shape_str = cstr_to_string("vertical"); break;
+ case SHAPE_HOR: shape_str = cstr_to_string("horizontal"); break;
+ default: shape_str = cstr_to_string("unknown");
+ }
+ PUT(dic, "cursor_shape", STRING_OBJ(shape_str));
+ PUT(dic, "cell_percentage", INTEGER_OBJ(cur->percentage));
+ PUT(dic, "blinkwait", INTEGER_OBJ(cur->blinkwait));
+ PUT(dic, "blinkon", INTEGER_OBJ(cur->blinkon));
+ PUT(dic, "blinkoff", INTEGER_OBJ(cur->blinkoff));
+ PUT(dic, "hl_id", INTEGER_OBJ(cur->id));
+ PUT(dic, "id_lm", INTEGER_OBJ(cur->id_lm));
+ }
+ PUT(dic, "name", STRING_OBJ(cstr_to_string(cur->full_name)));
+ PUT(dic, "short_name", STRING_OBJ(cstr_to_string(cur->name)));
+
+ ADD(all, DICTIONARY_OBJ(dic));
+ }
+
+ return all;
+}
+
+/// Parse the 'guicursor' option
+///
+/// @param what SHAPE_CURSOR or SHAPE_MOUSE ('mouseshape')
+///
+/// @returns error message for an illegal option, NULL otherwise.
char_u *parse_shape_opt(int what)
{
char_u *modep;
@@ -55,14 +93,13 @@ char_u *parse_shape_opt(int what)
int found_ve = false; /* found "ve" flag */
int round;
- /*
- * First round: check for errors; second round: do it for real.
- */
- for (round = 1; round <= 2; ++round) {
- /*
- * Repeat for all comma separated parts.
- */
+ // First round: check for errors; second round: do it for real.
+ for (round = 1; round <= 2; round++) {
+ // Repeat for all comma separated parts.
modep = p_guicursor;
+ if (*p_guicursor == NUL) {
+ modep = (char_u *)"a:block-blinkon0";
+ }
while (*modep != NUL) {
colonp = vim_strchr(modep, ':');
if (colonp == NULL)
@@ -71,19 +108,18 @@ char_u *parse_shape_opt(int what)
return (char_u *)N_("E546: Illegal mode");
commap = vim_strchr(modep, ',');
- /*
- * Repeat for all mode's before the colon.
- * For the 'a' mode, we loop to handle all the modes.
- */
+ // Repeat for all modes before the colon.
+ // For the 'a' mode, we loop to handle all the modes.
all_idx = -1;
assert(modep < colonp);
while (modep < colonp || all_idx >= 0) {
if (all_idx < 0) {
- /* Find the mode. */
- if (modep[1] == '-' || modep[1] == ':')
+ // Find the mode
+ if (modep[1] == '-' || modep[1] == ':') {
len = 1;
- else
+ } else {
len = 2;
+ }
if (len == 1 && TOLOWER_ASC(modep[0]) == 'a') {
all_idx = SHAPE_IDX_COUNT - 1;
@@ -100,15 +136,15 @@ char_u *parse_shape_opt(int what)
modep += len + 1;
}
- if (all_idx >= 0)
+ if (all_idx >= 0) {
idx = all_idx--;
- else if (round == 2) {
+ } else if (round == 2) {
{
- /* Set the defaults, for the missing parts */
+ // Set the defaults, for the missing parts
shape_table[idx].shape = SHAPE_BLOCK;
- shape_table[idx].blinkwait = 700L;
- shape_table[idx].blinkon = 400L;
- shape_table[idx].blinkoff = 250L;
+ shape_table[idx].blinkwait = 0L;
+ shape_table[idx].blinkon = 0L;
+ shape_table[idx].blinkoff = 0L;
}
}
@@ -208,6 +244,55 @@ char_u *parse_shape_opt(int what)
shape_table[SHAPE_IDX_VE].id_lm = shape_table[SHAPE_IDX_V].id_lm;
}
}
-
+ ui_mode_info_set();
return NULL;
}
+
+
+/// Map cursor mode from string to integer
+///
+/// @param mode Fullname of the mode whose id we are looking for
+/// @return -1 in case of failure, else the matching SHAPE_ID* integer
+int cursor_mode_str2int(const char *mode)
+{
+ for (int current_mode = 0; current_mode < SHAPE_IDX_COUNT; current_mode++) {
+ if (strcmp(shape_table[current_mode].full_name, mode) == 0) {
+ return current_mode;
+ }
+ }
+ WLOG("Unknown mode %s", mode);
+ return -1;
+}
+
+
+/// Return the index into shape_table[] for the current mode.
+int cursor_get_mode_idx(void)
+{
+ if (State == SHOWMATCH) {
+ return SHAPE_IDX_SM;
+ } else if (State & VREPLACE_FLAG) {
+ return SHAPE_IDX_R;
+ } else if (State & REPLACE_FLAG) {
+ return SHAPE_IDX_R;
+ } else if (State & INSERT) {
+ return SHAPE_IDX_I;
+ } else if (State & CMDLINE) {
+ if (cmdline_at_end()) {
+ return SHAPE_IDX_C;
+ } else if (cmdline_overstrike()) {
+ return SHAPE_IDX_CR;
+ } else {
+ return SHAPE_IDX_CI;
+ }
+ } else if (finish_op) {
+ return SHAPE_IDX_O;
+ } else if (VIsual_active) {
+ if (*p_sel == 'e') {
+ return SHAPE_IDX_VE;
+ } else {
+ return SHAPE_IDX_V;
+ }
+ } else {
+ return SHAPE_IDX_N;
+ }
+}
diff --git a/src/nvim/cursor_shape.h b/src/nvim/cursor_shape.h
index 9ce1b6e0a0..2c466603f0 100644
--- a/src/nvim/cursor_shape.h
+++ b/src/nvim/cursor_shape.h
@@ -1,32 +1,37 @@
#ifndef NVIM_CURSOR_SHAPE_H
#define NVIM_CURSOR_SHAPE_H
-/*
- * struct to store values from 'guicursor' and 'mouseshape'
- */
-/* Indexes in shape_table[] */
-#define SHAPE_IDX_N 0 /* Normal mode */
-#define SHAPE_IDX_V 1 /* Visual mode */
-#define SHAPE_IDX_I 2 /* Insert mode */
-#define SHAPE_IDX_R 3 /* Replace mode */
-#define SHAPE_IDX_C 4 /* Command line Normal mode */
-#define SHAPE_IDX_CI 5 /* Command line Insert mode */
-#define SHAPE_IDX_CR 6 /* Command line Replace mode */
-#define SHAPE_IDX_O 7 /* Operator-pending mode */
-#define SHAPE_IDX_VE 8 /* Visual mode with 'selection' exclusive */
-#define SHAPE_IDX_CLINE 9 /* On command line */
-#define SHAPE_IDX_STATUS 10 /* A status line */
-#define SHAPE_IDX_SDRAG 11 /* dragging a status line */
-#define SHAPE_IDX_VSEP 12 /* A vertical separator line */
-#define SHAPE_IDX_VDRAG 13 /* dragging a vertical separator line */
-#define SHAPE_IDX_MORE 14 /* Hit-return or More */
-#define SHAPE_IDX_MOREL 15 /* Hit-return or More in last line */
-#define SHAPE_IDX_SM 16 /* showing matching paren */
-#define SHAPE_IDX_COUNT 17
-
-#define SHAPE_BLOCK 0 /* block cursor */
-#define SHAPE_HOR 1 /* horizontal bar cursor */
-#define SHAPE_VER 2 /* vertical bar cursor */
+#include "nvim/types.h"
+#include "nvim/api/private/defs.h"
+
+/// struct to store values from 'guicursor' and 'mouseshape'
+/// Indexes in shape_table[]
+typedef enum {
+SHAPE_IDX_N = 0, ///< Normal mode
+SHAPE_IDX_V = 1, ///< Visual mode
+SHAPE_IDX_I = 2, ///< Insert mode
+SHAPE_IDX_R = 3, ///< Replace mode
+SHAPE_IDX_C = 4, ///< Command line Normal mode
+SHAPE_IDX_CI = 5, ///< Command line Insert mode
+SHAPE_IDX_CR = 6, ///< Command line Replace mode
+SHAPE_IDX_O = 7, ///< Operator-pending mode
+SHAPE_IDX_VE = 8, ///< Visual mode with 'selection' exclusive
+SHAPE_IDX_CLINE = 9, ///< On command line
+SHAPE_IDX_STATUS = 10, ///< On status line
+SHAPE_IDX_SDRAG = 11, ///< dragging a status line
+SHAPE_IDX_VSEP = 12, ///< On vertical separator line
+SHAPE_IDX_VDRAG = 13, ///< dragging a vertical separator line
+SHAPE_IDX_MORE = 14, ///< Hit-return or More
+SHAPE_IDX_MOREL = 15, ///< Hit-return or More in last line
+SHAPE_IDX_SM = 16, ///< showing matching paren
+SHAPE_IDX_COUNT = 17
+} ModeShape;
+
+typedef enum {
+SHAPE_BLOCK = 0, ///< block cursor
+SHAPE_HOR = 1, ///< horizontal bar cursor
+SHAPE_VER = 2 ///< vertical bar cursor
+} CursorShape;
#define MSHAPE_NUMBERED 1000 /* offset for shapes identified by number */
#define MSHAPE_HIDE 1 /* hide mouse pointer */
@@ -35,18 +40,20 @@
#define SHAPE_CURSOR 2 /* used for text cursor shape */
typedef struct cursor_entry {
- int shape; /* one of the SHAPE_ defines */
- int mshape; /* one of the MSHAPE defines */
- int percentage; /* percentage of cell for bar */
- long blinkwait; /* blinking, wait time before blinking starts */
- long blinkon; /* blinking, on time */
- long blinkoff; /* blinking, off time */
- int id; /* highlight group ID */
- int id_lm; /* highlight group ID for :lmap mode */
- char *name; /* mode name (fixed) */
- char used_for; /* SHAPE_MOUSE and/or SHAPE_CURSOR */
+ char *full_name; ///< mode description
+ CursorShape shape; ///< cursor shape: one of the SHAPE_ defines
+ int mshape; ///< mouse shape: one of the MSHAPE defines
+ int percentage; ///< percentage of cell for bar
+ long blinkwait; ///< blinking, wait time before blinking starts
+ long blinkon; ///< blinking, on time
+ long blinkoff; ///< blinking, off time
+ int id; ///< highlight group ID
+ int id_lm; ///< highlight group ID for :lmap mode
+ char *name; ///< mode short name
+ char used_for; ///< SHAPE_MOUSE and/or SHAPE_CURSOR
} cursorentry_T;
+extern cursorentry_T shape_table[SHAPE_IDX_COUNT];
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "cursor_shape.h.generated.h"
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index f7b96ba3e1..17de4284ce 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// @file diff.c
///
/// Code for diff'ing two, three or four buffers.
@@ -129,7 +132,7 @@ void diff_buf_add(buf_T *buf)
}
}
- EMSGN(_("E96: Can not diff more than %" PRId64 " buffers"), DB_COUNT);
+ EMSGN(_("E96: Cannot diff more than %" PRId64 " buffers"), DB_COUNT);
}
/// Find buffer "buf" in the list of diff buffers for the current tab page.
@@ -1004,7 +1007,12 @@ theend:
void ex_diffsplit(exarg_T *eap)
{
win_T *old_curwin = curwin;
- buf_T *old_curbuf = curbuf;
+ bufref_T old_curbuf;
+ set_bufref(&old_curbuf, curbuf);
+
+ // Need to compute w_fraction when no redraw happened yet.
+ validate_cursor();
+ set_fraction(curwin);
// don't use a new tab page, each tab page has its own diffs
cmdmod.tab = 0;
@@ -1022,15 +1030,15 @@ void ex_diffsplit(exarg_T *eap)
if (win_valid(old_curwin)) {
diff_win_options(old_curwin, true);
- if (buf_valid(old_curbuf)) {
+ if (bufref_valid(&old_curbuf)) {
// Move the cursor position to that of the old window.
curwin->w_cursor.lnum = diff_get_corresponding_line(
- old_curbuf,
- old_curwin->w_cursor.lnum,
- curbuf,
- curwin->w_cursor.lnum);
+ old_curbuf.br_buf, old_curwin->w_cursor.lnum);
}
}
+ // Now that lines are folded scroll to show the cursor at the same
+ // relative position.
+ scroll_to_fraction(curwin, curwin->w_height);
}
}
}
@@ -1068,8 +1076,8 @@ void diff_win_options(win_T *wp, int addbuf)
if (!wp->w_p_diff) {
wp->w_p_wrap_save = wp->w_p_wrap;
}
- wp->w_p_wrap = FALSE;
- curwin = wp;
+ wp->w_p_wrap = false;
+ curwin = wp; // -V519
curbuf = curwin->w_buffer;
if (!wp->w_p_diff) {
@@ -1153,10 +1161,13 @@ void ex_diffoff(exarg_T *eap)
}
foldUpdateAll(wp);
-
- // make sure topline is not halfway through a fold
- changed_window_setting_win(wp);
}
+ // remove filler lines
+ wp->w_topfill = 0;
+
+ // make sure topline is not halfway a fold and cursor is
+ // invalidated
+ changed_window_setting_win(wp);
// Note: 'sbo' is not restored, it's a global option.
diff_buf_adjust(wp);
@@ -1575,7 +1586,7 @@ static int diff_cmp(char_u *s1, char_u *s2)
}
if ((diff_flags & DIFF_ICASE) && !(diff_flags & DIFF_IWHITE)) {
- return mb_stricmp(s1, s2);
+ return mb_stricmp((const char *)s1, (const char *)s2);
}
// Ignore white space changes and possibly ignore case.
@@ -2297,7 +2308,7 @@ void ex_diffgetput(exarg_T *eap)
// Adjust marks. This will change the following entries!
if (added != 0) {
- mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, (long)added);
+ mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, (long)added, false);
if (curwin->w_cursor.lnum >= lnum) {
// Adjust the cursor position if it's in/after the changed
// lines.
@@ -2449,25 +2460,17 @@ int diff_move_to(int dir, long count)
return OK;
}
-/// Finds the corresponding line in a diff.
-///
-/// @param buf1
-/// @param lnum1
-/// @param buf2
-/// @param lnum3
-///
-/// @return The corresponding line.
-linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1, buf_T *buf2,
- linenr_T lnum3)
+/// Return the line number in the current window that is closest to "lnum1" in
+/// "buf1" in diff mode.
+static linenr_T diff_get_corresponding_line_int(buf_T *buf1, linenr_T lnum1)
{
int idx1;
int idx2;
diff_T *dp;
int baseline = 0;
- linenr_T lnum2;
idx1 = diff_buf_idx(buf1);
- idx2 = diff_buf_idx(buf2);
+ idx2 = diff_buf_idx(curbuf);
if ((idx1 == DB_COUNT)
|| (idx2 == DB_COUNT)
@@ -2487,15 +2490,9 @@ linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1, buf_T *buf2,
for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next) {
if (dp->df_lnum[idx1] > lnum1) {
- lnum2 = lnum1 - baseline;
-
- // don't end up past the end of the file
- if (lnum2 > buf2->b_ml.ml_line_count) {
- lnum2 = buf2->b_ml.ml_line_count;
- }
-
- return lnum2;
- } else if ((dp->df_lnum[idx1] + dp->df_count[idx1]) > lnum1) {
+ return lnum1 - baseline;
+ }
+ if ((dp->df_lnum[idx1] + dp->df_count[idx1]) > lnum1) {
// Inside the diffblock
baseline = lnum1 - dp->df_lnum[idx1];
@@ -2504,30 +2501,42 @@ linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1, buf_T *buf2,
}
return dp->df_lnum[idx2] + baseline;
- } else if ((dp->df_lnum[idx1] == lnum1)
- && (dp->df_count[idx1] == 0)
- && (dp->df_lnum[idx2] <= lnum3)
- && ((dp->df_lnum[idx2] + dp->df_count[idx2]) > lnum3)) {
+ }
+ if ((dp->df_lnum[idx1] == lnum1)
+ && (dp->df_count[idx1] == 0)
+ && (dp->df_lnum[idx2] <= curwin->w_cursor.lnum)
+ && ((dp->df_lnum[idx2] + dp->df_count[idx2])
+ > curwin->w_cursor.lnum)) {
// Special case: if the cursor is just after a zero-count
// block (i.e. all filler) and the target cursor is already
// inside the corresponding block, leave the target cursor
// unmoved. This makes repeated CTRL-W W operations work
// as expected.
- return lnum3;
+ return curwin->w_cursor.lnum;
}
baseline = (dp->df_lnum[idx1] + dp->df_count[idx1])
- - (dp->df_lnum[idx2] + dp->df_count[idx2]);
+ - (dp->df_lnum[idx2] + dp->df_count[idx2]);
}
// If we get here then the cursor is after the last diff
- lnum2 = lnum1 - baseline;
+ return lnum1 - baseline;
+}
+
+/// Finds the corresponding line in a diff.
+///
+/// @param buf1
+/// @param lnum1
+///
+/// @return The corresponding line.
+linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1)
+{
+ linenr_T lnum = diff_get_corresponding_line_int(buf1, lnum1);
// don't end up past the end of the file
- if (lnum2 > buf2->b_ml.ml_line_count) {
- lnum2 = buf2->b_ml.ml_line_count;
+ if (lnum > curbuf->b_ml.ml_line_count) {
+ return curbuf->b_ml.ml_line_count;
}
-
- return lnum2;
+ return lnum;
}
/// For line "lnum" in the current window find the equivalent lnum in window
diff --git a/src/nvim/diff.h b/src/nvim/diff.h
index f6cef1cafd..3624ce29bb 100644
--- a/src/nvim/diff.h
+++ b/src/nvim/diff.h
@@ -1,6 +1,9 @@
#ifndef NVIM_DIFF_H
#define NVIM_DIFF_H
+#include "nvim/pos.h"
+#include "nvim/ex_cmds_defs.h"
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "diff.h.generated.h"
#endif
diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c
index 6ba6e659a6..bfb1b94738 100644
--- a/src/nvim/digraph.c
+++ b/src/nvim/digraph.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// @file digraph.c
///
/// code for digraphs
@@ -790,6 +793,7 @@ static digr_T digraphdefault[] =
{ '/', '-', 0x2020 },
{ '/', '=', 0x2021 },
{ '.', '.', 0x2025 },
+ { ',', '.', 0x2026 },
{ '%', '0', 0x2030 },
{ '1', '\'', 0x2032 },
{ '2', '\'', 0x2033 },
@@ -1448,10 +1452,8 @@ int get_digraph(int cmdline)
{
int cc;
no_mapping++;
- allow_keys++;
int c = plain_vgetc();
no_mapping--;
- allow_keys--;
if (c != ESC) {
// ESC cancels CTRL-K
@@ -1468,10 +1470,8 @@ int get_digraph(int cmdline)
add_to_showcmd(c);
}
no_mapping++;
- allow_keys++;
cc = plain_vgetc();
no_mapping--;
- allow_keys--;
if (cc != ESC) {
// ESC cancels CTRL-K
@@ -1573,7 +1573,8 @@ int getdigraph(int char1, int char2, int meta_char)
if (((retval = getexactdigraph(char1, char2, meta_char)) == char2)
&& (char1 != char2)
- && ((retval = getexactdigraph(char2, char1, meta_char)) == char1)) {
+ && ((retval = getexactdigraph(char2, char1, meta_char)) // -V764
+ == char1)) {
return char2;
}
return retval;
@@ -1679,11 +1680,7 @@ static void printdigraph(digr_T *dp)
int list_width;
- if ((dy_flags & DY_UHEX) || has_mbyte) {
- list_width = 13;
- } else {
- list_width = 11;
- }
+ list_width = 13;
if (dp->result != 0) {
if (msg_col > Columns - list_width) {
@@ -1704,15 +1701,11 @@ static void printdigraph(digr_T *dp)
*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;
+ // add a space to draw a composing char on
+ if (utf_iscomposing(dp->result)) {
+ *p++ = ' ';
}
+ p += (*mb_char2bytes)(dp->result, p);
if (char2cells(dp->result) == 1) {
*p++ = ' ';
diff --git a/src/nvim/digraph.h b/src/nvim/digraph.h
index b623969e08..1b73ccaf3f 100644
--- a/src/nvim/digraph.h
+++ b/src/nvim/digraph.h
@@ -1,6 +1,9 @@
#ifndef NVIM_DIGRAPH_H
#define NVIM_DIGRAPH_H
+#include "nvim/types.h"
+#include "nvim/ex_cmds_defs.h"
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "digraph.h.generated.h"
#endif
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index bb946337b5..17f0b8ef82 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* edit.c: functions for Insert mode
*/
@@ -15,6 +18,7 @@
#include "nvim/cursor.h"
#include "nvim/digraph.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
#include "nvim/farsi.h"
@@ -458,7 +462,7 @@ static void insert_enter(InsertState *s)
// Always update o_lnum, so that a "CTRL-O ." that adds a line
// still puts the cursor back after the inserted text.
- if (ins_at_eol && gchar_cursor() == NUL) {
+ if (ins_at_eol) {
o_lnum = curwin->w_cursor.lnum;
}
@@ -689,11 +693,9 @@ static int insert_execute(VimState *state, int key)
if (s->c == Ctrl_BSL) {
// may need to redraw when no more chars available now
ins_redraw(false);
- ++no_mapping;
- ++allow_keys;
+ no_mapping++;
s->c = plain_vgetc();
- --no_mapping;
- --allow_keys;
+ no_mapping--;
if (s->c != Ctrl_N && s->c != Ctrl_G && s->c != Ctrl_O) {
// it's something else
vungetc(s->c);
@@ -800,9 +802,9 @@ static int insert_handle_key(InsertState *s)
if (!p_im) {
goto normalchar; // insert CTRL-Z as normal char
}
- stuffReadbuff((char_u *)":st\r");
- s->c = Ctrl_O;
- // FALLTHROUGH
+ do_cmdline_cmd("stop");
+ ui_cursor_shape(); // may need to update cursor shape
+ break;
case Ctrl_O: // execute one command
if (ctrl_x_mode == CTRL_X_OMNI) {
@@ -844,6 +846,11 @@ static int insert_handle_key(InsertState *s)
return 0; // exit insert mode
+ case ' ':
+ if (mod_mask != 4) {
+ goto normalchar;
+ }
+ // FALLTHROUGH
case K_ZERO: // Insert the previously inserted text.
case NUL:
case Ctrl_A:
@@ -1419,7 +1426,7 @@ static void ins_ctrl_v(void)
edit_putchar('^', TRUE);
did_putchar = TRUE;
}
- AppendToRedobuff((char_u *)CTRL_V_STR); /* CTRL-V */
+ AppendToRedobuff(CTRL_V_STR);
add_to_showcmd_c(Ctrl_V);
@@ -1859,8 +1866,9 @@ static bool check_compl_option(bool dict_opt)
: (*curbuf->b_p_tsr == NUL && *p_tsr == NUL)) {
ctrl_x_mode = 0;
edit_submode = NULL;
- msg_attr(dict_opt ? (char_u *)_("'dictionary' option is empty")
- : (char_u *)_("'thesaurus' option is empty"), hl_attr(HLF_E));
+ msg_attr((dict_opt
+ ? _("'dictionary' option is empty")
+ : _("'thesaurus' option is empty")), hl_attr(HLF_E));
if (emsg_silent == 0) {
vim_beep(BO_COMPL);
setcursor();
@@ -1972,7 +1980,6 @@ static bool ins_compl_accept_char(int c)
*/
int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int dir, int flags)
{
- char_u *p;
int i, c;
int actual_len; /* Take multi-byte characters */
int actual_compl_length; /* into account. */
@@ -1982,11 +1989,11 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
int was_letter = FALSE;
if (p_ic && curbuf->b_p_inf && len > 0) {
- /* Infer case of completed part. */
+ // Infer case of completed part.
- /* Find actual length of completion. */
+ // Find actual length of completion.
if (has_mbyte) {
- p = str;
+ const char_u *p = str;
actual_len = 0;
while (*p != NUL) {
mb_ptr_adv(p);
@@ -1997,7 +2004,7 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
/* Find actual length of original text. */
if (has_mbyte) {
- p = compl_orig_text;
+ const char_u *p = compl_orig_text;
actual_compl_length = 0;
while (*p != NUL) {
mb_ptr_adv(p);
@@ -2013,27 +2020,35 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
/* Allocate wide character array for the completion and fill it. */
wca = xmalloc(actual_len * sizeof(*wca));
- p = str;
- for (i = 0; i < actual_len; ++i)
- if (has_mbyte)
- wca[i] = mb_ptr2char_adv(&p);
- else
- wca[i] = *(p++);
+ {
+ const char_u *p = str;
+ for (i = 0; i < actual_len; i++) {
+ if (has_mbyte) {
+ wca[i] = mb_ptr2char_adv(&p);
+ } else {
+ wca[i] = *(p++);
+ }
+ }
+ }
- /* Rule 1: Were any chars converted to lower? */
- p = compl_orig_text;
- for (i = 0; i < min_len; ++i) {
- if (has_mbyte)
- c = mb_ptr2char_adv(&p);
- else
- c = *(p++);
- if (vim_islower(c)) {
- has_lower = TRUE;
- if (vim_isupper(wca[i])) {
- /* Rule 1 is satisfied. */
- for (i = actual_compl_length; i < actual_len; ++i)
- wca[i] = vim_tolower(wca[i]);
- break;
+ // Rule 1: Were any chars converted to lower?
+ {
+ const char_u *p = compl_orig_text;
+ for (i = 0; i < min_len; i++) {
+ if (has_mbyte) {
+ c = mb_ptr2char_adv(&p);
+ } else {
+ c = *(p++);
+ }
+ if (mb_islower(c)) {
+ has_lower = true;
+ if (mb_isupper(wca[i])) {
+ // Rule 1 is satisfied.
+ for (i = actual_compl_length; i < actual_len; i++) {
+ wca[i] = mb_tolower(wca[i]);
+ }
+ break;
+ }
}
}
}
@@ -2043,84 +2058,110 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
* upper case.
*/
if (!has_lower) {
- p = compl_orig_text;
- for (i = 0; i < min_len; ++i) {
- if (has_mbyte)
+ const char_u *p = compl_orig_text;
+ for (i = 0; i < min_len; i++) {
+ if (has_mbyte) {
c = mb_ptr2char_adv(&p);
- else
+ } else {
c = *(p++);
- if (was_letter && vim_isupper(c) && vim_islower(wca[i])) {
- /* Rule 2 is satisfied. */
- for (i = actual_compl_length; i < actual_len; ++i)
- wca[i] = vim_toupper(wca[i]);
+ }
+ if (was_letter && mb_isupper(c) && mb_islower(wca[i])) {
+ // Rule 2 is satisfied.
+ for (i = actual_compl_length; i < actual_len; i++) {
+ wca[i] = mb_toupper(wca[i]);
+ }
break;
}
- was_letter = vim_islower(c) || vim_isupper(c);
+ was_letter = mb_islower(c) || mb_isupper(c);
}
}
- /* Copy the original case of the part we typed. */
- p = compl_orig_text;
- for (i = 0; i < min_len; ++i) {
- if (has_mbyte)
- c = mb_ptr2char_adv(&p);
- else
- c = *(p++);
- if (vim_islower(c))
- wca[i] = vim_tolower(wca[i]);
- else if (vim_isupper(c))
- wca[i] = vim_toupper(wca[i]);
+ // Copy the original case of the part we typed.
+ {
+ const char_u *p = compl_orig_text;
+ for (i = 0; i < min_len; i++) {
+ if (has_mbyte) {
+ c = mb_ptr2char_adv(&p);
+ } else {
+ c = *(p++);
+ }
+ if (mb_islower(c)) {
+ wca[i] = mb_tolower(wca[i]);
+ } else if (mb_isupper(c)) {
+ wca[i] = mb_toupper(wca[i]);
+ }
+ }
}
- /*
- * Generate encoding specific output from wide character array.
- * Multi-byte characters can occupy up to five bytes more than
- * ASCII characters, and we also need one byte for NUL, so stay
- * six bytes away from the edge of IObuff.
- */
- p = IObuff;
- i = 0;
- while (i < actual_len && (p - IObuff + 6) < IOSIZE)
- if (has_mbyte)
- p += (*mb_char2bytes)(wca[i++], p);
- else
- *(p++) = wca[i++];
- *p = NUL;
+ // Generate encoding specific output from wide character array.
+ // Multi-byte characters can occupy up to five bytes more than
+ // ASCII characters, and we also need one byte for NUL, so stay
+ // six bytes away from the edge of IObuff.
+ {
+ char_u *p = IObuff;
+ i = 0;
+ while (i < actual_len && (p - IObuff + 6) < IOSIZE) {
+ if (has_mbyte) {
+ p += (*mb_char2bytes)(wca[i++], p);
+ } else {
+ *(p++) = wca[i++];
+ }
+ }
+ *p = NUL;
+ }
xfree(wca);
- return ins_compl_add(IObuff, len, icase, fname, NULL, dir,
- flags, FALSE);
+ return ins_compl_add(IObuff, len, icase, fname, NULL, false, dir, flags,
+ false);
}
- return ins_compl_add(str, len, icase, fname, NULL, dir, flags, FALSE);
+ return ins_compl_add(str, len, icase, fname, NULL, false, dir, flags, false);
}
-/*
- * Add a match to the list of matches.
- * If the given string is already in the list of completions, then return
- * NOTDONE, otherwise add it to the list and return OK. If there is an error
- * then FAIL is returned.
- */
-static int
-ins_compl_add (
- char_u *str,
- int len,
- int icase,
- char_u *fname,
- char_u **cptext, /* extra text for popup menu or NULL */
- int cdir,
- int flags,
- int adup /* accept duplicate match */
-)
+/// Add a match to the list of matches
+///
+/// @param[in] str Match to add.
+/// @param[in] len Match length, -1 to use #STRLEN.
+/// @param[in] icase Whether case is to be ignored.
+/// @param[in] fname File name match comes from. May be NULL.
+/// @param[in] cptext Extra text for popup menu. May be NULL. If not NULL,
+/// must have exactly #CPT_COUNT items.
+/// @param[in] cptext_allocated If true, will not copy cptext strings.
+///
+/// @note Will free strings in case of error.
+/// cptext itself will not be freed.
+/// @param[in] cdir Completion direction.
+/// @param[in] adup True if duplicate matches are to be accepted.
+///
+/// @return NOTDONE if the given string is already in the list of completions,
+/// otherwise it is added to the list and OK is returned. FAIL will be
+/// returned in case of error.
+static int ins_compl_add(char_u *const str, int len,
+ const bool icase, char_u *const fname,
+ char_u *const *const cptext,
+ const bool cptext_allocated,
+ const Direction cdir, int flags, const bool adup)
+ FUNC_ATTR_NONNULL_ARG(1)
{
compl_T *match;
- int dir = (cdir == 0 ? compl_direction : cdir);
+ int dir = (cdir == kDirectionNotSet ? compl_direction : cdir);
os_breakcheck();
- if (got_int)
+#define FREE_CPTEXT(cptext, cptext_allocated) \
+ do { \
+ if (cptext != NULL && cptext_allocated) { \
+ for (size_t i = 0; i < CPT_COUNT; i++) { \
+ xfree(cptext[i]); \
+ } \
+ } \
+ } while (0)
+ if (got_int) {
+ FREE_CPTEXT(cptext, cptext_allocated);
return FAIL;
- if (len < 0)
+ }
+ if (len < 0) {
len = (int)STRLEN(str);
+ }
/*
* If the same match is already present, don't add it.
@@ -2128,10 +2169,12 @@ ins_compl_add (
if (compl_first_match != NULL && !adup) {
match = compl_first_match;
do {
- if ( !(match->cp_flags & ORIGINAL_TEXT)
- && STRNCMP(match->cp_str, str, len) == 0
- && match->cp_str[len] == NUL)
+ if (!(match->cp_flags & ORIGINAL_TEXT)
+ && STRNCMP(match->cp_str, str, len) == 0
+ && match->cp_str[len] == NUL) {
+ FREE_CPTEXT(cptext, cptext_allocated);
return NOTDONE;
+ }
match = match->cp_next;
} while (match != NULL && match != compl_first_match);
}
@@ -2162,16 +2205,26 @@ ins_compl_add (
else if (fname != NULL) {
match->cp_fname = vim_strsave(fname);
flags |= FREE_FNAME;
- } else
+ } else {
match->cp_fname = NULL;
+ }
match->cp_flags = flags;
if (cptext != NULL) {
int i;
- for (i = 0; i < CPT_COUNT; ++i)
- if (cptext[i] != NULL && *cptext[i] != NUL)
- match->cp_text[i] = vim_strsave(cptext[i]);
+ for (i = 0; i < CPT_COUNT; i++) {
+ if (cptext[i] == NULL) {
+ continue;
+ }
+ if (*cptext[i] != NUL) {
+ match->cp_text[i] = (cptext_allocated
+ ? cptext[i]
+ : (char_u *)xstrdup((char *)cptext[i]));
+ } else if (cptext_allocated) {
+ xfree(cptext[i]);
+ }
+ }
}
/*
@@ -2252,9 +2305,10 @@ static void ins_compl_longest_match(compl_T *match)
c1 = *p;
c2 = *s;
}
- if (match->cp_icase ? (vim_tolower(c1) != vim_tolower(c2))
- : (c1 != c2))
+ if (match->cp_icase ? (mb_tolower(c1) != mb_tolower(c2))
+ : (c1 != c2)) {
break;
+ }
if (has_mbyte) {
mb_ptr_adv(p);
mb_ptr_adv(s);
@@ -2294,9 +2348,10 @@ static void ins_compl_add_matches(int num_matches, char_u **matches, int icase)
for (i = 0; i < num_matches && add_r != FAIL; i++)
if ((add_r = ins_compl_add(matches[i], -1, icase,
- NULL, NULL, dir, 0, FALSE)) == OK)
- /* if dir was BACKWARD then honor it just once */
+ NULL, NULL, false, dir, 0, false)) == OK) {
+ // If dir was BACKWARD then honor it just once.
dir = FORWARD;
+ }
FreeWild(num_matches, matches);
}
@@ -2351,6 +2406,7 @@ void set_completion(colnr_T startcol, list_T *list)
ins_compl_prep(' ');
}
ins_compl_clear();
+ ins_compl_free();
compl_direction = FORWARD;
if (startcol > curwin->w_cursor.col)
@@ -2360,8 +2416,8 @@ void set_completion(colnr_T startcol, list_T *list)
/* compl_pattern doesn't need to be set */
compl_orig_text = vim_strnsave(get_cursor_line_ptr() + compl_col,
compl_length);
- if (ins_compl_add(compl_orig_text, -1, p_ic, NULL, NULL, 0,
- ORIGINAL_TEXT, FALSE) != OK) {
+ if (ins_compl_add(compl_orig_text, -1, p_ic, NULL, NULL, false, 0,
+ ORIGINAL_TEXT, false) != OK) {
return;
}
@@ -2373,6 +2429,7 @@ void set_completion(colnr_T startcol, list_T *list)
compl_used_match = TRUE;
compl_cont_status = 0;
int save_w_wrow = curwin->w_wrow;
+ int save_w_leftcol = curwin->w_leftcol;
compl_curr_match = compl_first_match;
if (compl_no_insert || compl_no_select) {
@@ -2387,7 +2444,7 @@ void set_completion(colnr_T startcol, list_T *list)
// Lazily show the popup menu, unless we got interrupted.
if (!compl_interrupted) {
- show_pum(save_w_wrow);
+ show_pum(save_w_wrow, save_w_leftcol);
}
ui_flush();
@@ -2882,7 +2939,7 @@ static void ins_compl_clear(void)
compl_orig_text = NULL;
compl_enter_selects = FALSE;
// clear v:completed_item
- set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
+ set_vim_var_dict(VV_COMPLETED_ITEM, tv_dict_alloc());
}
/// Check that Insert completion is active.
@@ -2907,11 +2964,14 @@ static int ins_compl_bs(void)
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. */
+ // Stop completion when the whole word was deleted. For Omni completion
+ // allow the word to be deleted, we won't match everything.
+ // Respect the 'backspace' option.
if ((int)(p - line) - (int)compl_col < 0
|| ((int)(p - line) - (int)compl_col == 0
- && ctrl_x_mode != CTRL_X_OMNI) || ctrl_x_mode == CTRL_X_EVAL) {
+ && ctrl_x_mode != CTRL_X_OMNI) || ctrl_x_mode == CTRL_X_EVAL
+ || (!can_bs(BS_START) && (int)(p - line) - (int)compl_col
+ - compl_length < 0)) {
return K_BS;
}
@@ -3000,6 +3060,9 @@ static void ins_compl_addleader(int c)
{
int cc;
+ if (stop_arrow() == FAIL) {
+ return;
+ }
if (has_mbyte && (cc = (*mb_char2len)(c)) > 1) {
char_u buf[MB_MAXBYTES + 1];
@@ -3368,10 +3431,10 @@ static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg)
len -= (*mb_head_off)(p, p + len);
for (p += len; *p != NUL; mb_ptr_adv(p))
AppendCharToRedobuff(K_BS);
- } else
+ } else {
len = 0;
- if (ptr != NULL)
- AppendToRedobuffLit(ptr + len, -1);
+ }
+ AppendToRedobuffLit(ptr + len, -1);
}
/*
@@ -3421,7 +3484,6 @@ expand_by_function (
{
list_T *matchlist = NULL;
dict_T *matchdict = NULL;
- char_u *args[2];
char_u *funcname;
pos_T pos;
win_T *curwin_save;
@@ -3432,9 +3494,8 @@ expand_by_function (
if (*funcname == NUL)
return;
- /* Call 'completefunc' to obtain the list of matches. */
- args[0] = (char_u *)"0";
- args[1] = base;
+ // Call 'completefunc' to obtain the list of matches.
+ const char_u *const args[2] = { (char_u *)"0", base };
pos = curwin->w_cursor;
curwin_save = curwin;
@@ -3450,8 +3511,8 @@ expand_by_function (
matchdict = rettv.vval.v_dict;
break;
default:
- /* TODO: Give error message? */
- clear_tv(&rettv);
+ // TODO(brammool): Give error message?
+ tv_clear(&rettv);
break;
}
}
@@ -3473,10 +3534,12 @@ expand_by_function (
ins_compl_add_dict(matchdict);
theend:
- if (matchdict != NULL)
- dict_unref(matchdict);
- if (matchlist != NULL)
- list_unref(matchlist);
+ if (matchdict != NULL) {
+ tv_dict_unref(matchdict);
+ }
+ if (matchlist != NULL) {
+ tv_list_unref(matchlist);
+ }
}
/*
@@ -3505,53 +3568,60 @@ static void ins_compl_add_dict(dict_T *dict)
dictitem_T *di_refresh;
dictitem_T *di_words;
- /* Check for optional "refresh" item. */
- compl_opt_refresh_always = FALSE;
- di_refresh = dict_find(dict, (char_u *)"refresh", 7);
+ // Check for optional "refresh" item.
+ compl_opt_refresh_always = false;
+ di_refresh = tv_dict_find(dict, S_LEN("refresh"));
if (di_refresh != NULL && di_refresh->di_tv.v_type == VAR_STRING) {
- char_u *v = di_refresh->di_tv.vval.v_string;
+ const char *v = (const char *)di_refresh->di_tv.vval.v_string;
- if (v != NULL && STRCMP(v, (char_u *)"always") == 0)
- compl_opt_refresh_always = TRUE;
+ if (v != NULL && strcmp(v, "always") == 0) {
+ compl_opt_refresh_always = true;
+ }
}
- /* Add completions from a "words" list. */
- di_words = dict_find(dict, (char_u *)"words", 5);
- if (di_words != NULL && di_words->di_tv.v_type == VAR_LIST)
+ // Add completions from a "words" list.
+ di_words = tv_dict_find(dict, S_LEN("words"));
+ if (di_words != NULL && di_words->di_tv.v_type == VAR_LIST) {
ins_compl_add_list(di_words->di_tv.vval.v_list);
+ }
}
-/*
- * Add a match to the list of matches from a typeval_T.
- * If the given string is already in the list of completions, then return
- * NOTDONE, otherwise add it to the list and return OK. If there is an error
- * then FAIL is returned.
- */
-int ins_compl_add_tv(typval_T *tv, int dir)
-{
- char_u *word;
- int icase = FALSE;
- int adup = FALSE;
- int aempty = FALSE;
- char_u *(cptext[CPT_COUNT]);
+/// Add a match to the list of matches from VimL object
+///
+/// @param[in] tv Object to get matches from.
+/// @param[in] dir Completion direction.
+///
+/// @return NOTDONE if the given string is already in the list of completions,
+/// otherwise it is added to the list and OK is returned. FAIL will be
+/// returned in case of error.
+int ins_compl_add_tv(typval_T *const tv, const Direction dir)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const char *word;
+ bool icase = false;
+ bool adup = false;
+ bool aempty = false;
+ char *(cptext[CPT_COUNT]);
if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL) {
- word = get_dict_string(tv->vval.v_dict, "word", false);
- cptext[CPT_ABBR] = get_dict_string(tv->vval.v_dict, "abbr", false);
- cptext[CPT_MENU] = get_dict_string(tv->vval.v_dict, "menu", false);
- cptext[CPT_KIND] = get_dict_string(tv->vval.v_dict, "kind", false);
- cptext[CPT_INFO] = get_dict_string(tv->vval.v_dict, "info", false);
-
- icase = get_dict_number(tv->vval.v_dict, "icase");
- adup = get_dict_number(tv->vval.v_dict, "dup");
- aempty = get_dict_number(tv->vval.v_dict, "empty");
+ word = tv_dict_get_string(tv->vval.v_dict, "word", false);
+ cptext[CPT_ABBR] = tv_dict_get_string(tv->vval.v_dict, "abbr", true);
+ cptext[CPT_MENU] = tv_dict_get_string(tv->vval.v_dict, "menu", true);
+ cptext[CPT_KIND] = tv_dict_get_string(tv->vval.v_dict, "kind", true);
+ cptext[CPT_INFO] = tv_dict_get_string(tv->vval.v_dict, "info", true);
+
+ icase = (bool)tv_dict_get_number(tv->vval.v_dict, "icase");
+ adup = (bool)tv_dict_get_number(tv->vval.v_dict, "dup");
+ aempty = (bool)tv_dict_get_number(tv->vval.v_dict, "empty");
} else {
- word = get_tv_string_chk(tv);
+ word = (const char *)tv_get_string_chk(tv);
memset(cptext, 0, sizeof(cptext));
}
- if (word == NULL || (!aempty && *word == NUL))
+ if (word == NULL || (!aempty && *word == NUL)) {
return FAIL;
- return ins_compl_add(word, -1, icase, NULL, cptext, dir, 0, adup);
+ }
+ return ins_compl_add((char_u *)word, -1, icase, NULL,
+ (char_u **)cptext, true, dir, 0, adup);
}
/*
@@ -3847,13 +3917,11 @@ static int ins_compl_get_exp(pos_T *ini)
if ((compl_cont_status & CONT_ADDING)
&& len == compl_length) {
if (pos->lnum < ins_buf->b_ml.ml_line_count) {
- /* Try next line, if any. the new word will be
- * "join" as if the normal command "J" was used.
- * IOSIZE is always greater than
- * compl_length, so the next STRNCPY always
- * works -- Acevedo */
+ // Try next line, if any. the new word will be "join" as if the
+ // normal command "J" was used. IOSIZE is always greater than
+ // compl_length, so the next STRNCPY always works -- Acevedo
STRNCPY(IObuff, ptr, len);
- ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE);
+ ptr = ml_get_buf(ins_buf, pos->lnum + 1, false);
tmp_ptr = ptr = skipwhite(ptr);
/* Find start of next word. */
tmp_ptr = find_word_start(tmp_ptr);
@@ -3968,7 +4036,7 @@ static void ins_compl_delete(void)
// causes flicker, thus we can't do that.
changed_cline_bef_curs();
// clear v:completed_item
- set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
+ set_vim_var_dict(VV_COMPLETED_ITEM, tv_dict_alloc());
}
// Insert the new text being completed.
@@ -3983,17 +4051,21 @@ static void ins_compl_insert(int in_compl_func)
// Set completed item.
// { word, abbr, menu, kind, info }
- dict_T *dict = dict_alloc();
- dict_add_nr_str(dict, "word", 0L,
- EMPTY_IF_NULL(compl_shown_match->cp_str));
- dict_add_nr_str(dict, "abbr", 0L,
- EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_ABBR]));
- dict_add_nr_str(dict, "menu", 0L,
- EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_MENU]));
- dict_add_nr_str(dict, "kind", 0L,
- EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_KIND]));
- dict_add_nr_str(dict, "info", 0L,
- EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_INFO]));
+ dict_T *dict = tv_dict_alloc();
+ tv_dict_add_str(dict, S_LEN("word"),
+ (const char *)EMPTY_IF_NULL(compl_shown_match->cp_str));
+ tv_dict_add_str(
+ dict, S_LEN("abbr"),
+ (const char *)EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_ABBR]));
+ tv_dict_add_str(
+ dict, S_LEN("menu"),
+ (const char *)EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_MENU]));
+ tv_dict_add_str(
+ dict, S_LEN("kind"),
+ (const char *)EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_KIND]));
+ tv_dict_add_str(
+ dict, S_LEN("info"),
+ (const char *)EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_INFO]));
set_vim_var_dict(VV_COMPLETED_ITEM, dict);
if (!in_compl_func) {
compl_curr_match = compl_shown_match;
@@ -4331,7 +4403,9 @@ static int ins_complete(int c, bool enable_pum)
colnr_T curs_col; /* cursor column */
int n;
int save_w_wrow;
+ int save_w_leftcol;
int insert_match;
+ int save_did_ai = did_ai;
compl_direction = ins_compl_key2dir(c);
insert_match = ins_compl_use_match(c);
@@ -4533,7 +4607,6 @@ static int ins_complete(int c, bool enable_pum)
* Call user defined function 'completefunc' with "a:findstart"
* set to 1 to obtain the length of text to use for completion.
*/
- char_u *args[2];
int col;
char_u *funcname;
pos_T pos;
@@ -4547,11 +4620,12 @@ static int ins_complete(int c, bool enable_pum)
if (*funcname == NUL) {
EMSG2(_(e_notset), ctrl_x_mode == CTRL_X_FUNCTION
? "completefunc" : "omnifunc");
+ // restore did_ai, so that adding comment leader works
+ did_ai = save_did_ai;
return FAIL;
}
- args[0] = (char_u *)"1";
- args[1] = NULL;
+ const char_u *const args[2] = { (char_u *)"1", NULL };
pos = curwin->w_cursor;
curwin_save = curwin;
curbuf_save = curbuf;
@@ -4651,8 +4725,8 @@ static int ins_complete(int c, bool enable_pum)
/* Always add completion for the original text. */
xfree(compl_orig_text);
compl_orig_text = vim_strnsave(line + compl_col, compl_length);
- if (ins_compl_add(compl_orig_text, -1, p_ic, NULL, NULL, 0,
- ORIGINAL_TEXT, FALSE) != OK) {
+ if (ins_compl_add(compl_orig_text, -1, p_ic, NULL, NULL, false, 0,
+ ORIGINAL_TEXT, false) != OK) {
xfree(compl_pattern);
compl_pattern = NULL;
xfree(compl_orig_text);
@@ -4680,6 +4754,7 @@ static int ins_complete(int c, bool enable_pum)
* Find next match (and following matches).
*/
save_w_wrow = curwin->w_wrow;
+ save_w_leftcol = curwin->w_leftcol;
n = ins_compl_next(true, ins_compl_key2count(c), insert_match, false);
/* may undisplay the popup menu */
@@ -4803,9 +4878,9 @@ static int ins_complete(int c, bool enable_pum)
if (!shortmess(SHM_COMPLETIONMENU)) {
if (edit_submode_extra != NULL) {
if (!p_smd) {
- msg_attr(edit_submode_extra,
- edit_submode_highl < HLF_COUNT
- ? hl_attr(edit_submode_highl) : 0);
+ msg_attr((const char *)edit_submode_extra,
+ (edit_submode_highl < HLF_COUNT
+ ? hl_attr(edit_submode_highl) : 0));
}
} else {
msg_clr_cmdline(); // necessary for "noshowmode"
@@ -4814,7 +4889,7 @@ static int ins_complete(int c, bool enable_pum)
// Show the popup menu, unless we got interrupted.
if (enable_pum && !compl_interrupted) {
- show_pum(save_w_wrow);
+ show_pum(save_w_wrow, save_w_leftcol);
}
compl_was_interrupted = compl_interrupted;
compl_interrupted = FALSE;
@@ -4840,14 +4915,17 @@ static unsigned quote_meta(char_u *dest, char_u *src, int len)
if (ctrl_x_mode == CTRL_X_DICTIONARY
|| ctrl_x_mode == CTRL_X_THESAURUS)
break;
+ // fallthrough
case '~':
if (!p_magic) /* quote these only if magic is set */
break;
+ // fallthrough
case '\\':
if (ctrl_x_mode == CTRL_X_DICTIONARY
|| ctrl_x_mode == CTRL_X_THESAURUS)
break;
- case '^': /* currently it's not needed. */
+ // fallthrough
+ case '^': // currently it's not needed.
case '$':
m++;
if (dest != NULL)
@@ -5730,15 +5808,16 @@ comp_textwidth (
*/
static void redo_literal(int c)
{
- char_u buf[10];
+ char buf[10];
- /* Only digits need special treatment. Translate them into a string of
- * three digits. */
+ // Only digits need special treatment. Translate them into a string of
+ // three digits.
if (ascii_isdigit(c)) {
- vim_snprintf((char *)buf, sizeof(buf), "%03d", c);
+ vim_snprintf(buf, sizeof(buf), "%03d", c);
AppendToRedobuff(buf);
- } else
+ } else {
AppendCharToRedobuff(c);
+ }
}
// start_arrow() is called when an arrow key is used in insert mode.
@@ -5767,8 +5846,8 @@ static void start_arrow_common(pos_T *end_insert_pos, bool end_change)
{
if (!arrow_used && end_change) { // something has been inserted
AppendToRedobuff(ESC_STR);
- stop_insert(end_insert_pos, FALSE, FALSE);
- arrow_used = TRUE; /* this means we stopped the current insert */
+ stop_insert(end_insert_pos, false, false);
+ arrow_used = true; // This means we stopped the current insert.
}
check_spell_redraw();
}
@@ -5825,7 +5904,7 @@ int stop_arrow(void)
vr_lines_changed = 1;
}
ResetRedobuff();
- AppendToRedobuff((char_u *)"1i"); /* pretend we start an insertion */
+ AppendToRedobuff("1i"); // Pretend we start an insertion.
new_insert_skip = 2;
} else if (ins_need_undo) {
if (u_save_cursor() == OK)
@@ -6290,12 +6369,13 @@ stuff_inserted (
}
do {
- stuffReadbuff(ptr);
- /* a trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^" */
- if (last)
- stuffReadbuff((char_u *)(last == '0'
- ? "\026\060\064\070"
- : "\026^"));
+ stuffReadbuff((const char *)ptr);
+ // A trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^".
+ if (last) {
+ stuffReadbuff((last == '0'
+ ? "\026\060\064\070"
+ : "\026^"));
+ }
} while (--count > 0);
if (last)
@@ -7052,8 +7132,8 @@ static void ins_ctrl_g(void)
*/
static void ins_ctrl_hat(void)
{
- if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE)) {
- /* ":lmap" mappings exists, Toggle use of ":lmap" mappings. */
+ if (map_to_exists_mode("", LANGMAP, false)) {
+ // ":lmap" mappings exists, Toggle use of ":lmap" mappings.
if (State & LANGMAP) {
curbuf->b_p_iminsert = B_IMODE_NONE;
State &= ~LANGMAP;
@@ -7088,13 +7168,12 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
disabled_redraw = false;
}
if (!arrow_used) {
- /*
- * Don't append the ESC for "r<CR>" and "grx".
- * When 'insertmode' is set only CTRL-L stops Insert mode. Needed for
- * when "count" is non-zero.
- */
- if (cmdchar != 'r' && cmdchar != 'v')
- AppendToRedobuff(p_im ? (char_u *)"\014" : ESC_STR);
+ // Don't append the ESC for "r<CR>" and "grx".
+ // When 'insertmode' is set only CTRL-L stops Insert mode. Needed for
+ // when "count" is non-zero.
+ if (cmdchar != 'r' && cmdchar != 'v') {
+ AppendToRedobuff(p_im ? "\014" : ESC_STR);
+ }
/*
* Repeating insert may take a long time. Check for
@@ -7248,7 +7327,8 @@ static bool ins_start_select(int c)
// Execute the key in (insert) Select mode.
stuffcharReadbuff(Ctrl_O);
if (mod_mask) {
- char_u buf[4] = { K_SPECIAL, KS_MODIFIER, mod_mask, NUL };
+ const char buf[] = { (char)K_SPECIAL, (char)KS_MODIFIER,
+ (char)(uint8_t)mod_mask, NUL };
stuffReadbuff(buf);
}
stuffcharReadbuff(c);
@@ -8056,11 +8136,11 @@ static bool ins_tab(void)
return true;
}
- did_ai = FALSE;
- did_si = FALSE;
- can_si = FALSE;
- can_si_back = FALSE;
- AppendToRedobuff((char_u *)"\t");
+ did_ai = false;
+ did_si = false;
+ can_si = false;
+ can_si_back = false;
+ AppendToRedobuff("\t");
if (p_sta && ind) { // insert tab in indent, use "shiftwidth"
temp = get_sw_value(curbuf);
@@ -8287,17 +8367,16 @@ static int ins_digraph(void)
}
- /* don't map the digraph chars. This also prevents the
- * mode message to be deleted when ESC is hit */
- ++no_mapping;
- ++allow_keys;
+ // don't map the digraph chars. This also prevents the
+ // mode message to be deleted when ESC is hit
+ no_mapping++;
c = plain_vgetc();
- --no_mapping;
- --allow_keys;
- if (did_putchar)
- /* when the line fits in 'columns' the '?' is at the start of the next
- * line and will not be removed by the redraw */
+ no_mapping--;
+ if (did_putchar) {
+ // when the line fits in 'columns' the '?' is at the start of the next
+ // line and will not be removed by the redraw
edit_unputchar();
+ }
if (IS_SPECIAL(c) || mod_mask) { /* special key */
clear_showcmd();
@@ -8317,18 +8396,17 @@ static int ins_digraph(void)
}
add_to_showcmd_c(c);
}
- ++no_mapping;
- ++allow_keys;
+ no_mapping++;
cc = plain_vgetc();
- --no_mapping;
- --allow_keys;
- if (did_putchar)
- /* when the line fits in 'columns' the '?' is at the start of the
- * next line and will not be removed by a redraw */
+ no_mapping--;
+ if (did_putchar) {
+ // when the line fits in 'columns' the '?' is at the start of the
+ // next line and will not be removed by a redraw
edit_unputchar();
+ }
if (cc != ESC) {
- AppendToRedobuff((char_u *)CTRL_V_STR);
- c = getdigraph(c, cc, TRUE);
+ AppendToRedobuff(CTRL_V_STR);
+ c = getdigraph(c, cc, true);
clear_showcmd();
return c;
}
@@ -8390,12 +8468,13 @@ static int ins_ctrl_ey(int tc)
if (c != NUL) {
long tw_save;
- /* The character must be taken literally, insert like it
- * was typed after a CTRL-V, and pretend 'textwidth'
- * wasn't set. Digits, 'o' and 'x' are special after a
- * CTRL-V, don't use it for these. */
- if (c < 256 && !isalnum(c))
- AppendToRedobuff((char_u *)CTRL_V_STR); /* CTRL-V */
+ // The character must be taken literally, insert like it
+ // was typed after a CTRL-V, and pretend 'textwidth'
+ // wasn't set. Digits, 'o' and 'x' are special after a
+ // CTRL-V, don't use it for these.
+ if (c < 256 && !isalnum(c)) {
+ AppendToRedobuff(CTRL_V_STR);
+ }
tw_save = curbuf->b_p_tw;
curbuf->b_p_tw = -1;
insert_special(c, TRUE, FALSE);
@@ -8542,15 +8621,16 @@ static char_u *do_insert_char_pre(int c)
return res;
}
-static void show_pum(int save_w_wrow)
+static void show_pum(int prev_w_wrow, int prev_w_leftcol)
{
// RedrawingDisabled may be set when invoked through complete().
int n = RedrawingDisabled;
RedrawingDisabled = 0;
- // If the cursor moved we need to remove the pum first.
+ // If the cursor moved or the display scrolled we need to remove the pum
+ // first.
setcursor();
- if (save_w_wrow != curwin->w_wrow) {
+ if (prev_w_wrow != curwin->w_wrow || prev_w_leftcol != curwin->w_leftcol) {
ins_compl_del_pum();
}
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 17e89e5757..d6ee13857a 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -1,8 +1,12 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* eval.c: Expression evaluation.
*/
#include <assert.h>
+#include <float.h>
#include <inttypes.h>
#include <stdarg.h>
#include <string.h>
@@ -30,6 +34,7 @@
#include "nvim/ex_eval.h"
#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
+#include "nvim/os/fileio.h"
#include "nvim/func_attr.h"
#include "nvim/fold.h"
#include "nvim/getchar.h"
@@ -42,6 +47,7 @@
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
+#include "nvim/menu.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
#include "nvim/keymap.h"
@@ -93,7 +99,13 @@
#include "nvim/lib/kvec.h"
#include "nvim/lib/khash.h"
#include "nvim/lib/queue.h"
-#include "nvim/eval/typval_encode.h"
+#include "nvim/lua/executor.h"
+#include "nvim/eval/typval.h"
+#include "nvim/eval/executor.h"
+#include "nvim/eval/gc.h"
+#include "nvim/macros.h"
+
+// TODO(ZyX-I): Remove DICT_MAXNEST, make users be non-recursive instead
#define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */
@@ -131,31 +143,28 @@
* "newkey" is the key for the new item.
*/
typedef struct lval_S {
- char_u *ll_name; /* start of variable name (can be NULL) */
- char_u *ll_exp_name; /* NULL or expanded name in allocated memory. */
- typval_T *ll_tv; /* Typeval of item being used. If "newkey"
- isn't NULL it's the Dict to which to add
- the item. */
- listitem_T *ll_li; /* The list item or NULL. */
- list_T *ll_list; /* The list or NULL. */
- int ll_range; /* TRUE when a [i:j] range was used */
- long ll_n1; /* First index for list */
- long ll_n2; /* Second index for list range */
- int ll_empty2; /* Second index is empty: [i:] */
- dict_T *ll_dict; /* The Dictionary or NULL */
- dictitem_T *ll_di; /* The dictitem or NULL */
- char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */
+ const char *ll_name; ///< Start of variable name (can be NULL).
+ size_t ll_name_len; ///< Length of the .ll_name.
+ char *ll_exp_name; ///< NULL or expanded name in allocated memory.
+ typval_T *ll_tv; ///< Typeval of item being used. If "newkey"
+ ///< isn't NULL it's the Dict to which to add the item.
+ listitem_T *ll_li; ///< The list item or NULL.
+ list_T *ll_list; ///< The list or NULL.
+ int ll_range; ///< TRUE when a [i:j] range was used.
+ long ll_n1; ///< First index for list.
+ long ll_n2; ///< Second index for list range.
+ int ll_empty2; ///< Second index is empty: [i:].
+ dict_T *ll_dict; ///< The Dictionary or NULL.
+ dictitem_T *ll_di; ///< The dictitem or NULL.
+ char_u *ll_newkey; ///< New key for Dict in allocated memory or NULL.
} lval_T;
static char *e_letunexp = N_("E18: Unexpected characters in :let");
-static char *e_listidx = N_("E684: list index out of range: %" PRId64);
-static char *e_undefvar = N_("E121: Undefined variable: %s");
static char *e_missbrac = N_("E111: Missing ']'");
static char *e_listarg = N_("E686: Argument of %s must be a List");
static char *e_listdictarg = N_(
"E712: Argument of %s must be a List or Dictionary");
-static char *e_emptykey = N_("E713: Cannot use empty key for Dictionary");
static char *e_listreq = N_("E714: List required");
static char *e_dictreq = N_("E715: Dictionary required");
static char *e_stringreq = N_("E928: String required");
@@ -166,15 +175,20 @@ static char *e_funcexts = N_(
static char *e_funcdict = N_("E717: Dictionary entry already exists");
static char *e_funcref = N_("E718: Funcref required");
static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary");
-static char *e_letwrong = N_("E734: Wrong variable type for %s=");
static char *e_nofunc = N_("E130: Unknown function: %s");
static char *e_illvar = N_("E461: Illegal variable name: %s");
-static char *e_float_as_string = N_("E806: using Float as a String");
+static const char *e_readonlyvar = N_(
+ "E46: Cannot change read-only variable \"%.*s\"");
+
+// TODO(ZyX-I): move to eval/executor
+static char *e_letwrong = N_("E734: Wrong variable type for %s=");
-static char_u * const empty_string = (char_u *)"";
static char_u * const namespace_char = (char_u *)"abglstvw";
-static dictitem_T globvars_var; /* variable used for g: */
+/// Variable used for g:
+static ScopeDictDictItem globvars_var;
+
+/// g: value
#define globvarht globvardict.dv_hashtab
/*
@@ -185,12 +199,15 @@ static hashtab_T compat_hashtab;
hashtab_T func_hashtab;
+// Used for checking if local variables or arguments used in a lambda.
+static int *eval_lavars_used = NULL;
+
/*
* Array to hold the hashtab with variables local to each sourced script.
* Each item holds a variable (nameless) that points to the dict_T.
*/
typedef struct {
- dictitem_T sv_var;
+ ScopeDictDictItem sv_var;
dict_T sv_dict;
} scriptvar_T;
@@ -200,61 +217,72 @@ static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL};
static int echo_attr = 0; /* attributes used for ":echo" */
-/* Values for trans_function_name() argument: */
-#define TFN_INT 1 /* internal function name OK */
-#define TFN_QUIET 2 /* no error messages */
-#define TFN_NO_AUTOLOAD 4 /* do not use script autoloading */
-
-/* Values for get_lval() flags argument: */
-#define GLV_QUIET TFN_QUIET /* no error messages */
-#define GLV_NO_AUTOLOAD TFN_NO_AUTOLOAD /* do not use script autoloading */
-
-/* function flags */
-#define FC_ABORT 1 /* abort function on error */
-#define FC_RANGE 2 /* function accepts range */
-#define FC_DICT 4 /* Dict function, uses "self" */
-
-/* The names of packages that once were loaded are remembered. */
-static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
-
-// List heads for garbage collection. Although there can be a reference loop
-// from partial to dict to partial, we don't need to keep track of the partial,
-// since it will get freed when the dict is unused and gets freed.
-static dict_T *first_dict = NULL; // list of all dicts
-static list_T *first_list = NULL; // list of all lists
+/// trans_function_name() flags
+typedef enum {
+ TFN_INT = 1, ///< May use internal function name
+ TFN_QUIET = 2, ///< Do not emit error messages.
+ TFN_NO_AUTOLOAD = 4, ///< Do not use script autoloading.
+ TFN_NO_DEREF = 8, ///< Do not dereference a Funcref.
+ TFN_READ_ONLY = 16, ///< Will not change the variable.
+} TransFunctionNameFlags;
+
+/// get_lval() flags
+typedef enum {
+ GLV_QUIET = TFN_QUIET, ///< Do not emit error messages.
+ GLV_NO_AUTOLOAD = TFN_NO_AUTOLOAD, ///< Do not use script autoloading.
+ GLV_READ_ONLY = TFN_READ_ONLY, ///< Indicates that caller will not change
+ ///< the value (prevents error message).
+} GetLvalFlags;
+
+// function flags
+#define FC_ABORT 0x01 // abort function on error
+#define FC_RANGE 0x02 // function accepts range
+#define FC_DICT 0x04 // Dict function, uses "self"
+#define FC_CLOSURE 0x08 // closure, uses outer scope variables
+#define FC_DELETED 0x10 // :delfunction used while uf_refcount > 0
+#define FC_REMOVED 0x20 // function redefined while uf_refcount > 0
+
+// The names of packages that once were loaded are remembered.
+static garray_T ga_loaded = { 0, 0, sizeof(char_u *), 4, NULL };
#define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j]
#define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j]
-#define VAR_SHORT_LEN 20 /* short variable name length */
-#define FIXVAR_CNT 12 /* number of fixed variables */
-
-/* structure to hold info for a function that is currently being executed. */
-typedef struct funccall_S funccall_T;
+/// Short variable name length
+#define VAR_SHORT_LEN 20
+/// Number of fixed variables used for arguments
+#define FIXVAR_CNT 12
struct funccall_S {
- ufunc_T *func; /* function being called */
- int linenr; /* next line to be executed */
- int returned; /* ":return" used */
- struct /* fixed variables for arguments */
- {
- dictitem_T var; /* variable (without room for name) */
- char_u room[VAR_SHORT_LEN]; /* room for the name */
- } fixvar[FIXVAR_CNT];
- dict_T l_vars; /* l: local function variables */
- dictitem_T l_vars_var; /* variable for l: scope */
- dict_T l_avars; /* a: argument variables */
- dictitem_T l_avars_var; /* variable for a: scope */
- list_T l_varlist; /* list for a:000 */
- listitem_T l_listitems[MAX_FUNC_ARGS]; /* listitems for a:000 */
- typval_T *rettv; /* return value */
- linenr_T breakpoint; /* next line with breakpoint or zero */
- int dbg_tick; /* debug_tick when breakpoint was set */
- int level; /* top nesting level of executed function */
- proftime_T prof_child; /* time spent in a child */
- funccall_T *caller; /* calling function or NULL */
+ ufunc_T *func; ///< Function being called.
+ int linenr; ///< Next line to be executed.
+ int returned; ///< ":return" used.
+ /// Fixed variables for arguments.
+ TV_DICTITEM_STRUCT(VAR_SHORT_LEN + 1) fixvar[FIXVAR_CNT];
+ dict_T l_vars; ///< l: local function variables.
+ ScopeDictDictItem l_vars_var; ///< Variable for l: scope.
+ dict_T l_avars; ///< a: argument variables.
+ ScopeDictDictItem l_avars_var; ///< Variable for a: scope.
+ list_T l_varlist; ///< List for a:000.
+ listitem_T l_listitems[MAX_FUNC_ARGS]; ///< List items for a:000.
+ typval_T *rettv; ///< Return value.
+ linenr_T breakpoint; ///< Next line with breakpoint or zero.
+ int dbg_tick; ///< Debug_tick when breakpoint was set.
+ int level; ///< Top nesting level of executed function.
+ proftime_T prof_child; ///< Time spent in a child.
+ funccall_T *caller; ///< Calling function or NULL.
+ int fc_refcount; ///< Number of user functions that reference this funccall.
+ int fc_copyID; ///< CopyID used for garbage collection.
+ garray_T fc_funcs; ///< List of ufunc_T* which keep a reference to "func".
};
+///< Structure used by trans_function_name()
+typedef struct {
+ dict_T *fd_dict; ///< Dictionary used.
+ char_u *fd_newkey; ///< New key in "dict" in allocated memory.
+ dictitem_T *fd_di; ///< Dictionary item used.
+} funcdict_T;
+
/*
* Info used by a ":for" loop.
*/
@@ -266,15 +294,6 @@ typedef struct {
} forinfo_T;
/*
- * Struct used by trans_function_name()
- */
-typedef struct {
- dict_T *fd_dict; /* Dictionary used */
- char_u *fd_newkey; /* new key in "dict" in allocated memory */
- dictitem_T *fd_di; /* Dictionary item used */
-} funcdict_T;
-
-/*
* enum used by var_flavour()
*/
typedef enum {
@@ -305,8 +324,8 @@ typedef enum {
// variables with the VV_ defines.
static struct vimvar {
char *vv_name; ///< Name of the variable, without v:.
- dictitem16_T vv_di; ///< Value and name for key (max 16 chars)
- char vv_flags; ///< Flags: #VV_COMPAT, #VV_RO, #VV_RO_SBX.
+ TV_DICTITEM_STRUCT(17) vv_di; ///< Value and name for key (max 16 chars).
+ char vv_flags; ///< Flags: #VV_COMPAT, #VV_RO, #VV_RO_SBX.
} vimvars[] =
{
// VV_ tails differing from upcased string literals:
@@ -389,6 +408,7 @@ static struct vimvar {
VV(VV__NULL_LIST, "_null_list", VAR_LIST, VV_RO),
VV(VV__NULL_DICT, "_null_dict", VAR_DICT, VV_RO),
VV(VV_VIM_DID_ENTER, "vim_did_enter", VAR_NUMBER, VV_RO),
+ VV(VV_TESTING, "testing", VAR_NUMBER, 0),
VV(VV_TYPE_NUMBER, "t_number", VAR_NUMBER, VV_RO),
VV(VV_TYPE_STRING, "t_string", VAR_NUMBER, VV_RO),
VV(VV_TYPE_FUNC, "t_func", VAR_NUMBER, VV_RO),
@@ -410,23 +430,11 @@ static struct vimvar {
#define vv_dict vv_di.di_tv.vval.v_dict
#define vv_tv vv_di.di_tv
-static dictitem_T vimvars_var; // variable used for v:
-#define vimvarht vimvardict.dv_hashtab
+/// Variable used for v:
+static ScopeDictDictItem vimvars_var;
-typedef enum {
- kCallbackNone,
- kCallbackFuncref,
- kCallbackPartial,
-} CallbackType;
-
-typedef struct {
- union {
- char_u *funcref;
- partial_T *partial;
- } data;
- CallbackType type;
-} Callback;
-#define CALLBACK_NONE ((Callback){ .type = kCallbackNone })
+/// v: hashtab
+#define vimvarht vimvardict.dv_hashtab
typedef struct {
union {
@@ -440,18 +448,11 @@ typedef struct {
bool rpc;
int refcount;
Callback on_stdout, on_stderr, on_exit;
- int *status_ptr;
+ varnumber_T *status_ptr;
uint64_t id;
MultiQueue *events;
} TerminalJobData;
-typedef struct dict_watcher {
- Callback callback;
- char *key_pattern;
- QUEUE node;
- bool busy; // prevent recursion if the dict is changed in the callback
-} DictWatcher;
-
typedef struct {
TerminalJobData *data;
Callback *callback;
@@ -467,6 +468,7 @@ typedef struct {
int refcount;
long timeout;
bool stopped;
+ bool paused;
Callback callback;
} timer_T;
@@ -486,6 +488,24 @@ typedef struct fst {
KHASH_MAP_INIT_STR(functions, VimLFuncDef)
+/// Type of assert_* check being performed
+typedef enum
+{
+ ASSERT_EQUAL,
+ ASSERT_NOTEQUAL,
+ ASSERT_MATCH,
+ ASSERT_NOTMATCH,
+ ASSERT_INRANGE,
+ ASSERT_OTHER,
+} assert_type_T;
+
+/// Type for dict_list function
+typedef enum {
+ kDictListKeys, ///< List dictionary keys.
+ kDictListValues, ///< List dictionary values.
+ kDictListItems, ///< List dictionary contents: [keys, values].
+} DictListType;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval.c.generated.h"
#endif
@@ -498,6 +518,14 @@ static PMap(uint64_t) *jobs = NULL;
static uint64_t last_timer_id = 0;
static PMap(uint64_t) *timers = NULL;
+/// Dummy va_list for passing to vim_snprintf
+///
+/// Used because:
+/// - passing a NULL pointer doesn't work when va_list isn't a pointer
+/// - locally in the function results in a "used before set" warning
+/// - using va_start() to initialize it gives "function with fixed args" error
+static va_list dummy_ap;
+
static const char *const msgpack_type_names[] = {
[kMPNil] = "nil",
[kMPBoolean] = "boolean",
@@ -558,19 +586,19 @@ void eval_init(void)
}
vimvars[VV_VERSION].vv_nr = VIM_VERSION_100;
- dict_T *const msgpack_types_dict = dict_alloc();
+ dict_T *const msgpack_types_dict = tv_dict_alloc();
for (size_t i = 0; i < ARRAY_SIZE(msgpack_type_names); i++) {
- list_T *const type_list = list_alloc();
+ list_T *const type_list = tv_list_alloc();
type_list->lv_lock = VAR_FIXED;
type_list->lv_refcount = 1;
- dictitem_T *const di = dictitem_alloc((char_u *) msgpack_type_names[i]);
- di->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
+ dictitem_T *const di = tv_dict_item_alloc(msgpack_type_names[i]);
+ di->di_flags |= DI_FLAGS_RO|DI_FLAGS_FIX;
di->di_tv = (typval_T) {
.v_type = VAR_LIST,
.vval = { .v_list = type_list, },
};
eval_msgpack_type_lists[i] = type_list;
- if (dict_add(msgpack_types_dict, di) == FAIL) {
+ if (tv_dict_add(msgpack_types_dict, di) == FAIL) {
// There must not be duplicate items in this dictionary by definition.
assert(false);
}
@@ -578,12 +606,12 @@ void eval_init(void)
msgpack_types_dict->dv_lock = VAR_FIXED;
set_vim_var_dict(VV_MSGPACK_TYPES, msgpack_types_dict);
- set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
+ set_vim_var_dict(VV_COMPLETED_ITEM, tv_dict_alloc());
- dict_T *v_event = dict_alloc();
+ dict_T *v_event = tv_dict_alloc();
v_event->dv_lock = VAR_FIXED;
set_vim_var_dict(VV_EVENT, v_event);
- set_vim_var_list(VV_ERRORS, list_alloc());
+ set_vim_var_list(VV_ERRORS, tv_list_alloc());
set_vim_var_nr(VV_SEARCHFORWARD, 1L);
set_vim_var_nr(VV_HLSEARCH, 1L);
set_vim_var_nr(VV_COUNT1, 1);
@@ -614,7 +642,7 @@ void eval_clear(void)
xfree(p->vv_str);
p->vv_str = NULL;
} else if (p->vv_di.di_tv.v_type == VAR_LIST) {
- list_unref(p->vv_list);
+ tv_list_unref(p->vv_list);
p->vv_list = NULL;
}
}
@@ -640,12 +668,11 @@ void eval_clear(void)
xfree(SCRIPT_SV(i));
ga_clear(&ga_scripts);
- /* unreferenced lists and dicts */
- (void)garbage_collect();
+ // unreferenced lists and dicts
+ (void)garbage_collect(false);
- /* functions */
+ // functions
free_all_functions();
- hash_clear(&func_hashtab);
}
#endif
@@ -703,18 +730,17 @@ int current_func_returned(void)
*/
void set_internal_string_var(char_u *name, char_u *value)
{
- char_u *val = vim_strsave(value);
- typval_T *tvp = xcalloc(1, sizeof(typval_T));
+ const typval_T tv = {
+ .v_type = VAR_STRING,
+ .vval.v_string = value,
+ };
- tvp->v_type = VAR_STRING;
- tvp->vval.v_string = val;
- set_var(name, tvp, FALSE);
- free_tv(tvp);
+ set_var((const char *)name, STRLEN(name), (typval_T *)&tv, true);
}
static lval_T *redir_lval = NULL;
-static garray_T redir_ga; /* only valid when redir_lval is not NULL */
-static char_u *redir_endp = NULL;
+static garray_T redir_ga; // Only valid when redir_lval is not NULL.
+static char_u *redir_endp = NULL;
static char_u *redir_varname = NULL;
/*
@@ -745,11 +771,11 @@ var_redir_start (
/* The output is stored in growarray "redir_ga" until redirection ends. */
ga_init(&redir_ga, (int)sizeof(char), 500);
- /* Parse the variable name (can be a dict or list entry). */
- redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, 0,
- FNE_CHECK_START);
- if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp !=
- NUL) {
+ // Parse the variable name (can be a dict or list entry).
+ redir_endp = (char_u *)get_lval(redir_varname, NULL, redir_lval, false, false,
+ 0, FNE_CHECK_START);
+ if (redir_endp == NULL || redir_lval->ll_name == NULL
+ || *redir_endp != NUL) {
clear_lval(redir_lval);
if (redir_endp != NULL && *redir_endp != NUL)
/* Trailing characters are present after the variable name */
@@ -823,12 +849,13 @@ void var_redir_stop(void)
ga_append(&redir_ga, NUL); /* Append the trailing NUL. */
tv.v_type = VAR_STRING;
tv.vval.v_string = redir_ga.ga_data;
- /* Call get_lval() again, if it's inside a Dict or List it may
- * have changed. */
- redir_endp = get_lval(redir_varname, NULL, redir_lval,
- FALSE, FALSE, 0, FNE_CHECK_START);
- if (redir_endp != NULL && redir_lval->ll_name != NULL)
- set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)".");
+ // Call get_lval() again, if it's inside a Dict or List it may
+ // have changed.
+ redir_endp = (char_u *)get_lval(redir_varname, NULL, redir_lval,
+ false, false, 0, FNE_CHECK_START);
+ if (redir_endp != NULL && redir_lval->ll_name != NULL) {
+ set_var_lval(redir_lval, redir_endp, &tv, false, (char_u *)".");
+ }
clear_lval(redir_lval);
}
@@ -846,7 +873,7 @@ void var_redir_stop(void)
int eval_charconvert(const char *const enc_from, const char *const enc_to,
const char *const fname_from, const char *const fname_to)
{
- int err = false;
+ bool err = false;
set_vim_var_string(VV_CC_FROM, enc_from, -1);
set_vim_var_string(VV_CC_TO, enc_to, -1);
@@ -868,7 +895,7 @@ int eval_charconvert(const char *const enc_from, const char *const enc_to,
int eval_printexpr(const char *const fname, const char *const args)
{
- int err = false;
+ bool err = false;
set_vim_var_string(VV_FNAME_IN, fname, -1);
set_vim_var_string(VV_CMDARG, args, -1);
@@ -888,7 +915,7 @@ int eval_printexpr(const char *const fname, const char *const args)
void eval_diff(const char *const origfile, const char *const newfile,
const char *const outfile)
{
- int err = FALSE;
+ bool err = false;
set_vim_var_string(VV_FNAME_IN, origfile, -1);
set_vim_var_string(VV_FNAME_NEW, newfile, -1);
@@ -902,7 +929,7 @@ void eval_diff(const char *const origfile, const char *const newfile,
void eval_patch(const char *const origfile, const char *const difffile,
const char *const outfile)
{
- int err;
+ bool err = false;
set_vim_var_string(VV_FNAME_IN, origfile, -1);
set_vim_var_string(VV_FNAME_DIFF, difffile, -1);
@@ -921,56 +948,61 @@ void eval_patch(const char *const origfile, const char *const difffile,
int
eval_to_bool (
char_u *arg,
- int *error,
+ bool *error,
char_u **nextcmd,
int skip /* only parse, don't execute */
)
{
typval_T tv;
- int retval = FALSE;
+ bool retval = false;
- if (skip)
- ++emsg_skip;
- if (eval0(arg, &tv, nextcmd, !skip) == FAIL)
- *error = TRUE;
- else {
- *error = FALSE;
+ if (skip) {
+ emsg_skip++;
+ }
+ if (eval0(arg, &tv, nextcmd, !skip) == FAIL) {
+ *error = true;
+ } else {
+ *error = false;
if (!skip) {
- retval = (get_tv_number_chk(&tv, error) != 0);
- clear_tv(&tv);
+ retval = (tv_get_number_chk(&tv, error) != 0);
+ tv_clear(&tv);
}
}
- if (skip)
- --emsg_skip;
+ if (skip) {
+ emsg_skip--;
+ }
return retval;
}
-/*
- * Top level evaluation function, returning a string. If "skip" is TRUE,
- * only parsing to "nextcmd" is done, without reporting errors. Return
- * pointer to allocated memory, or NULL for failure or when "skip" is TRUE.
- */
-char_u *
-eval_to_string_skip (
- char_u *arg,
- char_u **nextcmd,
- int skip /* only parse, don't execute */
-)
+/// Top level evaluation function, returning a string
+///
+/// @param[in] arg String to evaluate.
+/// @param nextcmd Pointer to the start of the next Ex command.
+/// @param[in] skip If true, only do parsing to nextcmd without reporting
+/// errors or actually evaluating anything.
+///
+/// @return [allocated] string result of evaluation or NULL in case of error or
+/// when skipping.
+char *eval_to_string_skip(const char *arg, const char **nextcmd,
+ const bool skip)
+ FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT
{
typval_T tv;
- char_u *retval;
+ char *retval;
- if (skip)
- ++emsg_skip;
- if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip)
+ if (skip) {
+ emsg_skip++;
+ }
+ if (eval0((char_u *)arg, &tv, (char_u **)nextcmd, !skip) == FAIL || skip) {
retval = NULL;
- else {
- retval = vim_strsave(get_tv_string(&tv));
- clear_tv(&tv);
+ } else {
+ retval = xstrdup(tv_get_string(&tv));
+ tv_clear(&tv);
+ }
+ if (skip) {
+ emsg_skip--;
}
- if (skip)
- --emsg_skip;
return retval;
}
@@ -996,31 +1028,33 @@ int skip_expr(char_u **pp)
char_u *eval_to_string(char_u *arg, char_u **nextcmd, int convert)
{
typval_T tv;
- char_u *retval;
+ char *retval;
garray_T ga;
- char_u numbuf[NUMBUFLEN];
- if (eval0(arg, &tv, nextcmd, TRUE) == FAIL)
+ if (eval0(arg, &tv, nextcmd, true) == FAIL) {
retval = NULL;
- else {
+ } else {
if (convert && tv.v_type == VAR_LIST) {
ga_init(&ga, (int)sizeof(char), 80);
if (tv.vval.v_list != NULL) {
- list_join(&ga, tv.vval.v_list, "\n");
- if (tv.vval.v_list->lv_len > 0)
+ tv_list_join(&ga, tv.vval.v_list, "\n");
+ if (tv.vval.v_list->lv_len > 0) {
ga_append(&ga, NL);
+ }
}
ga_append(&ga, NUL);
- retval = (char_u *)ga.ga_data;
+ retval = (char *)ga.ga_data;
} else if (convert && tv.v_type == VAR_FLOAT) {
- vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv.vval.v_float);
- retval = vim_strsave(numbuf);
- } else
- retval = vim_strsave(get_tv_string(&tv));
- clear_tv(&tv);
+ char numbuf[NUMBUFLEN];
+ vim_snprintf(numbuf, NUMBUFLEN, "%g", tv.vval.v_float);
+ retval = xstrdup(numbuf);
+ } else {
+ retval = xstrdup(tv_get_string(&tv));
+ }
+ tv_clear(&tv);
}
- return retval;
+ return (char_u *)retval;
}
/*
@@ -1049,19 +1083,19 @@ char_u *eval_to_string_safe(char_u *arg, char_u **nextcmd, int use_sandbox)
* Evaluates "expr" silently.
* Returns -1 for an error.
*/
-int eval_to_number(char_u *expr)
+varnumber_T eval_to_number(char_u *expr)
{
typval_T rettv;
- int retval;
+ varnumber_T retval;
char_u *p = skipwhite(expr);
++emsg_off;
- if (eval1(&p, &rettv, TRUE) == FAIL)
+ if (eval1(&p, &rettv, true) == FAIL) {
retval = -1;
- else {
- retval = get_tv_number_chk(&rettv, NULL);
- clear_tv(&rettv);
+ } else {
+ retval = tv_get_number_chk(&rettv, NULL);
+ tv_clear(&rettv);
}
--emsg_off;
@@ -1118,11 +1152,12 @@ list_T *eval_spell_expr(char_u *badword, char_u *expr)
if (p_verbose == 0)
++emsg_off;
- if (eval1(&p, &rettv, TRUE) == OK) {
- if (rettv.v_type != VAR_LIST)
- clear_tv(&rettv);
- else
+ if (eval1(&p, &rettv, true) == OK) {
+ if (rettv.v_type != VAR_LIST) {
+ tv_clear(&rettv);
+ } else {
list = rettv.vval.v_list;
+ }
}
if (p_verbose == 0)
@@ -1138,54 +1173,39 @@ list_T *eval_spell_expr(char_u *badword, char_u *expr)
* Return -1 if anything isn't right.
* Used to get the good word and score from the eval_spell_expr() result.
*/
-int get_spellword(list_T *list, char_u **pp)
+int get_spellword(list_T *list, const char **pp)
{
listitem_T *li;
li = list->lv_first;
- if (li == NULL)
+ if (li == NULL) {
return -1;
- *pp = get_tv_string(&li->li_tv);
+ }
+ *pp = tv_get_string(&li->li_tv);
li = li->li_next;
- if (li == NULL)
+ 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(char_u *arg, char_u **nextcmd)
-{
- typval_T *tv = xmalloc(sizeof(typval_T));
-
- if (eval0(arg, tv, nextcmd, TRUE) == FAIL) {
- xfree(tv);
- return NULL;
}
-
- return tv;
+ return tv_get_number(&li->li_tv);
}
-// Call some vimL function and return the result in "*rettv".
+// Call some vim script function and return the result in "*rettv".
// Uses argv[argc] for the function arguments. Only Number and String
// arguments are currently supported.
//
// Return OK or FAIL.
int call_vim_function(
- char_u *func,
+ const char_u *func,
int argc,
- char_u **argv,
+ const char_u *const *const argv,
int safe, // use the sandbox
int str_arg_only, // all arguments are strings
typval_T *rettv
)
{
- long n;
+ varnumber_T n;
int len;
int doesrange;
void *save_funccalp = NULL;
@@ -1212,7 +1232,7 @@ int call_vim_function(
argvars[i].vval.v_number = n;
} else {
argvars[i].v_type = VAR_STRING;
- argvars[i].vval.v_string = argv[i];
+ argvars[i].vval.v_string = (char_u *)argv[i];
}
}
@@ -1221,8 +1241,8 @@ int call_vim_function(
++sandbox;
}
- rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */
- ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars,
+ rettv->v_type = VAR_UNKNOWN; // tv_clear() uses this.
+ ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, NULL,
curwin->w_cursor.lnum, curwin->w_cursor.lnum,
&doesrange, true, NULL, NULL);
if (safe) {
@@ -1232,74 +1252,72 @@ int call_vim_function(
xfree(argvars);
if (ret == FAIL) {
- clear_tv(rettv);
+ tv_clear(rettv);
}
return ret;
}
-/*
- * Call vimL function "func" and return the result as a number.
- * Returns -1 when calling the function fails.
- * Uses argv[argc] for the function arguments.
- */
-long
-call_func_retnr (
- char_u *func,
- int argc,
- char_u **argv,
- int safe /* use the sandbox */
-)
+/// Call Vim script function and return the result as a number
+///
+/// @param[in] func Function name.
+/// @param[in] argc Number of arguments.
+/// @param[in] argv Array with string arguments.
+/// @param[in] safe Use with sandbox.
+///
+/// @return -1 when calling function fails, result of function otherwise.
+varnumber_T call_func_retnr(char_u *func, int argc,
+ const char_u *const *const argv, int safe)
{
typval_T rettv;
- long retval;
+ varnumber_T retval;
/* All arguments are passed as strings, no conversion to number. */
if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
return -1;
- retval = get_tv_number_chk(&rettv, NULL);
- clear_tv(&rettv);
+ retval = tv_get_number_chk(&rettv, NULL);
+ tv_clear(&rettv);
return retval;
}
-/*
- * Call vimL function "func" and return the result as a string.
- * Returns NULL when calling the function fails.
- * Uses argv[argc] for the function arguments.
- */
-void *
-call_func_retstr (
- char_u *func,
- int argc,
- char_u **argv,
- int safe /* use the sandbox */
-)
+/// Call Vim script function and return the result as a string
+///
+/// @param[in] func Function name.
+/// @param[in] argc Number of arguments.
+/// @param[in] argv Array with string arguments.
+/// @param[in] safe Use the sandbox.
+///
+/// @return [allocated] NULL when calling function fails, allocated string
+/// otherwise.
+char *call_func_retstr(const char *const func, const int argc,
+ const char_u *const *const argv,
+ const bool safe)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
{
typval_T rettv;
- char_u *retval;
-
- /* All arguments are passed as strings, no conversion to number. */
- if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
+ // All arguments are passed as strings, no conversion to number.
+ if (call_vim_function((const char_u *)func, argc, argv, safe, true, &rettv)
+ == FAIL) {
return NULL;
+ }
- retval = vim_strsave(get_tv_string(&rettv));
- clear_tv(&rettv);
+ char *const retval = xstrdup(tv_get_string(&rettv));
+ tv_clear(&rettv);
return retval;
}
-/*
- * Call vimL function "func" and return the result as a List.
- * Uses argv[argc] for the function arguments.
- * Returns NULL when there is something wrong.
- */
-void *
-call_func_retlist (
- char_u *func,
- int argc,
- char_u **argv,
- int safe /* use the sandbox */
-)
+/// Call Vim script function and return the result as a List
+///
+/// @param[in] func Function name.
+/// @param[in] argc Number of arguments.
+/// @param[in] argv Array with string arguments.
+/// @param[in] safe Use the sandbox.
+///
+/// @return [allocated] NULL when calling function fails or return tv is not a
+/// List, allocated List otherwise.
+void *call_func_retlist(char_u *func, int argc, const char_u *const *const argv,
+ int safe)
{
typval_T rettv;
@@ -1308,7 +1326,7 @@ call_func_retlist (
return NULL;
if (rettv.v_type != VAR_LIST) {
- clear_tv(&rettv);
+ tv_clear(&rettv);
return NULL;
}
@@ -1380,7 +1398,7 @@ void prof_child_exit(proftime_T *tm /* where waittime was stored */
int eval_foldexpr(char_u *arg, int *cp)
{
typval_T tv;
- int retval;
+ varnumber_T retval;
char_u *s;
int use_sandbox = was_set_insecurely((char_u *)"foldexpr",
OPT_LOCAL);
@@ -1406,14 +1424,14 @@ int eval_foldexpr(char_u *arg, int *cp)
*cp = *s++;
retval = atol((char *)s);
}
- clear_tv(&tv);
+ tv_clear(&tv);
}
--emsg_off;
if (use_sandbox)
--sandbox;
--textlock;
- return retval;
+ return (int)retval;
}
/*
@@ -1437,22 +1455,24 @@ void ex_let(exarg_T *eap)
char_u *argend;
int first = TRUE;
- argend = skip_var_list(arg, &var_count, &semicolon);
- if (argend == NULL)
+ argend = (char_u *)skip_var_list(arg, &var_count, &semicolon);
+ if (argend == NULL) {
return;
- if (argend > arg && argend[-1] == '.') /* for var.='str' */
- --argend;
+ }
+ if (argend > arg && argend[-1] == '.') { // For var.='str'.
+ argend--;
+ }
expr = skipwhite(argend);
if (*expr != '=' && !(vim_strchr((char_u *)"+-.", *expr) != NULL
&& expr[1] == '=')) {
// ":let" without "=": list variables
- if (*arg == '[')
+ if (*arg == '[') {
EMSG(_(e_invarg));
- else if (!ends_excmd(*arg))
- /* ":let var1 var2" */
- arg = list_arg_vars(eap, arg, &first);
- else if (!eap->skip) {
- /* ":let" */
+ } else if (!ends_excmd(*arg)) {
+ // ":let var1 var2"
+ arg = (char_u *)list_arg_vars(eap, (const char *)arg, &first);
+ } else if (!eap->skip) {
+ // ":let"
list_glob_vars(&first);
list_buf_vars(&first);
list_win_vars(&first);
@@ -1478,13 +1498,13 @@ void ex_let(exarg_T *eap)
++emsg_skip;
i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip);
if (eap->skip) {
- if (i != FAIL)
- clear_tv(&rettv);
- --emsg_skip;
+ if (i != FAIL) {
+ tv_clear(&rettv);
+ }
+ emsg_skip--;
} else if (i != FAIL) {
- (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count,
- op);
- clear_tv(&rettv);
+ (void)ex_let_vars(eap->arg, &rettv, false, semicolon, var_count, op);
+ tv_clear(&rettv);
}
}
}
@@ -1507,7 +1527,7 @@ ex_let_vars (
char_u *nextchars
)
{
- char_u *arg = arg_start;
+ char_u *arg = arg_start;
list_T *l;
int i;
listitem_T *item;
@@ -1530,7 +1550,7 @@ ex_let_vars (
return FAIL;
}
- i = list_len(l);
+ i = tv_list_len(l);
if (semicolon == 0 && var_count < i) {
EMSG(_("E687: Less targets than List items"));
return FAIL;
@@ -1552,9 +1572,9 @@ ex_let_vars (
if (*arg == ';') {
/* Put the rest of the list (may be empty) in the var after ';'.
* Create a new list for this. */
- l = list_alloc();
+ l = tv_list_alloc();
while (item != NULL) {
- list_append_tv(l, &item->li_tv);
+ tv_list_append_tv(l, &item->li_tv);
item = item->li_next;
}
@@ -1563,11 +1583,12 @@ ex_let_vars (
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)
+ arg = ex_let_one(skipwhite(arg + 1), &ltv, false,
+ (char_u *)"]", nextchars);
+ tv_clear(&ltv);
+ if (arg == NULL) {
return FAIL;
+ }
break;
} else if (*arg != ',' && *arg != ']') {
EMSG2(_(e_intern2), "ex_let_vars()");
@@ -1585,9 +1606,11 @@ ex_let_vars (
* for "[var, var; var]" set "semicolon".
* Return NULL for an error.
*/
-static char_u *skip_var_list(char_u *arg, int *var_count, int *semicolon)
+static const char_u *skip_var_list(const char_u *arg, int *var_count,
+ int *semicolon)
{
- char_u *p, *s;
+ const char_u *p;
+ const char_u *s;
if (*arg == '[') {
/* "[var, var]": find the matching ']'. */
@@ -1624,7 +1647,7 @@ static char_u *skip_var_list(char_u *arg, int *var_count, int *semicolon)
* Skip one (assignable) variable name, including @r, $VAR, &option, d.key,
* l[idx].
*/
-static char_u *skip_var_one(char_u *arg)
+static const char_u *skip_var_one(const char_u *arg)
{
if (*arg == '@' && arg[1] != NUL)
return arg + 2;
@@ -1636,7 +1659,8 @@ static char_u *skip_var_one(char_u *arg)
* List variables for hashtab "ht" with prefix "prefix".
* If "empty" is TRUE also list NULL strings as empty strings.
*/
-static void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *first)
+static void list_hashtable_vars(hashtab_T *ht, const char *prefix, int empty,
+ int *first)
{
hashitem_T *hi;
dictitem_T *di;
@@ -1645,11 +1669,12 @@ static void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *f
todo = (int)ht->ht_used;
for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) {
if (!HASHITEM_EMPTY(hi)) {
- --todo;
- di = HI2DI(hi);
+ todo--;
+ di = TV_DICT_HI2DI(hi);
if (empty || di->di_tv.v_type != VAR_STRING
- || di->di_tv.vval.v_string != NULL)
+ || di->di_tv.vval.v_string != NULL) {
list_one_var(di, prefix, first);
+ }
}
}
}
@@ -1659,7 +1684,7 @@ static void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *f
*/
static void list_glob_vars(int *first)
{
- list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first);
+ list_hashtable_vars(&globvarht, "", true, first);
}
/*
@@ -1667,14 +1692,7 @@ static void list_glob_vars(int *first)
*/
static void list_buf_vars(int *first)
{
- char_u numbuf[NUMBUFLEN];
-
- list_hashtable_vars(&curbuf->b_vars->dv_hashtab, (char_u *)"b:",
- TRUE, first);
-
- sprintf((char *)numbuf, "%" PRId64, (int64_t)curbuf->b_changedtick);
- list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER,
- numbuf, first);
+ list_hashtable_vars(&curbuf->b_vars->dv_hashtab, "b:", true, first);
}
/*
@@ -1682,8 +1700,7 @@ static void list_buf_vars(int *first)
*/
static void list_win_vars(int *first)
{
- list_hashtable_vars(&curwin->w_vars->dv_hashtab,
- (char_u *)"w:", TRUE, first);
+ list_hashtable_vars(&curwin->w_vars->dv_hashtab, "w:", true, first);
}
/*
@@ -1691,8 +1708,7 @@ static void list_win_vars(int *first)
*/
static void list_tab_vars(int *first)
{
- list_hashtable_vars(&curtab->tp_vars->dv_hashtab,
- (char_u *)"t:", TRUE, first);
+ list_hashtable_vars(&curtab->tp_vars->dv_hashtab, "t:", true, first);
}
/*
@@ -1700,7 +1716,7 @@ static void list_tab_vars(int *first)
*/
static void list_vim_vars(int *first)
{
- list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first);
+ list_hashtable_vars(&vimvarht, "v:", false, first);
}
/*
@@ -1708,9 +1724,9 @@ static void list_vim_vars(int *first)
*/
static void list_script_vars(int *first)
{
- if (current_SID > 0 && current_SID <= ga_scripts.ga_len)
- list_hashtable_vars(&SCRIPT_VARS(current_SID),
- (char_u *)"s:", FALSE, first);
+ if (current_SID > 0 && current_SID <= ga_scripts.ga_len) {
+ list_hashtable_vars(&SCRIPT_VARS(current_SID), "s:", false, first);
+ }
}
/*
@@ -1718,36 +1734,37 @@ static void list_script_vars(int *first)
*/
static void list_func_vars(int *first)
{
- if (current_funccal != NULL)
- list_hashtable_vars(&current_funccal->l_vars.dv_hashtab,
- (char_u *)"l:", FALSE, first);
+ if (current_funccal != NULL) {
+ list_hashtable_vars(&current_funccal->l_vars.dv_hashtab, "l:", false,
+ first);
+ }
}
/*
* List variables in "arg".
*/
-static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first)
+static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first)
{
int error = FALSE;
int len;
- char_u *name;
- char_u *name_start;
- char_u *arg_subsc;
- char_u *tofree;
+ const char *name;
+ const char *name_start;
typval_T tv;
while (!ends_excmd(*arg) && !got_int) {
if (error || eap->skip) {
- arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
+ arg = (const char *)find_name_end((char_u *)arg, NULL, NULL,
+ FNE_INCL_BR | FNE_CHECK_START);
if (!ascii_iswhite(*arg) && !ends_excmd(*arg)) {
emsg_severe = TRUE;
EMSG(_(e_trailing));
break;
}
} else {
- /* get_name_len() takes care of expanding curly braces */
+ // get_name_len() takes care of expanding curly braces
name_start = name = arg;
- len = get_name_len(&arg, &tofree, TRUE, TRUE);
+ char *tofree;
+ len = get_name_len(&arg, &tofree, true, true);
if (len <= 0) {
/* This is mainly to keep test 49 working: when expanding
* curly braces fails overrule the exception error message. */
@@ -1761,14 +1778,15 @@ static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first)
if (tofree != NULL) {
name = tofree;
}
- if (get_var_tv(name, len, &tv, NULL, true, false) == FAIL) {
+ if (get_var_tv((const char *)name, len, &tv, NULL, true, false)
+ == FAIL) {
error = true;
} else {
// handle d.key, l[idx], f(expr)
- arg_subsc = arg;
- if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL)
- error = TRUE;
- else {
+ const char *const arg_subsc = arg;
+ if (handle_subscript(&arg, &tv, true, true) == FAIL) {
+ error = true;
+ } else {
if (arg == arg_subsc && len == 2 && name[1] == ':') {
switch (*name) {
case 'g': list_glob_vars(first); break;
@@ -1782,20 +1800,18 @@ static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first)
EMSG2(_("E738: Can't list variables for %s"), name);
}
} else {
- int c;
-
- char_u *s = (char_u *) encode_tv2echo(&tv, NULL);
- c = *arg;
- *arg = NUL;
- list_one_var_a((char_u *)"",
- arg == arg_subsc ? name : name_start,
- tv.v_type,
- s == NULL ? (char_u *)"" : s,
- first);
- *arg = c;
+ char *const s = encode_tv2echo(&tv, NULL);
+ const char *const used_name = (arg == arg_subsc
+ ? name
+ : name_start);
+ const ptrdiff_t name_size = (used_name == tofree
+ ? (ptrdiff_t)strlen(used_name)
+ : (arg - used_name));
+ list_one_var_a("", used_name, name_size,
+ tv.v_type, s == NULL ? "" : s, first);
xfree(s);
}
- clear_tv(&tv);
+ tv_clear(&tv);
}
}
}
@@ -1803,152 +1819,153 @@ static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first)
xfree(tofree);
}
- arg = skipwhite(arg);
+ arg = (const char *)skipwhite((const char_u *)arg);
}
return arg;
}
-/*
- * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value.
- * Returns a pointer to the char just after the var name.
- * Returns NULL if there is an error.
- */
-static char_u *
-ex_let_one (
- char_u *arg, /* points to variable name */
- typval_T *tv, /* value to assign to variable */
- int copy, /* copy value from "tv" */
- char_u *endchars, /* valid chars after variable name or NULL */
- char_u *op /* "+", "-", "." or NULL*/
-)
-{
- int c1;
- char_u *name;
- char_u *p;
- char_u *arg_end = NULL;
+// TODO(ZyX-I): move to eval/ex_cmds
+
+/// Set one item of `:let var = expr` or `:let [v1, v2] = list` to its value
+///
+/// @param[in] arg Start of the variable name.
+/// @param[in] tv Value to assign to the variable.
+/// @param[in] copy If true, copy value from `tv`.
+/// @param[in] endchars Valid characters after variable name or NULL.
+/// @param[in] op Operation performed: *op is `+`, `-`, `.` for `+=`, etc.
+/// NULL for `=`.
+///
+/// @return a pointer to the char just after the var name or NULL in case of
+/// error.
+static char_u *ex_let_one(char_u *arg, typval_T *const tv,
+ const bool copy, const char_u *const endchars,
+ const char_u *const op)
+ FUNC_ATTR_NONNULL_ARG(1, 2) FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ char_u *arg_end = NULL;
int len;
int opt_flags;
- char_u *tofree = NULL;
+ char_u *tofree = NULL;
/*
* ":let $VAR = expr": Set environment variable.
*/
if (*arg == '$') {
- /* Find the end of the name. */
- ++arg;
- name = arg;
- len = get_env_len(&arg);
- if (len == 0)
+ // Find the end of the name.
+ arg++;
+ char *name = (char *)arg;
+ len = get_env_len((const char_u **)&arg);
+ if (len == 0) {
EMSG2(_(e_invarg2), name - 1);
- else {
- if (op != NULL && (*op == '+' || *op == '-'))
+ } else {
+ if (op != NULL && (*op == '+' || *op == '-')) {
EMSG2(_(e_letwrong), op);
- else if (endchars != NULL
- && vim_strchr(endchars, *skipwhite(arg)) == NULL)
+ } else if (endchars != NULL
+ && vim_strchr(endchars, *skipwhite(arg)) == NULL) {
EMSG(_(e_letunexp));
- else if (!check_secure()) {
- c1 = name[len];
+ } else if (!check_secure()) {
+ const char c1 = name[len];
name[len] = NUL;
- p = get_tv_string_chk(tv);
+ const char *p = tv_get_string_chk(tv);
if (p != NULL && op != NULL && *op == '.') {
- char *s = vim_getenv((char *)name);
+ char *s = vim_getenv(name);
if (s != NULL) {
- p = tofree = concat_str((char_u *)s, p);
+ tofree = concat_str((const char_u *)s, (const char_u *)p);
+ p = (const char *)tofree;
xfree(s);
}
}
if (p != NULL) {
- vim_setenv((char *)name, (char *)p);
- if (STRICMP(name, "HOME") == 0)
+ vim_setenv(name, p);
+ if (STRICMP(name, "HOME") == 0) {
init_homedir();
- else if (didset_vim && STRICMP(name, "VIM") == 0)
- didset_vim = FALSE;
- else if (didset_vimruntime
- && STRICMP(name, "VIMRUNTIME") == 0)
- didset_vimruntime = FALSE;
+ } else if (didset_vim && STRICMP(name, "VIM") == 0) {
+ didset_vim = false;
+ } else if (didset_vimruntime
+ && STRICMP(name, "VIMRUNTIME") == 0) {
+ didset_vimruntime = false;
+ }
arg_end = arg;
}
name[len] = c1;
xfree(tofree);
}
}
- }
- /*
- * ":let &option = expr": Set option value.
- * ":let &l:option = expr": Set local option value.
- * ":let &g:option = expr": Set global option value.
- */
- else if (*arg == '&') {
- /* Find the end of the name. */
- p = find_option_end(&arg, &opt_flags);
- if (p == NULL || (endchars != NULL
- && vim_strchr(endchars, *skipwhite(p)) == NULL))
+ // ":let &option = expr": Set option value.
+ // ":let &l:option = expr": Set local option value.
+ // ":let &g:option = expr": Set global option value.
+ } else if (*arg == '&') {
+ // Find the end of the name.
+ char *const p = (char *)find_option_end((const char **)&arg, &opt_flags);
+ if (p == NULL
+ || (endchars != NULL
+ && vim_strchr(endchars, *skipwhite((const char_u *)p)) == NULL)) {
EMSG(_(e_letunexp));
- else {
- long n;
+ } else {
int opt_type;
long numval;
- char_u *stringval = NULL;
- char_u *s;
+ char *stringval = NULL;
- c1 = *p;
+ const char c1 = *p;
*p = NUL;
- n = get_tv_number(tv);
- s = get_tv_string_chk(tv); /* != NULL if number or string */
+ varnumber_T n = tv_get_number(tv);
+ const char *s = tv_get_string_chk(tv); // != NULL if number or string.
if (s != NULL && op != NULL && *op != '=') {
- opt_type = get_option_value(arg, &numval,
- &stringval, opt_flags);
+ opt_type = get_option_value(arg, &numval, (char_u **)&stringval,
+ opt_flags);
if ((opt_type == 1 && *op == '.')
- || (opt_type == 0 && *op != '.'))
+ || (opt_type == 0 && *op != '.')) {
EMSG2(_(e_letwrong), op);
- else {
- if (opt_type == 1) { /* number */
- if (*op == '+')
+ } else {
+ if (opt_type == 1) { // number
+ if (*op == '+') {
n = numval + n;
- else
+ } else {
n = numval - n;
- } else if (opt_type == 0 && stringval != NULL) { /* string */
- s = concat_str(stringval, s);
- xfree(stringval);
- stringval = s;
+ }
+ } else if (opt_type == 0 && stringval != NULL) { // string
+ char *const oldstringval = stringval;
+ stringval = (char *)concat_str((const char_u *)stringval,
+ (const char_u *)s);
+ xfree(oldstringval);
+ s = stringval;
}
}
}
if (s != NULL) {
- set_option_value(arg, n, s, opt_flags);
- arg_end = p;
+ set_option_value((const char *)arg, n, s, opt_flags);
+ arg_end = (char_u *)p;
}
*p = c1;
xfree(stringval);
}
- }
- /*
- * ":let @r = expr": Set register contents.
- */
- else if (*arg == '@') {
- ++arg;
- if (op != NULL && (*op == '+' || *op == '-'))
- EMSG2(_(e_letwrong), op);
- else if (endchars != NULL
- && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL)
- EMSG(_(e_letunexp));
- else {
- char_u *ptofree = NULL;
+ // ":let @r = expr": Set register contents.
+ } else if (*arg == '@') {
+ arg++;
+ if (op != NULL && (*op == '+' || *op == '-')) {
+ emsgf(_(e_letwrong), op);
+ } else if (endchars != NULL
+ && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) {
+ emsgf(_(e_letunexp));
+ } else {
char_u *s;
- p = get_tv_string_chk(tv);
+ char_u *ptofree = NULL;
+ const char *p = tv_get_string_chk(tv);
if (p != NULL && op != NULL && *op == '.') {
s = get_reg_contents(*arg == '@' ? '"' : *arg, kGRegExprSrc);
if (s != NULL) {
- p = ptofree = concat_str(s, p);
+ ptofree = concat_str(s, (const char_u *)p);
+ p = (const char *)ptofree;
xfree(s);
}
}
if (p != NULL) {
- write_reg_contents(*arg == '@' ? '"' : *arg, p, STRLEN(p), false);
+ write_reg_contents(*arg == '@' ? '"' : *arg,
+ (const char_u *)p, STRLEN(p), false);
arg_end = arg + 1;
}
xfree(ptofree);
@@ -1961,11 +1978,11 @@ ex_let_one (
else if (eval_isnamec1(*arg) || *arg == '{') {
lval_T lv;
- p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START);
+ char_u *const p = get_lval(arg, tv, &lv, false, false, 0, FNE_CHECK_START);
if (p != NULL && lv.ll_name != NULL) {
- if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL)
+ if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) {
EMSG(_(e_letunexp));
- else {
+ } else {
set_var_lval(&lv, p, tv, copy, op);
arg_end = p;
}
@@ -1977,57 +1994,41 @@ ex_let_one (
return arg_end;
}
-/*
- * If "arg" is equal to "b:changedtick" give an error and return TRUE.
- */
-static int check_changedtick(char_u *arg)
-{
- if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) {
- EMSG2(_(e_readonlyvar), arg);
- return TRUE;
- }
- return FALSE;
-}
+// TODO(ZyX-I): move to eval/executor
-/*
- * Get an lval: variable, Dict item or List item that can be assigned a value
- * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]",
- * "name.key", "name.key[expr]" etc.
- * Indexing only works if "name" is an existing List or Dictionary.
- * "name" points to the start of the name.
- * If "rettv" is not NULL it points to the value to be assigned.
- * "unlet" is TRUE for ":unlet": slightly different behavior when something is
- * wrong; must end in space or cmd separator.
- *
- * flags:
- * GLV_QUIET: do not give error messages
- * GLV_NO_AUTOLOAD: do not use script autoloading
- *
- * Returns a pointer to just after the name, including indexes.
- * When an evaluation error occurs "lp->ll_name" is NULL;
- * Returns NULL for a parsing error. Still need to free items in "lp"!
- */
-static char_u *
-get_lval (
- char_u *name,
- typval_T *rettv,
- lval_T *lp,
- int unlet,
- int skip,
- int flags, /* GLV_ values */
- int fne_flags /* flags for find_name_end() */
-)
+/// Get an lvalue
+///
+/// Lvalue may be
+/// - variable: "name", "na{me}"
+/// - dictionary item: "dict.key", "dict['key']"
+/// - list item: "list[expr]"
+/// - list slice: "list[expr:expr]"
+///
+/// Indexing only works if trying to use it with an existing List or Dictionary.
+///
+/// @param[in] name Name to parse.
+/// @param rettv Pointer to the value to be assigned or NULL.
+/// @param[out] lp Lvalue definition. When evaluation errors occur `->ll_name`
+/// is NULL.
+/// @param[in] unlet True if using `:unlet`. This results in slightly
+/// different behaviour when something is wrong; must end in
+/// space or cmd separator.
+/// @param[in] skip True when skipping.
+/// @param[in] flags @see GetLvalFlags.
+/// @param[in] fne_flags Flags for find_name_end().
+///
+/// @return A pointer to just after the name, including indexes. Returns NULL
+/// for a parsing error, but it is still needed to free items in lp.
+static char_u *get_lval(char_u *const name, typval_T *const rettv,
+ lval_T *const lp, const bool unlet, const bool skip,
+ const int flags, const int fne_flags)
+ FUNC_ATTR_NONNULL_ARG(1, 3)
{
- char_u *p;
- char_u *expr_start, *expr_end;
- int cc;
dictitem_T *v;
typval_T var1;
typval_T var2;
int empty1 = FALSE;
listitem_T *ni;
- char_u *key = NULL;
- int len;
hashtab_T *ht;
int quiet = flags & GLV_QUIET;
@@ -2035,13 +2036,19 @@ get_lval (
memset(lp, 0, sizeof(lval_T));
if (skip) {
- /* When skipping just find the end of the name. */
- lp->ll_name = name;
- return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags);
+ // When skipping just find the end of the name.
+ lp->ll_name = (const char *)name;
+ return (char_u *)find_name_end((const char_u *)name, NULL, NULL,
+ FNE_INCL_BR | fne_flags);
}
- /* Find the end of the name. */
- p = find_name_end(name, &expr_start, &expr_end, fne_flags);
+ // Find the end of the name.
+ char_u *expr_start;
+ char_u *expr_end;
+ char_u *p = (char_u *)find_name_end(name,
+ (const char_u **)&expr_start,
+ (const char_u **)&expr_end,
+ fne_flags);
if (expr_start != NULL) {
/* Don't expand the name when we already know there is an error. */
if (unlet && !ascii_iswhite(*p) && !ends_excmd(*p)
@@ -2050,7 +2057,9 @@ get_lval (
return NULL;
}
- lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p);
+ lp->ll_exp_name = (char *)make_expanded_name(name, expr_start, expr_end,
+ (char_u *)p);
+ lp->ll_name = lp->ll_exp_name;
if (lp->ll_exp_name == NULL) {
/* Report an invalid expression in braces, unless the
* expression evaluation has been cancelled due to an
@@ -2060,23 +2069,28 @@ get_lval (
EMSG2(_(e_invarg2), name);
return NULL;
}
+ lp->ll_name_len = 0;
+ } else {
+ lp->ll_name_len = strlen(lp->ll_name);
}
- lp->ll_name = lp->ll_exp_name;
- } else
- lp->ll_name = name;
+ } else {
+ lp->ll_name = (const char *)name;
+ lp->ll_name_len = (size_t)((const char *)p - lp->ll_name);
+ }
- /* Without [idx] or .key we are done. */
- if ((*p != '[' && *p != '.') || lp->ll_name == NULL)
+ // Without [idx] or .key we are done.
+ if ((*p != '[' && *p != '.') || lp->ll_name == NULL) {
return p;
+ }
- cc = *p;
- *p = NUL;
- v = find_var(lp->ll_name, &ht, flags & GLV_NO_AUTOLOAD);
- if (v == NULL && !quiet)
- EMSG2(_(e_undefvar), lp->ll_name);
- *p = cc;
- if (v == NULL)
+ v = find_var(lp->ll_name, lp->ll_name_len, &ht, flags & GLV_NO_AUTOLOAD);
+ if (v == NULL && !quiet) {
+ emsgf(_("E121: Undefined variable: %.*s"),
+ (int)lp->ll_name_len, lp->ll_name);
+ }
+ if (v == NULL) {
return NULL;
+ }
/*
* Loop until no more [idx] or .key is following.
@@ -2096,29 +2110,32 @@ get_lval (
return NULL;
}
- len = -1;
+ int len = -1;
+ char_u *key = NULL;
if (*p == '.') {
key = p + 1;
- for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len)
- ;
+ for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; len++) {
+ }
if (len == 0) {
- if (!quiet)
- EMSG(_(e_emptykey));
+ if (!quiet) {
+ EMSG(_("E713: Cannot use empty key after ."));
+ }
return NULL;
}
p = key + len;
} else {
/* Get the index [expr] or the first index [expr: ]. */
p = skipwhite(p + 1);
- if (*p == ':')
- empty1 = TRUE;
- else {
- empty1 = FALSE;
- if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */
+ if (*p == ':') {
+ empty1 = true;
+ } else {
+ empty1 = false;
+ if (eval1(&p, &var1, true) == FAIL) { // Recursive!
return NULL;
- if (get_tv_string_chk(&var1) == NULL) {
- /* not a number or string */
- clear_tv(&var1);
+ }
+ if (!tv_check_str(&var1)) {
+ // Not a number or string.
+ tv_clear(&var1);
return NULL;
}
}
@@ -2126,35 +2143,41 @@ get_lval (
/* Optionally get the second index [ :expr]. */
if (*p == ':') {
if (lp->ll_tv->v_type == VAR_DICT) {
- if (!quiet)
+ if (!quiet) {
EMSG(_(e_dictrange));
- if (!empty1)
- clear_tv(&var1);
+ }
+ if (!empty1) {
+ tv_clear(&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);
+ if (!quiet) {
+ emsgf(_("E709: [:] requires a List value"));
+ }
+ if (!empty1) {
+ tv_clear(&var1);
+ }
return NULL;
}
p = skipwhite(p + 1);
- if (*p == ']')
- lp->ll_empty2 = TRUE;
- else {
- lp->ll_empty2 = FALSE;
- if (eval1(&p, &var2, TRUE) == FAIL) { /* recursive! */
- if (!empty1)
- clear_tv(&var1);
+ if (*p == ']') {
+ lp->ll_empty2 = true;
+ } else {
+ lp->ll_empty2 = false;
+ if (eval1(&p, &var2, true) == FAIL) { // Recursive!
+ if (!empty1) {
+ tv_clear(&var1);
+ }
return NULL;
}
- if (get_tv_string_chk(&var2) == NULL) {
- /* not a number or string */
- if (!empty1)
- clear_tv(&var1);
- clear_tv(&var2);
+ if (!tv_check_str(&var2)) {
+ // Not a number or string.
+ if (!empty1) {
+ tv_clear(&var1);
+ }
+ tv_clear(&var2);
return NULL;
}
}
@@ -2163,12 +2186,15 @@ get_lval (
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);
+ if (!quiet) {
+ emsgf(_(e_missbrac));
+ }
+ if (!empty1) {
+ tv_clear(&var1);
+ }
+ if (lp->ll_range && !lp->ll_empty2) {
+ tv_clear(&var2);
+ }
return NULL;
}
@@ -2179,15 +2205,15 @@ get_lval (
if (lp->ll_tv->v_type == VAR_DICT) {
if (len == -1) {
// "[key]": get key from "var1"
- key = get_tv_string_chk(&var1); // is number or string
+ key = (char_u *)tv_get_string(&var1); // is number or string
if (key == NULL) {
- clear_tv(&var1);
+ tv_clear(&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);
+ lp->ll_di = tv_dict_find(lp->ll_dict, (const char *)key, len);
/* When assigning to a scope dictionary check that a function and
* variable name is valid (only variable name unless it is l: or
@@ -2199,16 +2225,19 @@ get_lval (
if (len != -1) {
prevval = key[len];
key[len] = NUL;
- } else
- prevval = 0; /* avoid compiler warning */
- wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE
- && rettv->v_type == VAR_FUNC
- && var_check_func_name(key, lp->ll_di == NULL))
- || !valid_varname(key);
- if (len != -1)
+ } else {
+ prevval = 0; // Avoid compiler warning.
+ }
+ wrong = ((lp->ll_dict->dv_scope == VAR_DEF_SCOPE
+ && tv_is_func(*rettv)
+ && !var_check_func_name((const char *)key, lp->ll_di == NULL))
+ || !valid_varname((const char *)key));
+ if (len != -1) {
key[len] = prevval;
- if (wrong)
+ }
+ if (wrong) {
return NULL;
+ }
}
if (lp->ll_di == NULL) {
@@ -2220,51 +2249,61 @@ get_lval (
/* Key does not exist in dict: may need to add it. */
if (*p == '[' || *p == '.' || unlet) {
- if (!quiet)
- EMSG2(_(e_dictkey), key);
- if (len == -1)
- clear_tv(&var1);
+ if (!quiet) {
+ emsgf(_(e_dictkey), key);
+ }
+ if (len == -1) {
+ tv_clear(&var1);
+ }
return NULL;
}
- if (len == -1)
+ if (len == -1) {
lp->ll_newkey = vim_strsave(key);
- else
+ } else {
lp->ll_newkey = vim_strnsave(key, len);
- if (len == -1)
- clear_tv(&var1);
+ }
+ if (len == -1) {
+ tv_clear(&var1);
+ }
break;
- } else if (var_check_ro(lp->ll_di->di_flags, name, false)) {
- // existing variable, need to check if it can be changed
+ // existing variable, need to check if it can be changed
+ } else if (!(flags & GLV_READ_ONLY) && var_check_ro(lp->ll_di->di_flags,
+ (const char *)name,
+ (size_t)(p - name))) {
+ if (len == -1) {
+ tv_clear(&var1);
+ }
return NULL;
}
- if (len == -1)
- clear_tv(&var1);
+ if (len == -1) {
+ tv_clear(&var1);
+ }
lp->ll_tv = &lp->ll_di->di_tv;
} else {
- /*
- * Get the number and item for the only or first index of the List.
- */
- if (empty1)
+ // Get the number and item for the only or first index of the List.
+ if (empty1) {
lp->ll_n1 = 0;
- else {
- lp->ll_n1 = get_tv_number(&var1); /* is number or string */
- clear_tv(&var1);
+ } else {
+ lp->ll_n1 = (long)tv_get_number(&var1); // Is number or string.
+ tv_clear(&var1);
}
lp->ll_dict = NULL;
lp->ll_list = lp->ll_tv->vval.v_list;
- lp->ll_li = list_find(lp->ll_list, lp->ll_n1);
+ lp->ll_li = tv_list_find(lp->ll_list, lp->ll_n1);
if (lp->ll_li == NULL) {
if (lp->ll_n1 < 0) {
lp->ll_n1 = 0;
- lp->ll_li = list_find(lp->ll_list, lp->ll_n1);
+ lp->ll_li = tv_list_find(lp->ll_list, lp->ll_n1);
}
}
if (lp->ll_li == NULL) {
- if (lp->ll_range && !lp->ll_empty2)
- clear_tv(&var2);
- if (!quiet)
+ if (lp->ll_range && !lp->ll_empty2) {
+ tv_clear(&var2);
+ }
+ if (!quiet) {
EMSGN(_(e_listidx), lp->ll_n1);
+ }
return NULL;
}
@@ -2275,24 +2314,26 @@ get_lval (
* Otherwise "lp->ll_n2" is set to the second index.
*/
if (lp->ll_range && !lp->ll_empty2) {
- lp->ll_n2 = get_tv_number(&var2); /* is number or string */
- clear_tv(&var2);
+ lp->ll_n2 = (long)tv_get_number(&var2); // Is number or string.
+ tv_clear(&var2);
if (lp->ll_n2 < 0) {
- ni = list_find(lp->ll_list, lp->ll_n2);
+ ni = tv_list_find(lp->ll_list, lp->ll_n2);
if (ni == NULL) {
if (!quiet)
EMSGN(_(e_listidx), lp->ll_n2);
return NULL;
}
- lp->ll_n2 = list_idx_of_item(lp->ll_list, ni);
+ lp->ll_n2 = tv_list_idx_of_item(lp->ll_list, ni);
}
- /* Check that lp->ll_n2 isn't before lp->ll_n1. */
- if (lp->ll_n1 < 0)
- lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li);
+ // Check that lp->ll_n2 isn't before lp->ll_n1.
+ if (lp->ll_n1 < 0) {
+ lp->ll_n1 = tv_list_idx_of_item(lp->ll_list, lp->ll_li);
+ }
if (lp->ll_n2 < lp->ll_n1) {
- if (!quiet)
+ if (!quiet) {
EMSGN(_(e_listidx), lp->ll_n2);
+ }
return NULL;
}
}
@@ -2304,6 +2345,8 @@ get_lval (
return p;
}
+// TODO(ZyX-I): move to eval/executor
+
/*
* Clear lval "lp" that was filled by get_lval().
*/
@@ -2313,44 +2356,48 @@ static void clear_lval(lval_T *lp)
xfree(lp->ll_newkey);
}
+// TODO(ZyX-I): move to eval/executor
+
/*
* Set a variable that was parsed by get_lval() to "rettv".
* "endp" points to just after the parsed name.
* "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=".
*/
-static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)
+static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv,
+ int copy, const char_u *op)
{
int cc;
listitem_T *ri;
dictitem_T *di;
if (lp->ll_tv == NULL) {
- if (!check_changedtick(lp->ll_name)) {
- cc = *endp;
- *endp = NUL;
- if (op != NULL && *op != '=') {
- typval_T tv;
-
- // handle +=, -= and .=
- di = NULL;
- if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
- &tv, &di, true, false) == OK) {
- if ((di == NULL
- || (!var_check_ro(di->di_flags, lp->ll_name, false)
- && !tv_check_lock(di->di_tv.v_lock, lp->ll_name, false)))
- && tv_op(&tv, rettv, op) == OK) {
- set_var(lp->ll_name, &tv, false);
- }
- clear_tv(&tv);
+ cc = *endp;
+ *endp = NUL;
+ if (op != NULL && *op != '=') {
+ typval_T tv;
+
+ // handle +=, -= and .=
+ di = NULL;
+ if (get_var_tv((const char *)lp->ll_name, (int)STRLEN(lp->ll_name),
+ &tv, &di, true, false) == OK) {
+ if ((di == NULL
+ || (!var_check_ro(di->di_flags, (const char *)lp->ll_name,
+ TV_CSTRING)
+ && !tv_check_lock(di->di_tv.v_lock, (const char *)lp->ll_name,
+ TV_CSTRING)))
+ && eexe_mod_op(&tv, rettv, (const char *)op) == OK) {
+ set_var(lp->ll_name, lp->ll_name_len, &tv, false);
}
- } else
- set_var(lp->ll_name, rettv, copy);
- *endp = cc;
+ tv_clear(&tv);
+ }
+ } else {
+ set_var(lp->ll_name, lp->ll_name_len, rettv, copy);
}
+ *endp = cc;
} else if (tv_check_lock(lp->ll_newkey == NULL
? lp->ll_tv->v_lock
: lp->ll_tv->vval.v_dict->dv_lock,
- lp->ll_name, false)) {
+ (const char *)lp->ll_name, TV_CSTRING)) {
} else if (lp->ll_range) {
listitem_T *ll_li = lp->ll_li;
int ll_n1 = lp->ll_n1;
@@ -2358,7 +2405,8 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, ch
// Check whether any of the list items is locked
for (listitem_T *ri = rettv->vval.v_list->lv_first;
ri != NULL && ll_li != NULL; ) {
- if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name, false)) {
+ if (tv_check_lock(ll_li->li_tv.v_lock, (const char *)lp->ll_name,
+ TV_CSTRING)) {
return;
}
ri = ri->li_next;
@@ -2373,18 +2421,18 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, ch
* 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);
+ if (op != NULL && *op != '=') {
+ eexe_mod_op(&lp->ll_li->li_tv, &ri->li_tv, (const char *)op);
+ } else {
+ tv_clear(&lp->ll_li->li_tv);
+ tv_copy(&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. */
- list_append_number(lp->ll_list, 0);
+ // Need to add an empty item.
+ tv_list_append_number(lp->ll_list, 0);
assert(lp->ll_li->li_next);
}
lp->ll_li = lp->ll_li->li_next;
@@ -2397,198 +2445,60 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, ch
: lp->ll_n1 != lp->ll_n2)
EMSG(_("E711: List value has not enough items"));
} else {
- typval_T oldtv;
+ typval_T oldtv = TV_INITIAL_VALUE;
dict_T *dict = lp->ll_dict;
- bool watched = is_watched(dict);
+ bool watched = tv_dict_is_watched(dict);
- if (watched) {
- init_tv(&oldtv);
- }
-
- /*
- * Assign to a List or Dictionary item.
- */
+ // Assign to a List or Dictionary item.
if (lp->ll_newkey != NULL) {
if (op != NULL && *op != '=') {
EMSG2(_(e_letwrong), op);
return;
}
- /* Need to add an item to the Dictionary. */
- di = dictitem_alloc(lp->ll_newkey);
- if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) {
+ // Need to add an item to the Dictionary.
+ di = tv_dict_item_alloc((const char *)lp->ll_newkey);
+ if (tv_dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) {
xfree(di);
return;
}
lp->ll_tv = &di->di_tv;
} else {
if (watched) {
- copy_tv(lp->ll_tv, &oldtv);
+ tv_copy(lp->ll_tv, &oldtv);
}
if (op != NULL && *op != '=') {
- tv_op(lp->ll_tv, rettv, op);
+ eexe_mod_op(lp->ll_tv, rettv, (const char *)op);
goto notify;
} else {
- clear_tv(lp->ll_tv);
+ tv_clear(lp->ll_tv);
}
}
// Assign the value to the variable or list item.
if (copy) {
- copy_tv(rettv, lp->ll_tv);
+ tv_copy(rettv, lp->ll_tv);
} else {
*lp->ll_tv = *rettv;
lp->ll_tv->v_lock = 0;
- init_tv(rettv);
+ tv_init(rettv);
}
notify:
if (watched) {
if (oldtv.v_type == VAR_UNKNOWN) {
- dictwatcher_notify(dict, (char *)lp->ll_newkey, lp->ll_tv, NULL);
+ tv_dict_watcher_notify(dict, (char *)lp->ll_newkey, lp->ll_tv, NULL);
} else {
dictitem_T *di = lp->ll_di;
- dictwatcher_notify(dict, (char *)di->di_key, lp->ll_tv, &oldtv);
- clear_tv(&oldtv);
- }
- }
- }
-}
-
-/*
- * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2"
- * Returns OK or FAIL.
- */
-static int tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
-{
- long n;
- char_u numbuf[NUMBUFLEN];
- char_u *s;
-
- // Can't do anything with a Funcref, a Dict or special value on the right.
- if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) {
- switch (tv1->v_type) {
- case VAR_DICT:
- case VAR_FUNC:
- case VAR_PARTIAL:
- case VAR_SPECIAL:
- break;
-
- case VAR_LIST:
- if (*op != '+' || tv2->v_type != VAR_LIST)
- break;
- /* List += List */
- if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL)
- 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;
+ tv_dict_watcher_notify(dict, (char *)di->di_key, lp->ll_tv, &oldtv);
+ tv_clear(&oldtv);
}
- return OK;
-
- case VAR_FLOAT:
- {
- float_T f;
-
- if (*op == '.' || (tv2->v_type != VAR_FLOAT
- && tv2->v_type != VAR_NUMBER
- && tv2->v_type != VAR_STRING))
- break;
- if (tv2->v_type == VAR_FLOAT)
- f = tv2->vval.v_float;
- else
- f = get_tv_number(tv2);
- if (*op == '+')
- tv1->vval.v_float += f;
- else
- tv1->vval.v_float -= f;
- }
- return OK;
-
- case VAR_UNKNOWN:
- assert(false);
}
}
-
- EMSG2(_(e_letwrong), op);
- return FAIL;
}
-/*
- * Add a watcher to a list.
- */
-void list_add_watch(list_T *l, listwatch_T *lw)
-{
- lw->lw_next = l->lv_watch;
- l->lv_watch = lw;
-}
-
-/*
- * Remove a watcher from a list.
- * No warning when it isn't found...
- */
-void list_rem_watch(list_T *l, listwatch_T *lwrem)
-{
- listwatch_T *lw, **lwp;
-
- lwp = &l->lv_watch;
- for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) {
- if (lw == lwrem) {
- *lwp = lw->lw_next;
- break;
- }
- lwp = &lw->lw_next;
- }
-}
-
-/*
- * Just before removing an item from a list: advance watchers to the next
- * item.
- */
-static void list_fix_watch(list_T *l, listitem_T *item)
-{
- listwatch_T *lw;
-
- for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next)
- if (lw->lw_item == item)
- lw->lw_item = item->li_next;
-}
+// TODO(ZyX-I): move to eval/ex_cmds
/*
* Evaluate the expression used in a ":for var in expr" command.
@@ -2596,14 +2506,14 @@ static void list_fix_watch(list_T *l, listitem_T *item)
* Set "*errp" to TRUE for an error, FALSE otherwise;
* Return a pointer that holds the info. Null when there is an error.
*/
-void *eval_for_line(char_u *arg, int *errp, char_u **nextcmdp, int skip)
+void *eval_for_line(const char_u *arg, bool *errp, char_u **nextcmdp, int skip)
{
forinfo_T *fi = xcalloc(1, sizeof(forinfo_T));
- char_u *expr;
+ const char_u *expr;
typval_T tv;
list_T *l;
- *errp = TRUE; /* default: there is an error */
+ *errp = true; // Default: there is an error.
expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon);
if (expr == NULL)
@@ -2618,20 +2528,20 @@ void *eval_for_line(char_u *arg, int *errp, char_u **nextcmdp, int skip)
if (skip)
++emsg_skip;
if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) {
- *errp = FALSE;
+ *errp = false;
if (!skip) {
l = tv.vval.v_list;
if (tv.v_type != VAR_LIST) {
EMSG(_(e_listreq));
- clear_tv(&tv);
+ tv_clear(&tv);
} else if (l == NULL) {
// a null list is like an empty list: do nothing
- clear_tv(&tv);
+ tv_clear(&tv);
} else {
/* No need to increment the refcount, it's already set for the
* list being used in "tv". */
fi->fi_list = l;
- list_add_watch(l, &fi->fi_lw);
+ tv_list_watch_add(l, &fi->fi_lw);
fi->fi_lw.lw_item = l->lv_first;
}
}
@@ -2642,6 +2552,8 @@ void *eval_for_line(char_u *arg, int *errp, char_u **nextcmdp, int skip)
return fi;
}
+// TODO(ZyX-I): move to eval/ex_cmds
+
/*
* Use the first item in a ":for" list. Advance to the next.
* Assign the values to the variable (list). "arg" points to the first one.
@@ -2665,6 +2577,8 @@ int next_for_item(void *fi_void, char_u *arg)
return result;
}
+// TODO(ZyX-I): move to eval/ex_cmds
+
/*
* Free the structure used to store info used by ":for".
*/
@@ -2673,8 +2587,8 @@ void free_for_info(void *fi_void)
forinfo_T *fi = (forinfo_T *)fi_void;
if (fi != NULL && fi->fi_list != NULL) {
- list_rem_watch(fi->fi_list, &fi->fi_lw);
- list_unref(fi->fi_list);
+ tv_list_watch_remove(fi->fi_list, &fi->fi_lw);
+ tv_list_unref(fi->fi_list);
}
xfree(fi);
}
@@ -2762,6 +2676,7 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
xp->xp_pattern = arg;
}
+// TODO(ZyX-I): move to eval/ex_cmds
/*
* ":1,25call func(arg1, arg2)" function call.
@@ -2781,13 +2696,14 @@ void ex_call(exarg_T *eap)
partial_T *partial = NULL;
if (eap->skip) {
- /* trans_function_name() doesn't work well when skipping, use eval0()
- * instead to skip to any following command, e.g. for:
- * :if 0 | call dict.foo().bar() | endif */
- ++emsg_skip;
- if (eval0(eap->arg, &rettv, &eap->nextcmd, FALSE) != FAIL)
- clear_tv(&rettv);
- --emsg_skip;
+ // trans_function_name() doesn't work well when skipping, use eval0()
+ // instead to skip to any following command, e.g. for:
+ // :if 0 | call dict.foo().bar() | endif.
+ emsg_skip++;
+ if (eval0(eap->arg, &rettv, &eap->nextcmd, false) != FAIL) {
+ tv_clear(&rettv);
+ }
+ emsg_skip--;
return;
}
@@ -2809,13 +2725,13 @@ void ex_call(exarg_T *eap)
// contents. For VAR_PARTIAL get its partial, unless we already have one
// from trans_function_name().
len = (int)STRLEN(tofree);
- name = deref_func_name(tofree, &len,
+ name = deref_func_name((const char *)tofree, &len,
partial != NULL ? NULL : &partial, false);
/* Skip white space to allow ":call func ()". Not good, but required for
* backward compatibility. */
startarg = skipwhite(arg);
- rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */
+ rettv.v_type = VAR_UNKNOWN; // tv_clear() uses this.
if (*startarg != '(') {
EMSG2(_("E107: Missing parentheses: %s"), eap->arg);
@@ -2829,12 +2745,13 @@ void ex_call(exarg_T *eap)
* call, and the loop is broken.
*/
if (eap->skip) {
- ++emsg_skip;
- lnum = eap->line2; /* do it once, also with an invalid range */
- } else
+ 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) {
+ }
+ for (; lnum <= eap->line2; lnum++) {
+ if (!eap->skip && eap->addr_count > 0) { // -V560
curwin->w_cursor.lnum = lnum;
curwin->w_cursor.col = 0;
curwin->w_cursor.coladd = 0;
@@ -2847,15 +2764,17 @@ void ex_call(exarg_T *eap)
break;
}
- /* Handle a function returning a Funcref, Dictionary or List. */
- if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL) {
- failed = TRUE;
+ // Handle a function returning a Funcref, Dictionary or List.
+ if (handle_subscript((const char **)&arg, &rettv, !eap->skip, true)
+ == FAIL) {
+ failed = true;
break;
}
- clear_tv(&rettv);
- if (doesrange || eap->skip)
+ tv_clear(&rettv);
+ if (doesrange || eap->skip) { // -V560
break;
+ }
/* Stop when immediately aborting on error, or when an interrupt
* occurred or an exception was thrown but not caught.
@@ -2877,10 +2796,12 @@ void ex_call(exarg_T *eap)
}
end:
- dict_unref(fudi.fd_dict);
+ tv_dict_unref(fudi.fd_dict);
xfree(tofree);
}
+// TODO(ZyX-I): move to eval/ex_cmds
+
/*
* ":unlet[!] var1 ... " command.
*/
@@ -2889,6 +2810,8 @@ void ex_unlet(exarg_T *eap)
ex_unletlock(eap, eap->arg, 0);
}
+// TODO(ZyX-I): move to eval/ex_cmds
+
/*
* ":lockvar" and ":unlockvar" commands
*/
@@ -2907,22 +2830,25 @@ void ex_lockvar(exarg_T *eap)
ex_unletlock(eap, arg, deep);
}
+// TODO(ZyX-I): move to eval/ex_cmds
+
/*
* ":unlet", ":lockvar" and ":unlockvar" are quite similar.
*/
static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep)
{
char_u *arg = argstart;
- char_u *name_end;
- int error = FALSE;
+ bool error = false;
lval_T lv;
do {
- /* Parse the name and find the end. */
- name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, 0,
- FNE_CHECK_START);
- if (lv.ll_name == NULL)
- error = TRUE; /* error but continue parsing */
+ // Parse the name and find the end.
+ char_u *const name_end = (char_u *)get_lval(arg, NULL, &lv, true,
+ eap->skip || error,
+ 0, FNE_CHECK_START);
+ if (lv.ll_name == NULL) {
+ error = true; // error, but continue parsing.
+ }
if (name_end == NULL || (!ascii_iswhite(*name_end)
&& !ends_excmd(*name_end))) {
if (name_end != NULL) {
@@ -2940,8 +2866,9 @@ static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep)
error = TRUE;
} else {
if (do_lock_var(&lv, name_end, deep,
- eap->cmdidx == CMD_lockvar) == FAIL)
- error = TRUE;
+ eap->cmdidx == CMD_lockvar) == FAIL) {
+ error = true;
+ }
}
}
@@ -2954,7 +2881,9 @@ static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep)
eap->nextcmd = check_nextcmd(arg);
}
-static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit)
+// TODO(ZyX-I): move to eval/ex_cmds
+
+static int do_unlet_var(lval_T *const lp, char_u *const name_end, int forceit)
{
int ret = OK;
int cc;
@@ -2963,16 +2892,18 @@ static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit)
cc = *name_end;
*name_end = NUL;
- /* Normal name or expanded name. */
- if (check_changedtick(lp->ll_name))
- ret = FAIL;
- else if (do_unlet(lp->ll_name, forceit) == FAIL)
+ // Normal name or expanded name.
+ if (do_unlet(lp->ll_name, lp->ll_name_len, forceit) == FAIL) {
ret = FAIL;
+ }
*name_end = cc;
} else if ((lp->ll_list != NULL
- && tv_check_lock(lp->ll_list->lv_lock, lp->ll_name, false))
+ && tv_check_lock(lp->ll_list->lv_lock, (const char *)lp->ll_name,
+ lp->ll_name_len))
|| (lp->ll_dict != NULL
- && tv_check_lock(lp->ll_dict->dv_lock, lp->ll_name, false))) {
+ && tv_check_lock(lp->ll_dict->dv_lock,
+ (const char *)lp->ll_name,
+ lp->ll_name_len))) {
return FAIL;
} else if (lp->ll_range) {
listitem_T *li;
@@ -2981,7 +2912,8 @@ static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit)
while (ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= ll_n1)) {
li = ll_li->li_next;
- if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name, false)) {
+ if (tv_check_lock(ll_li->li_tv.v_lock, (const char *)lp->ll_name,
+ lp->ll_name_len)) {
return false;
}
ll_li = li;
@@ -2991,33 +2923,33 @@ static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit)
/* 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);
+ tv_list_item_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);
+ tv_list_item_remove(lp->ll_list, lp->ll_li);
} else {
// unlet a Dictionary item.
dict_T *d = lp->ll_dict;
dictitem_T *di = lp->ll_di;
- bool watched = is_watched(d);
+ bool watched = tv_dict_is_watched(d);
char *key = NULL;
typval_T oldtv;
if (watched) {
- copy_tv(&di->di_tv, &oldtv);
+ tv_copy(&di->di_tv, &oldtv);
// need to save key because dictitem_remove will free it
key = xstrdup((char *)di->di_key);
}
- dictitem_remove(d, di);
+ tv_dict_item_remove(d, di);
if (watched) {
- dictwatcher_notify(d, key, NULL, &oldtv);
- clear_tv(&oldtv);
+ tv_dict_watcher_notify(d, key, NULL, &oldtv);
+ tv_clear(&oldtv);
xfree(key);
}
}
@@ -3026,21 +2958,24 @@ static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit)
return ret;
}
-/*
- * "unlet" a variable. Return OK if it existed, FAIL if not.
- * When "forceit" is TRUE don't complain if the variable doesn't exist.
- */
-int do_unlet(char_u *name, int forceit)
+// TODO(ZyX-I): move to eval/ex_cmds
+
+/// unlet a variable
+///
+/// @param[in] name Variable name to unlet.
+/// @param[in] name_len Variable name length.
+/// @param[in] fonceit If true, do not complain if variable doesn’t exist.
+///
+/// @return OK if it existed, FAIL otherwise.
+int do_unlet(const char *const name, const size_t name_len, const int forceit)
+ FUNC_ATTR_NONNULL_ALL
{
- hashtab_T *ht;
- hashitem_T *hi;
- char_u *varname;
- dict_T *d;
- dictitem_T *di;
+ const char *varname;
dict_T *dict;
- ht = find_var_ht_dict(name, &varname, &dict);
+ hashtab_T *ht = find_var_ht_dict(name, name_len, &varname, &dict);
if (ht != NULL && *varname != NUL) {
+ dict_T *d;
if (ht == &globvarht) {
d = &globvardict;
} else if (current_funccal != NULL
@@ -3049,38 +2984,41 @@ int do_unlet(char_u *name, int forceit)
} else if (ht == &compat_hashtab) {
d = &vimvardict;
} else {
- di = find_var_in_ht(ht, *name, (char_u *)"", false);
+ dictitem_T *const di = find_var_in_ht(ht, *name, "", 0, false);
d = di->di_tv.vval.v_dict;
}
if (d == NULL) {
EMSG2(_(e_intern2), "do_unlet()");
return FAIL;
}
- hi = hash_find(ht, varname);
- if (!HASHITEM_EMPTY(hi)) {
- di = HI2DI(hi);
- if (var_check_fixed(di->di_flags, name, false)
- || var_check_ro(di->di_flags, name, false)
- || tv_check_lock(d->dv_lock, name, false)) {
+ hashitem_T *hi = hash_find(ht, (const char_u *)varname);
+ if (HASHITEM_EMPTY(hi)) {
+ hi = find_hi_in_scoped_ht((const char *)name, &ht);
+ }
+ if (hi != NULL && !HASHITEM_EMPTY(hi)) {
+ dictitem_T *const di = TV_DICT_HI2DI(hi);
+ if (var_check_fixed(di->di_flags, (const char *)name, TV_CSTRING)
+ || var_check_ro(di->di_flags, (const char *)name, TV_CSTRING)
+ || tv_check_lock(d->dv_lock, (const char *)name, TV_CSTRING)) {
return FAIL;
}
- if (d == NULL || tv_check_lock(d->dv_lock, name, false)) {
+ if (tv_check_lock(d->dv_lock, (const char *)name, TV_CSTRING)) {
return FAIL;
}
typval_T oldtv;
- bool watched = is_watched(dict);
+ bool watched = tv_dict_is_watched(dict);
if (watched) {
- copy_tv(&di->di_tv, &oldtv);
+ tv_copy(&di->di_tv, &oldtv);
}
delete_var(ht, hi);
if (watched) {
- dictwatcher_notify(dict, (char *)varname, NULL, &oldtv);
- clear_tv(&oldtv);
+ tv_dict_watcher_notify(dict, varname, NULL, &oldtv);
+ tv_clear(&oldtv);
}
return OK;
}
@@ -3091,162 +3029,74 @@ int do_unlet(char_u *name, int forceit)
return FAIL;
}
+// TODO(ZyX-I): move to eval/ex_cmds
+
/*
* Lock or unlock variable indicated by "lp".
* "deep" is the levels to go (-1 for unlimited);
* "lock" is TRUE for ":lockvar", FALSE for ":unlockvar".
*/
-static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock)
+static int do_lock_var(lval_T *lp, char_u *const name_end, const int deep,
+ const bool lock)
{
int ret = OK;
- int cc;
- dictitem_T *di;
- if (deep == 0) /* nothing to do */
+ if (deep == 0) { // Nothing to do.
return OK;
+ }
if (lp->ll_tv == NULL) {
- cc = *name_end;
- *name_end = NUL;
-
- /* Normal name or expanded name. */
- if (check_changedtick(lp->ll_name))
+ // Normal name or expanded name.
+ dictitem_T *const di = find_var(
+ (const char *)lp->ll_name, lp->ll_name_len, NULL,
+ true);
+ if (di == NULL) {
ret = FAIL;
- else {
- di = find_var(lp->ll_name, NULL, TRUE);
- if (di == NULL)
- ret = FAIL;
- else {
- if (lock)
- di->di_flags |= DI_FLAGS_LOCK;
- else
- di->di_flags &= ~DI_FLAGS_LOCK;
- item_lock(&di->di_tv, deep, lock);
+ } else if ((di->di_flags & DI_FLAGS_FIX)
+ && di->di_tv.v_type != VAR_DICT
+ && di->di_tv.v_type != VAR_LIST) {
+ // For historical reasons this error is not given for Lists and
+ // Dictionaries. E.g. b: dictionary may be locked/unlocked.
+ emsgf(_("E940: Cannot lock or unlock variable %s"), lp->ll_name);
+ } else {
+ if (lock) {
+ di->di_flags |= DI_FLAGS_LOCK;
+ } else {
+ di->di_flags &= ~DI_FLAGS_LOCK;
}
+ tv_item_lock(&di->di_tv, deep, lock);
}
- *name_end = cc;
} else if (lp->ll_range) {
listitem_T *li = lp->ll_li;
/* (un)lock a range of List items. */
while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) {
- item_lock(&li->li_tv, deep, lock);
+ tv_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);
+ tv_item_lock(&lp->ll_li->li_tv, deep, lock);
} else {
// (un)lock a Dictionary item.
- item_lock(&lp->ll_di->di_tv, deep, lock);
+ tv_item_lock(&lp->ll_di->di_tv, deep, lock);
}
return ret;
}
/*
- * Lock or unlock an item. "deep" is nr of levels to go.
- */
-static void item_lock(typval_T *tv, int deep, int lock)
-{
- static int recurse = 0;
- list_T *l;
- listitem_T *li;
- dict_T *d;
- hashitem_T *hi;
- int todo;
-
- if (recurse >= DICT_MAXNEST) {
- EMSG(_("E743: variable nested too deep for (un)lock"));
- return;
- }
- if (deep == 0)
- return;
- ++recurse;
-
- /* lock/unlock the item itself */
- if (lock)
- tv->v_lock |= VAR_LOCKED;
- else
- tv->v_lock &= ~VAR_LOCKED;
-
- switch (tv->v_type) {
- case VAR_LIST:
- if ((l = tv->vval.v_list) != NULL) {
- if (lock)
- l->lv_lock |= VAR_LOCKED;
- else
- l->lv_lock &= ~VAR_LOCKED;
- if (deep < 0 || deep > 1)
- /* recursive: lock/unlock the items the List contains */
- for (li = l->lv_first; li != NULL; li = li->li_next)
- item_lock(&li->li_tv, deep - 1, lock);
- }
- break;
- case VAR_DICT:
- if ((d = tv->vval.v_dict) != NULL) {
- if (lock)
- d->dv_lock |= VAR_LOCKED;
- else
- d->dv_lock &= ~VAR_LOCKED;
- if (deep < 0 || deep > 1) {
- /* recursive: lock/unlock the items the List contains */
- todo = (int)d->dv_hashtab.ht_used;
- for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- --todo;
- item_lock(&HI2DI(hi)->di_tv, deep - 1, lock);
- }
- }
- }
- }
- break;
- case VAR_NUMBER:
- case VAR_FLOAT:
- case VAR_STRING:
- case VAR_FUNC:
- case VAR_PARTIAL:
- case VAR_SPECIAL:
- break;
- case VAR_UNKNOWN:
- assert(false);
- }
- --recurse;
-}
-
-/*
- * Return TRUE if typeval "tv" is locked: Either that value is locked itself
- * or it refers to a List or Dictionary that is locked.
- */
-static int tv_islocked(typval_T *tv)
-{
- return (tv->v_lock & VAR_LOCKED)
- || (tv->v_type == VAR_LIST
- && tv->vval.v_list != NULL
- && (tv->vval.v_list->lv_lock & VAR_LOCKED))
- || (tv->v_type == VAR_DICT
- && tv->vval.v_dict != NULL
- && (tv->vval.v_dict->dv_lock & VAR_LOCKED));
-}
-
-/*
* Delete all "menutrans_" variables.
*/
void del_menutrans_vars(void)
{
- hashitem_T *hi;
- int todo;
-
hash_lock(&globvarht);
- todo = (int)globvarht.ht_used;
- for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- --todo;
- if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0)
- delete_var(&globvarht, hi);
+ HASHTAB_ITER(&globvarht, hi, {
+ if (STRNCMP(hi->hi_key, "menutrans_", 10) == 0) {
+ delete_var(&globvarht, hi);
}
- }
+ });
hash_unlock(&globvarht);
}
@@ -3322,10 +3172,6 @@ char_u *get_user_var_name(expand_T *xp, int idx)
++hi;
return cat_prefix_varname('b', hi->hi_key);
}
- if (bdone == ht->ht_used) {
- ++bdone;
- return (char_u *)"b:changedtick";
- }
/* w: variables */
ht = &curwin->w_vars->dv_hashtab;
@@ -3362,6 +3208,7 @@ char_u *get_user_var_name(expand_T *xp, int idx)
return NULL;
}
+// TODO(ZyX-I): move to eval/expressions
/// Return TRUE if "pat" matches "text".
/// Does not use 'cpo' and always uses 'magic'.
@@ -3398,6 +3245,8 @@ typedef enum {
, TYPE_NOMATCH /* !~ */
} exptype_T;
+// TODO(ZyX-I): move to eval/expressions
+
/*
* The "evaluate" argument: When FALSE, the argument is only parsed but not
* executed. The function may return OK, but the rettv will be of type
@@ -3411,7 +3260,7 @@ typedef enum {
* Note: "rettv.v_lock" is not set.
* Return OK or FAIL.
*/
-static int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)
+int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)
{
int ret;
char_u *p;
@@ -3419,15 +3268,15 @@ static int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)
p = skipwhite(arg);
ret = eval1(&p, rettv, evaluate);
if (ret == FAIL || !ends_excmd(*p)) {
- if (ret != FAIL)
- clear_tv(rettv);
- /*
- * Report the invalid expression unless the expression evaluation has
- * been cancelled due to an aborting error, an interrupt, or an
- * exception.
- */
- if (!aborting())
- EMSG2(_(e_invexpr2), arg);
+ if (ret != FAIL) {
+ tv_clear(rettv);
+ }
+ // Report the invalid expression unless the expression evaluation has
+ // been cancelled due to an aborting error, an interrupt, or an
+ // exception.
+ if (!aborting()) {
+ emsgf(_(e_invexpr2), arg);
+ }
ret = FAIL;
}
if (nextcmd != NULL)
@@ -3436,6 +3285,8 @@ static int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)
return ret;
}
+// TODO(ZyX-I): move to eval/expressions
+
/*
* Handle top level expression:
* expr2 ? expr1 : expr1
@@ -3461,13 +3312,15 @@ static int eval1(char_u **arg, typval_T *rettv, int evaluate)
if ((*arg)[0] == '?') {
result = FALSE;
if (evaluate) {
- int error = FALSE;
+ bool error = false;
- if (get_tv_number_chk(rettv, &error) != 0)
- result = TRUE;
- clear_tv(rettv);
- if (error)
+ if (tv_get_number_chk(rettv, &error) != 0) {
+ result = true;
+ }
+ tv_clear(rettv);
+ if (error) {
return FAIL;
+ }
}
/*
@@ -3481,9 +3334,10 @@ static int eval1(char_u **arg, typval_T *rettv, int evaluate)
* Check for the ":".
*/
if ((*arg)[0] != ':') {
- EMSG(_("E109: Missing ':' after '?'"));
- if (evaluate && result)
- clear_tv(rettv);
+ emsgf(_("E109: Missing ':' after '?'"));
+ if (evaluate && result) {
+ tv_clear(rettv);
+ }
return FAIL;
}
@@ -3491,9 +3345,10 @@ static int eval1(char_u **arg, typval_T *rettv, int evaluate)
* Get the third variable.
*/
*arg = skipwhite(*arg + 1);
- if (eval1(arg, &var2, evaluate && !result) == FAIL) { /* recursive! */
- if (evaluate && result)
- clear_tv(rettv);
+ if (eval1(arg, &var2, evaluate && !result) == FAIL) { // Recursive!
+ if (evaluate && result) {
+ tv_clear(rettv);
+ }
return FAIL;
}
if (evaluate && !result)
@@ -3503,6 +3358,8 @@ static int eval1(char_u **arg, typval_T *rettv, int evaluate)
return OK;
}
+// TODO(ZyX-I): move to eval/expressions
+
/*
* Handle first level expression:
* expr2 || expr2 || expr2 logical OR
@@ -3517,7 +3374,7 @@ static int eval2(char_u **arg, typval_T *rettv, int evaluate)
typval_T var2;
long result;
int first;
- int error = FALSE;
+ bool error = false;
/*
* Get the first variable.
@@ -3532,12 +3389,14 @@ static int eval2(char_u **arg, typval_T *rettv, int evaluate)
result = FALSE;
while ((*arg)[0] == '|' && (*arg)[1] == '|') {
if (evaluate && first) {
- if (get_tv_number_chk(rettv, &error) != 0)
- result = TRUE;
- clear_tv(rettv);
- if (error)
+ if (tv_get_number_chk(rettv, &error) != 0) {
+ result = true;
+ }
+ tv_clear(rettv);
+ if (error) {
return FAIL;
- first = FALSE;
+ }
+ first = false;
}
/*
@@ -3551,11 +3410,13 @@ static int eval2(char_u **arg, typval_T *rettv, int evaluate)
* Compute the result.
*/
if (evaluate && !result) {
- if (get_tv_number_chk(&var2, &error) != 0)
- result = TRUE;
- clear_tv(&var2);
- if (error)
+ if (tv_get_number_chk(&var2, &error) != 0) {
+ result = true;
+ }
+ tv_clear(&var2);
+ if (error) {
return FAIL;
+ }
}
if (evaluate) {
rettv->v_type = VAR_NUMBER;
@@ -3566,6 +3427,8 @@ static int eval2(char_u **arg, typval_T *rettv, int evaluate)
return OK;
}
+// TODO(ZyX-I): move to eval/expressions
+
/*
* Handle second level expression:
* expr3 && expr3 && expr3 logical AND
@@ -3580,7 +3443,7 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate)
typval_T var2;
long result;
int first;
- int error = FALSE;
+ bool error = false;
/*
* Get the first variable.
@@ -3595,12 +3458,14 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate)
result = TRUE;
while ((*arg)[0] == '&' && (*arg)[1] == '&') {
if (evaluate && first) {
- if (get_tv_number_chk(rettv, &error) == 0)
- result = FALSE;
- clear_tv(rettv);
- if (error)
+ if (tv_get_number_chk(rettv, &error) == 0) {
+ result = false;
+ }
+ tv_clear(rettv);
+ if (error) {
return FAIL;
- first = FALSE;
+ }
+ first = false;
}
/*
@@ -3614,11 +3479,13 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate)
* Compute the result.
*/
if (evaluate && result) {
- if (get_tv_number_chk(&var2, &error) == 0)
- result = FALSE;
- clear_tv(&var2);
- if (error)
+ if (tv_get_number_chk(&var2, &error) == 0) {
+ result = false;
+ }
+ tv_clear(&var2);
+ if (error) {
return FAIL;
+ }
}
if (evaluate) {
rettv->v_type = VAR_NUMBER;
@@ -3629,6 +3496,8 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate)
return OK;
}
+// TODO(ZyX-I): move to eval/expressions
+
/*
* Handle third level expression:
* var1 == var2
@@ -3655,9 +3524,7 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
exptype_T type = TYPE_UNKNOWN;
int type_is = FALSE; /* TRUE for "is" and "isnot" */
int len = 2;
- long n1, n2;
- char_u *s1, *s2;
- char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
+ varnumber_T n1, n2;
int ic;
/*
@@ -3725,7 +3592,7 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
*/
*arg = skipwhite(p + len);
if (eval5(arg, &var2, evaluate) == FAIL) {
- clear_tv(rettv);
+ tv_clear(rettv);
return FAIL;
}
@@ -3747,15 +3614,15 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
} else {
EMSG(_("E692: Invalid operation for List"));
}
- clear_tv(rettv);
- clear_tv(&var2);
+ tv_clear(rettv);
+ tv_clear(&var2);
return FAIL;
} else {
- /* Compare two Lists for being equal or unequal. */
- n1 = list_equal(rettv->vval.v_list, var2.vval.v_list,
- ic, FALSE);
- if (type == TYPE_NEQUAL)
+ // Compare two Lists for being equal or unequal.
+ n1 = tv_list_equal(rettv->vval.v_list, var2.vval.v_list, ic, false);
+ if (type == TYPE_NEQUAL) {
n1 = !n1;
+ }
}
} else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) {
if (type_is) {
@@ -3769,23 +3636,22 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
EMSG(_("E735: Can only compare Dictionary with Dictionary"));
else
EMSG(_("E736: Invalid operation for Dictionary"));
- clear_tv(rettv);
- clear_tv(&var2);
+ tv_clear(rettv);
+ tv_clear(&var2);
return FAIL;
} else {
- /* Compare two Dictionaries for being equal or unequal. */
- n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict,
- ic, FALSE);
- if (type == TYPE_NEQUAL)
+ // Compare two Dictionaries for being equal or unequal.
+ n1 = tv_dict_equal(rettv->vval.v_dict, var2.vval.v_dict,
+ ic, false);
+ if (type == TYPE_NEQUAL) {
n1 = !n1;
+ }
}
- } else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC
- || rettv->v_type == VAR_PARTIAL
- || var2.v_type == VAR_PARTIAL) {
+ } else if (tv_is_func(*rettv) || tv_is_func(var2)) {
if (type != TYPE_EQUAL && type != TYPE_NEQUAL) {
EMSG(_("E694: Invalid operation for Funcrefs"));
- clear_tv(rettv);
- clear_tv(&var2);
+ tv_clear(rettv);
+ tv_clear(&var2);
return FAIL;
}
if ((rettv->v_type == VAR_PARTIAL
@@ -3820,25 +3686,27 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
&& type != TYPE_MATCH && type != TYPE_NOMATCH) {
float_T f1, f2;
- if (rettv->v_type == VAR_FLOAT)
+ if (rettv->v_type == VAR_FLOAT) {
f1 = rettv->vval.v_float;
- else
- f1 = get_tv_number(rettv);
- if (var2.v_type == VAR_FLOAT)
+ } else {
+ f1 = tv_get_number(rettv);
+ }
+ if (var2.v_type == VAR_FLOAT) {
f2 = var2.vval.v_float;
- else
- f2 = get_tv_number(&var2);
- n1 = FALSE;
+ } else {
+ f2 = tv_get_number(&var2);
+ }
+ n1 = false;
switch (type) {
- case TYPE_EQUAL: n1 = (f1 == f2); break;
- case TYPE_NEQUAL: n1 = (f1 != f2); break;
- case TYPE_GREATER: n1 = (f1 > f2); break;
- case TYPE_GEQUAL: n1 = (f1 >= f2); break;
- case TYPE_SMALLER: n1 = (f1 < f2); break;
- case TYPE_SEQUAL: n1 = (f1 <= f2); break;
- case TYPE_UNKNOWN:
- case TYPE_MATCH:
- case TYPE_NOMATCH: break; /* avoid gcc warning */
+ case TYPE_EQUAL: n1 = (f1 == f2); break;
+ case TYPE_NEQUAL: n1 = (f1 != f2); break;
+ case TYPE_GREATER: n1 = (f1 > f2); break;
+ case TYPE_GEQUAL: n1 = (f1 >= f2); break;
+ case TYPE_SMALLER: n1 = (f1 < f2); break;
+ case TYPE_SEQUAL: n1 = (f1 <= f2); break;
+ case TYPE_UNKNOWN:
+ case TYPE_MATCH:
+ case TYPE_NOMATCH: break;
}
}
/*
@@ -3847,48 +3715,51 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
*/
else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER)
&& type != TYPE_MATCH && type != TYPE_NOMATCH) {
- n1 = get_tv_number(rettv);
- n2 = get_tv_number(&var2);
+ n1 = tv_get_number(rettv);
+ n2 = tv_get_number(&var2);
switch (type) {
- case TYPE_EQUAL: n1 = (n1 == n2); break;
- case TYPE_NEQUAL: n1 = (n1 != n2); break;
- case TYPE_GREATER: n1 = (n1 > n2); break;
- case TYPE_GEQUAL: n1 = (n1 >= n2); break;
- case TYPE_SMALLER: n1 = (n1 < n2); break;
- case TYPE_SEQUAL: n1 = (n1 <= n2); break;
- case TYPE_UNKNOWN:
- case TYPE_MATCH:
- case TYPE_NOMATCH: break; /* avoid gcc warning */
+ case TYPE_EQUAL: n1 = (n1 == n2); break;
+ case TYPE_NEQUAL: n1 = (n1 != n2); break;
+ case TYPE_GREATER: n1 = (n1 > n2); break;
+ case TYPE_GEQUAL: n1 = (n1 >= n2); break;
+ case TYPE_SMALLER: n1 = (n1 < n2); break;
+ case TYPE_SEQUAL: n1 = (n1 <= n2); break;
+ case TYPE_UNKNOWN:
+ case TYPE_MATCH:
+ case TYPE_NOMATCH: break;
}
} else {
- s1 = get_tv_string_buf(rettv, buf1);
- s2 = get_tv_string_buf(&var2, buf2);
- if (type != TYPE_MATCH && type != TYPE_NOMATCH)
- i = ic ? mb_stricmp(s1, s2) : STRCMP(s1, s2);
- else
+ char buf1[NUMBUFLEN];
+ char buf2[NUMBUFLEN];
+ const char *const s1 = tv_get_string_buf(rettv, buf1);
+ const char *const s2 = tv_get_string_buf(&var2, buf2);
+ if (type != TYPE_MATCH && type != TYPE_NOMATCH) {
+ i = mb_strcmp_ic((bool)ic, s1, s2);
+ } else {
i = 0;
- n1 = FALSE;
+ }
+ n1 = false;
switch (type) {
- case TYPE_EQUAL: n1 = (i == 0); break;
- case TYPE_NEQUAL: n1 = (i != 0); break;
- case TYPE_GREATER: n1 = (i > 0); break;
- case TYPE_GEQUAL: n1 = (i >= 0); break;
- case TYPE_SMALLER: n1 = (i < 0); break;
- case TYPE_SEQUAL: n1 = (i <= 0); break;
-
- case TYPE_MATCH:
- case TYPE_NOMATCH:
- n1 = pattern_match(s2, s1, ic);
- if (type == TYPE_NOMATCH) {
- n1 = !n1;
+ case TYPE_EQUAL: n1 = (i == 0); break;
+ case TYPE_NEQUAL: n1 = (i != 0); break;
+ case TYPE_GREATER: n1 = (i > 0); break;
+ case TYPE_GEQUAL: n1 = (i >= 0); break;
+ case TYPE_SMALLER: n1 = (i < 0); break;
+ case TYPE_SEQUAL: n1 = (i <= 0); break;
+
+ case TYPE_MATCH:
+ case TYPE_NOMATCH: {
+ n1 = pattern_match((char_u *)s2, (char_u *)s1, ic);
+ if (type == TYPE_NOMATCH) {
+ n1 = !n1;
+ }
+ break;
}
- break;
-
- case TYPE_UNKNOWN: break; /* avoid gcc warning */
+ case TYPE_UNKNOWN: break; // Avoid gcc warning.
}
}
- clear_tv(rettv);
- clear_tv(&var2);
+ tv_clear(rettv);
+ tv_clear(&var2);
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = n1;
}
@@ -3897,6 +3768,8 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
return OK;
}
+// TODO(ZyX-I): move to eval/expressions
+
/*
* Handle fourth level expression:
* + number addition
@@ -3913,10 +3786,8 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
typval_T var2;
typval_T var3;
int op;
- long n1, n2;
+ varnumber_T n1, n2;
float_T f1 = 0, f2 = 0;
- char_u *s1, *s2;
- char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
char_u *p;
/*
@@ -3934,17 +3805,16 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
break;
if ((op != '+' || rettv->v_type != VAR_LIST)
- && (op == '.' || rettv->v_type != VAR_FLOAT)
- ) {
- /* For "list + ...", an illegal use of the first operand as
- * a number cannot be determined before evaluating the 2nd
- * operand: if this is also a list, all is ok.
- * For "something . ...", "something - ..." or "non-list + ...",
- * we know that the first operand needs to be a string or number
- * without evaluating the 2nd operand. So check before to avoid
- * side effects after an error. */
- if (evaluate && get_tv_string_chk(rettv) == NULL) {
- clear_tv(rettv);
+ && (op == '.' || rettv->v_type != VAR_FLOAT)) {
+ // For "list + ...", an illegal use of the first operand as
+ // a number cannot be determined before evaluating the 2nd
+ // operand: if this is also a list, all is ok.
+ // For "something . ...", "something - ..." or "non-list + ...",
+ // we know that the first operand needs to be a string or number
+ // without evaluating the 2nd operand. So check before to avoid
+ // side effects after an error.
+ if (evaluate && !tv_check_str(rettv)) {
+ tv_clear(rettv);
return FAIL;
}
}
@@ -3954,7 +3824,7 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
*/
*arg = skipwhite(*arg + 1);
if (eval6(arg, &var2, evaluate, op == '.') == FAIL) {
- clear_tv(rettv);
+ tv_clear(rettv);
return FAIL;
}
@@ -3963,41 +3833,44 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
* Compute the result.
*/
if (op == '.') {
- s1 = get_tv_string_buf(rettv, buf1); /* already checked */
- s2 = get_tv_string_buf_chk(&var2, buf2);
- if (s2 == NULL) { /* type error ? */
- clear_tv(rettv);
- clear_tv(&var2);
+ char buf1[NUMBUFLEN];
+ char buf2[NUMBUFLEN];
+ // s1 already checked
+ const char *const s1 = tv_get_string_buf(rettv, buf1);
+ const char *const s2 = tv_get_string_buf_chk(&var2, buf2);
+ if (s2 == NULL) { // Type error?
+ tv_clear(rettv);
+ tv_clear(&var2);
return FAIL;
}
- p = concat_str(s1, s2);
- clear_tv(rettv);
+ p = concat_str((const char_u *)s1, (const char_u *)s2);
+ tv_clear(rettv);
rettv->v_type = VAR_STRING;
rettv->vval.v_string = p;
} else if (op == '+' && rettv->v_type == VAR_LIST
&& var2.v_type == VAR_LIST) {
- /* concatenate Lists */
- if (list_concat(rettv->vval.v_list, var2.vval.v_list,
- &var3) == FAIL) {
- clear_tv(rettv);
- clear_tv(&var2);
+ // Concatenate Lists.
+ if (tv_list_concat(rettv->vval.v_list, var2.vval.v_list, &var3)
+ == FAIL) {
+ tv_clear(rettv);
+ tv_clear(&var2);
return FAIL;
}
- clear_tv(rettv);
+ tv_clear(rettv);
*rettv = var3;
} else {
- int error = FALSE;
+ bool error = false;
if (rettv->v_type == VAR_FLOAT) {
f1 = rettv->vval.v_float;
n1 = 0;
} else {
- n1 = get_tv_number_chk(rettv, &error);
+ n1 = tv_get_number_chk(rettv, &error);
if (error) {
/* This can only happen for "list + non-list". For
* "non-list + ..." or "something - ...", we returned
* before evaluating the 2nd operand. */
- clear_tv(rettv);
+ tv_clear(rettv);
return FAIL;
}
if (var2.v_type == VAR_FLOAT)
@@ -4007,16 +3880,16 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
f2 = var2.vval.v_float;
n2 = 0;
} else {
- n2 = get_tv_number_chk(&var2, &error);
+ n2 = tv_get_number_chk(&var2, &error);
if (error) {
- clear_tv(rettv);
- clear_tv(&var2);
+ tv_clear(rettv);
+ tv_clear(&var2);
return FAIL;
}
if (rettv->v_type == VAR_FLOAT)
f2 = n2;
}
- clear_tv(rettv);
+ tv_clear(rettv);
/* If there is a float on either side the result is a float. */
if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) {
@@ -4035,37 +3908,36 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
rettv->vval.v_number = n1;
}
}
- clear_tv(&var2);
+ tv_clear(&var2);
}
}
return OK;
}
-/*
- * Handle fifth level expression:
- * * number multiplication
- * / number division
- * % number modulo
- *
- * "arg" must point to the first non-white of the expression.
- * "arg" is advanced to the next non-white after the recognized expression.
- *
- * Return OK or FAIL.
- */
-static int
-eval6 (
- char_u **arg,
- typval_T *rettv,
- int evaluate,
- int want_string /* after "." operator */
-)
+// TODO(ZyX-I): move to eval/expressions
+
+/// Handle fifth level expression:
+/// - * number multiplication
+/// - / number division
+/// - % number modulo
+///
+/// @param[in,out] arg Points to the first non-whitespace character of the
+/// expression. Is advanced to the next non-whitespace
+/// character after the recognized expression.
+/// @param[out] rettv Location where result is saved.
+/// @param[in] evaluate If not true, rettv is not populated.
+/// @param[in] want_string True if "." is string_concatenation, otherwise
+/// float
+/// @return OK or FAIL.
+static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string)
+ FUNC_ATTR_NO_SANITIZE_UNDEFINED
{
typval_T var2;
int op;
- long n1, n2;
- int use_float = FALSE;
+ varnumber_T n1, n2;
+ bool use_float = false;
float_T f1 = 0, f2;
- int error = FALSE;
+ bool error = false;
/*
* Get the first variable.
@@ -4084,15 +3956,18 @@ eval6 (
if (evaluate) {
if (rettv->v_type == VAR_FLOAT) {
f1 = rettv->vval.v_float;
- use_float = TRUE;
+ use_float = true;
n1 = 0;
- } else
- n1 = get_tv_number_chk(rettv, &error);
- clear_tv(rettv);
- if (error)
+ } else {
+ n1 = tv_get_number_chk(rettv, &error);
+ }
+ tv_clear(rettv);
+ if (error) {
return FAIL;
- } else
+ }
+ } else {
n1 = 0;
+ }
/*
* Get the second variable.
@@ -4105,17 +3980,19 @@ eval6 (
if (var2.v_type == VAR_FLOAT) {
if (!use_float) {
f1 = n1;
- use_float = TRUE;
+ use_float = true;
}
f2 = var2.vval.v_float;
n2 = 0;
} else {
- n2 = get_tv_number_chk(&var2, &error);
- clear_tv(&var2);
- if (error)
+ n2 = tv_get_number_chk(&var2, &error);
+ tv_clear(&var2);
+ if (error) {
return FAIL;
- if (use_float)
+ }
+ if (use_float) {
f2 = n2;
+ }
}
/*
@@ -4146,18 +4023,20 @@ eval6 (
rettv->v_type = VAR_FLOAT;
rettv->vval.v_float = f1;
} else {
- if (op == '*')
+ if (op == '*') {
n1 = n1 * n2;
- else if (op == '/') {
- if (n2 == 0) { /* give an error message? */
- if (n1 == 0)
- n1 = -0x7fffffffL - 1L; /* similar to NaN */
- else if (n1 < 0)
- n1 = -0x7fffffffL;
- else
- n1 = 0x7fffffffL;
- } else
+ } else if (op == '/') {
+ if (n2 == 0) { // give an error message?
+ if (n1 == 0) {
+ n1 = VARNUMBER_MIN; // similar to NaN
+ } else if (n1 < 0) {
+ n1 = -VARNUMBER_MAX;
+ } else {
+ n1 = VARNUMBER_MAX;
+ }
+ } else {
n1 = n1 / n2;
+ }
} else {
if (n2 == 0) /* give an error message? */
n1 = 0;
@@ -4173,6 +4052,8 @@ eval6 (
return OK;
}
+// TODO(ZyX-I): move to eval/expressions
+
// Handle sixth level expression:
// number number constant
// "string" string constant
@@ -4204,18 +4085,18 @@ static int eval7(
int want_string // after "." operator
)
{
- long n;
+ varnumber_T n;
int len;
char_u *s;
char_u *start_leader, *end_leader;
int ret = OK;
char_u *alias;
- // Initialise variable so that clear_tv() can't mistake this for a
+ // Initialise variable so that tv_clear() can't mistake this for a
// string and free a string that isn't there.
rettv->v_type = VAR_UNKNOWN;
- // Skip '!' and '-' characters. They are handled later.
+ // Skip '!', '-' and '+' characters. They are handled later.
start_leader = *arg;
while (**arg == '!' || **arg == '-' || **arg == '+') {
*arg = skipwhite(*arg + 1);
@@ -4292,14 +4173,19 @@ static int eval7(
case '[': ret = get_list_tv(arg, rettv, evaluate);
break;
+ // Lambda: {arg, arg -> expr}
// Dictionary: {key: val, key: val}
- case '{': ret = get_dict_tv(arg, rettv, evaluate);
+ case '{': ret = get_lambda_tv(arg, rettv, evaluate);
+ if (ret == NOTDONE) {
+ ret = get_dict_tv(arg, rettv, evaluate);
+ }
break;
// Option value: &name
- case '&': ret = get_option_tv(arg, rettv, evaluate);
+ case '&': {
+ ret = get_option_tv((const char **)arg, rettv, evaluate);
break;
-
+ }
// Environment variable: $VAR.
case '$': ret = get_env_tv(arg, rettv, evaluate);
break;
@@ -4322,7 +4208,7 @@ static int eval7(
++*arg;
} else if (ret == OK) {
EMSG(_("E110: Missing ')'"));
- clear_tv(rettv);
+ tv_clear(rettv);
ret = FAIL;
}
break;
@@ -4335,7 +4221,7 @@ static int eval7(
// Must be a variable or function name.
// Can also be a curly-braces kind of name: {expr}.
s = *arg;
- len = get_name_len(arg, &alias, evaluate, true);
+ len = get_name_len((const char **)arg, (char **)&alias, evaluate, true);
if (alias != NULL) {
s = alias;
}
@@ -4345,20 +4231,31 @@ static int eval7(
} else {
if (**arg == '(') { // recursive!
partial_T *partial;
+
+ if (!evaluate) {
+ check_vars((const char *)s, len);
+ }
+
// If "s" is the name of a variable of type VAR_FUNC
// use its contents.
- s = deref_func_name(s, &len, &partial, !evaluate);
+ s = deref_func_name((const char *)s, &len, &partial, !evaluate);
+
+ // Need to make a copy, in case evaluating the arguments makes
+ // the name invalid.
+ s = xmemdupz(s, len);
// Invoke the function.
ret = get_func_tv(s, len, rettv, arg,
curwin->w_cursor.lnum, curwin->w_cursor.lnum,
&len, evaluate, partial, NULL);
+ xfree(s);
+
// If evaluate is false rettv->v_type was not set in
// get_func_tv, but it's needed in handle_subscript() to parse
// what follows. So set it here.
if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(') {
- rettv->vval.v_string = empty_string;
+ rettv->vval.v_string = (char_u *)tv_empty_string;
rettv->v_type = VAR_FUNC;
}
@@ -4367,13 +4264,14 @@ static int eval7(
// an exception was thrown but not caught.
if (aborting()) {
if (ret == OK) {
- clear_tv(rettv);
+ tv_clear(rettv);
}
ret = FAIL;
}
} else if (evaluate) {
- ret = get_var_tv(s, len, rettv, NULL, true, false);
+ ret = get_var_tv((const char *)s, len, rettv, NULL, true, false);
} else {
+ check_vars((const char *)s, len);
ret = OK;
}
}
@@ -4385,22 +4283,22 @@ static int eval7(
// Handle following '[', '(' and '.' for expr[expr], expr.name,
// expr(expr).
if (ret == OK) {
- ret = handle_subscript(arg, rettv, evaluate, true);
+ ret = handle_subscript((const char **)arg, rettv, evaluate, true);
}
// Apply logical NOT and unary '-', from right to left, ignore '+'.
if (ret == OK && evaluate && end_leader > start_leader) {
- int error = false;
- int val = 0;
+ bool error = false;
+ varnumber_T val = 0;
float_T f = 0.0;
if (rettv->v_type == VAR_FLOAT) {
f = rettv->vval.v_float;
} else {
- val = get_tv_number_chk(rettv, &error);
+ val = tv_get_number_chk(rettv, &error);
}
if (error) {
- clear_tv(rettv);
+ tv_clear(rettv);
ret = FAIL;
} else {
while (end_leader > start_leader) {
@@ -4420,10 +4318,10 @@ static int eval7(
}
}
if (rettv->v_type == VAR_FLOAT) {
- clear_tv(rettv);
+ tv_clear(rettv);
rettv->vval.v_float = f;
} else {
- clear_tv(rettv);
+ tv_clear(rettv);
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = val;
}
@@ -4433,6 +4331,8 @@ static int eval7(
return ret;
}
+// TODO(ZyX-I): move to eval/expressions
+
/*
* Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key".
* "*arg" points to the '[' or '.'.
@@ -4446,12 +4346,11 @@ eval_index (
int verbose /* give error messages */
)
{
- int empty1 = FALSE, empty2 = FALSE;
- typval_T var1, var2;
+ bool empty1 = false;
+ bool empty2 = false;
long n1, n2 = 0;
- long len = -1;
- int range = FALSE;
- char_u *s;
+ ptrdiff_t len = -1;
+ int range = false;
char_u *key = NULL;
switch (rettv->v_type) {
@@ -4488,8 +4387,8 @@ eval_index (
}
}
- init_tv(&var1);
- init_tv(&var2);
+ typval_T var1 = TV_INITIAL_VALUE;
+ typval_T var2 = TV_INITIAL_VALUE;
if (**arg == '.') {
/*
* dict.name
@@ -4507,13 +4406,13 @@ eval_index (
* Get the (first) variable from inside the [].
*/
*arg = skipwhite(*arg + 1);
- if (**arg == ':')
- empty1 = TRUE;
- else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */
+ if (**arg == ':') {
+ empty1 = true;
+ } else if (eval1(arg, &var1, evaluate) == FAIL) { // Recursive!
return FAIL;
- else if (evaluate && get_tv_string_chk(&var1) == NULL) {
- /* not a number or string */
- clear_tv(&var1);
+ } else if (evaluate && !tv_check_str(&var1)) {
+ // Not a number or string.
+ tv_clear(&var1);
return FAIL;
}
@@ -4523,28 +4422,32 @@ eval_index (
if (**arg == ':') {
range = TRUE;
*arg = skipwhite(*arg + 1);
- if (**arg == ']')
- empty2 = TRUE;
- else if (eval1(arg, &var2, evaluate) == FAIL) { /* recursive! */
- if (!empty1)
- clear_tv(&var1);
+ if (**arg == ']') {
+ empty2 = true;
+ } else if (eval1(arg, &var2, evaluate) == FAIL) { // Recursive!
+ if (!empty1) {
+ tv_clear(&var1);
+ }
return FAIL;
- } else if (evaluate && get_tv_string_chk(&var2) == NULL) {
- /* not a number or string */
- if (!empty1)
- clear_tv(&var1);
- clear_tv(&var2);
+ } else if (evaluate && !tv_check_str(&var2)) {
+ // Not a number or string.
+ if (!empty1) {
+ tv_clear(&var1);
+ }
+ tv_clear(&var2);
return FAIL;
}
}
/* Check for the ']'. */
if (**arg != ']') {
- if (verbose)
- EMSG(_(e_missbrac));
- clear_tv(&var1);
- if (range)
- clear_tv(&var2);
+ if (verbose) {
+ emsgf(_(e_missbrac));
+ }
+ tv_clear(&var1);
+ if (range) {
+ tv_clear(&var2);
+ }
return FAIL;
}
*arg = skipwhite(*arg + 1); /* skip the ']' */
@@ -4553,168 +4456,181 @@ eval_index (
if (evaluate) {
n1 = 0;
if (!empty1 && rettv->v_type != VAR_DICT) {
- n1 = get_tv_number(&var1);
- clear_tv(&var1);
+ n1 = tv_get_number(&var1);
+ tv_clear(&var1);
}
if (range) {
- if (empty2)
+ if (empty2) {
n2 = -1;
- else {
- n2 = get_tv_number(&var2);
- clear_tv(&var2);
+ } else {
+ n2 = tv_get_number(&var2);
+ tv_clear(&var2);
}
}
switch (rettv->v_type) {
- case VAR_NUMBER:
- case VAR_STRING:
- s = get_tv_string(rettv);
- len = (long)STRLEN(s);
- if (range) {
- /* The resulting variable is a substring. If the indexes
- * are out of range the result is empty. */
+ case VAR_NUMBER:
+ case VAR_STRING: {
+ const char *const s = tv_get_string(rettv);
+ char *v;
+ len = (ptrdiff_t)strlen(s);
+ if (range) {
+ // The resulting variable is a substring. If the indexes
+ // are out of range the result is empty.
+ if (n1 < 0) {
+ n1 = len + n1;
+ if (n1 < 0) {
+ n1 = 0;
+ }
+ }
+ if (n2 < 0) {
+ n2 = len + n2;
+ } else if (n2 >= len) {
+ n2 = len;
+ }
+ if (n1 >= len || n2 < 0 || n1 > n2) {
+ v = NULL;
+ } else {
+ v = xmemdupz(s + n1, (size_t)(n2 - n1 + 1));
+ }
+ } else {
+ // The resulting variable is a string of a single
+ // character. If the index is too big or negative the
+ // result is empty.
+ if (n1 >= len || n1 < 0) {
+ v = NULL;
+ } else {
+ v = xmemdupz(s + n1, 1);
+ }
+ }
+ tv_clear(rettv);
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = (char_u *)v;
+ break;
+ }
+ case VAR_LIST: {
+ len = tv_list_len(rettv->vval.v_list);
if (n1 < 0) {
n1 = len + n1;
- if (n1 < 0)
- n1 = 0;
}
- if (n2 < 0)
- n2 = len + n2;
- else if (n2 >= len)
- n2 = len;
- if (n1 >= len || n2 < 0 || n1 > n2)
- s = NULL;
- else
- s = vim_strnsave(s + n1, (int)(n2 - n1 + 1));
- } else {
- /* The resulting variable is a string of a single
- * character. If the index is too big or negative the
- * result is empty. */
- if (n1 >= len || n1 < 0)
- s = NULL;
- else
- s = vim_strnsave(s + n1, 1);
- }
- clear_tv(rettv);
- rettv->v_type = VAR_STRING;
- rettv->vval.v_string = s;
- break;
-
- case VAR_LIST:
- len = list_len(rettv->vval.v_list);
- if (n1 < 0)
- n1 = len + n1;
- if (!empty1 && (n1 < 0 || n1 >= len)) {
- /* For a range we allow invalid values and return an empty
- * list. A list index out of range is an error. */
- if (!range) {
- if (verbose)
- EMSGN(_(e_listidx), n1);
- return FAIL;
+ if (!empty1 && (n1 < 0 || n1 >= len)) {
+ // For a range we allow invalid values and return an empty
+ // list. A list index out of range is an error.
+ if (!range) {
+ if (verbose) {
+ EMSGN(_(e_listidx), n1);
+ }
+ return FAIL;
+ }
+ n1 = len;
}
- n1 = len;
- }
- if (range) {
- list_T *l;
- listitem_T *item;
-
- if (n2 < 0)
- n2 = len + n2;
- else if (n2 >= len)
- n2 = len - 1;
- if (!empty2 && (n2 < 0 || n2 + 1 < n1))
- n2 = -1;
- l = list_alloc();
- item = list_find(rettv->vval.v_list, n1);
- while (n1++ <= n2) {
- list_append_tv(l, &item->li_tv);
- item = item->li_next;
+ if (range) {
+ list_T *l;
+ listitem_T *item;
+
+ if (n2 < 0) {
+ n2 = len + n2;
+ } else if (n2 >= len) {
+ n2 = len - 1;
+ }
+ if (!empty2 && (n2 < 0 || n2 + 1 < n1)) {
+ n2 = -1;
+ }
+ l = tv_list_alloc();
+ item = tv_list_find(rettv->vval.v_list, n1);
+ while (n1++ <= n2) {
+ tv_list_append_tv(l, &item->li_tv);
+ item = item->li_next;
+ }
+ tv_clear(rettv);
+ rettv->v_type = VAR_LIST;
+ rettv->vval.v_list = l;
+ l->lv_refcount++;
+ } else {
+ tv_copy(&tv_list_find(rettv->vval.v_list, n1)->li_tv, &var1);
+ tv_clear(rettv);
+ *rettv = var1;
}
- clear_tv(rettv);
- rettv->v_type = VAR_LIST;
- rettv->vval.v_list = l;
- ++l->lv_refcount;
- } else {
- copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, &var1);
- clear_tv(rettv);
- *rettv = var1;
- }
- break;
-
- case VAR_DICT:
- if (range) {
- if (verbose)
- EMSG(_(e_dictrange));
- if (len == -1)
- clear_tv(&var1);
- return FAIL;
+ break;
}
- {
- dictitem_T *item;
+ case VAR_DICT: {
+ if (range) {
+ if (verbose) {
+ emsgf(_(e_dictrange));
+ }
+ if (len == -1) {
+ tv_clear(&var1);
+ }
+ return FAIL;
+ }
if (len == -1) {
- key = get_tv_string_chk(&var1);
+ key = (char_u *)tv_get_string_chk(&var1);
if (key == NULL) {
- clear_tv(&var1);
+ tv_clear(&var1);
return FAIL;
}
}
- item = dict_find(rettv->vval.v_dict, key, (int)len);
+ dictitem_T *const item = tv_dict_find(rettv->vval.v_dict,
+ (const char *)key, len);
- if (item == NULL && verbose)
- EMSG2(_(e_dictkey), key);
- if (len == -1)
- clear_tv(&var1);
- if (item == NULL)
+ if (item == NULL && verbose) {
+ emsgf(_(e_dictkey), key);
+ }
+ if (len == -1) {
+ tv_clear(&var1);
+ }
+ if (item == NULL) {
return FAIL;
+ }
- copy_tv(&item->di_tv, &var1);
- clear_tv(rettv);
+ tv_copy(&item->di_tv, &var1);
+ tv_clear(rettv);
*rettv = var1;
+ break;
+ }
+ case VAR_SPECIAL:
+ case VAR_FUNC:
+ case VAR_FLOAT:
+ case VAR_PARTIAL:
+ case VAR_UNKNOWN: {
+ break; // Not evaluating, skipping over subscript
}
- break;
- case VAR_SPECIAL:
- case VAR_FUNC:
- case VAR_PARTIAL:
- case VAR_FLOAT:
- case VAR_UNKNOWN:
- break; // Not evaluating, skipping over subscript
}
}
return OK;
}
-/*
- * Get an option value.
- * "arg" points to the '&' or '+' before the option name.
- * "arg" is advanced to character after the option name.
- * Return OK or FAIL.
- */
-static int
-get_option_tv (
- char_u **arg,
- typval_T *rettv, /* when NULL, only check if option exists */
- int evaluate
-)
+// TODO(ZyX-I): move to eval/executor
+
+/// Get an option value
+///
+/// @param[in,out] arg Points to the '&' or '+' before the option name. Is
+/// advanced to the character after the option name.
+/// @param[out] rettv Location where result is saved.
+/// @param[in] evaluate If not true, rettv is not populated.
+///
+/// @return OK or FAIL.
+static int get_option_tv(const char **const arg, typval_T *const rettv,
+ const bool evaluate)
+ FUNC_ATTR_NONNULL_ARG(1)
{
- char_u *option_end;
long numval;
char_u *stringval;
int opt_type;
int c;
- int working = (**arg == '+'); /* has("+option") */
+ bool working = (**arg == '+'); // has("+option")
int ret = OK;
int opt_flags;
- /*
- * Isolate the option name and find its value.
- */
- option_end = find_option_end(arg, &opt_flags);
+ // Isolate the option name and find its value.
+ char *option_end = (char *)find_option_end(arg, &opt_flags);
if (option_end == NULL) {
- if (rettv != NULL)
+ if (rettv != NULL) {
EMSG2(_("E112: Option name missing: %s"), *arg);
+ }
return FAIL;
}
@@ -4725,8 +4641,8 @@ get_option_tv (
c = *option_end;
*option_end = NUL;
- opt_type = get_option_value(*arg, &numval,
- rettv == NULL ? NULL : &stringval, opt_flags);
+ opt_type = get_option_value((char_u *)(*arg), &numval,
+ rettv == NULL ? NULL : &stringval, opt_flags);
if (opt_type == -3) { /* invalid name */
if (rettv != NULL)
@@ -4856,7 +4772,7 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
// Special key, e.g.: "\<C-W>"
case '<':
- extra = trans_special((const char_u **) &p, STRLEN(p), name, true);
+ extra = trans_special((const char_u **)&p, STRLEN(p), name, true, true);
if (extra != 0) {
name += extra;
break;
@@ -4871,7 +4787,10 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
}
*name = NUL;
- *arg = p + 1;
+ if (*p != NUL) { // just in case
+ p++;
+ }
+ *arg = p;
return OK;
}
@@ -4930,18 +4849,35 @@ static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate)
return OK;
}
+/// @return the function name of the partial.
+char_u *partial_name(partial_T *pt)
+{
+ if (pt->pt_name != NULL) {
+ return pt->pt_name;
+ }
+ return pt->pt_func->uf_name;
+}
+
+// TODO(ZyX-I): Move to eval/typval.h
+
static void partial_free(partial_T *pt)
{
for (int i = 0; i < pt->pt_argc; i++) {
- clear_tv(&pt->pt_argv[i]);
+ tv_clear(&pt->pt_argv[i]);
}
xfree(pt->pt_argv);
- dict_unref(pt->pt_dict);
- func_unref(pt->pt_name);
- xfree(pt->pt_name);
+ tv_dict_unref(pt->pt_dict);
+ if (pt->pt_name != NULL) {
+ func_unref(pt->pt_name);
+ xfree(pt->pt_name);
+ } else {
+ func_ptr_unref(pt->pt_func);
+ }
xfree(pt);
}
+// TODO(ZyX-I): Move to eval/typval.h
+
/// Unreference a closure: decrement the reference count and free it when it
/// becomes zero.
void partial_unref(partial_T *pt)
@@ -4960,7 +4896,7 @@ static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate)
listitem_T *item;
if (evaluate) {
- l = list_alloc();
+ l = tv_list_alloc();
}
*arg = skipwhite(*arg + 1);
@@ -4968,10 +4904,10 @@ static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate)
if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */
goto failret;
if (evaluate) {
- item = listitem_alloc();
+ item = tv_list_item_alloc();
item->li_tv = tv;
item->li_tv.v_lock = 0;
- list_append(l, item);
+ tv_list_append(l, item);
}
if (**arg == ']')
@@ -4987,7 +4923,7 @@ static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate)
EMSG2(_("E697: Missing end of List ']': %s"), *arg);
failret:
if (evaluate) {
- list_free(l);
+ tv_list_free(l);
}
return FAIL;
}
@@ -5002,196 +4938,7 @@ failret:
return OK;
}
-/*
- * Allocate an empty header for a list.
- * Caller should take care of the reference count.
- */
-list_T *list_alloc(void) FUNC_ATTR_NONNULL_RET
-{
- list_T *list = xcalloc(1, sizeof(list_T));
-
- /* Prepend the list to the list of lists for garbage collection. */
- if (first_list != NULL)
- first_list->lv_used_prev = list;
- list->lv_used_prev = NULL;
- list->lv_used_next = first_list;
- first_list = list;
- return list;
-}
-
-/*
- * Allocate an empty list for a return value.
- */
-static list_T *rettv_list_alloc(typval_T *rettv)
-{
- list_T *l = list_alloc();
- rettv->vval.v_list = l;
- rettv->v_type = VAR_LIST;
- rettv->v_lock = VAR_UNLOCKED;
- l->lv_refcount++;
- return l;
-}
-
-/// Unreference a list: decrement the reference count and free it when it
-/// becomes zero.
-void list_unref(list_T *l) {
- if (l != NULL && --l->lv_refcount <= 0) {
- list_free(l);
- }
-}
-
-/// Free a list, including all items it points to.
-/// Ignores the reference count.
-static void list_free_contents(list_T *l) {
- listitem_T *item;
-
- for (item = l->lv_first; item != NULL; item = l->lv_first) {
- // Remove the item before deleting it.
- l->lv_first = item->li_next;
- clear_tv(&item->li_tv);
- xfree(item);
- }
-}
-
-static void list_free_list(list_T *l) {
- // 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;
- }
-
- xfree(l);
-}
-
-void list_free(list_T *l) {
- if (!in_free_unref_items) {
- list_free_contents(l);
- list_free_list(l);
- }
-}
-
-/*
- * Allocate a list item.
- * It is not initialized, don't forget to set v_lock.
- */
-listitem_T *listitem_alloc(void) FUNC_ATTR_NONNULL_RET
-{
- return xmalloc(sizeof(listitem_T));
-}
-
-/*
- * Free a list item. Also clears the value. Does not notify watchers.
- */
-void listitem_free(listitem_T *item)
-{
- clear_tv(&item->li_tv);
- xfree(item);
-}
-
-/*
- * Remove a list item from a List and free it. Also clears the value.
- */
-void listitem_remove(list_T *l, listitem_T *item)
-{
- vim_list_remove(l, item, item);
- listitem_free(item);
-}
-
-/*
- * Get the number of items in a list.
- */
-static long list_len(list_T *l)
-{
- if (l == NULL)
- return 0L;
- return l->lv_len;
-}
-
-/*
- * Return TRUE when two lists have exactly the same values.
- */
-static int
-list_equal (
- list_T *l1,
- list_T *l2,
- int ic, /* ignore case for strings */
- int recursive /* TRUE when used recursively */
-)
-{
- listitem_T *item1, *item2;
-
- if (l1 == NULL || l2 == NULL)
- return FALSE;
- if (l1 == l2)
- return TRUE;
- if (list_len(l1) != list_len(l2))
- return FALSE;
-
- for (item1 = l1->lv_first, item2 = l2->lv_first;
- item1 != NULL && item2 != NULL;
- item1 = item1->li_next, item2 = item2->li_next)
- if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive))
- return FALSE;
- return item1 == NULL && item2 == NULL;
-}
-
-/*
- * Return the dictitem that an entry in a hashtable points to.
- */
-dictitem_T *dict_lookup(hashitem_T *hi)
-{
- return HI2DI(hi);
-}
-
-/*
- * Return TRUE when two dictionaries have exactly the same key/values.
- */
-static int
-dict_equal (
- dict_T *d1,
- dict_T *d2,
- int ic, /* ignore case for strings */
- int recursive /* TRUE when used recursively */
-)
-{
- hashitem_T *hi;
- dictitem_T *item2;
- int todo;
-
- if (d1 == NULL && d2 == NULL) {
- return true;
- }
- 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;
-
-static bool func_equal(
+bool func_equal(
typval_T *tv1,
typval_T *tv2,
bool ic // ignore case
@@ -5202,12 +4949,12 @@ static bool func_equal(
// empty and NULL function name considered the same
s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
- : tv1->vval.v_partial->pt_name;
+ : partial_name(tv1->vval.v_partial);
if (s1 != NULL && *s1 == NUL) {
s1 = NULL;
}
s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
- : tv2->vval.v_partial->pt_name;
+ : partial_name(tv2->vval.v_partial);
if (s2 != NULL && *s2 == NUL) {
s2 = NULL;
}
@@ -5226,7 +4973,7 @@ static bool func_equal(
if (d1 != d2) {
return false;
}
- } else if (!dict_equal(d1, d2, ic, true)) {
+ } else if (!tv_dict_equal(d1, d2, ic, true)) {
return false;
}
@@ -5245,550 +4992,6 @@ static bool func_equal(
return true;
}
-/*
- * 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 (
- 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;
-
- /* 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;
- }
-
- // For VAR_FUNC and VAR_PARTIAL only compare the function name.
- if ((tv1->v_type == VAR_FUNC
- || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL))
- && (tv2->v_type == VAR_FUNC
- || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL))) {
- recursive_cnt++;
- r = func_equal(tv1, tv2, ic);
- recursive_cnt--;
- return r;
- }
- if (tv1->v_type != tv2->v_type) {
- return false;
- }
-
- 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_NUMBER:
- return tv1->vval.v_number == tv2->vval.v_number;
-
- case VAR_FLOAT:
- return tv1->vval.v_float == tv2->vval.v_float;
-
- case VAR_STRING:
- s1 = get_tv_string_buf(tv1, buf1);
- s2 = get_tv_string_buf(tv2, buf2);
- return (ic ? mb_stricmp(s1, s2) : STRCMP(s1, s2)) == 0;
-
- case VAR_SPECIAL:
- return tv1->vval.v_special == tv2->vval.v_special;
-
- case VAR_FUNC:
- case VAR_PARTIAL:
- case VAR_UNKNOWN:
- // VAR_UNKNOWN can be the result of an invalid expression, let’s say it does
- // not equal anything, not even self.
- return false;
- }
-
- assert(false);
- return false;
-}
-
-/*
- * Locate item with index "n" in list "l" and return it.
- * A negative index is counted from the end; -1 is the last item.
- * Returns NULL when "n" is out of range.
- */
-listitem_T *list_find(list_T *l, long n)
-{
- listitem_T *item;
- long idx;
-
- if (l == NULL)
- return NULL;
-
- /* Negative index is relative to the end. */
- if (n < 0)
- n = l->lv_len + n;
-
- /* Check for index out of range. */
- if (n < 0 || n >= l->lv_len)
- return NULL;
-
- /* When there is a cached index may start search from there. */
- if (l->lv_idx_item != NULL) {
- if (n < l->lv_idx / 2) {
- /* closest to the start of the list */
- item = l->lv_first;
- idx = 0;
- } else if (n > (l->lv_idx + l->lv_len) / 2) {
- /* closest to the end of the list */
- item = l->lv_last;
- idx = l->lv_len - 1;
- } else {
- /* closest to the cached index */
- item = l->lv_idx_item;
- idx = l->lv_idx;
- }
- } else {
- if (n < l->lv_len / 2) {
- /* closest to the start of the list */
- item = l->lv_first;
- idx = 0;
- } else {
- /* closest to the end of the list */
- item = l->lv_last;
- idx = l->lv_len - 1;
- }
- }
-
- while (n > idx) {
- /* search forward */
- item = item->li_next;
- ++idx;
- }
- while (n < idx) {
- /* search backward */
- item = item->li_prev;
- --idx;
- }
-
- /* cache the used index */
- l->lv_idx = idx;
- l->lv_idx_item = item;
-
- return item;
-}
-
-/*
- * Get list item "l[idx]" as a number.
- */
-static long
-list_find_nr (
- list_T *l,
- long idx,
- int *errorp /* set to TRUE when something wrong */
-)
-{
- listitem_T *li;
-
- li = list_find(l, idx);
- if (li == NULL) {
- if (errorp != NULL)
- *errorp = TRUE;
- return -1L;
- }
- return get_tv_number_chk(&li->li_tv, errorp);
-}
-
-/*
- * Get list item "l[idx - 1]" as a string. Returns NULL for failure.
- */
-char_u *list_find_str(list_T *l, long idx)
-{
- listitem_T *li;
-
- li = list_find(l, idx - 1);
- if (li == NULL) {
- EMSGN(_(e_listidx), idx);
- return NULL;
- }
- return get_tv_string(&li->li_tv);
-}
-
-/*
- * Locate "item" list "l" and return its index.
- * Returns -1 when "item" is not in the list.
- */
-static long list_idx_of_item(list_T *l, listitem_T *item)
-{
- long idx = 0;
- listitem_T *li;
-
- if (l == NULL)
- return -1;
- idx = 0;
- for (li = l->lv_first; li != NULL && li != item; li = li->li_next)
- ++idx;
- if (li == NULL)
- return -1;
- return idx;
-}
-
-/*
- * Append item "item" to the end of list "l".
- */
-void list_append(list_T *l, listitem_T *item)
-{
- if (l->lv_last == NULL) {
- /* empty list */
- l->lv_first = item;
- l->lv_last = item;
- item->li_prev = NULL;
- } else {
- l->lv_last->li_next = item;
- item->li_prev = l->lv_last;
- l->lv_last = item;
- }
- ++l->lv_len;
- item->li_next = NULL;
-}
-
-/*
- * Append typval_T "tv" to the end of list "l".
- */
-void list_append_tv(list_T *l, typval_T *tv)
-{
- listitem_T *li = listitem_alloc();
- copy_tv(tv, &li->li_tv);
- list_append(l, li);
-}
-
-/*
- * Add a list to a list.
- */
-void list_append_list(list_T *list, list_T *itemlist)
-{
- listitem_T *li = listitem_alloc();
-
- li->li_tv.v_type = VAR_LIST;
- li->li_tv.v_lock = 0;
- li->li_tv.vval.v_list = itemlist;
- list_append(list, li);
- ++itemlist->lv_refcount;
-}
-
-/*
- * Add a dictionary to a list. Used by getqflist().
- */
-void list_append_dict(list_T *list, dict_T *dict)
-{
- listitem_T *li = listitem_alloc();
-
- li->li_tv.v_type = VAR_DICT;
- li->li_tv.v_lock = 0;
- li->li_tv.vval.v_dict = dict;
- list_append(list, li);
- ++dict->dv_refcount;
-}
-
-/// Make a copy of "str" and append it as an item to list "l"
-///
-/// @param[out] l List to append to.
-/// @param[in] str String to append.
-/// @param[in] len Length of the appended string. May be negative, in this
-/// case string is considered to be usual zero-terminated
-/// string.
-void list_append_string(list_T *l, const char_u *str, int len)
- FUNC_ATTR_NONNULL_ARG(1)
-{
- if (str == NULL) {
- list_append_allocated_string(l, NULL);
- } else {
- list_append_allocated_string(l, (len >= 0
- ? xmemdupz((char *) str, len)
- : xstrdup((char *) str)));
- }
-}
-
-/// Append given string to the list
-///
-/// Unlike list_append_string this function does not copy the string.
-///
-/// @param[out] l List to append to.
-/// @param[in] str String to append.
-void list_append_allocated_string(list_T *l, char *const str)
- FUNC_ATTR_NONNULL_ARG(1)
-{
- listitem_T *li = listitem_alloc();
-
- list_append(l, li);
- li->li_tv.v_type = VAR_STRING;
- li->li_tv.v_lock = 0;
- li->li_tv.vval.v_string = (char_u *) str;
-}
-
-/*
- * Append "n" to list "l".
- */
-void list_append_number(list_T *l, varnumber_T n)
-{
- listitem_T *li = listitem_alloc();
- li->li_tv.v_type = VAR_NUMBER;
- li->li_tv.v_lock = 0;
- li->li_tv.vval.v_number = n;
- list_append(l, li);
-}
-
-/*
- * Insert typval_T "tv" in list "l" before "item".
- * If "item" is NULL append at the end.
- */
-void list_insert_tv(list_T *l, typval_T *tv, listitem_T *item)
-{
- listitem_T *ni = listitem_alloc();
-
- copy_tv(tv, &ni->li_tv);
- list_insert(l, ni, item);
-}
-
-void list_insert(list_T *l, listitem_T *ni, listitem_T *item)
-{
- if (item == NULL)
- /* Append new item at end of list. */
- list_append(l, ni);
- else {
- /* Insert new item before existing item. */
- ni->li_prev = item->li_prev;
- ni->li_next = item;
- if (item->li_prev == NULL) {
- l->lv_first = ni;
- ++l->lv_idx;
- } else {
- item->li_prev->li_next = ni;
- l->lv_idx_item = NULL;
- }
- item->li_prev = ni;
- ++l->lv_len;
- }
-}
-
-/*
- * Extend "l1" with "l2".
- * If "bef" is NULL append at the end, otherwise insert before this item.
- */
-static void list_extend(list_T *l1, list_T *l2, listitem_T *bef)
-{
- listitem_T *item;
- int todo = l2->lv_len;
-
- /* We also quit the loop when we have inserted the original item count of
- * the list, avoid a hang when we extend a list with itself. */
- for (item = l2->lv_first; item != NULL && --todo >= 0; item = item->li_next) {
- list_insert_tv(l1, &item->li_tv, bef);
- }
-}
-
-/*
- * Concatenate lists "l1" and "l2" into a new list, stored in "tv".
- * Return FAIL on failure to copy.
- */
-static int list_concat(list_T *l1, list_T *l2, typval_T *tv)
-{
- list_T *l;
-
- if (l1 == NULL || l2 == NULL)
- return FAIL;
-
- /* make a copy of the first list. */
- l = list_copy(NULL, l1, false, 0);
- if (l == NULL)
- return FAIL;
- tv->v_type = VAR_LIST;
- tv->vval.v_list = l;
-
- /* append all items from the second list */
- list_extend(l, l2, NULL);
- return OK;
-}
-
-/// Make a copy of list
-///
-/// @param[in] conv If non-NULL, then all internal strings will be converted.
-/// @param[in] orig Original list to copy.
-/// @param[in] deep If false, then shallow copy will be done.
-/// @param[in] copyID See var_item_copy().
-///
-/// @return Copied list. May be NULL in case original list is NULL or some
-/// failure happens. The refcount of the new list is set to 1.
-static list_T *list_copy(const vimconv_T *const conv,
- list_T *const orig,
- const bool deep,
- const int copyID)
- FUNC_ATTR_WARN_UNUSED_RESULT
-{
- listitem_T *item;
- listitem_T *ni;
-
- if (orig == NULL)
- return NULL;
-
- list_T *copy = list_alloc();
- if (copyID != 0) {
- /* Do this before adding the items, because one of the items may
- * refer back to this list. */
- orig->lv_copyID = copyID;
- orig->lv_copylist = copy;
- }
- for (item = orig->lv_first; item != NULL && !got_int;
- item = item->li_next) {
- ni = listitem_alloc();
- if (deep) {
- if (var_item_copy(conv, &item->li_tv, &ni->li_tv, deep, copyID) == FAIL) {
- xfree(ni);
- break;
- }
- } else
- copy_tv(&item->li_tv, &ni->li_tv);
- list_append(copy, ni);
- }
- ++copy->lv_refcount;
- if (item != NULL) {
- list_unref(copy);
- copy = NULL;
- }
-
- return copy;
-}
-
-/// Remove items "item" to "item2" from list "l".
-/// @warning Does not free the listitem or the value!
-void vim_list_remove(list_T *l, listitem_T *item, listitem_T *item2)
-{
- // notify watchers
- for (listitem_T *ip = item; ip != NULL; ip = ip->li_next) {
- --l->lv_len;
- list_fix_watch(l, ip);
- if (ip == item2) {
- break;
- }
- }
-
- if (item2->li_next == NULL) {
- l->lv_last = item->li_prev;
- } else {
- item2->li_next->li_prev = item->li_prev;
- }
- if (item->li_prev == NULL) {
- l->lv_first = item2->li_next;
- } else {
- item->li_prev->li_next = item2->li_next;
- }
- l->lv_idx_item = NULL;
-}
-
-typedef struct join_S {
- char_u *s;
- char_u *tofree;
-} join_T;
-
-/// Join list into a string, helper function
-///
-/// @param[out] gap Garray where result will be saved.
-/// @param[in] l List to join.
-/// @param[in] sep Used separator.
-/// @param[in] join_gap Garray to keep each list item string.
-///
-/// @return OK in case of success, FAIL otherwise.
-static int list_join_inner(garray_T *const gap, list_T *const l,
- const char *const sep, garray_T *const join_gap)
- FUNC_ATTR_NONNULL_ALL
-{
- int sumlen = 0;
- bool first = true;
- listitem_T *item;
-
- /* Stringify each item in the list. */
- for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) {
- char *s;
- size_t len;
- s = encode_tv2echo(&item->li_tv, &len);
- if (s == NULL) {
- return FAIL;
- }
-
- sumlen += (int) len;
-
- join_T *const p = GA_APPEND_VIA_PTR(join_T, join_gap);
- p->tofree = p->s = (char_u *) s;
-
- line_breakcheck();
- }
-
- /* Allocate result buffer with its total size, avoid re-allocation and
- * multiple copy operations. Add 2 for a tailing ']' and NUL. */
- if (join_gap->ga_len >= 2)
- sumlen += (int)STRLEN(sep) * (join_gap->ga_len - 1);
- ga_grow(gap, sumlen + 2);
-
- for (int i = 0; i < join_gap->ga_len && !got_int; ++i) {
- if (first) {
- first = false;
- } else {
- ga_concat(gap, (const char_u *) sep);
- }
- const join_T *const p = ((const join_T *)join_gap->ga_data) + i;
-
- if (p->s != NULL)
- ga_concat(gap, p->s);
- line_breakcheck();
- }
-
- return OK;
-}
-
-/// Join list into a string using given separator
-///
-/// @param[out] gap Garray where result will be saved.
-/// @param[in] l Joined list.
-/// @param[in] sep Separator.
-///
-/// @return OK in case of success, FAIL otherwise.
-static int list_join(garray_T *const gap, list_T *const l,
- const char *const sep)
- FUNC_ATTR_NONNULL_ALL
-{
- if (l->lv_len < 1) {
- return OK;
- }
-
- garray_T join_ga;
- int retval;
-
- ga_init(&join_ga, (int)sizeof(join_T), l->lv_len);
- retval = list_join_inner(gap, l, sep, &join_ga);
-
-# define FREE_JOIN_TOFREE(join) xfree((join)->tofree)
- GA_DEEP_CLEAR(&join_ga, join_T, FREE_JOIN_TOFREE);
-
- return retval;
-}
-
/// Get next (unique) copy ID
///
/// Used for traversing nested structures e.g. when serializing them or garbage
@@ -5805,6 +5008,9 @@ int get_copyID(void)
return current_copyID;
}
+// Used by get_func_tv()
+static garray_T funcargs = GA_EMPTY_INIT_VALUE;
+
/*
* Garbage collection for lists and dictionaries.
*
@@ -5827,19 +5033,22 @@ int get_copyID(void)
/// Do garbage collection for lists and dicts.
///
+/// @param testing true if called from test_garbagecollect_now().
/// @returns true if some memory was freed.
-bool garbage_collect(void)
+bool garbage_collect(bool testing)
{
bool abort = false;
#define ABORTING(func) abort = abort || func
- // Only do this once.
- want_garbage_collect = false;
- may_garbage_collect = false;
- garbage_collect_at_exit = false;
+ if (!testing) {
+ // Only do this once.
+ want_garbage_collect = false;
+ may_garbage_collect = false;
+ garbage_collect_at_exit = false;
+ }
- // We advance by two because we add one for items referenced through
- // previous_funccal.
+ // We advance by two (COPYID_INC) because we add one for items referenced
+ // through previous_funccal.
const int copyID = get_copyID();
// 1. Go through all accessible variables and mark all lists and dicts
@@ -5849,6 +5058,7 @@ bool garbage_collect(void)
// referenced through previous_funccal. This must be first, because if
// the item is referenced elsewhere the funccal must not be freed.
for (funccall_T *fc = previous_funccal; fc != NULL; fc = fc->caller) {
+ fc->fc_copyID = copyID + 1;
ABORTING(set_ref_in_ht)(&fc->l_vars.dv_hashtab, copyID + 1, NULL);
ABORTING(set_ref_in_ht)(&fc->l_avars.dv_hashtab, copyID + 1, NULL);
}
@@ -5894,7 +5104,8 @@ bool garbage_collect(void)
do {
yankreg_T reg;
char name = NUL;
- reg_iter = op_register_iter(reg_iter, &name, &reg);
+ bool is_unnamed = false;
+ reg_iter = op_register_iter(reg_iter, &name, &reg, &is_unnamed);
if (name != NUL) {
ABORTING(set_ref_dict)(reg.additional_data, copyID);
}
@@ -5924,10 +5135,14 @@ bool garbage_collect(void)
// function-local variables
for (funccall_T *fc = current_funccal; fc != NULL; fc = fc->caller) {
+ fc->fc_copyID = copyID;
ABORTING(set_ref_in_ht)(&fc->l_vars.dv_hashtab, copyID, NULL);
ABORTING(set_ref_in_ht)(&fc->l_avars.dv_hashtab, copyID, NULL);
}
+ // named functions (matters for closures)
+ ABORTING(set_ref_in_functions(copyID));
+
// Jobs
{
TerminalJobData *data;
@@ -5946,6 +5161,12 @@ bool garbage_collect(void)
})
}
+ // function call arguments, if v:testing is set.
+ for (int i = 0; i < funcargs.ga_len; i++) {
+ ABORTING(set_ref_in_item)(((typval_T **)funcargs.ga_data)[i],
+ copyID, NULL, NULL);
+ }
+
// v: vars
ABORTING(set_ref_in_ht)(&vimvarht, copyID, NULL);
@@ -6000,7 +5221,7 @@ bool garbage_collect(void)
if (did_free_funccal) {
// When a funccal was freed some more items might be garbage
// collected, so run again.
- (void)garbage_collect();
+ (void)garbage_collect(testing);
}
} else if (p_verbose > 0) {
verb_msg((char_u *)_(
@@ -6012,7 +5233,7 @@ bool garbage_collect(void)
/// Free lists and dictionaries that are no longer referenced.
///
-/// Note: This function may only be called from garbage_collect().
+/// @note This function may only be called from garbage_collect().
///
/// @param copyID Free lists/dictionaries that don't have this ID.
/// @return true, if something was freed.
@@ -6025,19 +5246,19 @@ static int free_unref_items(int copyID)
// Let all "free" functions know that we are here. This means no
// dictionaries, lists, or jobs are to be freed, because we will
// do that here.
- in_free_unref_items = true;
+ tv_in_free_unref_items = true;
// PASS 1: free the contents of the items. We don't free the items
// themselves yet, so that it is possible to decrement refcount counters.
// Go through the list of dicts and free items without the copyID.
// Don't free dicts that are referenced internally.
- for (dict_T *dd = first_dict; dd != NULL; dd = dd->dv_used_next) {
+ for (dict_T *dd = gc_first_dict; dd != NULL; dd = dd->dv_used_next) {
if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) {
// Free the Dictionary and ordinary items it contains, but don't
// recurse into Lists and Dictionaries, they will be in the list
// of dicts or list of lists.
- dict_free_contents(dd);
+ tv_dict_free_contents(dd);
did_free = true;
}
}
@@ -6045,36 +5266,36 @@ static int free_unref_items(int copyID)
// Go through the list of lists and free items without the copyID.
// But don't free a list that has a watcher (used in a for loop), these
// are not referenced anywhere.
- for (list_T *ll = first_list; ll != NULL; ll = ll->lv_used_next) {
+ for (list_T *ll = gc_first_list; ll != NULL; ll = ll->lv_used_next) {
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_contents(ll);
+ tv_list_free_contents(ll);
did_free = true;
}
}
// PASS 2: free the items themselves.
- for (dd = first_dict; dd != NULL; dd = dd_next) {
+ for (dd = gc_first_dict; dd != NULL; dd = dd_next) {
dd_next = dd->dv_used_next;
if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) {
- dict_free_dict(dd);
+ tv_dict_free_dict(dd);
}
}
- for (ll = first_list; ll != NULL; ll = ll_next) {
+ for (ll = gc_first_list; ll != NULL; ll = ll_next) {
ll_next = ll->lv_used_next;
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_list(ll);
+ tv_list_free_list(ll);
}
}
- in_free_unref_items = false;
+ tv_in_free_unref_items = false;
return did_free;
}
@@ -6097,14 +5318,10 @@ bool set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack)
// Mark each item in the hashtab. If the item contains a hashtab
// it is added to ht_stack, if it contains a list it is added to
// list_stack.
- int todo = (int)cur_ht->ht_used;
- for (hashitem_T *hi = cur_ht->ht_array; todo > 0; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- --todo;
- abort = abort || set_ref_in_item(&HI2DI(hi)->di_tv, copyID, &ht_stack,
- list_stack);
- }
- }
+ HASHTAB_ITER(cur_ht, hi, {
+ abort = abort || set_ref_in_item(
+ &TV_DICT_HI2DI(hi)->di_tv, copyID, &ht_stack, list_stack);
+ });
}
if (ht_stack == NULL) {
@@ -6196,21 +5413,10 @@ bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack,
QUEUE *w = NULL;
DictWatcher *watcher = NULL;
QUEUE_FOREACH(w, &dd->watchers) {
- watcher = dictwatcher_node_data(w);
+ watcher = tv_dict_watcher_node_data(w);
set_ref_in_callback(&watcher->callback, copyID, ht_stack, list_stack);
}
}
- if (tv->v_type == VAR_PARTIAL) {
- partial_T *pt = tv->vval.v_partial;
- int i;
-
- if (pt != NULL) {
- for (i = 0; i < pt->pt_argc; i++) {
- abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID,
- ht_stack, list_stack);
- }
- }
- }
break;
}
@@ -6240,6 +5446,7 @@ bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack,
// A partial does not have a copyID, because it cannot contain itself.
if (pt != NULL) {
+ abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID);
if (pt->pt_dict != NULL) {
typval_T dtv;
@@ -6256,6 +5463,8 @@ bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack,
break;
}
case VAR_FUNC:
+ abort = set_ref_in_func(tv->vval.v_string, NULL, copyID);
+ break;
case VAR_UNKNOWN:
case VAR_SPECIAL:
case VAR_FLOAT:
@@ -6267,6 +5476,29 @@ bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack,
return abort;
}
+/// Set "copyID" in all functions available by name.
+bool set_ref_in_functions(int copyID)
+{
+ int todo;
+ hashitem_T *hi = NULL;
+ bool abort = false;
+ ufunc_T *fp;
+
+ todo = (int)func_hashtab.ht_used;
+ for (hi = func_hashtab.ht_array; todo > 0 && !got_int; hi++) {
+ if (!HASHITEM_EMPTY(hi)) {
+ todo--;
+ fp = HI2UF(hi);
+ if (!func_name_refcount(fp->uf_name)) {
+ abort = abort || set_ref_in_func(NULL, fp, copyID);
+ }
+ }
+ }
+ return abort;
+}
+
+
+
/// Mark all lists and dicts referenced in given mark
///
/// @returns true if setting references failed somehow.
@@ -6313,447 +5545,17 @@ static inline bool set_ref_dict(dict_T *dict, int copyID)
return false;
}
-/*
- * Allocate an empty header for a dictionary.
- */
-dict_T *dict_alloc(void) FUNC_ATTR_NONNULL_RET
-{
- dict_T *d = xmalloc(sizeof(dict_T));
-
- /* Add the dict to the list of dicts for garbage collection. */
- if (first_dict != NULL)
- first_dict->dv_used_prev = d;
- d->dv_used_next = first_dict;
- d->dv_used_prev = NULL;
- first_dict = d;
-
- hash_init(&d->dv_hashtab);
- d->dv_lock = 0;
- d->dv_scope = 0;
- d->dv_refcount = 0;
- d->dv_copyID = 0;
- QUEUE_INIT(&d->watchers);
-
- return d;
-}
-
-/*
- * Allocate an empty dict for a return value.
- */
-static void rettv_dict_alloc(typval_T *rettv)
-{
- dict_T *d = dict_alloc();
-
- rettv->vval.v_dict = d;
- rettv->v_type = VAR_DICT;
- rettv->v_lock = VAR_UNLOCKED;
- d->dv_refcount++;
-}
-
-/// Clear all the keys of a Dictionary. "d" remains a valid empty Dictionary.
-///
-/// @param d The Dictionary to clear
-void dict_clear(dict_T *d)
- FUNC_ATTR_NONNULL_ALL
-{
- hash_lock(&d->dv_hashtab);
- assert(d->dv_hashtab.ht_locked > 0);
-
- size_t todo = d->dv_hashtab.ht_used;
- for (hashitem_T *hi = d->dv_hashtab.ht_array; todo > 0; hi++) {
- if (!HASHITEM_EMPTY(hi)) {
- dictitem_free(HI2DI(hi));
- hash_remove(&d->dv_hashtab, hi);
- todo--;
- }
- }
-
- hash_unlock(&d->dv_hashtab);
-}
-
-
-/*
- * Unreference a Dictionary: decrement the reference count and free it when it
- * becomes zero.
- */
-void dict_unref(dict_T *d)
-{
- if (d != NULL && --d->dv_refcount <= 0) {
- dict_free(d);
- }
-}
-
-/// Free a Dictionary, including all items it contains.
-/// Ignores the reference count.
-static void dict_free_contents(dict_T *d) {
- int todo;
- hashitem_T *hi;
- dictitem_T *di;
-
-
- /* Lock the hashtab, we don't want it to resize while freeing items. */
- hash_lock(&d->dv_hashtab);
- assert(d->dv_hashtab.ht_locked > 0);
- todo = (int)d->dv_hashtab.ht_used;
- for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- /* Remove the item before deleting it, just in case there is
- * something recursive causing trouble. */
- di = HI2DI(hi);
- hash_remove(&d->dv_hashtab, hi);
- clear_tv(&di->di_tv);
- xfree(di);
- --todo;
- }
- }
-
- while (!QUEUE_EMPTY(&d->watchers)) {
- QUEUE *w = QUEUE_HEAD(&d->watchers);
- DictWatcher *watcher = dictwatcher_node_data(w);
- dictwatcher_free(watcher);
- QUEUE_REMOVE(w);
- }
-
- hash_clear(&d->dv_hashtab);
-}
-
-static void dict_free_dict(dict_T *d) {
- // 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;
- }
-
- xfree(d);
-}
-
-void dict_free(dict_T *d) {
- if (!in_free_unref_items) {
- dict_free_contents(d);
- dict_free_dict(d);
- }
-}
-
-/*
- * Allocate a Dictionary item.
- * The "key" is copied to the new item.
- * Note that the value of the item "di_tv" still needs to be initialized!
- */
-dictitem_T *dictitem_alloc(char_u *key) FUNC_ATTR_NONNULL_RET
-{
- dictitem_T *di = xmalloc(offsetof(dictitem_T, di_key) + STRLEN(key) + 1);
-#ifndef __clang_analyzer__
- STRCPY(di->di_key, key);
-#endif
- di->di_flags = DI_FLAGS_ALLOC;
- return di;
-}
-
-/*
- * Make a copy of a Dictionary item.
- */
-static dictitem_T *dictitem_copy(dictitem_T *org) FUNC_ATTR_NONNULL_RET
-{
- dictitem_T *di = xmalloc(sizeof(dictitem_T) + STRLEN(org->di_key));
-
- STRCPY(di->di_key, org->di_key);
- di->di_flags = DI_FLAGS_ALLOC;
- copy_tv(&org->di_tv, &di->di_tv);
-
- return di;
-}
-
-/*
- * Remove item "item" from Dictionary "dict" and free it.
- */
-static void dictitem_remove(dict_T *dict, dictitem_T *item)
+static bool set_ref_in_funccal(funccall_T *fc, int copyID)
{
- hashitem_T *hi;
-
- hi = hash_find(&dict->dv_hashtab, item->di_key);
- if (HASHITEM_EMPTY(hi)) {
- EMSG2(_(e_intern2), "dictitem_remove()");
- } else {
- hash_remove(&dict->dv_hashtab, hi);
- }
- dictitem_free(item);
-}
-
-/*
- * Free a dict item. Also clears the value.
- */
-void dictitem_free(dictitem_T *item)
-{
- clear_tv(&item->di_tv);
- if (item->di_flags & DI_FLAGS_ALLOC) {
- xfree(item);
- }
-}
-
-/// Make a copy of dictionary
-///
-/// @param[in] conv If non-NULL, then all internal strings will be converted.
-/// @param[in] orig Original dictionary to copy.
-/// @param[in] deep If false, then shallow copy will be done.
-/// @param[in] copyID See var_item_copy().
-///
-/// @return Copied dictionary. May be NULL in case original dictionary is NULL
-/// or some failure happens. The refcount of the new dictionary is set
-/// to 1.
-static dict_T *dict_copy(const vimconv_T *const conv,
- dict_T *const orig,
- const bool deep,
- const int copyID)
-{
- dictitem_T *di;
- int todo;
- hashitem_T *hi;
-
- if (orig == NULL)
- return NULL;
-
- dict_T *copy = dict_alloc();
- {
- if (copyID != 0) {
- orig->dv_copyID = copyID;
- orig->dv_copydict = copy;
- }
- todo = (int)orig->dv_hashtab.ht_used;
- for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- --todo;
-
- if (conv == NULL || conv->vc_type == CONV_NONE) {
- di = dictitem_alloc(hi->hi_key);
- } else {
- char *const key = (char *) string_convert((vimconv_T *) conv,
- hi->hi_key, NULL);
- if (key == NULL) {
- di = dictitem_alloc(hi->hi_key);
- } else {
- di = dictitem_alloc((char_u *) key);
- xfree(key);
- }
- }
- if (deep) {
- if (var_item_copy(conv, &HI2DI(hi)->di_tv, &di->di_tv, deep,
- copyID) == FAIL) {
- xfree(di);
- break;
- }
- } else
- copy_tv(&HI2DI(hi)->di_tv, &di->di_tv);
- if (dict_add(copy, di) == FAIL) {
- dictitem_free(di);
- break;
- }
- }
- }
-
- ++copy->dv_refcount;
- if (todo > 0) {
- dict_unref(copy);
- copy = NULL;
- }
- }
-
- return copy;
-}
-
-/*
- * Add item "item" to Dictionary "d".
- * Returns FAIL when key already exists.
- */
-int dict_add(dict_T *d, dictitem_T *item)
-{
- return hash_add(&d->dv_hashtab, item->di_key);
-}
-
-/*
- * Add a number or string entry to dictionary "d".
- * When "str" is NULL use number "nr", otherwise use "str".
- * Returns FAIL when key already exists.
- */
-int dict_add_nr_str(dict_T *d, char *key, long nr, char_u *str)
-{
- dictitem_T *item;
-
- item = dictitem_alloc((char_u *)key);
- item->di_tv.v_lock = 0;
- if (str == NULL) {
- item->di_tv.v_type = VAR_NUMBER;
- item->di_tv.vval.v_number = nr;
- } else {
- item->di_tv.v_type = VAR_STRING;
- item->di_tv.vval.v_string = vim_strsave(str);
- }
- if (dict_add(d, item) == FAIL) {
- dictitem_free(item);
- return FAIL;
- }
- return OK;
-}
-
-/*
- * Add a list entry to dictionary "d".
- * Returns FAIL when key already exists.
- */
-int dict_add_list(dict_T *d, char *key, list_T *list)
-{
- dictitem_T *item = dictitem_alloc((char_u *)key);
-
- item->di_tv.v_lock = 0;
- item->di_tv.v_type = VAR_LIST;
- item->di_tv.vval.v_list = list;
- if (dict_add(d, item) == FAIL) {
- dictitem_free(item);
- return FAIL;
- }
- ++list->lv_refcount;
- return OK;
-}
-
-/// Add a dict entry to dictionary "d".
-/// Returns FAIL when out of memory and when key already exists.
-int dict_add_dict(dict_T *d, char *key, dict_T *dict)
-{
- dictitem_T *item = dictitem_alloc((char_u *)key);
-
- item->di_tv.v_lock = 0;
- item->di_tv.v_type = VAR_DICT;
- item->di_tv.vval.v_dict = dict;
- if (dict_add(d, item) == FAIL) {
- dictitem_free(item);
- return FAIL;
- }
- dict->dv_refcount++;
- return OK;
-}
-
-/// Set all existing keys in "dict" as read-only.
-///
-/// This does not protect against adding new keys to the Dictionary.
-///
-/// @param dict The dict whose keys should be frozen
-void dict_set_keys_readonly(dict_T *dict)
- FUNC_ATTR_NONNULL_ALL
-{
- size_t todo = dict->dv_hashtab.ht_used;
- for (hashitem_T *hi = dict->dv_hashtab.ht_array; todo > 0 ; hi++) {
- if (HASHITEM_EMPTY(hi)) {
- continue;
- }
- todo--;
- HI2DI(hi)->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX;
- }
-}
-
-/*
- * Get the number of items in a Dictionary.
- */
-static long dict_len(dict_T *d)
-{
- if (d == NULL)
- return 0L;
- return (long)d->dv_hashtab.ht_used;
-}
-
-/*
- * Find item "key[len]" in Dictionary "d".
- * If "len" is negative use strlen(key).
- * Returns NULL when not found.
- */
-dictitem_T *dict_find(dict_T *d, char_u *key, int len)
-{
-#define AKEYLEN 200
- char_u buf[AKEYLEN];
- char_u *akey;
- char_u *tofree = NULL;
- hashitem_T *hi;
-
- if (d == NULL) {
- return NULL;
- }
- if (len < 0) {
- akey = key;
- } else if (len >= AKEYLEN) {
- tofree = akey = vim_strnsave(key, len);
- } else {
- /* Avoid a malloc/free by using buf[]. */
- STRLCPY(buf, key, len + 1);
- akey = buf;
- }
-
- hi = hash_find(&d->dv_hashtab, akey);
- xfree(tofree);
- if (HASHITEM_EMPTY(hi))
- return NULL;
- return HI2DI(hi);
-}
-
-/// Get a function from a dictionary
-/// @param[out] result The address where a pointer to the wanted callback
-/// will be left.
-/// @return true/false on success/failure.
-static bool get_dict_callback(dict_T *d, char *key, Callback *result)
-{
- dictitem_T *di = dict_find(d, (uint8_t *)key, -1);
-
- if (di == NULL) {
- result->type = kCallbackNone;
- return true;
- }
-
- if (di->di_tv.v_type != VAR_FUNC && di->di_tv.v_type != VAR_STRING
- && di->di_tv.v_type != VAR_PARTIAL) {
- EMSG(_("Argument is not a function or function name"));
- result->type = kCallbackNone;
- return false;
- }
-
- typval_T tv;
- copy_tv(&di->di_tv, &tv);
- set_selfdict(&tv, d);
- bool res = callback_from_typval(result, &tv);
- clear_tv(&tv);
- return res;
-}
-
-/// Get a string item from a dictionary.
-///
-/// @param save whether memory should be allocated for the return value
-///
-/// @return the entry or NULL if the entry doesn't exist.
-char_u *get_dict_string(dict_T *d, char *key, bool save)
-{
- dictitem_T *di;
- char_u *s;
-
- di = dict_find(d, (char_u *)key, -1);
- if (di == NULL) {
- return NULL;
- }
- s = get_tv_string(&di->di_tv);
- if (save) {
- s = vim_strsave(s);
- }
- return s;
-}
+ bool abort = false;
-/// Get a number item from a dictionary.
-///
-/// @return the entry or 0 if the entry doesn't exist.
-long get_dict_number(dict_T *d, char *key)
-{
- dictitem_T *di = dict_find(d, (char_u *)key, -1);
- if (di == NULL) {
- return 0;
+ if (fc->fc_copyID != copyID) {
+ fc->fc_copyID = copyID;
+ abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL);
+ abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL);
+ abort = abort || set_ref_in_func(NULL, fc->func, copyID);
}
- return get_tv_number(&di->di_tv);
+ return abort;
}
/*
@@ -6768,7 +5570,7 @@ static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate)
char_u *key = NULL;
dictitem_T *item;
char_u *start = skipwhite(*arg + 1);
- char_u buf[NUMBUFLEN];
+ char buf[NUMBUFLEN];
/*
* First check if it's not a curly-braces thing: {expr}.
@@ -6785,7 +5587,7 @@ static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate)
}
if (evaluate) {
- d = dict_alloc();
+ d = tv_dict_alloc();
}
tvkey.v_type = VAR_UNKNOWN;
tv.v_type = VAR_UNKNOWN;
@@ -6796,38 +5598,39 @@ static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate)
goto failret;
if (**arg != ':') {
EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg);
- clear_tv(&tvkey);
+ tv_clear(&tvkey);
goto failret;
}
if (evaluate) {
- key = get_tv_string_buf_chk(&tvkey, buf);
+ key = (char_u *)tv_get_string_buf_chk(&tvkey, buf);
if (key == NULL) {
- // "key" is NULL when get_tv_string_buf_chk() gave an errmsg
- clear_tv(&tvkey);
+ // "key" is NULL when tv_get_string_buf_chk() gave an errmsg
+ tv_clear(&tvkey);
goto failret;
}
}
*arg = skipwhite(*arg + 1);
- if (eval1(arg, &tv, evaluate) == FAIL) { /* recursive! */
- if (evaluate)
- clear_tv(&tvkey);
+ if (eval1(arg, &tv, evaluate) == FAIL) { // Recursive!
+ if (evaluate) {
+ tv_clear(&tvkey);
+ }
goto failret;
}
if (evaluate) {
- item = dict_find(d, key, -1);
+ item = tv_dict_find(d, (const char *)key, -1);
if (item != NULL) {
EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key);
- clear_tv(&tvkey);
- clear_tv(&tv);
+ tv_clear(&tvkey);
+ tv_clear(&tv);
goto failret;
}
- item = dictitem_alloc(key);
- clear_tv(&tvkey);
+ item = tv_dict_item_alloc((const char *)key);
+ tv_clear(&tvkey);
item->di_tv = tv;
item->di_tv.v_lock = 0;
- if (dict_add(d, item) == FAIL) {
- dictitem_free(item);
+ if (tv_dict_add(d, item) == FAIL) {
+ tv_dict_item_free(item);
}
}
@@ -6844,7 +5647,7 @@ static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate)
EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg);
failret:
if (evaluate) {
- dict_free(d);
+ tv_dict_free(d);
}
return FAIL;
}
@@ -6859,6 +5662,232 @@ failret:
return OK;
}
+/// Get function arguments.
+static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs,
+ int *varargs, bool skip)
+{
+ bool mustend = false;
+ char_u *arg = *argp;
+ char_u *p = arg;
+ int c;
+ int i;
+
+ if (newargs != NULL) {
+ ga_init(newargs, (int)sizeof(char_u *), 3);
+ }
+
+ if (varargs != NULL) {
+ *varargs = false;
+ }
+
+ // Isolate the arguments: "arg1, arg2, ...)"
+ while (*p != endchar) {
+ if (p[0] == '.' && p[1] == '.' && p[2] == '.') {
+ if (varargs != NULL) {
+ *varargs = true;
+ }
+ p += 3;
+ mustend = true;
+ } else {
+ arg = p;
+ while (ASCII_ISALNUM(*p) || *p == '_') {
+ p++;
+ }
+ if (arg == p || isdigit(*arg)
+ || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0)
+ || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) {
+ if (!skip) {
+ EMSG2(_("E125: Illegal argument: %s"), arg);
+ }
+ break;
+ }
+ if (newargs != NULL) {
+ ga_grow(newargs, 1);
+ c = *p;
+ *p = NUL;
+ arg = vim_strsave(arg);
+ if (arg == NULL) {
+ *p = c;
+ goto err_ret;
+ }
+
+ // Check for duplicate argument name.
+ for (i = 0; i < newargs->ga_len; i++) {
+ if (STRCMP(((char_u **)(newargs->ga_data))[i], arg) == 0) {
+ EMSG2(_("E853: Duplicate argument name: %s"), arg);
+ xfree(arg);
+ goto err_ret;
+ }
+ }
+ ((char_u **)(newargs->ga_data))[newargs->ga_len] = arg;
+ newargs->ga_len++;
+
+ *p = c;
+ }
+ if (*p == ',') {
+ p++;
+ } else {
+ mustend = true;
+ }
+ }
+ p = skipwhite(p);
+ if (mustend && *p != endchar) {
+ if (!skip) {
+ EMSG2(_(e_invarg2), *argp);
+ }
+ break;
+ }
+ }
+ if (*p != endchar) {
+ goto err_ret;
+ }
+ p++; // skip "endchar"
+
+ *argp = p;
+ return OK;
+
+err_ret:
+ if (newargs != NULL) {
+ ga_clear_strings(newargs);
+ }
+ return FAIL;
+}
+
+/// Register function "fp" as using "current_funccal" as its scope.
+static void register_closure(ufunc_T *fp)
+{
+ if (fp->uf_scoped == current_funccal) {
+ // no change
+ return;
+ }
+ funccal_unref(fp->uf_scoped, fp, false);
+ fp->uf_scoped = current_funccal;
+ current_funccal->fc_refcount++;
+ ga_grow(&current_funccal->fc_funcs, 1);
+ ((ufunc_T **)current_funccal->fc_funcs.ga_data)
+ [current_funccal->fc_funcs.ga_len++] = fp;
+}
+
+/// Parse a lambda expression and get a Funcref from "*arg".
+///
+/// @return OK or FAIL. Returns NOTDONE for dict or {expr}.
+static int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate)
+{
+ garray_T newargs = GA_EMPTY_INIT_VALUE;
+ garray_T *pnewargs;
+ ufunc_T *fp = NULL;
+ int varargs;
+ int ret;
+ char_u *start = skipwhite(*arg + 1);
+ char_u *s, *e;
+ static int lambda_no = 0;
+ int *old_eval_lavars = eval_lavars_used;
+ int eval_lavars = false;
+
+ // First, check if this is a lambda expression. "->" must exists.
+ ret = get_function_args(&start, '-', NULL, NULL, true);
+ if (ret == FAIL || *start != '>') {
+ return NOTDONE;
+ }
+
+ // Parse the arguments again.
+ if (evaluate) {
+ pnewargs = &newargs;
+ } else {
+ pnewargs = NULL;
+ }
+ *arg = skipwhite(*arg + 1);
+ ret = get_function_args(arg, '-', pnewargs, &varargs, false);
+ if (ret == FAIL || **arg != '>') {
+ goto errret;
+ }
+
+ // Set up a flag for checking local variables and arguments.
+ if (evaluate) {
+ eval_lavars_used = &eval_lavars;
+ }
+
+ // Get the start and the end of the expression.
+ *arg = skipwhite(*arg + 1);
+ s = *arg;
+ ret = skip_expr(arg);
+ if (ret == FAIL) {
+ goto errret;
+ }
+ e = *arg;
+ *arg = skipwhite(*arg);
+ if (**arg != '}') {
+ goto errret;
+ }
+ (*arg)++;
+
+ if (evaluate) {
+ int len, flags = 0;
+ char_u *p;
+ char_u name[20];
+ partial_T *pt;
+ garray_T newlines;
+
+ lambda_no++;
+ snprintf((char *)name, sizeof(name), "<lambda>%d", lambda_no);
+
+ fp = (ufunc_T *)xcalloc(1, sizeof(ufunc_T) + STRLEN(name));
+ pt = (partial_T *)xcalloc(1, sizeof(partial_T));
+ if (pt == NULL) {
+ xfree(fp);
+ goto errret;
+ }
+
+ ga_init(&newlines, (int)sizeof(char_u *), 1);
+ ga_grow(&newlines, 1);
+
+ // Add "return " before the expression.
+ len = 7 + e - s + 1;
+ p = (char_u *)xmalloc(len);
+ ((char_u **)(newlines.ga_data))[newlines.ga_len++] = p;
+ STRCPY(p, "return ");
+ STRLCPY(p + 7, s, e - s + 1);
+
+ fp->uf_refcount = 1;
+ STRCPY(fp->uf_name, name);
+ hash_add(&func_hashtab, UF2HIKEY(fp));
+ fp->uf_args = newargs;
+ fp->uf_lines = newlines;
+ if (current_funccal != NULL && eval_lavars) {
+ flags |= FC_CLOSURE;
+ register_closure(fp);
+ } else {
+ fp->uf_scoped = NULL;
+ }
+
+ fp->uf_tml_count = NULL;
+ fp->uf_tml_total = NULL;
+ fp->uf_tml_self = NULL;
+ fp->uf_profiling = false;
+ if (prof_def_func()) {
+ func_do_profile(fp);
+ }
+ fp->uf_varargs = true;
+ fp->uf_flags = flags;
+ fp->uf_calls = 0;
+ fp->uf_script_ID = current_SID;
+
+ pt->pt_func = fp;
+ pt->pt_refcount = 1;
+ rettv->vval.v_partial = pt;
+ rettv->v_type = VAR_PARTIAL;
+ }
+
+ eval_lavars_used = old_eval_lavars;
+ return OK;
+
+errret:
+ ga_clear_strings(&newargs);
+ xfree(fp);
+ eval_lavars_used = old_eval_lavars;
+ return FAIL;
+}
+
/// Convert the string to a floating point number
///
/// This uses strtod(). setlocale(LC_NUMERIC, "C") has been used earlier to
@@ -6873,6 +5902,19 @@ size_t string2float(const char *const text, float_T *const ret_value)
{
char *s = NULL;
+ // MS-Windows does not deal with "inf" and "nan" properly
+ if (STRNICMP(text, "inf", 3) == 0) {
+ *ret_value = INFINITY;
+ return 3;
+ }
+ if (STRNICMP(text, "-inf", 3) == 0) {
+ *ret_value = -INFINITY;
+ return 4;
+ }
+ if (STRNICMP(text, "nan", 3) == 0) {
+ *ret_value = NAN;
+ return 3;
+ }
*ret_value = strtod(text, &s);
return (size_t) (s - text);
}
@@ -6893,7 +5935,7 @@ static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate)
++*arg;
name = *arg;
- len = get_env_len(arg);
+ len = get_env_len((const char_u **)arg);
if (evaluate) {
if (len == 0) {
@@ -6981,64 +6023,67 @@ char_u *get_expr_name(expand_T *xp, int idx)
return get_user_var_name(xp, ++intidx);
}
-
-
-
/// Find internal function in hash functions
///
/// @param[in] name Name of the function.
///
/// Returns pointer to the function definition or NULL if not found.
-static VimLFuncDef *find_internal_func(const char *const name)
+static const VimLFuncDef *find_internal_func(const char *const name)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE FUNC_ATTR_NONNULL_ALL
{
size_t len = strlen(name);
return find_internal_func_gperf(name, len);
}
-/// Check if "name" is a variable of type VAR_FUNC. If so, return the function
-/// name it contains, otherwise return "name".
-/// If "partialp" is not NULL, and "name" is of type VAR_PARTIAL also set
-/// "partialp".
-static char_u *deref_func_name(
- char_u *name, int *lenp,
- partial_T **partialp, bool no_autoload
-)
+/// Return name of the function corresponding to `name`
+///
+/// If `name` points to variable that is either a function or partial then
+/// corresponding function name is returned. Otherwise it returns `name` itself.
+///
+/// @param[in] name Function name to check.
+/// @param[in,out] lenp Location where length of the returned name is stored.
+/// Must be set to the length of the `name` argument.
+/// @param[out] partialp Location where partial will be stored if found
+/// function appears to be a partial. May be NULL if this
+/// is not needed.
+/// @param[in] no_autoload If true, do not source autoload scripts if function
+/// was not found.
+///
+/// @return name of the function.
+static char_u *deref_func_name(const char *name, int *lenp,
+ partial_T **const partialp, bool no_autoload)
+ FUNC_ATTR_NONNULL_ARG(1, 2)
{
- dictitem_T *v;
- int cc;
if (partialp != NULL) {
*partialp = NULL;
}
- cc = name[*lenp];
- name[*lenp] = NUL;
- v = find_var(name, NULL, no_autoload);
- name[*lenp] = cc;
+ dictitem_T *const v = find_var(name, (size_t)(*lenp), NULL, no_autoload);
if (v != NULL && v->di_tv.v_type == VAR_FUNC) {
- if (v->di_tv.vval.v_string == NULL) {
+ if (v->di_tv.vval.v_string == NULL) { // just in case
*lenp = 0;
- return (char_u *)""; /* just in case */
+ return (char_u *)"";
}
*lenp = (int)STRLEN(v->di_tv.vval.v_string);
return v->di_tv.vval.v_string;
}
if (v != NULL && v->di_tv.v_type == VAR_PARTIAL) {
- partial_T *pt = v->di_tv.vval.v_partial;
+ partial_T *const pt = v->di_tv.vval.v_partial;
- if (pt == NULL) {
+ if (pt == NULL) { // just in case
*lenp = 0;
- return (char_u *)""; // just in case
+ return (char_u *)"";
}
if (partialp != NULL) {
*partialp = pt;
}
- *lenp = (int)STRLEN(pt->pt_name);
- return pt->pt_name;
+ char_u *s = partial_name(pt);
+ *lenp = (int)STRLEN(s);
+ return s;
}
- return name;
+ return (char_u *)name;
}
/*
@@ -7087,9 +6132,24 @@ get_func_tv (
ret = FAIL;
if (ret == OK) {
- ret = call_func(name, len, rettv, argcount, argvars,
+ int i = 0;
+
+ if (get_vim_var_nr(VV_TESTING)) {
+ // Prepare for calling garbagecollect_for_testing(), need to know
+ // what variables are used on the call stack.
+ if (funcargs.ga_itemsize == 0) {
+ ga_init(&funcargs, (int)sizeof(typval_T *), 50);
+ }
+ for (i = 0; i < argcount; i++) {
+ ga_grow(&funcargs, 1);
+ ((typval_T **)funcargs.ga_data)[funcargs.ga_len++] = &argvars[i];
+ }
+ }
+ ret = call_func(name, len, rettv, argcount, argvars, NULL,
firstline, lastline, doesrange, evaluate,
partial, selfdict);
+
+ funcargs.ga_len -= i;
} else if (!aborting()) {
if (argcount == MAX_FUNC_ARGS) {
emsg_funcname(N_("E740: Too many arguments for function %s"), name);
@@ -7098,40 +6158,57 @@ get_func_tv (
}
}
- while (--argcount >= 0)
- clear_tv(&argvars[argcount]);
+ while (--argcount >= 0) {
+ tv_clear(&argvars[argcount]);
+ }
*arg = skipwhite(argp);
return ret;
}
-#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
-#define ERROR_BOTH 7
+typedef enum {
+ ERROR_UNKNOWN = 0,
+ ERROR_TOOMANY,
+ ERROR_TOOFEW,
+ ERROR_SCRIPT,
+ ERROR_DICT,
+ ERROR_NONE,
+ ERROR_OTHER,
+ ERROR_BOTH,
+ ERROR_DELETED,
+} FnameTransError;
+
#define FLEN_FIXED 40
-/// 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[FLEN_FIXED + 1]" when it fits, otherwise allocate memory
-/// (slow).
-static char_u *
-fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error) {
- int llen;
+/// In a script transform script-local names into actually used names
+///
+/// Transforms "<SID>" and "s:" prefixes to `K_SNR {N}` (e.g. K_SNR "123") and
+/// "<SNR>" prefix to `K_SNR`. Uses `fname_buf` buffer that is supposed to have
+/// #FLEN_FIXED + 1 length when it fits, otherwise it allocates memory.
+///
+/// @param[in] name Name to transform.
+/// @param fname_buf Buffer to save resulting function name to, if it fits.
+/// Must have at least #FLEN_FIXED + 1 length.
+/// @param[out] tofree Location where pointer to an allocated memory is saved
+/// in case result does not fit into fname_buf.
+/// @param[out] error Location where error type is saved, @see
+/// FnameTransError.
+///
+/// @return transformed name: either `fname_buf` or a pointer to an allocated
+/// memory.
+static char_u *fname_trans_sid(const char_u *const name,
+ char_u *const fname_buf,
+ char_u **const tofree, int *const error)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
char_u *fname;
- int i;
-
- llen = eval_fname_script(name);
+ const int llen = eval_fname_script((const char *)name);
if (llen > 0) {
fname_buf[0] = K_SPECIAL;
fname_buf[1] = KS_EXTRA;
fname_buf[2] = (int)KE_SNR;
- i = 3;
- if (eval_fname_sid(name)) { // "<SID>" or "s:"
+ int i = 3;
+ if (eval_fname_sid((const char *)name)) { // "<SID>" or "s:"
if (current_SID <= 0) {
*error = ERROR_SCRIPT;
} else {
@@ -7154,23 +6231,60 @@ fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error) {
}
}
} else {
- fname = name;
+ fname = (char_u *)name;
}
return fname;
}
+/// Mark all lists and dicts referenced through function "name" with "copyID".
+/// "list_stack" is used to add lists to be marked. Can be NULL.
+/// "ht_stack" is used to add hashtabs to be marked. Can be NULL.
+///
+/// @return true if setting references failed somehow.
+bool set_ref_in_func(char_u *name, ufunc_T *fp_in, int copyID)
+{
+ ufunc_T *fp = fp_in;
+ funccall_T *fc;
+ int error = ERROR_NONE;
+ char_u fname_buf[FLEN_FIXED + 1];
+ char_u *tofree = NULL;
+ char_u *fname;
+ bool abort = false;
+ if (name == NULL && fp_in == NULL) {
+ return false;
+ }
+
+ if (fp_in == NULL) {
+ fname = fname_trans_sid(name, fname_buf, &tofree, &error);
+ fp = find_func(fname);
+ }
+ if (fp != NULL) {
+ for (fc = fp->uf_scoped; fc != NULL; fc = fc->func->uf_scoped) {
+ abort = abort || set_ref_in_funccal(fc, copyID);
+ }
+ }
+ xfree(tofree);
+ return abort;
+}
+
/// Call a function with its resolved parameters
+///
+/// "argv_func", when not NULL, can be used to fill in arguments only when the
+/// invoked function uses them. It is called like this:
+/// new_argcount = argv_func(current_argcount, argv, called_func_argcount)
+///
/// Return FAIL when the function can't be called, OK otherwise.
/// Also returns OK when an error was encountered while executing the function.
int
call_func(
- char_u *funcname, // name of the function
+ const char_u *funcname, // name of the function
int len, // length of "name"
typval_T *rettv, // return value goes here
int argcount_in, // number of "argvars"
typval_T *argvars_in, // vars for arguments, must have "argcount"
// PLUS ONE elements!
+ ArgvFunc argv_func, // function to fill in argvars
linenr_T firstline, // first line of range
linenr_T lastline, // last line of range
int *doesrange, // return: function handled range
@@ -7213,7 +6327,7 @@ call_func(
}
if (error == ERROR_NONE && partial->pt_argc > 0) {
for (argv_clear = 0; argv_clear < partial->pt_argc; argv_clear++) {
- copy_tv(&partial->pt_argv[argv_clear], &argv[argv_clear]);
+ tv_copy(&partial->pt_argv[argv_clear], &argv[argv_clear]);
}
for (int i = 0; i < argcount_in; i++) {
argv[i + argv_clear] = argvars_in[i];
@@ -7237,44 +6351,53 @@ call_func(
rettv->vval.v_number = 0;
error = ERROR_UNKNOWN;
- if (!builtin_function(rfname, -1)) {
- /*
- * User defined function.
- */
- fp = find_func(rfname);
+ if (!builtin_function((const char *)rfname, -1)) {
+ // User defined function.
+ if (partial != NULL && partial->pt_func != NULL) {
+ fp = partial->pt_func;
+ } else {
+ fp = find_func(rfname);
+ }
- /* Trigger FuncUndefined event, may load the function. */
+ // Trigger FuncUndefined event, may load the function.
if (fp == NULL
&& apply_autocmds(EVENT_FUNCUNDEFINED, rfname, rfname, TRUE, NULL)
&& !aborting()) {
/* executed an autocommand, search for the function again */
fp = find_func(rfname);
}
- /* Try loading a package. */
- if (fp == NULL && script_autoload(rfname, TRUE) && !aborting()) {
- /* loaded a package, search for the function again */
+ // Try loading a package.
+ if (fp == NULL && script_autoload((const char *)rfname, STRLEN(rfname),
+ true) && !aborting()) {
+ // Loaded a package, search for the function again.
fp = find_func(rfname);
}
- if (fp != NULL) {
- if (fp->uf_flags & FC_RANGE)
- *doesrange = TRUE;
- if (argcount < fp->uf_args.ga_len)
+ if (fp != NULL && (fp->uf_flags & FC_DELETED)) {
+ error = ERROR_DELETED;
+ } else if (fp != NULL) {
+ if (argv_func != NULL) {
+ argcount = argv_func(argcount, argvars, fp->uf_args.ga_len);
+ }
+ if (fp->uf_flags & FC_RANGE) {
+ *doesrange = true;
+ }
+ if (argcount < fp->uf_args.ga_len) {
error = ERROR_TOOFEW;
- else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len)
+ } else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) {
error = ERROR_TOOMANY;
- else if ((fp->uf_flags & FC_DICT) && selfdict == NULL)
+ } else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) {
error = ERROR_DICT;
- else {
+ } else {
// Call the user function.
call_user_func(fp, argcount, argvars, rettv, firstline, lastline,
- (fp->uf_flags & FC_DICT) ? selfdict : NULL);
+ (fp->uf_flags & FC_DICT) ? selfdict : NULL);
error = ERROR_NONE;
}
}
} else {
// Find the function name in the table, call its implementation.
- VimLFuncDef *const fdef = find_internal_func((char *)fname);
+ const VimLFuncDef *const fdef = find_internal_func((const char *)fname);
if (fdef != NULL) {
if (argcount < fdef->min_argc) {
error = ERROR_TOOFEW;
@@ -7311,6 +6434,9 @@ call_func(
case ERROR_UNKNOWN:
emsg_funcname(N_("E117: Unknown function: %s"), name);
break;
+ case ERROR_DELETED:
+ emsg_funcname(N_("E933: Function was deleted: %s"), name);
+ break;
case ERROR_TOOMANY:
emsg_funcname(e_toomanyarg, name);
break;
@@ -7330,7 +6456,7 @@ call_func(
}
while (argv_clear > 0) {
- clear_tv(&argv[--argv_clear]);
+ tv_clear(&argv[--argv_clear]);
}
xfree(tofree);
xfree(name);
@@ -7360,11 +6486,13 @@ static void emsg_funcname(char *ermsg, char_u *name)
*/
static int non_zero_arg(typval_T *argvars)
{
- return (argvars[0].v_type == VAR_NUMBER
- && argvars[0].vval.v_number != 0)
- || (argvars[0].v_type == VAR_STRING
- && argvars[0].vval.v_string != NULL
- && *argvars[0].vval.v_string != NUL);
+ return ((argvars[0].v_type == VAR_NUMBER
+ && argvars[0].vval.v_number != 0)
+ || (argvars[0].v_type == VAR_SPECIAL
+ && argvars[0].vval.v_special == kSpecialVarTrue)
+ || (argvars[0].v_type == VAR_STRING
+ && argvars[0].vval.v_string != NULL
+ && *argvars[0].vval.v_string != NUL));
}
/*********************************************
@@ -7372,24 +6500,6 @@ static int non_zero_arg(typval_T *argvars)
*/
-/*
- * Get the float value of "argvars[0]" into "f".
- * Returns FAIL when the argument is not a Number or Float.
- */
-static inline int get_float_arg(typval_T *argvars, float_T *f)
-{
- if (argvars[0].v_type == VAR_FLOAT) {
- *f = argvars[0].vval.v_float;
- return OK;
- }
- if (argvars[0].v_type == VAR_NUMBER) {
- *f = (float_T)argvars[0].vval.v_number;
- return OK;
- }
- EMSG(_("E808: Number or Float required"));
- return FAIL;
-}
-
// Apply a floating point C function on a typval with one float_T.
//
// Some versions of glibc on i386 have an optimization that makes it harder to
@@ -7401,7 +6511,7 @@ static void float_op_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
float_T (*function)(float_T) = (float_T (*)(float_T))fptr;
rettv->v_type = VAR_FLOAT;
- if (get_float_arg(argvars, &f) == OK) {
+ if (tv_get_float_chk(argvars, &f)) {
rettv->vval.v_float = function(f);
} else {
rettv->vval.v_float = 0.0;
@@ -7419,9 +6529,9 @@ static void api_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
Error err = ERROR_INIT;
- Object result = fn(INTERNAL_CALL, args, &err);
+ Object result = fn(VIML_INTERNAL_CALL, args, &err);
- if (err.set) {
+ if (ERROR_SET(&err)) {
nvim_err_writeln(cstr_as_string(err.msg));
goto end;
}
@@ -7433,6 +6543,7 @@ static void api_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
end:
api_free_array(args);
api_free_object(result);
+ api_clear_error(&err);
}
/*
@@ -7444,15 +6555,16 @@ static void f_abs(typval_T *argvars, typval_T *rettv, FunPtr fptr)
float_op_wrapper(argvars, rettv, (FunPtr)&fabs);
} else {
varnumber_T n;
- int error = FALSE;
+ bool error = false;
- n = get_tv_number_chk(&argvars[0], &error);
- if (error)
+ n = tv_get_number_chk(&argvars[0], &error);
+ if (error) {
rettv->vval.v_number = -1;
- else if (n > 0)
+ } else if (n > 0) {
rettv->vval.v_number = n;
- else
+ } else {
rettv->vval.v_number = -n;
+ }
}
}
@@ -7466,13 +6578,13 @@ static void f_add(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = 1; /* Default: Failed */
if (argvars[0].v_type == VAR_LIST) {
if ((l = argvars[0].vval.v_list) != NULL
- && !tv_check_lock(l->lv_lock,
- (char_u *)N_("add() argument"), true)) {
- list_append_tv(l, &argvars[1]);
- copy_tv(&argvars[0], rettv);
+ && !tv_check_lock(l->lv_lock, "add() argument", TV_TRANSLATE)) {
+ tv_list_append_tv(l, &argvars[1]);
+ tv_copy(&argvars[0], rettv);
}
- } else
+ } else {
EMSG(_(e_listreq));
+ }
}
/*
@@ -7480,8 +6592,8 @@ static void f_add(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_and(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
- & get_tv_number_chk(&argvars[1], NULL);
+ rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL)
+ & tv_get_number_chk(&argvars[1], NULL);
}
@@ -7499,7 +6611,6 @@ static void f_api_info(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_append(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
long lnum;
- char_u *line;
list_T *l = NULL;
listitem_T *li = NULL;
typval_T *tv;
@@ -7512,7 +6623,7 @@ static void f_append(typval_T *argvars, typval_T *rettv, FunPtr fptr)
u_sync(TRUE);
}
- lnum = get_tv_lnum(argvars);
+ lnum = tv_get_lnum(argvars);
if (lnum >= 0
&& lnum <= curbuf->b_ml.ml_line_count
&& u_save(lnum, lnum + 1) == OK) {
@@ -7523,21 +6634,23 @@ static void f_append(typval_T *argvars, typval_T *rettv, FunPtr fptr)
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 */
+ 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.
+ }
+ const char *const line = tv_get_string_chk(tv);
+ if (line == NULL) { // Type error.
+ rettv->vval.v_number = 1; // Failed.
break;
}
- ml_append(lnum + added, line, (colnr_T)0, FALSE);
- ++added;
- if (l == NULL)
+ ml_append(lnum + added, (char_u *)line, (colnr_T)0, false);
+ added++;
+ if (l == NULL) {
break;
+ }
li = li->li_next;
}
@@ -7582,16 +6695,19 @@ static void f_argv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int idx;
if (argvars[0].v_type != VAR_UNKNOWN) {
- idx = get_tv_number_chk(&argvars[0], NULL);
- if (idx >= 0 && idx < ARGCOUNT)
- rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx]));
- else
+ idx = (int)tv_get_number_chk(&argvars[0], NULL);
+ if (idx >= 0 && idx < ARGCOUNT) {
+ rettv->vval.v_string = (char_u *)xstrdup(
+ (const char *)alist_name(&ARGLIST[idx]));
+ } else {
rettv->vval.v_string = NULL;
+ }
rettv->v_type = VAR_STRING;
} else {
- rettv_list_alloc(rettv);
- for (idx = 0; idx < ARGCOUNT; ++idx) {
- list_append_string(rettv->vval.v_list, alist_name(&ARGLIST[idx]), -1);
+ tv_list_alloc_ret(rettv);
+ for (idx = 0; idx < ARGCOUNT; idx++) {
+ tv_list_append_string(rettv->vval.v_list,
+ (const char *)alist_name(&ARGLIST[idx]), -1);
}
}
}
@@ -7663,10 +6779,10 @@ static void assert_error(garray_T *gap)
if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL) {
// Make sure v:errors is a list.
- set_vim_var_list(VV_ERRORS, list_alloc());
+ set_vim_var_list(VV_ERRORS, tv_list_alloc());
}
- list_append_string(vimvars[VV_ERRORS].vv_list,
- gap->ga_data, gap->ga_len);
+ tv_list_append_string(vimvars[VV_ERRORS].vv_list,
+ (const char *)gap->ga_data, (ptrdiff_t)gap->ga_len);
}
static void assert_equal_common(typval_T *argvars, assert_type_T atype)
@@ -7695,12 +6811,23 @@ static void f_assert_notequal(typval_T *argvars, typval_T *rettv, FunPtr fptr)
assert_equal_common(argvars, ASSERT_NOTEQUAL);
}
+/// "assert_report(msg)
+static void f_assert_report(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ garray_T ga;
+
+ prepare_assert_error(&ga);
+ ga_concat(&ga, (const char_u *)tv_get_string(&argvars[0]));
+ assert_error(&ga);
+ ga_clear(&ga);
+}
+
/// "assert_exception(string[, msg])" function
static void f_assert_exception(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
garray_T ga;
- char *error = (char *)get_tv_string_chk(&argvars[0]);
+ const char *const error = tv_get_string_chk(&argvars[0]);
if (vimvars[VV_EXCEPTION].vv_str == NULL) {
prepare_assert_error(&ga);
ga_concat(&ga, (char_u *)"v:exception is not set");
@@ -7719,22 +6846,22 @@ static void f_assert_exception(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// "assert_fails(cmd [, error])" function
static void f_assert_fails(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *cmd = get_tv_string_chk(&argvars[0]);
+ const char *const cmd = tv_get_string_chk(&argvars[0]);
garray_T ga;
called_emsg = false;
suppress_errthrow = true;
emsg_silent = true;
- do_cmdline_cmd((char *)cmd);
+ do_cmdline_cmd(cmd);
if (!called_emsg) {
prepare_assert_error(&ga);
- ga_concat(&ga, (char_u *)"command did not fail: ");
- ga_concat(&ga, cmd);
+ ga_concat(&ga, (const char_u *)"command did not fail: ");
+ ga_concat(&ga, (const char_u *)cmd);
assert_error(&ga);
ga_clear(&ga);
} else if (argvars[1].v_type != VAR_UNKNOWN) {
- char_u buf[NUMBUFLEN];
- char *error = (char *)get_tv_string_buf_chk(&argvars[1], buf);
+ char buf[NUMBUFLEN];
+ const char *const error = tv_get_string_buf_chk(&argvars[1], buf);
if (error == NULL
|| strstr((char *)vimvars[VV_ERRMSG].vv_str, error) == NULL) {
@@ -7753,14 +6880,39 @@ static void f_assert_fails(typval_T *argvars, typval_T *rettv, FunPtr fptr)
set_vim_var_string(VV_ERRMSG, NULL, 0);
}
+void assert_inrange(typval_T *argvars)
+{
+ bool error = false;
+ const varnumber_T lower = tv_get_number_chk(&argvars[0], &error);
+ const varnumber_T upper = tv_get_number_chk(&argvars[1], &error);
+ const varnumber_T actual = tv_get_number_chk(&argvars[2], &error);
+
+ if (error) {
+ return;
+ }
+ if (actual < lower || actual > upper) {
+ garray_T ga;
+ prepare_assert_error(&ga);
+
+ char msg[55];
+ vim_snprintf(msg, sizeof(msg),
+ "range %" PRIdVARNUMBER " - %" PRIdVARNUMBER ",",
+ lower, upper);
+ fill_assert_error(&ga, &argvars[3], (char_u *)msg, NULL, &argvars[2],
+ ASSERT_INRANGE);
+ assert_error(&ga);
+ ga_clear(&ga);
+ }
+}
+
// Common for assert_true() and assert_false().
static void assert_bool(typval_T *argvars, bool is_true)
{
- int error = (int)false;
+ bool error = false;
garray_T ga;
if ((argvars[0].v_type != VAR_NUMBER
- || (get_tv_number_chk(&argvars[0], &error) == 0) == is_true
+ || (tv_get_number_chk(&argvars[0], &error) == 0) == is_true
|| error)
&& (argvars[0].v_type != VAR_SPECIAL
|| (argvars[0].vval.v_special
@@ -7784,14 +6936,15 @@ static void f_assert_false(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void assert_match_common(typval_T *argvars, assert_type_T atype)
{
- char_u buf1[NUMBUFLEN];
- char_u buf2[NUMBUFLEN];
- char_u *pat = get_tv_string_buf_chk(&argvars[0], buf1);
- char_u *text = get_tv_string_buf_chk(&argvars[1], buf2);
+ char buf1[NUMBUFLEN];
+ char buf2[NUMBUFLEN];
+ const char *const pat = tv_get_string_buf_chk(&argvars[0], buf1);
+ const char *const text = tv_get_string_buf_chk(&argvars[1], buf2);
if (pat == NULL || text == NULL) {
EMSG(_(e_invarg));
- } else if (pattern_match(pat, text, false) != (atype == ASSERT_MATCH)) {
+ } else if (pattern_match((char_u *)pat, (char_u *)text, false)
+ != (atype == ASSERT_MATCH)) {
garray_T ga;
prepare_assert_error(&ga);
fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1], atype);
@@ -7800,6 +6953,12 @@ static void assert_match_common(typval_T *argvars, assert_type_T atype)
}
}
+/// "assert_inrange(lower, upper[, msg])" function
+static void f_assert_inrange(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ assert_inrange(argvars);
+}
+
/// "assert_match(pattern, actual[, msg])" function
static void f_assert_match(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -7823,14 +6982,15 @@ static void f_assert_true(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_atan2(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- float_T fx, fy;
+ float_T fx;
+ float_T fy;
rettv->v_type = VAR_FLOAT;
- if (get_float_arg(argvars, &fx) == OK
- && get_float_arg(&argvars[1], &fy) == OK)
+ if (tv_get_float_chk(argvars, &fx) && tv_get_float_chk(&argvars[1], &fy)) {
rettv->vval.v_float = atan2(fx, fy);
- else
+ } else {
rettv->vval.v_float = 0.0;
+ }
}
/*
@@ -7954,17 +7114,17 @@ static buf_T *get_buf_tv(typval_T *tv, int curtab_only)
*/
static void f_bufname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
-
- (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */
- ++emsg_off;
- buf = get_buf_tv(&argvars[0], FALSE);
rettv->v_type = VAR_STRING;
- if (buf != NULL && buf->b_fname != NULL)
- rettv->vval.v_string = vim_strsave(buf->b_fname);
- else
- rettv->vval.v_string = NULL;
- --emsg_off;
+ rettv->vval.v_string = NULL;
+ if (!tv_check_str_or_nr(&argvars[0])) {
+ return;
+ }
+ emsg_off++;
+ const buf_T *const buf = get_buf_tv(&argvars[0], false);
+ emsg_off--;
+ if (buf != NULL && buf->b_fname != NULL) {
+ rettv->vval.v_string = (char_u *)xstrdup((char *)buf->b_fname);
+ }
}
/*
@@ -7972,36 +7132,36 @@ static void f_bufname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_bufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
- int error = FALSE;
- char_u *name;
+ bool error = false;
- (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */
- ++emsg_off;
- buf = get_buf_tv(&argvars[0], FALSE);
- --emsg_off;
+ rettv->vval.v_number = -1;
+ if (!tv_check_str_or_nr(&argvars[0])) {
+ return;
+ }
+ emsg_off++;
+ const buf_T *buf = 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 the buffer isn't found and the second argument is not zero create a
+ // new buffer.
+ const char *name;
if (buf == NULL
&& argvars[1].v_type != VAR_UNKNOWN
- && get_tv_number_chk(&argvars[1], &error) != 0
+ && tv_get_number_chk(&argvars[1], &error) != 0
&& !error
- && (name = get_tv_string_chk(&argvars[0])) != NULL
- && !error)
- buf = buflist_new(name, NULL, (linenr_T)1, 0);
+ && (name = tv_get_string_chk(&argvars[0])) != NULL
+ && !error) {
+ buf = buflist_new((char_u *)name, NULL, 1, 0);
+ }
- if (buf != NULL)
+ if (buf != NULL) {
rettv->vval.v_number = buf->b_fnum;
- else
- rettv->vval.v_number = -1;
+ }
}
static void buf_win_common(typval_T *argvars, typval_T *rettv, bool get_nr)
{
- int error = false;
- (void)get_tv_number_chk(&argvars[0], &error); // issue errmsg if type error
- if (error) { // the argument has an invalid type
+ if (!tv_check_str_or_nr(&argvars[0])) {
rettv->vval.v_number = -1;
return;
}
@@ -8045,36 +7205,34 @@ static void f_bufwinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_byte2line(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- long boff = 0;
-
- boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */
- if (boff < 0)
+ long boff = tv_get_number(&argvars[0]) - 1;
+ if (boff < 0) {
rettv->vval.v_number = -1;
- else
- rettv->vval.v_number = ml_find_line_or_offset(curbuf,
- (linenr_T)0, &boff);
+ } else {
+ rettv->vval.v_number = (varnumber_T)ml_find_line_or_offset(curbuf, 0,
+ &boff);
+ }
}
static void byteidx(typval_T *argvars, typval_T *rettv, int comp)
{
- char_u *t;
- char_u *str;
- long idx;
-
- str = get_tv_string_chk(&argvars[0]);
- idx = get_tv_number_chk(&argvars[1], NULL);
+ const char *const str = tv_get_string_chk(&argvars[0]);
+ varnumber_T idx = tv_get_number_chk(&argvars[1], NULL);
rettv->vval.v_number = -1;
- if (str == NULL || idx < 0)
+ if (str == NULL || idx < 0) {
return;
+ }
- t = str;
+ const char *t = str;
for (; idx > 0; idx--) {
- if (*t == NUL) /* EOL reached */
+ if (*t == NUL) { // EOL reached.
return;
- if (enc_utf8 && comp)
- t += utf_ptr2len(t);
- else
- t += (*mb_ptr2len)(t);
+ }
+ if (enc_utf8 && comp) {
+ t += utf_ptr2len((const char_u *)t);
+ } else {
+ t += (*mb_ptr2len)((const char_u *)t);
+ }
}
rettv->vval.v_number = (varnumber_T)(t - str);
}
@@ -8113,18 +7271,19 @@ int func_call(char_u *name, typval_T *args, partial_T *partial,
/* 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++]);
+ tv_copy(&item->li_tv, &argv[argc++]);
}
if (item == NULL) {
- r = call_func(name, (int)STRLEN(name), rettv, argc, argv,
+ r = call_func(name, (int)STRLEN(name), rettv, argc, argv, NULL,
curwin->w_cursor.lnum, curwin->w_cursor.lnum,
&dummy, true, partial, selfdict);
}
- /* Free the arguments. */
- while (argc > 0)
- clear_tv(&argv[--argc]);
+ // Free the arguments.
+ while (argc > 0) {
+ tv_clear(&argv[--argc]);
+ }
return r;
}
@@ -8132,24 +7291,24 @@ int func_call(char_u *name, typval_T *args, partial_T *partial,
/// "call(func, arglist [, dict])" function
static void f_call(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *func;
- partial_T *partial = NULL;
- dict_T *selfdict = NULL;
-
if (argvars[1].v_type != VAR_LIST) {
EMSG(_(e_listreq));
return;
}
- if (argvars[1].vval.v_list == NULL)
+ if (argvars[1].vval.v_list == NULL) {
return;
+ }
+ char_u *func;
+ partial_T *partial = NULL;
+ dict_T *selfdict = NULL;
if (argvars[0].v_type == VAR_FUNC) {
func = argvars[0].vval.v_string;
} else if (argvars[0].v_type == VAR_PARTIAL) {
partial = argvars[0].vval.v_partial;
- func = partial->pt_name;
+ func = partial_name(partial);
} else {
- func = get_tv_string(&argvars[0]);
+ func = (char_u *)tv_get_string(&argvars[0]);
}
if (*func == NUL) {
return; // type error or empty name
@@ -8179,18 +7338,14 @@ static void f_changenr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_char2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- if (has_mbyte) {
- int utf8 = 0;
-
- if (argvars[1].v_type != VAR_UNKNOWN)
- utf8 = get_tv_number_chk(&argvars[1], NULL);
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ if (!tv_check_num(&argvars[1])) {
+ return;
+ }
+ }
- if (utf8)
- rettv->vval.v_number = (*utf_ptr2char)(get_tv_string(&argvars[0]));
- else
- rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0]));
- } else
- rettv->vval.v_number = get_tv_string(&argvars[0])[0];
+ rettv->vval.v_number = utf_ptr2char(
+ (const char_u *)tv_get_string(&argvars[0]));
}
/*
@@ -8202,7 +7357,7 @@ static void f_cindent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
linenr_T lnum;
pos = curwin->w_cursor;
- lnum = get_tv_lnum(argvars);
+ lnum = tv_get_lnum(argvars);
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
curwin->w_cursor.lnum = lnum;
rettv->vval.v_number = get_c_indent();
@@ -8261,8 +7416,6 @@ static void f_col(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_complete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int startcol;
-
if ((State & INSERT) == 0) {
EMSG(_("E785: complete() can only be used in Insert mode"));
return;
@@ -8278,9 +7431,10 @@ static void f_complete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- startcol = get_tv_number_chk(&argvars[0], NULL);
- if (startcol <= 0)
+ const colnr_T startcol = tv_get_number_chk(&argvars[0], NULL);
+ if (startcol <= 0) {
return;
+ }
set_completion(startcol - 1, argvars[1].vval.v_list);
}
@@ -8311,47 +7465,51 @@ static void f_complete_check(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *message;
- char_u *buttons = NULL;
- char_u buf[NUMBUFLEN];
- char_u buf2[NUMBUFLEN];
+ char buf[NUMBUFLEN];
+ char buf2[NUMBUFLEN];
+ const char *message;
+ const char *buttons = NULL;
int def = 1;
int type = VIM_GENERIC;
- char_u *typestr;
- int error = FALSE;
+ const char *typestr;
+ bool error = false;
- message = get_tv_string_chk(&argvars[0]);
- if (message == NULL)
- error = TRUE;
+ message = tv_get_string_chk(&argvars[0]);
+ if (message == NULL) {
+ error = true;
+ }
if (argvars[1].v_type != VAR_UNKNOWN) {
- buttons = get_tv_string_buf_chk(&argvars[1], buf);
- if (buttons == NULL)
- error = TRUE;
+ buttons = tv_get_string_buf_chk(&argvars[1], buf);
+ if (buttons == NULL) {
+ error = true;
+ }
if (argvars[2].v_type != VAR_UNKNOWN) {
- def = get_tv_number_chk(&argvars[2], &error);
+ def = tv_get_number_chk(&argvars[2], &error);
if (argvars[3].v_type != VAR_UNKNOWN) {
- typestr = get_tv_string_buf_chk(&argvars[3], buf2);
- if (typestr == NULL)
- error = TRUE;
- else {
+ typestr = tv_get_string_buf_chk(&argvars[3], buf2);
+ if (typestr == NULL) {
+ error = true;
+ } else {
switch (TOUPPER_ASC(*typestr)) {
- case 'E': type = VIM_ERROR; break;
- case 'Q': type = VIM_QUESTION; break;
- case 'I': type = VIM_INFO; break;
- case 'W': type = VIM_WARNING; break;
- case 'G': type = VIM_GENERIC; break;
+ case 'E': type = VIM_ERROR; break;
+ case 'Q': type = VIM_QUESTION; break;
+ case 'I': type = VIM_INFO; break;
+ case 'W': type = VIM_WARNING; break;
+ case 'G': type = VIM_GENERIC; break;
}
}
}
}
}
- if (buttons == NULL || *buttons == NUL)
- buttons = (char_u *)_("&Ok");
+ if (buttons == NULL || *buttons == NUL) {
+ buttons = _("&Ok");
+ }
- if (!error)
- rettv->vval.v_number = do_dialog(type, NULL, message, buttons,
- def, NULL, FALSE);
+ if (!error) {
+ rettv->vval.v_number = do_dialog(
+ type, NULL, (char_u *)message, (char_u *)buttons, def, NULL, false);
+ }
}
/*
@@ -8378,15 +7536,16 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if ((l = argvars[0].vval.v_list) != NULL) {
li = l->lv_first;
if (argvars[2].v_type != VAR_UNKNOWN) {
- int error = FALSE;
+ bool error = false;
- ic = get_tv_number_chk(&argvars[2], &error);
+ ic = tv_get_number_chk(&argvars[2], &error);
if (argvars[3].v_type != VAR_UNKNOWN) {
- idx = get_tv_number_chk(&argvars[3], &error);
+ idx = tv_get_number_chk(&argvars[3], &error);
if (!error) {
- li = list_find(l, idx);
- if (li == NULL)
+ li = tv_list_find(l, idx);
+ if (li == NULL) {
EMSGN(_(e_listidx), idx);
+ }
}
}
if (error)
@@ -8403,20 +7562,22 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr)
hashitem_T *hi;
if ((d = argvars[0].vval.v_dict) != NULL) {
- int error = FALSE;
+ bool error = false;
if (argvars[2].v_type != VAR_UNKNOWN) {
- ic = get_tv_number_chk(&argvars[2], &error);
- if (argvars[3].v_type != VAR_UNKNOWN)
+ ic = tv_get_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;
+ todo--;
+ if (tv_equal(&TV_DICT_HI2DI(hi)->di_tv, &argvars[1], ic, false)) {
+ n++;
+ }
}
}
}
@@ -8433,19 +7594,21 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_cscope_connection(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int num = 0;
- char_u *dbpath = NULL;
- char_u *prepend = NULL;
- char_u buf[NUMBUFLEN];
+ const char *dbpath = NULL;
+ const char *prepend = NULL;
+ char buf[NUMBUFLEN];
if (argvars[0].v_type != VAR_UNKNOWN
&& argvars[1].v_type != VAR_UNKNOWN) {
- num = (int)get_tv_number(&argvars[0]);
- dbpath = get_tv_string(&argvars[1]);
- if (argvars[2].v_type != VAR_UNKNOWN)
- prepend = get_tv_string_buf(&argvars[2], buf);
+ num = (int)tv_get_number(&argvars[0]);
+ dbpath = tv_get_string(&argvars[1]);
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ prepend = tv_get_string_buf(&argvars[2], buf);
+ }
}
- rettv->vval.v_number = cs_connection(num, dbpath, prepend);
+ rettv->vval.v_number = cs_connection(num, (char_u *)dbpath,
+ (char_u *)prepend);
}
/// "cursor(lnum, col)" function, or
@@ -8478,10 +7641,10 @@ static void f_cursor(typval_T *argvars, typval_T *rettv, FunPtr fptr)
set_curswant = false;
}
} else {
- line = get_tv_lnum(argvars);
- col = get_tv_number_chk(&argvars[1], NULL);
+ line = tv_get_lnum(argvars);
+ col = (long)tv_get_number_chk(&argvars[1], NULL);
if (argvars[2].v_type != VAR_UNKNOWN) {
- coladd = get_tv_number_chk(&argvars[2], NULL);
+ coladd = (long)tv_get_number_chk(&argvars[2], NULL);
}
}
if (line < 0 || col < 0
@@ -8514,10 +7677,11 @@ static void f_deepcopy(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int noref = 0;
- if (argvars[1].v_type != VAR_UNKNOWN)
- noref = get_tv_number_chk(&argvars[1], NULL);
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ noref = tv_get_number_chk(&argvars[1], NULL);
+ }
if (noref < 0 || noref > 1) {
- EMSG(_(e_invarg));
+ emsgf(_(e_invarg));
} else {
var_item_copy(NULL, &argvars[0], rettv, true, (noref == 0
? get_copyID()
@@ -8528,34 +7692,32 @@ static void f_deepcopy(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// "delete()" function
static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u nbuf[NUMBUFLEN];
- char_u *name;
- char_u *flags;
-
rettv->vval.v_number = -1;
if (check_restricted() || check_secure()) {
return;
}
- name = get_tv_string(&argvars[0]);
+ const char *const name = tv_get_string(&argvars[0]);
if (name == NULL || *name == NUL) {
EMSG(_(e_invarg));
return;
}
+ char nbuf[NUMBUFLEN];
+ const char *flags;
if (argvars[1].v_type != VAR_UNKNOWN) {
- flags = get_tv_string_buf(&argvars[1], nbuf);
+ flags = tv_get_string_buf(&argvars[1], nbuf);
} else {
- flags = (char_u *)"";
+ flags = "";
}
if (*flags == NUL) {
// delete a file
- rettv->vval.v_number = os_remove((char *)name) == 0 ? 0 : -1;
- } else if (STRCMP(flags, "d") == 0) {
+ rettv->vval.v_number = os_remove(name) == 0 ? 0 : -1;
+ } else if (strcmp(flags, "d") == 0) {
// delete an empty directory
- rettv->vval.v_number = os_rmdir((char *)name) == 0 ? 0 : -1;
- } else if (STRCMP(flags, "rf") == 0) {
+ rettv->vval.v_number = os_rmdir(name) == 0 ? 0 : -1;
+ } else if (strcmp(flags, "rf") == 0) {
// delete a directory recursively
rettv->vval.v_number = delete_recursive(name);
} else {
@@ -8571,39 +7733,34 @@ static void f_dictwatcheradd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (argvars[0].v_type != VAR_DICT) {
- EMSG2(e_invarg2, "dict");
+ emsgf(_(e_invarg2), "dict");
return;
- }
-
- if (argvars[1].v_type != VAR_STRING && argvars[1].v_type != VAR_NUMBER) {
- EMSG2(e_invarg2, "key");
+ } else if (argvars[0].vval.v_dict == NULL) {
+ const char *const arg_errmsg = _("dictwatcheradd() argument");
+ const size_t arg_errmsg_len = strlen(arg_errmsg);
+ emsgf(_(e_readonlyvar), (int)arg_errmsg_len, arg_errmsg);
return;
}
- if (argvars[2].v_type != VAR_FUNC && argvars[2].v_type != VAR_STRING) {
- EMSG2(e_invarg2, "funcref");
+ if (argvars[1].v_type != VAR_STRING && argvars[1].v_type != VAR_NUMBER) {
+ emsgf(_(e_invarg2), "key");
return;
}
- char *key_pattern = (char *)get_tv_string_chk(argvars + 1);
- assert(key_pattern);
- const size_t key_len = STRLEN(argvars[1].vval.v_string);
-
- if (key_len == 0) {
- EMSG(_(e_emptykey));
+ const char *const key_pattern = tv_get_string_chk(argvars + 1);
+ if (key_pattern == NULL) {
return;
}
+ const size_t key_pattern_len = strlen(key_pattern);
Callback callback;
if (!callback_from_typval(&callback, &argvars[2])) {
+ emsgf(_(e_invarg2), "funcref");
return;
}
- DictWatcher *watcher = xmalloc(sizeof(DictWatcher));
- watcher->key_pattern = xmemdupz(key_pattern, key_len);
- watcher->callback = callback;
- watcher->busy = false;
- QUEUE_INSERT_TAIL(&argvars[0].vval.v_dict->watchers, &watcher->node);
+ tv_dict_watcher_add(argvars[0].vval.v_dict, key_pattern, key_pattern_len,
+ callback);
}
// dictwatcherdel(dict, key, funcref) function
@@ -8614,26 +7771,17 @@ static void f_dictwatcherdel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (argvars[0].v_type != VAR_DICT) {
- EMSG2(e_invarg2, "dict");
- return;
- }
-
- if (argvars[1].v_type != VAR_STRING && argvars[1].v_type != VAR_NUMBER) {
- EMSG2(e_invarg2, "key");
+ emsgf(_(e_invarg2), "dict");
return;
}
if (argvars[2].v_type != VAR_FUNC && argvars[2].v_type != VAR_STRING) {
- EMSG2(e_invarg2, "funcref");
+ emsgf(_(e_invarg2), "funcref");
return;
}
- char *key_pattern = (char *)get_tv_string_chk(argvars + 1);
- assert(key_pattern);
- const size_t key_len = STRLEN(argvars[1].vval.v_string);
-
- if (key_len == 0) {
- EMSG(_(e_emptykey));
+ const char *const key_pattern = tv_get_string_chk(argvars + 1);
+ if (key_pattern == NULL) {
return;
}
@@ -8642,28 +7790,12 @@ static void f_dictwatcherdel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- dict_T *dict = argvars[0].vval.v_dict;
- QUEUE *w = NULL;
- DictWatcher *watcher = NULL;
- bool matched = false;
- QUEUE_FOREACH(w, &dict->watchers) {
- watcher = dictwatcher_node_data(w);
- if (callback_equal(&watcher->callback, &callback)
- && !strcmp(watcher->key_pattern, key_pattern)) {
- matched = true;
- break;
- }
- }
-
- callback_free(&callback);
-
- if (!matched) {
+ if (!tv_dict_watcher_remove(argvars[0].vval.v_dict, key_pattern,
+ strlen(key_pattern), callback)) {
EMSG("Couldn't find a watcher matching key and callback");
- return;
}
- QUEUE_REMOVE(w);
- dictwatcher_free(watcher);
+ callback_free(&callback);
}
/*
@@ -8679,7 +7811,7 @@ static void f_did_filetype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_diff_filler(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars));
+ rettv->vval.v_number = diff_check_fill(curwin, tv_get_lnum(argvars));
}
/*
@@ -8687,7 +7819,7 @@ static void f_diff_filler(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_diff_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum = get_tv_lnum(argvars);
+ linenr_T lnum = tv_get_lnum(argvars);
static linenr_T prev_lnum = 0;
static int changedtick = 0;
static int fnum = 0;
@@ -8722,11 +7854,12 @@ static void f_diff_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (hlID == HLF_CHD || hlID == HLF_TXD) {
- col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */
- if (col >= change_start && col <= change_end)
- hlID = HLF_TXD; /* changed text */
- else
- hlID = HLF_CHD; /* changed line */
+ col = tv_get_number(&argvars[1]) - 1; // Ignore type error in {col}.
+ if (col >= change_start && col <= change_end) {
+ hlID = HLF_TXD; // Changed text.
+ } else {
+ hlID = HLF_CHD; // Changed line.
+ }
}
rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID;
}
@@ -8777,10 +7910,11 @@ static void f_empty(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_escape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u buf[NUMBUFLEN];
+ char buf[NUMBUFLEN];
- rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]),
- get_tv_string_buf(&argvars[1], buf));
+ rettv->vval.v_string = vim_strsave_escaped(
+ (const char_u *)tv_get_string(&argvars[0]),
+ (const char_u *)tv_get_string_buf(&argvars[1], buf));
rettv->v_type = VAR_STRING;
}
@@ -8789,16 +7923,15 @@ static void f_escape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_eval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *s;
-
- s = get_tv_string_chk(&argvars[0]);
- if (s != NULL)
- s = skipwhite(s);
+ const char *s = tv_get_string_chk(&argvars[0]);
+ if (s != NULL) {
+ s = (const char *)skipwhite((const char_u *)s);
+ }
- char_u *p = s;
- if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) {
- if (p != NULL && !aborting()) {
- EMSG2(_(e_invexpr2), p);
+ const char *const expr_start = s;
+ if (s == NULL || eval1((char_u **)&s, rettv, true) == FAIL) {
+ if (expr_start != NULL && !aborting()) {
+ EMSG2(_(e_invexpr2), expr_start);
}
need_clr_eos = FALSE;
rettv->v_type = VAR_NUMBER;
@@ -8821,91 +7954,92 @@ static void f_eventhandler(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_executable(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *name = get_tv_string(&argvars[0]);
+ const char *name = tv_get_string(&argvars[0]);
// Check in $PATH and also check directly if there is a directory name
- rettv->vval.v_number = os_can_exe(name, NULL, true)
- || (gettail_dir(name) != name && os_can_exe(name, NULL, false));
+ rettv->vval.v_number = (
+ os_can_exe((const char_u *)name, NULL, true)
+ || (gettail_dir(name) != name
+ && os_can_exe((const char_u *)name, NULL, false)));
}
-static char_u * get_list_line(int c, void *cookie, int indent)
+static char_u *get_list_line(int c, void *cookie, int indent)
{
- listitem_T **p = (listitem_T **)cookie;
- listitem_T *item = *p;
- char_u buf[NUMBUFLEN];
- char_u *s;
+ const listitem_T **const p = (const listitem_T **)cookie;
+ const listitem_T *item = *p;
if (item == NULL) {
return NULL;
}
- s = get_tv_string_buf_chk(&item->li_tv, buf);
+ char buf[NUMBUFLEN];
+ const char *const s = tv_get_string_buf_chk(&item->li_tv, buf);
*p = item->li_next;
- return s == NULL ? NULL : vim_strsave(s);
+ return (char_u *)(s == NULL ? NULL : xstrdup(s));
}
// "execute(command)" function
static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int save_msg_silent = msg_silent;
- int save_emsg_silent = emsg_silent;
- bool save_emsg_noredir = emsg_noredir;
- garray_T *save_capture_ga = capture_ga;
+ const int save_msg_silent = msg_silent;
+ const int save_emsg_silent = emsg_silent;
+ const bool save_emsg_noredir = emsg_noredir;
+ garray_T *const save_capture_ga = capture_ga;
- if (check_secure()) {
- return;
- }
+ if (check_secure()) {
+ return;
+ }
- if (argvars[1].v_type != VAR_UNKNOWN) {
- char_u buf[NUMBUFLEN];
- char_u *s = get_tv_string_buf_chk(&argvars[1], buf);
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ char buf[NUMBUFLEN];
+ const char *const s = tv_get_string_buf_chk(&argvars[1], buf);
- if (s == NULL) {
- return;
- }
- if (STRNCMP(s, "silent", 6) == 0) {
- msg_silent++;
- }
- if (STRCMP(s, "silent!") == 0) {
- emsg_silent = true;
- emsg_noredir = true;
- }
- } else {
+ if (s == NULL) {
+ return;
+ }
+ if (strncmp(s, "silent", 6) == 0) {
msg_silent++;
}
-
- garray_T capture_local;
- ga_init(&capture_local, (int)sizeof(char), 80);
- capture_ga = &capture_local;
-
- if (argvars[0].v_type != VAR_LIST) {
- do_cmdline_cmd((char *)get_tv_string(&argvars[0]));
- } else if (argvars[0].vval.v_list != NULL) {
- list_T *list = argvars[0].vval.v_list;
- list->lv_refcount++;
- listitem_T *item = list->lv_first;
- do_cmdline(NULL, get_list_line, (void *)&item,
- DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT|DOCMD_KEYTYPED);
- list->lv_refcount--;
+ if (strcmp(s, "silent!") == 0) {
+ emsg_silent = true;
+ emsg_noredir = true;
}
- msg_silent = save_msg_silent;
- emsg_silent = save_emsg_silent;
- emsg_noredir = save_emsg_noredir;
+ } else {
+ msg_silent++;
+ }
- ga_append(capture_ga, NUL);
- rettv->v_type = VAR_STRING;
- rettv->vval.v_string = vim_strsave(capture_ga->ga_data);
- ga_clear(capture_ga);
+ garray_T capture_local;
+ ga_init(&capture_local, (int)sizeof(char), 80);
+ capture_ga = &capture_local;
- capture_ga = save_capture_ga;
+ if (argvars[0].v_type != VAR_LIST) {
+ do_cmdline_cmd(tv_get_string(&argvars[0]));
+ } else if (argvars[0].vval.v_list != NULL) {
+ list_T *const list = argvars[0].vval.v_list;
+ list->lv_refcount++;
+ listitem_T *const item = list->lv_first;
+ do_cmdline(NULL, get_list_line, (void *)&item,
+ DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT|DOCMD_KEYTYPED);
+ list->lv_refcount--;
+ }
+ msg_silent = save_msg_silent;
+ emsg_silent = save_emsg_silent;
+ emsg_noredir = save_emsg_noredir;
+
+ ga_append(capture_ga, NUL);
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = vim_strsave(capture_ga->ga_data);
+ ga_clear(capture_ga);
+
+ capture_ga = save_capture_ga;
}
/// "exepath()" function
static void f_exepath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *arg = get_tv_string(&argvars[0]);
+ const char *arg = tv_get_string(&argvars[0]);
char_u *path = NULL;
- (void)os_can_exe(arg, &path, true);
+ (void)os_can_exe((const char_u *)arg, &path, true);
rettv->v_type = VAR_STRING;
rettv->vval.v_string = path;
@@ -8916,53 +8050,55 @@ static void f_exepath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p;
- char_u *name;
- int n = FALSE;
+ int n = false;
int len = 0;
- p = get_tv_string(&argvars[0]);
- if (*p == '$') { /* environment variable */
- /* first try "normal" environment variables (fast) */
- if (os_getenv((char *)(p + 1)) != NULL)
- n = TRUE;
- else {
- /* try expanding things like $VIM and ${HOME} */
- p = expand_env_save(p);
- if (p != NULL && *p != '$')
- n = TRUE;
- xfree(p);
+ const char *p = tv_get_string(&argvars[0]);
+ if (*p == '$') { // Environment variable.
+ // First try "normal" environment variables (fast).
+ if (os_getenv(p + 1) != NULL) {
+ n = true;
+ } else {
+ // Try expanding things like $VIM and ${HOME}.
+ char_u *const exp = expand_env_save((char_u *)p);
+ if (exp != NULL && *exp != '$') {
+ n = true;
+ }
+ xfree(exp);
+ }
+ } else if (*p == '&' || *p == '+') { // Option.
+ n = (get_option_tv(&p, NULL, true) == OK);
+ if (*skipwhite((const char_u *)p) != NUL) {
+ n = false; // Trailing garbage.
}
- } 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 == '*') { // Internal or user defined function.
+ n = function_exists(p + 1, false);
} else if (*p == ':') {
n = cmd_exists(p + 1);
} else if (*p == '#') {
- if (p[1] == '#')
+ if (p[1] == '#') {
n = autocmd_supported(p + 2);
- else
+ } else {
n = au_exists(p + 1);
- } else { /* internal variable */
- char_u *tofree;
+ }
+ } else { // Internal variable.
typval_T tv;
- /* get_name_len() takes care of expanding curly braces */
- name = p;
- len = get_name_len(&p, &tofree, TRUE, FALSE);
+ // get_name_len() takes care of expanding curly braces
+ const char *name = p;
+ char *tofree;
+ len = get_name_len((const char **)&p, &tofree, true, false);
if (len > 0) {
if (tofree != NULL) {
name = tofree;
}
n = (get_var_tv(name, len, &tv, NULL, false, true) == OK);
if (n) {
- /* handle d.key, l[idx], f(expr) */
- n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK);
- if (n)
- clear_tv(&tv);
+ // Handle d.key, l[idx], f(expr).
+ n = (handle_subscript(&p, &tv, true, false) == OK);
+ if (n) {
+ tv_clear(&tv);
+ }
}
}
if (*p != NUL)
@@ -8979,32 +8115,31 @@ static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *s;
size_t len;
char_u *errormsg;
int options = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND;
expand_T xpc;
- int error = FALSE;
- char_u *result;
+ bool error = false;
+ char_u *result;
rettv->v_type = VAR_STRING;
if (argvars[1].v_type != VAR_UNKNOWN
&& argvars[2].v_type != VAR_UNKNOWN
- && get_tv_number_chk(&argvars[2], &error)
+ && tv_get_number_chk(&argvars[2], &error)
&& !error) {
rettv->v_type = VAR_LIST;
rettv->vval.v_list = NULL;
}
- s = get_tv_string(&argvars[0]);
+ const char *s = tv_get_string(&argvars[0]);
if (*s == '%' || *s == '#' || *s == '<') {
- ++emsg_off;
- result = eval_vars(s, s, &len, NULL, &errormsg, NULL);
- --emsg_off;
+ emsg_off++;
+ result = eval_vars((char_u *)s, (char_u *)s, &len, NULL, &errormsg, NULL);
+ emsg_off--;
if (rettv->v_type == VAR_LIST) {
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
if (result != NULL) {
- list_append_string(rettv->vval.v_list, result, -1);
+ tv_list_append_string(rettv->vval.v_list, (const char *)result, -1);
}
} else
rettv->vval.v_string = result;
@@ -9012,94 +8147,44 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/* When the optional second argument is non-zero, don't remove matches
* for 'wildignore' and don't put matches for 'suffixes' at the end. */
if (argvars[1].v_type != VAR_UNKNOWN
- && get_tv_number_chk(&argvars[1], &error))
+ && tv_get_number_chk(&argvars[1], &error)) {
options |= WILD_KEEP_ALL;
+ }
if (!error) {
ExpandInit(&xpc);
xpc.xp_context = EXPAND_FILES;
- if (p_wic)
+ if (p_wic) {
options += WILD_ICASE;
- if (rettv->v_type == VAR_STRING)
- rettv->vval.v_string = ExpandOne(&xpc, s, NULL,
- options, WILD_ALL);
- else {
- rettv_list_alloc(rettv);
- ExpandOne(&xpc, s, NULL, options, WILD_ALL_KEEP);
+ }
+ if (rettv->v_type == VAR_STRING) {
+ rettv->vval.v_string = ExpandOne(&xpc, (char_u *)s, NULL, options,
+ WILD_ALL);
+ } else {
+ tv_list_alloc_ret(rettv);
+ ExpandOne(&xpc, (char_u *)s, NULL, options, WILD_ALL_KEEP);
for (int i = 0; i < xpc.xp_numfiles; i++) {
- list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1);
+ tv_list_append_string(rettv->vval.v_list,
+ (const char *)xpc.xp_files[i], -1);
}
ExpandCleanup(&xpc);
}
- } else
+ } else {
rettv->vval.v_string = NULL;
+ }
}
}
-/*
- * Go over all entries in "d2" and add them to "d1".
- * When "action" is "error" then a duplicate key is an error.
- * When "action" is "force" then a duplicate key is overwritten.
- * Otherwise duplicate keys are ignored ("action" is "keep").
- */
-void dict_extend(dict_T *d1, dict_T *d2, char_u *action)
-{
- dictitem_T *di1;
- hashitem_T *hi2;
- int todo;
- bool watched = is_watched(d1);
- char_u *arg_errmsg = (char_u *)N_("extend() argument");
-
- todo = (int)d2->dv_hashtab.ht_used;
- for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) {
- if (!HASHITEM_EMPTY(hi2)) {
- --todo;
- di1 = dict_find(d1, hi2->hi_key, -1);
- if (d1->dv_scope != 0) {
- /* Disallow replacing a builtin function in l: and g:.
- * Check the key to be valid when adding to any
- * scope. */
- if (d1->dv_scope == VAR_DEF_SCOPE
- && HI2DI(hi2)->di_tv.v_type == VAR_FUNC
- && var_check_func_name(hi2->hi_key,
- di1 == NULL))
- break;
- if (!valid_varname(hi2->hi_key))
- break;
- }
- if (di1 == NULL) {
- di1 = dictitem_copy(HI2DI(hi2));
- if (dict_add(d1, di1) == FAIL) {
- dictitem_free(di1);
- }
-
- if (watched) {
- dictwatcher_notify(d1, (char *)di1->di_key, &di1->di_tv, NULL);
- }
- } else if (*action == 'e') {
- EMSG2(_("E737: Key already exists: %s"), hi2->hi_key);
- break;
- } else if (*action == 'f' && HI2DI(hi2) != di1) {
- typval_T oldtv;
-
- if (tv_check_lock(di1->di_tv.v_lock, arg_errmsg, true)
- || var_check_ro(di1->di_flags, arg_errmsg, true)) {
- break;
- }
- if (watched) {
- copy_tv(&di1->di_tv, &oldtv);
- }
-
- clear_tv(&di1->di_tv);
- copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv);
-
- if (watched) {
- dictwatcher_notify(d1, (char *)di1->di_key, &di1->di_tv, &oldtv);
- clear_tv(&oldtv);
- }
- }
- }
+/// "menu_get(path [, modes])" function
+static void f_menu_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ tv_list_alloc_ret(rettv);
+ int modes = MENU_ALL_MODES;
+ if (argvars[1].v_type == VAR_STRING) {
+ const char_u *const strmodes = (char_u *)tv_get_string(&argvars[1]);
+ modes = get_menu_cmd_modes(strmodes, false, NULL, NULL);
}
+ menu_get((char_u *)tv_get_string(&argvars[0]), modes, rettv->vval.v_list);
}
/*
@@ -9108,27 +8193,33 @@ void dict_extend(dict_T *d1, dict_T *d2, char_u *action)
*/
static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *arg_errmsg = (char_u *)N_("extend() argument");
+ const char *const arg_errmsg = N_("extend() argument");
if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) {
- list_T *l1, *l2;
- listitem_T *item;
long before;
- int error = FALSE;
-
- l1 = argvars[0].vval.v_list;
- l2 = argvars[1].vval.v_list;
- if (l1 != NULL && !tv_check_lock(l1->lv_lock, arg_errmsg, true)
- && l2 != NULL) {
+ bool error = false;
+
+ list_T *const l1 = argvars[0].vval.v_list;
+ list_T *const l2 = argvars[1].vval.v_list;
+ if (l1 == NULL) {
+ const bool locked = tv_check_lock(VAR_FIXED, arg_errmsg, TV_TRANSLATE);
+ (void)locked;
+ assert(locked == true);
+ } else if (l2 == NULL) {
+ // Do nothing
+ tv_copy(&argvars[0], rettv);
+ } else if (!tv_check_lock(l1->lv_lock, arg_errmsg, TV_TRANSLATE)) {
+ listitem_T *item;
if (argvars[2].v_type != VAR_UNKNOWN) {
- before = get_tv_number_chk(&argvars[2], &error);
- if (error)
- return; /* type error; errmsg already given */
+ before = (long)tv_get_number_chk(&argvars[2], &error);
+ if (error) {
+ return; // Type error; errmsg already given.
+ }
- if (before == l1->lv_len)
+ if (before == l1->lv_len) {
item = NULL;
- else {
- item = list_find(l1, before);
+ } else {
+ item = tv_list_find(l1, before);
if (item == NULL) {
EMSGN(_(e_listidx), before);
return;
@@ -9136,43 +8227,50 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
} else
item = NULL;
- list_extend(l1, l2, item);
+ tv_list_extend(l1, l2, item);
- copy_tv(&argvars[0], rettv);
+ tv_copy(&argvars[0], rettv);
}
} else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type ==
VAR_DICT) {
- dict_T *d1, *d2;
- char_u *action;
- int i;
-
- d1 = argvars[0].vval.v_dict;
- d2 = argvars[1].vval.v_dict;
- if (d1 != NULL && !tv_check_lock(d1->dv_lock, arg_errmsg, true)
- && d2 != NULL) {
- /* Check the third argument. */
+ dict_T *const d1 = argvars[0].vval.v_dict;
+ dict_T *const d2 = argvars[1].vval.v_dict;
+ if (d1 == NULL) {
+ const bool locked = tv_check_lock(VAR_FIXED, arg_errmsg, TV_TRANSLATE);
+ (void)locked;
+ assert(locked == true);
+ } else if (d2 == NULL) {
+ // Do nothing
+ tv_copy(&argvars[0], rettv);
+ } else if (!tv_check_lock(d1->dv_lock, arg_errmsg, TV_TRANSLATE)) {
+ const char *action = "force";
+ // Check the third argument.
if (argvars[2].v_type != VAR_UNKNOWN) {
- static char *(av[]) = {"keep", "force", "error"};
+ const char *const av[] = { "keep", "force", "error" };
- action = get_tv_string_chk(&argvars[2]);
- if (action == NULL)
- return; /* type error; errmsg already given */
- for (i = 0; i < 3; ++i)
- if (STRCMP(action, av[i]) == 0)
+ action = tv_get_string_chk(&argvars[2]);
+ if (action == NULL) {
+ return; // Type error; error message already given.
+ }
+ size_t i;
+ for (i = 0; i < ARRAY_SIZE(av); i++) {
+ if (strcmp(action, av[i]) == 0) {
break;
+ }
+ }
if (i == 3) {
EMSG2(_(e_invarg2), action);
return;
}
- } else
- action = (char_u *)"force";
+ }
- dict_extend(d1, d2, action);
+ tv_dict_extend(d1, d2, action);
- copy_tv(&argvars[0], rettv);
+ tv_copy(&argvars[0], rettv);
}
- } else
+ } else {
EMSG2(_(e_listdictarg), "extend()");
+ }
}
/*
@@ -9180,19 +8278,18 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_feedkeys(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *keys, *flags = NULL;
- char_u nbuf[NUMBUFLEN];
-
- /* This is not allowed in the sandbox. If the commands would still be
- * executed in the sandbox it would be OK, but it probably happens later,
- * when "sandbox" is no longer set. */
- if (check_secure())
+ // This is not allowed in the sandbox. If the commands would still be
+ // executed in the sandbox it would be OK, but it probably happens later,
+ // when "sandbox" is no longer set.
+ if (check_secure()) {
return;
+ }
- keys = get_tv_string(&argvars[0]);
-
+ const char *const keys = tv_get_string(&argvars[0]);
+ char nbuf[NUMBUFLEN];
+ const char *flags = NULL;
if (argvars[1].v_type != VAR_UNKNOWN) {
- flags = get_tv_string_buf(&argvars[1], nbuf);
+ flags = tv_get_string_buf(&argvars[1], nbuf);
}
nvim_feedkeys(cstr_as_string((char *)keys),
@@ -9202,9 +8299,9 @@ static void f_feedkeys(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// "filereadable()" function
static void f_filereadable(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p = get_tv_string(&argvars[0]);
+ const char *const p = tv_get_string(&argvars[0]);
rettv->vval.v_number =
- (*p && !os_isdir(p) && os_file_is_readable((char*)p));
+ (*p && !os_isdir((const char_u *)p) && os_file_is_readable(p));
}
/*
@@ -9213,60 +8310,60 @@ static void f_filereadable(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_filewritable(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char *filename = (char *)get_tv_string(&argvars[0]);
+ const char *filename = tv_get_string(&argvars[0]);
rettv->vval.v_number = os_file_is_writable(filename);
}
static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what)
{
- char_u *fname;
- char_u *fresult = NULL;
- char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path;
- char_u *p;
- char_u pathbuf[NUMBUFLEN];
+ char_u *fresult = NULL;
+ char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path;
int count = 1;
- int first = TRUE;
- int error = FALSE;
+ bool first = true;
+ bool error = false;
rettv->vval.v_string = NULL;
rettv->v_type = VAR_STRING;
- fname = get_tv_string(&argvars[0]);
+ const char *fname = tv_get_string(&argvars[0]);
+ char pathbuf[NUMBUFLEN];
if (argvars[1].v_type != VAR_UNKNOWN) {
- p = get_tv_string_buf_chk(&argvars[1], pathbuf);
- if (p == NULL)
- error = TRUE;
- else {
- if (*p != NUL)
- path = p;
+ const char *p = tv_get_string_buf_chk(&argvars[1], pathbuf);
+ if (p == NULL) {
+ error = true;
+ } else {
+ if (*p != NUL) {
+ path = (char_u *)p;
+ }
- if (argvars[2].v_type != VAR_UNKNOWN)
- count = get_tv_number_chk(&argvars[2], &error);
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ count = tv_get_number_chk(&argvars[2], &error);
+ }
}
}
if (count < 0) {
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
}
if (*fname != NUL && !error) {
do {
if (rettv->v_type == VAR_STRING || rettv->v_type == VAR_LIST)
xfree(fresult);
- fresult = find_file_in_path_option(first ? fname : NULL,
- first ? STRLEN(fname) : 0,
+ fresult = find_file_in_path_option(first ? (char_u *)fname : NULL,
+ first ? strlen(fname) : 0,
0, first, path,
find_what, curbuf->b_ffname,
(find_what == FINDFILE_DIR
? (char_u *)""
: curbuf->b_p_sua));
- first = FALSE;
-
- if (fresult != NULL && rettv->v_type == VAR_LIST)
- list_append_string(rettv->vval.v_list, fresult, -1);
+ first = false;
+ if (fresult != NULL && rettv->v_type == VAR_LIST) {
+ tv_list_append_string(rettv->vval.v_list, (const char *)fresult, -1);
+ }
} while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL);
}
@@ -9280,8 +8377,7 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what)
*/
static void filter_map(typval_T *argvars, typval_T *rettv, int map)
{
- char_u buf[NUMBUFLEN];
- char_u *expr;
+ typval_T *expr;
listitem_T *li, *nli;
list_T *l = NULL;
dictitem_T *di;
@@ -9292,20 +8388,21 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map)
typval_T save_key;
int rem = false;
int todo;
- char_u *ermsg = (char_u *)(map ? "map()" : "filter()");
- char_u *arg_errmsg = (char_u *)(map ? N_("map() argument")
- : N_("filter() argument"));
+ char_u *ermsg = (char_u *)(map ? "map()" : "filter()");
+ const char *const arg_errmsg = (map
+ ? N_("map() argument")
+ : N_("filter() argument"));
int save_did_emsg;
int idx = 0;
if (argvars[0].v_type == VAR_LIST) {
if ((l = argvars[0].vval.v_list) == NULL
- || (!map && tv_check_lock(l->lv_lock, arg_errmsg, true))) {
+ || (!map && tv_check_lock(l->lv_lock, arg_errmsg, TV_TRANSLATE))) {
return;
}
} else if (argvars[0].v_type == VAR_DICT) {
if ((d = argvars[0].vval.v_dict) == NULL
- || (!map && tv_check_lock(d->dv_lock, arg_errmsg, true))) {
+ || (!map && tv_check_lock(d->dv_lock, arg_errmsg, TV_TRANSLATE))) {
return;
}
} else {
@@ -9313,16 +8410,15 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map)
return;
}
- expr = get_tv_string_buf_chk(&argvars[1], buf);
- /* On type errors, the preceding call has already displayed an error
- * message. Avoid a misleading error message for an empty string that
- * was not passed as argument. */
- if (expr != NULL) {
+ expr = &argvars[1];
+ // On type errors, the preceding call has already displayed an error
+ // message. Avoid a misleading error message for an empty string that
+ // was not passed as argument.
+ if (expr->v_type != VAR_UNKNOWN) {
prepare_vimvar(VV_VAL, &save_val);
- expr = skipwhite(expr);
- /* We reset "did_emsg" to be able to detect whether an error
- * occurred during evaluation of the expression. */
+ // We reset "did_emsg" to be able to detect whether an error
+ // occurred during evaluation of the expression.
save_did_emsg = did_emsg;
did_emsg = FALSE;
@@ -9337,24 +8433,25 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map)
if (!HASHITEM_EMPTY(hi)) {
--todo;
- di = HI2DI(hi);
+ di = TV_DICT_HI2DI(hi);
if (map
- && (tv_check_lock(di->di_tv.v_lock, arg_errmsg, true)
- || var_check_ro(di->di_flags, arg_errmsg, true))) {
+ && (tv_check_lock(di->di_tv.v_lock, arg_errmsg, TV_TRANSLATE)
+ || var_check_ro(di->di_flags, arg_errmsg, TV_TRANSLATE))) {
break;
}
vimvars[VV_KEY].vv_str = vim_strsave(di->di_key);
int r = filter_map_one(&di->di_tv, expr, map, &rem);
- clear_tv(&vimvars[VV_KEY].vv_tv);
- if (r == FAIL || did_emsg)
+ tv_clear(&vimvars[VV_KEY].vv_tv);
+ if (r == FAIL || did_emsg) {
break;
+ }
if (!map && rem) {
- if (var_check_fixed(di->di_flags, arg_errmsg, true)
- || var_check_ro(di->di_flags, arg_errmsg, true)) {
+ if (var_check_fixed(di->di_flags, arg_errmsg, TV_TRANSLATE)
+ || var_check_ro(di->di_flags, arg_errmsg, TV_TRANSLATE)) {
break;
}
- dictitem_remove(d, di);
+ tv_dict_item_remove(d, di);
}
}
}
@@ -9363,7 +8460,8 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map)
vimvars[VV_KEY].vv_type = VAR_NUMBER;
for (li = l->lv_first; li != NULL; li = nli) {
- if (map && tv_check_lock(li->li_tv.v_lock, arg_errmsg, true)) {
+ if (map
+ && tv_check_lock(li->li_tv.v_lock, arg_errmsg, TV_TRANSLATE)) {
break;
}
nli = li->li_next;
@@ -9371,9 +8469,10 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map)
if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL
|| did_emsg)
break;
- if (!map && rem)
- listitem_remove(l, li);
- ++idx;
+ if (!map && rem) {
+ tv_list_item_remove(l, li);
+ }
+ idx++;
}
}
@@ -9383,43 +8482,69 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map)
did_emsg |= save_did_emsg;
}
- copy_tv(&argvars[0], rettv);
+ tv_copy(&argvars[0], rettv);
}
-static int filter_map_one(typval_T *tv, char_u *expr, int map, int *remp)
+static int filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp)
{
typval_T rettv;
- char_u *s;
+ typval_T argv[3];
int retval = FAIL;
+ int dummy;
- copy_tv(tv, &vimvars[VV_VAL].vv_tv);
- s = expr;
- if (eval1(&s, &rettv, TRUE) == FAIL)
- goto theend;
- if (*s != NUL) { /* check for trailing chars after expr */
- EMSG2(_(e_invexpr2), s);
- clear_tv(&rettv);
- goto theend;
+ tv_copy(tv, &vimvars[VV_VAL].vv_tv);
+ argv[0] = vimvars[VV_KEY].vv_tv;
+ argv[1] = vimvars[VV_VAL].vv_tv;
+ if (expr->v_type == VAR_FUNC) {
+ const char_u *const s = expr->vval.v_string;
+ if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL,
+ 0L, 0L, &dummy, true, NULL, NULL) == FAIL) {
+ goto theend;
+ }
+ } else if (expr->v_type == VAR_PARTIAL) {
+ partial_T *partial = expr->vval.v_partial;
+
+ const char_u *const s = partial_name(partial);
+ if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL,
+ 0L, 0L, &dummy, true, partial, NULL) == FAIL) {
+ goto theend;
+ }
+ } else {
+ char buf[NUMBUFLEN];
+ const char *s = tv_get_string_buf_chk(expr, buf);
+ if (s == NULL) {
+ goto theend;
+ }
+ s = (const char *)skipwhite((const char_u *)s);
+ if (eval1((char_u **)&s, &rettv, true) == FAIL) {
+ goto theend;
+ }
+
+ if (*s != NUL) { // check for trailing chars after expr
+ emsgf(_(e_invexpr2), s);
+ goto theend;
+ }
}
if (map) {
- /* map(): replace the list item value */
- clear_tv(tv);
+ // map(): replace the list item value.
+ tv_clear(tv);
rettv.v_lock = 0;
*tv = rettv;
} else {
- int error = FALSE;
-
- /* filter(): when expr is zero remove the item */
- *remp = (get_tv_number_chk(&rettv, &error) == 0);
- clear_tv(&rettv);
- /* On type error, nothing has been removed; return FAIL to stop the
- * loop. The error message was given by get_tv_number_chk(). */
- if (error)
+ bool error = false;
+
+ // filter(): when expr is zero remove the item
+ *remp = (tv_get_number_chk(&rettv, &error) == 0);
+ tv_clear(&rettv);
+ // On type error, nothing has been removed; return FAIL to stop the
+ // loop. The error message was given by tv_get_number_chk().
+ if (error) {
goto theend;
+ }
}
retval = OK;
theend:
- clear_tv(&vimvars[VV_VAL].vv_tv);
+ tv_clear(&vimvars[VV_VAL].vv_tv);
return retval;
}
@@ -9454,13 +8579,14 @@ static void f_float2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
float_T f;
- if (get_float_arg(argvars, &f) == OK) {
- if (f < -0x7fffffff)
- rettv->vval.v_number = -0x7fffffff;
- else if (f > 0x7fffffff)
- rettv->vval.v_number = 0x7fffffff;
- else
+ if (tv_get_float_chk(argvars, &f)) {
+ if (f <= -VARNUMBER_MAX + DBL_EPSILON) {
+ rettv->vval.v_number = -VARNUMBER_MAX;
+ } else if (f >= VARNUMBER_MAX - DBL_EPSILON) {
+ rettv->vval.v_number = VARNUMBER_MAX;
+ } else {
rettv->vval.v_number = (varnumber_T)f;
+ }
}
}
@@ -9469,14 +8595,15 @@ static void f_float2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_fmod(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- float_T fx, fy;
+ float_T fx;
+ float_T fy;
rettv->v_type = VAR_FLOAT;
- if (get_float_arg(argvars, &fx) == OK
- && get_float_arg(&argvars[1], &fy) == OK)
+ if (tv_get_float_chk(argvars, &fx) && tv_get_float_chk(&argvars[1], &fy)) {
rettv->vval.v_float = fmod(fx, fy);
- else
+ } else {
rettv->vval.v_float = 0.0;
+ }
}
/*
@@ -9484,8 +8611,8 @@ static void f_fmod(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_fnameescape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_string = vim_strsave_fnameescape(
- get_tv_string(&argvars[0]), FALSE);
+ rettv->vval.v_string = (char_u *)vim_strsave_fnameescape(
+ tv_get_string(&argvars[0]), false);
rettv->v_type = VAR_STRING;
}
@@ -9494,27 +8621,26 @@ static void f_fnameescape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_fnamemodify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *fname;
- char_u *mods;
- size_t usedlen = 0;
+ char_u *fbuf = NULL;
size_t len;
- char_u *fbuf = NULL;
- char_u buf[NUMBUFLEN];
-
- fname = get_tv_string_chk(&argvars[0]);
- mods = get_tv_string_buf_chk(&argvars[1], buf);
- if (fname == NULL || mods == NULL)
+ char buf[NUMBUFLEN];
+ const char *fname = tv_get_string_chk(&argvars[0]);
+ const char *const mods = tv_get_string_buf_chk(&argvars[1], buf);
+ if (fname == NULL || mods == NULL) {
fname = NULL;
- else {
- len = STRLEN(fname);
- (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len);
+ } else {
+ len = strlen(fname);
+ size_t usedlen = 0;
+ (void)modify_fname((char_u *)mods, &usedlen, (char_u **)&fname, &fbuf,
+ &len);
}
rettv->v_type = VAR_STRING;
- if (fname == NULL)
+ if (fname == NULL) {
rettv->vval.v_string = NULL;
- else
- rettv->vval.v_string = vim_strnsave(fname, len);
+ } else {
+ rettv->vval.v_string = (char_u *)xmemdupz(fname, len);
+ }
xfree(fbuf);
}
@@ -9524,16 +8650,16 @@ static void f_fnamemodify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end)
{
- linenr_T lnum;
- linenr_T first, last;
-
- lnum = get_tv_lnum(argvars);
+ const linenr_T lnum = tv_get_lnum(argvars);
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
- if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) {
- if (end)
+ linenr_T first;
+ linenr_T last;
+ if (hasFoldingWin(curwin, lnum, &first, &last, false, NULL)) {
+ if (end) {
rettv->vval.v_number = (varnumber_T)last;
- else
+ } else {
rettv->vval.v_number = (varnumber_T)first;
+ }
return;
}
}
@@ -9561,11 +8687,10 @@ static void f_foldclosedend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_foldlevel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
-
- lnum = get_tv_lnum(argvars);
- if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
+ const linenr_T lnum = tv_get_lnum(argvars);
+ if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
rettv->vval.v_number = foldLevel(lnum);
+ }
}
/*
@@ -9573,24 +8698,28 @@ static void f_foldlevel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
+ linenr_T foldstart;
+ linenr_T foldend;
+ char_u *dashes;
+ linenr_T lnum;
char_u *s;
char_u *r;
- int len;
+ int len;
char *txt;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
- if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0
- && (linenr_T)vimvars[VV_FOLDEND].vv_nr
- <= curbuf->b_ml.ml_line_count
- && vimvars[VV_FOLDDASHES].vv_str != NULL) {
+
+ foldstart = (linenr_T)get_vim_var_nr(VV_FOLDSTART);
+ foldend = (linenr_T)get_vim_var_nr(VV_FOLDEND);
+ dashes = get_vim_var_str(VV_FOLDDASHES);
+ if (foldstart > 0 && foldend <= curbuf->b_ml.ml_line_count
+ && dashes != 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))
+ for (lnum = foldstart; lnum < foldend; ++lnum) {
+ if (!linewhite(lnum)) {
break;
- ++lnum;
+ }
}
/* Find interesting text in this line. */
@@ -9598,21 +8727,19 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/* skip C comment-start */
if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) {
s = skipwhite(s + 2);
- if (*skipwhite(s) == NUL
- && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) {
+ if (*skipwhite(s) == NUL && lnum + 1 < foldend) {
s = skipwhite(ml_get(lnum + 1));
if (*s == '*')
s = skipwhite(s + 1);
}
}
- txt = _("+-%s%3ld lines: ");
+ unsigned long count = (unsigned long)(foldend - foldstart + 1);
+ txt = ngettext("+-%s%3ld line: ", "+-%s%3ld lines: ", count);
r = xmalloc(STRLEN(txt)
- + STRLEN(vimvars[VV_FOLDDASHES].vv_str) // for %s
- + 20 // for %3ld
- + STRLEN(s)); // concatenated
- sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str,
- (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr
- - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1));
+ + STRLEN(dashes) // for %s
+ + 20 // for %3ld
+ + STRLEN(s)); // concatenated
+ sprintf((char *)r, txt, dashes, count);
len = (int)STRLEN(r);
STRCAT(r, s);
/* remove 'foldmarker' and 'commentstring' */
@@ -9626,24 +8753,24 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
char_u *text;
- char_u buf[51];
+ char_u buf[FOLD_TEXT_LEN];
foldinfo_T foldinfo;
int fold_count;
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)
+ linenr_T lnum = tv_get_lnum(argvars);
+ // Treat illegal types and illegal string values for {lnum} the same.
+ if (lnum < 0) {
lnum = 0;
+ }
fold_count = foldedCount(curwin, lnum, &foldinfo);
if (fold_count > 0) {
- text = get_foldtext(curwin, lnum, lnum + fold_count - 1,
- &foldinfo, buf);
- if (text == buf)
+ text = get_foldtext(curwin, lnum, lnum + fold_count - 1, &foldinfo, buf);
+ if (text == buf) {
text = vim_strsave(text);
+ }
rettv->vval.v_string = text;
}
}
@@ -9655,15 +8782,14 @@ static void f_foreground(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
}
-/*
- * "function()" function
- */
-static void f_function(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+static void common_function(typval_T *argvars, typval_T *rettv,
+ bool is_funcref, FunPtr fptr)
{
char_u *s;
char_u *name;
bool use_string = false;
partial_T *arg_pt = NULL;
+ char_u *trans_name = NULL;
if (argvars[0].v_type == VAR_FUNC) {
// function(MyFunc, [arg], dict)
@@ -9672,18 +8798,31 @@ static void f_function(typval_T *argvars, typval_T *rettv, FunPtr fptr)
&& argvars[0].vval.v_partial != NULL) {
// function(dict.MyFunc, [arg])
arg_pt = argvars[0].vval.v_partial;
- s = arg_pt->pt_name;
+ s = partial_name(arg_pt);
} else {
// function('MyFunc', [arg], dict)
- s = get_tv_string(&argvars[0]);
+ s = (char_u *)tv_get_string(&argvars[0]);
use_string = true;
}
- if (s == NULL || *s == NUL || (use_string && ascii_isdigit(*s))) {
- EMSG2(_(e_invarg2), s);
- } else if (use_string && vim_strchr(s, AUTOLOAD_CHAR) == NULL
- && !function_exists(s)) {
+ if ((use_string && vim_strchr(s, AUTOLOAD_CHAR) == NULL) || is_funcref) {
+ name = s;
+ trans_name = trans_function_name(&name, false,
+ TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD
+ | TFN_NO_DEREF, NULL, NULL);
+ if (*name != NUL) {
+ s = NULL;
+ }
+ }
+ if (s == NULL || *s == NUL || (use_string && ascii_isdigit(*s))
+ || (is_funcref && trans_name == NULL)) {
+ emsgf(_(e_invarg2), (use_string
+ ? tv_get_string(&argvars[0])
+ : (const char *)s));
// Don't check an autoload name for existence here.
+ } else if (trans_name != NULL
+ && (is_funcref ? find_func(trans_name) == NULL
+ : !translated_function_exists((const char *)trans_name))) {
EMSG2(_("E700: Unknown function: %s"), s);
} else {
int dict_idx = 0;
@@ -9724,7 +8863,7 @@ static void f_function(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (argvars[dict_idx].v_type != VAR_DICT) {
EMSG(_("E922: expected a dict"));
xfree(name);
- return;
+ goto theend;
}
if (argvars[dict_idx].vval.v_dict == NULL) {
dict_idx = 0;
@@ -9735,7 +8874,7 @@ static void f_function(typval_T *argvars, typval_T *rettv, FunPtr fptr)
EMSG(_("E923: Second argument of function() must be "
"a list or a dict"));
xfree(name);
- return;
+ goto theend;
}
list = argvars[arg_idx].vval.v_list;
if (list == NULL || list->lv_len == 0) {
@@ -9743,61 +8882,64 @@ static void f_function(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
}
- if (dict_idx > 0 || arg_idx > 0 || arg_pt != NULL) {
- partial_T *pt = (partial_T *)xcalloc(1, sizeof(partial_T));
+ if (dict_idx > 0 || arg_idx > 0 || arg_pt != NULL || is_funcref) {
+ partial_T *const pt = xcalloc(1, sizeof(*pt));
// result is a VAR_PARTIAL
- if (pt != NULL) {
- if (arg_idx > 0 || (arg_pt != NULL && arg_pt->pt_argc > 0)) {
- listitem_T *li;
- int i = 0;
- int arg_len = 0;
- int lv_len = 0;
-
- if (arg_pt != NULL) {
- arg_len = arg_pt->pt_argc;
- }
- if (list != NULL) {
- lv_len = list->lv_len;
- }
- pt->pt_argc = arg_len + lv_len;
- pt->pt_argv = (typval_T *)xmalloc(sizeof(typval_T) * pt->pt_argc);
- if (pt->pt_argv == NULL) {
- xfree(pt);
- xfree(name);
- return;
- } else {
- for (i = 0; i < arg_len; i++) {
- copy_tv(&arg_pt->pt_argv[i], &pt->pt_argv[i]);
- }
- if (lv_len > 0) {
- for (li = list->lv_first; li != NULL; li = li->li_next) {
- copy_tv(&li->li_tv, &pt->pt_argv[i++]);
- }
- }
+ if (arg_idx > 0 || (arg_pt != NULL && arg_pt->pt_argc > 0)) {
+ const int arg_len = (arg_pt == NULL ? 0 : arg_pt->pt_argc);
+ const int lv_len = (list == NULL ? 0 : list->lv_len);
+
+ pt->pt_argc = arg_len + lv_len;
+ pt->pt_argv = xmalloc(sizeof(pt->pt_argv[0]) * pt->pt_argc);
+ if (pt->pt_argv == NULL) {
+ xfree(pt);
+ xfree(name);
+ goto theend;
+ }
+ int i = 0;
+ for (; i < arg_len; i++) {
+ tv_copy(&arg_pt->pt_argv[i], &pt->pt_argv[i]);
+ }
+ if (lv_len > 0) {
+ for (listitem_T *li = list->lv_first;
+ li != NULL;
+ li = li->li_next) {
+ tv_copy(&li->li_tv, &pt->pt_argv[i++]);
}
}
+ }
- // For "function(dict.func, [], dict)" and "func" is a partial
- // use "dict". That is backwards compatible.
- if (dict_idx > 0) {
- // The dict is bound explicitly, pt_auto is false
- pt->pt_dict = argvars[dict_idx].vval.v_dict;
+ // For "function(dict.func, [], dict)" and "func" is a partial
+ // use "dict". That is backwards compatible.
+ if (dict_idx > 0) {
+ // The dict is bound explicitly, pt_auto is false
+ pt->pt_dict = argvars[dict_idx].vval.v_dict;
+ (pt->pt_dict->dv_refcount)++;
+ } else if (arg_pt != NULL) {
+ // If the dict was bound automatically the result is also
+ // bound automatically.
+ pt->pt_dict = arg_pt->pt_dict;
+ pt->pt_auto = arg_pt->pt_auto;
+ if (pt->pt_dict != NULL) {
(pt->pt_dict->dv_refcount)++;
- } else if (arg_pt != NULL) {
- // If the dict was bound automatically the result is also
- // bound automatically.
- pt->pt_dict = arg_pt->pt_dict;
- pt->pt_auto = arg_pt->pt_auto;
- if (pt->pt_dict != NULL) {
- (pt->pt_dict->dv_refcount)++;
- }
}
+ }
- pt->pt_refcount = 1;
+ pt->pt_refcount = 1;
+ if (arg_pt != NULL && arg_pt->pt_func != NULL) {
+ pt->pt_func = arg_pt->pt_func;
+ func_ptr_ref(pt->pt_func);
+ xfree(name);
+ } else if (is_funcref) {
+ pt->pt_func = find_func(trans_name);
+ func_ptr_ref(pt->pt_func);
+ xfree(name);
+ } else {
pt->pt_name = name;
- func_ref(pt->pt_name);
+ func_ref(name);
}
+
rettv->v_type = VAR_PARTIAL;
rettv->vval.v_partial = pt;
} else {
@@ -9807,17 +8949,30 @@ static void f_function(typval_T *argvars, typval_T *rettv, FunPtr fptr)
func_ref(name);
}
}
+theend:
+ xfree(trans_name);
+}
+
+static void f_funcref(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ common_function(argvars, rettv, true, fptr);
+}
+
+static void f_function(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ common_function(argvars, rettv, false, fptr);
}
/// "garbagecollect()" function
static void f_garbagecollect(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- /* This is postponed until we are back at the toplevel, because we may be
- * using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". */
- want_garbage_collect = TRUE;
+ // 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;
+ if (argvars[0].v_type != VAR_UNKNOWN && tv_get_number(&argvars[0]) == 1) {
+ garbage_collect_at_exit = true;
+ }
}
/*
@@ -9833,20 +8988,21 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (argvars[0].v_type == VAR_LIST) {
if ((l = argvars[0].vval.v_list) != NULL) {
- int error = FALSE;
+ bool error = false;
- li = list_find(l, get_tv_number_chk(&argvars[1], &error));
- if (!error && li != NULL)
+ li = tv_list_find(l, tv_get_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)
+ di = tv_dict_find(d, tv_get_string(&argvars[1]), -1);
+ if (di != NULL) {
tv = &di->di_tv;
+ }
}
- } else if (argvars[0].v_type == VAR_PARTIAL
- || argvars[0].v_type == VAR_FUNC) {
+ } else if (tv_is_func(argvars[0])) {
partial_T *pt;
partial_T fref_pt;
@@ -9859,26 +9015,27 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (pt != NULL) {
- char_u *what = get_tv_string(&argvars[1]);
+ const char *const what = tv_get_string(&argvars[1]);
- if (STRCMP(what, "func") == 0 || STRCMP(what, "name") == 0) {
+ if (strcmp(what, "func") == 0 || strcmp(what, "name") == 0) {
rettv->v_type = (*what == 'f' ? VAR_FUNC : VAR_STRING);
- if (pt->pt_name != NULL) {
- rettv->vval.v_string = vim_strsave(pt->pt_name);
+ const char *const n = (const char *)partial_name(pt);
+ assert(n != NULL);
+ rettv->vval.v_string = (char_u *)xstrdup(n);
+ if (rettv->v_type == VAR_FUNC) {
+ func_ref(rettv->vval.v_string);
}
- } else if (STRCMP(what, "dict") == 0) {
+ } else if (strcmp(what, "dict") == 0) {
rettv->v_type = VAR_DICT;
rettv->vval.v_dict = pt->pt_dict;
if (pt->pt_dict != NULL) {
(pt->pt_dict->dv_refcount)++;
}
- } else if (STRCMP(what, "args") == 0) {
+ } else if (strcmp(what, "args") == 0) {
rettv->v_type = VAR_LIST;
- if (rettv_list_alloc(rettv) != NULL) {
- int i;
-
- for (i = 0; i < pt->pt_argc; i++) {
- list_append_tv(rettv->vval.v_list, &pt->pt_argv[i]);
+ if (tv_list_alloc_ret(rettv) != NULL) {
+ for (int i = 0; i < pt->pt_argc; i++) {
+ tv_list_append_tv(rettv->vval.v_list, &pt->pt_argv[i]);
}
}
} else {
@@ -9891,60 +9048,63 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (tv == NULL) {
- if (argvars[2].v_type != VAR_UNKNOWN)
- copy_tv(&argvars[2], rettv);
- } else
- copy_tv(tv, rettv);
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ tv_copy(&argvars[2], rettv);
+ }
+ } else {
+ tv_copy(tv, rettv);
+ }
}
/// Returns information about signs placed in a buffer as list of dicts.
static void get_buffer_signs(buf_T *buf, list_T *l)
{
for (signlist_T *sign = buf->b_signlist; sign; sign = sign->next) {
- dict_T *d = dict_alloc();
+ dict_T *const d = tv_dict_alloc();
- dict_add_nr_str(d, "id", sign->id, NULL);
- dict_add_nr_str(d, "lnum", sign->lnum, NULL);
- dict_add_nr_str(d, "name", 0L, sign_typenr2name(sign->typenr));
+ tv_dict_add_nr(d, S_LEN("id"), sign->id);
+ tv_dict_add_nr(d, S_LEN("lnum"), sign->lnum);
+ tv_dict_add_str(d, S_LEN("name"),
+ (const char *)sign_typenr2name(sign->typenr));
- list_append_dict(l, d);
+ tv_list_append_dict(l, d);
}
}
/// Returns buffer options, variables and other attributes in a dictionary.
static dict_T *get_buffer_info(buf_T *buf)
{
- dict_T *dict = dict_alloc();
-
- dict_add_nr_str(dict, "bufnr", buf->b_fnum, NULL);
- dict_add_nr_str(dict, "name", 0L,
- buf->b_ffname != NULL ? buf->b_ffname : (char_u *)"");
- dict_add_nr_str(dict, "lnum", buflist_findlnum(buf), NULL);
- dict_add_nr_str(dict, "loaded", buf->b_ml.ml_mfp != NULL, NULL);
- dict_add_nr_str(dict, "listed", buf->b_p_bl, NULL);
- dict_add_nr_str(dict, "changed", bufIsChanged(buf), NULL);
- dict_add_nr_str(dict, "changedtick", buf->b_changedtick, NULL);
- dict_add_nr_str(dict, "hidden",
- buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0,
- NULL);
+ dict_T *const dict = tv_dict_alloc();
+
+ tv_dict_add_nr(dict, S_LEN("bufnr"), buf->b_fnum);
+ tv_dict_add_str(dict, S_LEN("name"),
+ buf->b_ffname != NULL ? (const char *)buf->b_ffname : "");
+ tv_dict_add_nr(dict, S_LEN("lnum"),
+ buf == curbuf ? curwin->w_cursor.lnum : buflist_findlnum(buf));
+ tv_dict_add_nr(dict, S_LEN("loaded"), buf->b_ml.ml_mfp != NULL);
+ tv_dict_add_nr(dict, S_LEN("listed"), buf->b_p_bl);
+ tv_dict_add_nr(dict, S_LEN("changed"), bufIsChanged(buf));
+ tv_dict_add_nr(dict, S_LEN("changedtick"), buf->b_changedtick);
+ tv_dict_add_nr(dict, S_LEN("hidden"),
+ buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0);
// Get a reference to buffer variables
- dict_add_dict(dict, "variables", buf->b_vars);
+ tv_dict_add_dict(dict, S_LEN("variables"), buf->b_vars);
// List of windows displaying this buffer
- list_T *windows = list_alloc();
+ list_T *const windows = tv_list_alloc();
FOR_ALL_TAB_WINDOWS(tp, wp) {
if (wp->w_buffer == buf) {
- list_append_number(windows, (varnumber_T)wp->handle);
+ tv_list_append_number(windows, (varnumber_T)wp->handle);
}
}
- dict_add_list(dict, "windows", windows);
+ tv_dict_add_list(dict, S_LEN("windows"), windows);
if (buf->b_signlist != NULL) {
// List of signs placed in this buffer
- list_T *signs = list_alloc();
+ list_T *const signs = tv_list_alloc();
get_buffer_signs(buf, signs);
- dict_add_list(dict, "signs", signs);
+ tv_dict_add_list(dict, S_LEN("signs"), signs);
}
return dict;
@@ -9958,7 +9118,7 @@ static void f_getbufinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
bool sel_buflisted = false;
bool sel_bufloaded = false;
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
// List of all the buffers or selected buffers
if (argvars[0].v_type == VAR_DICT) {
@@ -9969,24 +9129,25 @@ static void f_getbufinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
filtered = true;
- di = dict_find(sel_d, (char_u *)"buflisted", -1);
- if (di != NULL && get_tv_number(&di->di_tv)) {
+ di = tv_dict_find(sel_d, S_LEN("buflisted"));
+ if (di != NULL && tv_get_number(&di->di_tv)) {
sel_buflisted = true;
}
- di = dict_find(sel_d, (char_u *)"bufloaded", -1);
- if (di != NULL && get_tv_number(&di->di_tv)) {
+ di = tv_dict_find(sel_d, S_LEN("bufloaded"));
+ if (di != NULL && tv_get_number(&di->di_tv)) {
sel_bufloaded = true;
}
}
} else if (argvars[0].v_type != VAR_UNKNOWN) {
// Information about one buffer. Argument specifies the buffer
- (void)get_tv_number(&argvars[0]); // issue errmsg if type error
- emsg_off++;
- argbuf = get_buf_tv(&argvars[0], false);
- emsg_off--;
- if (argbuf == NULL) {
- return;
+ if (tv_check_num(&argvars[0])) { // issue errmsg if type error
+ emsg_off++;
+ argbuf = get_buf_tv(&argvars[0], false);
+ emsg_off--;
+ if (argbuf == NULL) {
+ return;
+ }
}
}
@@ -10000,9 +9161,9 @@ static void f_getbufinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
continue;
}
- dict_T *d = get_buffer_info(buf);
+ dict_T *const d = get_buffer_info(buf);
if (d != NULL) {
- list_append_dict(rettv->vval.v_list, d);
+ tv_list_append_dict(rettv->vval.v_list, d);
}
if (argbuf != NULL) {
return;
@@ -10023,7 +9184,7 @@ static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retli
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
if (retlist) {
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
}
if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0)
@@ -10044,33 +9205,54 @@ static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retli
if (end > buf->b_ml.ml_line_count)
end = buf->b_ml.ml_line_count;
while (start <= end) {
- list_append_string(
- rettv->vval.v_list, ml_get_buf(buf, start++, FALSE), -1);
+ tv_list_append_string(rettv->vval.v_list,
+ (const char *)ml_get_buf(buf, start++, false), -1);
}
}
}
+/// Get the line number from VimL object
+///
+/// @note Unlike tv_get_lnum(), this one supports only "$" special string.
+///
+/// @param[in] tv Object to get value from. Is expected to be a number or
+/// a special string "$".
+/// @param[in] buf Buffer to take last line number from in case tv is "$". May
+/// be NULL, in this case "$" results in zero return.
+///
+/// @return Line number or 0 in case of error.
+static linenr_T tv_get_lnum_buf(const typval_T *const tv,
+ const buf_T *const buf)
+ FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (tv->v_type == VAR_STRING
+ && tv->vval.v_string != NULL
+ && tv->vval.v_string[0] == '$'
+ && buf != NULL) {
+ return buf->b_ml.ml_line_count;
+ }
+ return tv_get_number_chk(tv, NULL);
+}
+
/*
* "getbufline()" function
*/
static void f_getbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
- linenr_T end;
- buf_T *buf;
+ buf_T *buf = NULL;
- (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */
- ++emsg_off;
- buf = get_buf_tv(&argvars[0], FALSE);
- --emsg_off;
+ if (tv_check_str_or_nr(&argvars[0])) {
+ emsg_off++;
+ buf = 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);
+ const linenr_T lnum = tv_get_lnum_buf(&argvars[1], buf);
+ const linenr_T end = (argvars[2].v_type == VAR_UNKNOWN
+ ? lnum
+ : tv_get_lnum_buf(&argvars[2], buf));
- get_buffer_lines(buf, lnum, end, TRUE, rettv);
+ get_buffer_lines(buf, lnum, end, true, rettv);
}
/*
@@ -10078,26 +9260,25 @@ static void f_getbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
- buf_T *save_curbuf;
- char_u *varname;
- dictitem_T *v;
- int done = FALSE;
-
- (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */
- varname = get_tv_string_chk(&argvars[1]);
- ++emsg_off;
- buf = get_buf_tv(&argvars[0], FALSE);
+ bool done = false;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
+ if (!tv_check_str_or_nr(&argvars[0])) {
+ goto f_getbufvar_end;
+ }
+
+ const char *varname = tv_get_string_chk(&argvars[1]);
+ emsg_off++;
+ buf_T *const buf = get_buf_tv(&argvars[0], false);
+
if (buf != NULL && varname != NULL) {
- /* set curbuf to be our buf, temporarily */
- save_curbuf = curbuf;
+ // set curbuf to be our buf, temporarily
+ buf_T *const save_curbuf = curbuf;
curbuf = buf;
- if (*varname == '&') { // buffer-local-option
+ if (*varname == '&') { // buffer-local-option
if (varname[1] == NUL) {
// get all buffer-local options in a dict
dict_T *opts = get_winbuf_options(true);
@@ -10112,30 +9293,27 @@ static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// buffer-local-option
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);
+ // Look up the variable.
+ // Let getbufvar({nr}, "") return the "b:" dictionary.
+ dictitem_T *const v = find_var_in_ht(&curbuf->b_vars->dv_hashtab, 'b',
+ varname, strlen(varname), false);
if (v != NULL) {
- copy_tv(&v->di_tv, rettv);
- done = TRUE;
+ tv_copy(&v->di_tv, rettv);
+ done = true;
}
}
- /* restore previous notion of curbuf */
+ // restore previous notion of curbuf
curbuf = save_curbuf;
}
+ emsg_off--;
- if (!done && argvars[2].v_type != VAR_UNKNOWN)
- /* use the default value */
- copy_tv(&argvars[2], rettv);
-
- --emsg_off;
+f_getbufvar_end:
+ if (!done && argvars[2].v_type != VAR_UNKNOWN) {
+ // use the default value
+ tv_copy(&argvars[2], rettv);
+ }
}
/*
@@ -10144,10 +9322,9 @@ static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
varnumber_T n;
- int error = FALSE;
+ bool error = false;
- ++no_mapping;
- ++allow_keys;
+ no_mapping++;
for (;; ) {
// Position the cursor. Needed after a message that ends in a space,
// or if event processing caused a redraw.
@@ -10165,7 +9342,7 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
n = safe_vgetc();
- } else if (get_tv_number_chk(&argvars[0], &error) == 1) {
+ } else if (tv_get_number_chk(&argvars[0], &error) == 1) {
// getchar(1): only check if char avail
n = vpeekc_any();
} else if (error || vpeekc_any() == NUL) {
@@ -10176,12 +9353,12 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
n = safe_vgetc();
}
- if (n == K_IGNORE)
+ if (n == K_IGNORE) {
continue;
+ }
break;
}
- --no_mapping;
- --allow_keys;
+ no_mapping--;
vimvars[VV_MOUSE_WIN].vv_nr = 0;
vimvars[VV_MOUSE_WINID].vv_nr = 0;
@@ -10248,13 +9425,13 @@ static void f_getcharmod(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_getcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv_dict_alloc(rettv);
+ tv_dict_alloc_ret(rettv);
dict_T *dict = rettv->vval.v_dict;
- dict_add_nr_str(dict, "char", 0L, last_csearch());
- dict_add_nr_str(dict, "forward", last_csearch_forward(), NULL);
- dict_add_nr_str(dict, "until", last_csearch_until(), NULL);
+ tv_dict_add_str(dict, S_LEN("char"), last_csearch());
+ tv_dict_add_nr(dict, S_LEN("forward"), last_csearch_forward());
+ tv_dict_add_nr(dict, S_LEN("until"), last_csearch_until());
}
/*
@@ -10305,7 +9482,7 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
| WILD_NO_BEEP;
if (argvars[2].v_type != VAR_UNKNOWN) {
- filtered = get_tv_number_chk(&argvars[2], NULL);
+ filtered = (bool)tv_get_number_chk(&argvars[2], NULL);
}
if (p_wic) {
@@ -10317,41 +9494,51 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
options |= WILD_KEEP_ALL;
}
+ if (argvars[0].v_type != VAR_STRING || argvars[1].v_type != VAR_STRING) {
+ EMSG(_(e_invarg));
+ return;
+ }
+
+ if (strcmp(tv_get_string(&argvars[1]), "cmdline") == 0) {
+ set_one_cmd_context(&xpc, tv_get_string(&argvars[0]));
+ xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
+ goto theend;
+ }
+
ExpandInit(&xpc);
- xpc.xp_pattern = get_tv_string(&argvars[0]);
- xpc.xp_pattern_len = STRLEN(xpc.xp_pattern);
- xpc.xp_context = cmdcomplete_str_to_type(get_tv_string(&argvars[1]));
+ xpc.xp_pattern = (char_u *)tv_get_string(&argvars[0]);
+ xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
+ xpc.xp_context = cmdcomplete_str_to_type(
+ (char_u *)tv_get_string(&argvars[1]));
if (xpc.xp_context == EXPAND_NOTHING) {
- if (argvars[1].v_type == VAR_STRING) {
- EMSG2(_(e_invarg2), argvars[1].vval.v_string);
- } else {
- EMSG(_(e_invarg));
- }
+ EMSG2(_(e_invarg2), argvars[1].vval.v_string);
return;
}
if (xpc.xp_context == EXPAND_MENUS) {
set_context_in_menu_cmd(&xpc, (char_u *)"menu", xpc.xp_pattern, false);
- xpc.xp_pattern_len = STRLEN(xpc.xp_pattern);
+ xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
}
if (xpc.xp_context == EXPAND_CSCOPE) {
- set_context_in_cscope_cmd(&xpc, xpc.xp_pattern, CMD_cscope);
- xpc.xp_pattern_len = STRLEN(xpc.xp_pattern);
+ set_context_in_cscope_cmd(&xpc, (const char *)xpc.xp_pattern, CMD_cscope);
+ xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
}
if (xpc.xp_context == EXPAND_SIGN) {
set_context_in_sign_cmd(&xpc, xpc.xp_pattern);
- xpc.xp_pattern_len = STRLEN(xpc.xp_pattern);
+ xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
}
+theend:
pat = addstar(xpc.xp_pattern, xpc.xp_pattern_len, xpc.xp_context);
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
if (pat != NULL) {
ExpandOne(&xpc, pat, NULL, options, WILD_ALL_KEEP);
for (int i = 0; i < xpc.xp_numfiles; i++) {
- list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1);
+ tv_list_append_string(rettv->vval.v_list, (const char *)xpc.xp_files[i],
+ -1);
}
}
xfree(pat);
@@ -10452,13 +9639,15 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (from) {
break;
}
- case kCdScopeTab: // FALLTHROUGH
+ // fallthrough
+ case kCdScopeTab:
assert(tp);
- from = tp->localdir;
+ from = tp->tp_localdir;
if (from) {
break;
}
- case kCdScopeGlobal: // FALLTHROUGH
+ // fallthrough
+ case kCdScopeGlobal:
if (globaldir) { // `globaldir` is not always set.
from = globaldir;
} else if (os_dirname(cwd, MAXPATHL) == FAIL) { // Get the OS CWD.
@@ -10495,20 +9684,21 @@ static void f_getfontname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_getfperm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *perm = NULL;
+ char *perm = NULL;
char_u flags[] = "rwx";
- char_u *filename = get_tv_string(&argvars[0]);
+ const char *filename = tv_get_string(&argvars[0]);
int32_t file_perm = os_getperm(filename);
if (file_perm >= 0) {
- perm = vim_strsave((char_u *)"---------");
+ perm = xstrdup("---------");
for (int i = 0; i < 9; i++) {
- if (file_perm & (1 << (8 - i)))
+ if (file_perm & (1 << (8 - i))) {
perm[i] = flags[i % 3];
+ }
}
}
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = perm;
+ rettv->vval.v_string = (char_u *)perm;
}
/*
@@ -10516,16 +9706,16 @@ static void f_getfperm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_getfsize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char *fname = (char *)get_tv_string(&argvars[0]);
+ const char *fname = tv_get_string(&argvars[0]);
rettv->v_type = VAR_NUMBER;
FileInfo file_info;
if (os_fileinfo(fname, &file_info)) {
uint64_t filesize = os_fileinfo_size(&file_info);
- if (os_isdir((char_u *)fname))
+ if (os_isdir((const char_u *)fname)) {
rettv->vval.v_number = 0;
- else {
+ } else {
rettv->vval.v_number = (varnumber_T)filesize;
/* non-perfect check for overflow */
@@ -10543,7 +9733,7 @@ static void f_getfsize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_getftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char *fname = (char *)get_tv_string(&argvars[0]);
+ const char *fname = tv_get_string(&argvars[0]);
FileInfo file_info;
if (os_fileinfo(fname, &file_info)) {
@@ -10558,15 +9748,14 @@ static void f_getftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_getftype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *fname;
char_u *type = NULL;
char *t;
- fname = get_tv_string(&argvars[0]);
+ const char *fname = tv_get_string(&argvars[0]);
rettv->v_type = VAR_STRING;
FileInfo file_info;
- if (os_fileinfo_link((char *)fname, &file_info)) {
+ if (os_fileinfo_link(fname, &file_info)) {
uint64_t mode = file_info.stat.st_mode;
#ifdef S_ISREG
if (S_ISREG(mode))
@@ -10618,10 +9807,11 @@ static void f_getftype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
default: t = "other";
}
# else
- if (os_isdir(fname))
+ if (os_isdir((const char_u *)fname)) {
t = "dir";
- else
+ } else {
t = "file";
+ }
# endif
#endif
type = vim_strsave((char_u *)t);
@@ -10634,22 +9824,52 @@ static void f_getftype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_getline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
linenr_T end;
- int retlist;
+ bool retlist;
- lnum = get_tv_lnum(argvars);
+ const linenr_T lnum = tv_get_lnum(argvars);
if (argvars[1].v_type == VAR_UNKNOWN) {
end = 0;
- retlist = FALSE;
+ retlist = false;
} else {
- end = get_tv_lnum(&argvars[1]);
- retlist = TRUE;
+ end = tv_get_lnum(&argvars[1]);
+ retlist = true;
}
get_buffer_lines(curbuf, lnum, end, retlist, rettv);
}
+static void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg,
+ typval_T *rettv)
+{
+ if (what_arg->v_type == VAR_UNKNOWN) {
+ tv_list_alloc_ret(rettv);
+ if (is_qf || wp != NULL) {
+ (void)get_errorlist(wp, -1, rettv->vval.v_list);
+ }
+ } else {
+ tv_dict_alloc_ret(rettv);
+ if (is_qf || wp != NULL) {
+ if (what_arg->v_type == VAR_DICT) {
+ dict_T *d = what_arg->vval.v_dict;
+
+ if (d != NULL) {
+ get_errorlist_properties(wp, d, rettv->vval.v_dict);
+ }
+ } else {
+ EMSG(_(e_dictreq));
+ }
+ }
+ }
+}
+
+/// "getloclist()" function
+static void f_getloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ win_T *wp = find_win_by_nr(&argvars[0], NULL);
+ get_qf_loc_list(false, wp, &argvars[1], rettv);
+}
+
/*
* "getmatches()" function
*/
@@ -10658,43 +9878,45 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
matchitem_T *cur = curwin->w_match_head;
int i;
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
while (cur != NULL) {
- dict_T *dict = dict_alloc();
+ dict_T *dict = tv_dict_alloc();
if (cur->match.regprog == NULL) {
// match added with matchaddpos()
for (i = 0; i < MAXPOSMATCH; ++i) {
llpos_T *llpos;
- char buf[6];
+ char buf[6];
llpos = &cur->pos.pos[i];
if (llpos->lnum == 0) {
break;
}
- list_T *l = list_alloc();
- list_append_number(l, (varnumber_T)llpos->lnum);
+ list_T *l = tv_list_alloc();
+ tv_list_append_number(l, (varnumber_T)llpos->lnum);
if (llpos->col > 0) {
- list_append_number(l, (varnumber_T)llpos->col);
- list_append_number(l, (varnumber_T)llpos->len);
+ tv_list_append_number(l, (varnumber_T)llpos->col);
+ tv_list_append_number(l, (varnumber_T)llpos->len);
}
- sprintf(buf, "pos%d", i + 1);
- dict_add_list(dict, buf, l);
+ int len = snprintf(buf, sizeof(buf), "pos%d", i + 1);
+ assert((size_t)len < sizeof(buf));
+ tv_dict_add_list(dict, buf, (size_t)len, l);
}
} else {
- dict_add_nr_str(dict, "pattern", 0L, cur->pattern);
+ tv_dict_add_str(dict, S_LEN("pattern"), (const char *)cur->pattern);
}
- dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id));
- dict_add_nr_str(dict, "priority", (long)cur->priority, NULL);
- dict_add_nr_str(dict, "id", (long)cur->id, NULL);
+ tv_dict_add_str(dict, S_LEN("group"),
+ (const char *)syn_id2name(cur->hlg_id));
+ tv_dict_add_nr(dict, S_LEN("priority"), (varnumber_T)cur->priority);
+ tv_dict_add_nr(dict, S_LEN("id"), (varnumber_T)cur->id);
if (cur->conceal_char) {
- char_u buf[MB_MAXBYTES + 1];
+ char buf[MB_MAXBYTES + 1];
- buf[(*mb_char2bytes)((int)cur->conceal_char, buf)] = NUL;
- dict_add_nr_str(dict, "conceal", 0L, (char_u *)&buf);
+ buf[(*mb_char2bytes)((int)cur->conceal_char, (char_u *)buf)] = NUL;
+ tv_dict_add_str(dict, S_LEN("conceal"), buf);
}
- list_append_dict(rettv->vval.v_list, dict);
+ tv_list_append_dict(rettv->vval.v_list, dict);
cur = cur->next;
}
}
@@ -10718,20 +9940,22 @@ static void getpos_both(typval_T *argvars, typval_T *rettv, bool getcurpos)
fp = var2fpos(&argvars[0], true, &fnum);
}
- list_T *l = rettv_list_alloc(rettv);
- list_append_number(l, (fnum != -1) ? (varnumber_T)fnum : (varnumber_T)0);
- list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum : (varnumber_T)0);
- list_append_number(l,
- (fp != NULL)
- ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1)
- : (varnumber_T)0);
- list_append_number(l,
- (fp != NULL) ? (varnumber_T)fp->coladd : (varnumber_T)0);
+ list_T *l = tv_list_alloc_ret(rettv);
+ tv_list_append_number(l, (fnum != -1) ? (varnumber_T)fnum : (varnumber_T)0);
+ tv_list_append_number(l, ((fp != NULL)
+ ? (varnumber_T)fp->lnum
+ : (varnumber_T)0));
+ tv_list_append_number(
+ l, ((fp != NULL)
+ ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1)
+ : (varnumber_T)0));
+ tv_list_append_number(
+ l, (fp != NULL) ? (varnumber_T)fp->coladd : (varnumber_T)0);
if (getcurpos) {
update_curswant();
- list_append_number(l, curwin->w_curswant == MAXCOL
+ tv_list_append_number(l, (curwin->w_curswant == MAXCOL
? (varnumber_T)MAXCOL
- : (varnumber_T)curwin->w_curswant + 1);
+ : (varnumber_T)curwin->w_curswant + 1));
}
}
@@ -10751,58 +9975,48 @@ static void f_getpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
getpos_both(argvars, rettv, false);
}
-/*
- * "getqflist()" and "getloclist()" functions
- */
+/// "getqflist()" functions
static void f_getqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv_list_alloc(rettv);
- win_T *wp = NULL;
- if (argvars[0].v_type != VAR_UNKNOWN) { /* getloclist() */
- wp = find_win_by_nr(&argvars[0], NULL);
- if (wp == NULL) {
- return;
- }
- }
- (void)get_errorlist(wp, rettv->vval.v_list);
+ get_qf_loc_list(true, NULL, &argvars[0], rettv);
}
/// "getreg()" function
static void f_getreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *strregname;
- int regname;
+ const char *strregname;
int arg2 = false;
bool return_list = false;
- int error = false;
+ bool error = false;
if (argvars[0].v_type != VAR_UNKNOWN) {
- strregname = get_tv_string_chk(&argvars[0]);
+ strregname = tv_get_string_chk(&argvars[0]);
error = strregname == NULL;
if (argvars[1].v_type != VAR_UNKNOWN) {
- arg2 = get_tv_number_chk(&argvars[1], &error);
+ arg2 = tv_get_number_chk(&argvars[1], &error);
if (!error && argvars[2].v_type != VAR_UNKNOWN) {
- return_list = get_tv_number_chk(&argvars[2], &error);
+ return_list = tv_get_number_chk(&argvars[2], &error);
}
}
} else {
- strregname = vimvars[VV_REG].vv_str;
+ strregname = (const char *)vimvars[VV_REG].vv_str;
}
if (error) {
return;
}
- regname = (strregname == NULL ? '"' : *strregname);
- if (regname == 0)
+ int regname = (uint8_t)(strregname == NULL ? '"' : *strregname);
+ if (regname == 0) {
regname = '"';
+ }
if (return_list) {
rettv->v_type = VAR_LIST;
rettv->vval.v_list =
get_reg_contents(regname, (arg2 ? kGRegExprSrc : 0) | kGRegList);
if (rettv->vval.v_list == NULL) {
- rettv->vval.v_list = list_alloc();
+ rettv->vval.v_list = tv_list_alloc();
}
rettv->vval.v_list->lv_refcount++;
} else {
@@ -10816,23 +10030,24 @@ static void f_getreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_getregtype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *strregname;
- int regname;
+ const char *strregname;
if (argvars[0].v_type != VAR_UNKNOWN) {
- strregname = get_tv_string_chk(&argvars[0]);
- if (strregname == NULL) { /* type error; errmsg already given */
+ strregname = tv_get_string_chk(&argvars[0]);
+ if (strregname == NULL) { // Type error; errmsg already given.
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
return;
}
- } else
- /* Default to v:register */
- strregname = vimvars[VV_REG].vv_str;
+ } else {
+ // Default to v:register.
+ strregname = (const char *)vimvars[VV_REG].vv_str;
+ }
- regname = (strregname == NULL ? '"' : *strregname);
- if (regname == 0)
+ int regname = (uint8_t)(strregname == NULL ? '"' : *strregname);
+ if (regname == 0) {
regname = '"';
+ }
colnr_T reglen = 0;
char buf[NUMBUFLEN + 2];
@@ -10847,18 +10062,18 @@ static void f_getregtype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// as a dictionary.
static dict_T *get_tabpage_info(tabpage_T *tp, int tp_idx)
{
- dict_T *dict = dict_alloc();
+ dict_T *const dict = tv_dict_alloc();
- dict_add_nr_str(dict, "tabnr", tp_idx, NULL);
+ tv_dict_add_nr(dict, S_LEN("tabnr"), tp_idx);
- list_T *l = list_alloc();
+ list_T *const l = tv_list_alloc();
FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
- list_append_number(l, (varnumber_T)wp->handle);
+ tv_list_append_number(l, (varnumber_T)wp->handle);
}
- dict_add_list(dict, "windows", l);
+ tv_dict_add_list(dict, S_LEN("windows"), l);
// Make a reference to tabpage variables
- dict_add_dict(dict, "variables", tp->tp_vars);
+ tv_dict_add_dict(dict, S_LEN("variables"), tp->tp_vars);
return dict;
}
@@ -10868,11 +10083,11 @@ static void f_gettabinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
tabpage_T *tparg = NULL;
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
if (argvars[0].v_type != VAR_UNKNOWN) {
// Information about one tab page
- tparg = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
+ tparg = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
if (tparg == NULL) {
return;
}
@@ -10885,9 +10100,9 @@ static void f_gettabinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (tparg != NULL && tp != tparg) {
continue;
}
- dict_T *d = get_tabpage_info(tp, tpnr);
+ dict_T *const d = get_tabpage_info(tp, tpnr);
if (d != NULL) {
- list_append_dict(rettv->vval.v_list, d);
+ tv_list_append_dict(rettv->vval.v_list, d);
}
if (tparg != NULL) {
return;
@@ -10903,14 +10118,13 @@ static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
win_T *oldcurwin;
tabpage_T *tp, *oldtabpage;
dictitem_T *v;
- char_u *varname;
bool done = false;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
- varname = get_tv_string_chk(&argvars[1]);
- tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
+ const char *const varname = tv_get_string_chk(&argvars[1]);
+ tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
if (tp != NULL && varname != NULL) {
// Set tp to be our tabpage, temporarily. Also set the window to the
// first window in the tabpage, otherwise the window is not valid.
@@ -10918,9 +10132,10 @@ static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (switch_win(&oldcurwin, &oldtabpage, window, tp, true) == OK) {
// look up the variable
// Let gettabvar({nr}, "") return the "t:" dictionary.
- v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', varname, FALSE);
+ v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't',
+ varname, strlen(varname), false);
if (v != NULL) {
- copy_tv(&v->di_tv, rettv);
+ tv_copy(&v->di_tv, rettv);
done = true;
}
}
@@ -10930,7 +10145,7 @@ static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (!done && argvars[2].v_type != VAR_UNKNOWN) {
- copy_tv(&argvars[2], rettv);
+ tv_copy(&argvars[2], rettv);
}
}
@@ -10945,22 +10160,21 @@ static void f_gettabwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// Returns information about a window as a dictionary.
static dict_T *get_win_info(win_T *wp, int16_t tpnr, int16_t winnr)
{
- dict_T *dict = dict_alloc();
+ dict_T *const dict = tv_dict_alloc();
- dict_add_nr_str(dict, "tabnr", tpnr, NULL);
- dict_add_nr_str(dict, "winnr", winnr, NULL);
- dict_add_nr_str(dict, "winid", wp->handle, NULL);
- dict_add_nr_str(dict, "height", wp->w_height, NULL);
- dict_add_nr_str(dict, "width", wp->w_width, NULL);
- dict_add_nr_str(dict, "bufnr", wp->w_buffer->b_fnum, NULL);
+ tv_dict_add_nr(dict, S_LEN("tabnr"), tpnr);
+ tv_dict_add_nr(dict, S_LEN("winnr"), winnr);
+ tv_dict_add_nr(dict, S_LEN("winid"), wp->handle);
+ tv_dict_add_nr(dict, S_LEN("height"), wp->w_height);
+ tv_dict_add_nr(dict, S_LEN("width"), wp->w_width);
+ tv_dict_add_nr(dict, S_LEN("bufnr"), wp->w_buffer->b_fnum);
- dict_add_nr_str(dict, "quickfix", bt_quickfix(wp->w_buffer), NULL);
- dict_add_nr_str(dict, "loclist",
- (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL),
- NULL);
+ tv_dict_add_nr(dict, S_LEN("quickfix"), bt_quickfix(wp->w_buffer));
+ tv_dict_add_nr(dict, S_LEN("loclist"),
+ (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL));
// Add a reference to window variables
- dict_add_dict(dict, "variables", wp->w_vars);
+ tv_dict_add_dict(dict, S_LEN("variables"), wp->w_vars);
return dict;
}
@@ -10970,7 +10184,7 @@ static void f_getwininfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
win_T *wparg = NULL;
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
if (argvars[0].v_type != VAR_UNKNOWN) {
wparg = win_id2wp(argvars);
@@ -10990,9 +10204,9 @@ static void f_getwininfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
continue;
}
winnr++;
- dict_T *d = get_win_info(wp, tabnr, winnr);
+ dict_T *const d = get_win_info(wp, tabnr, winnr);
if (d != NULL) {
- list_append_dict(rettv->vval.v_list, d);
+ tv_list_append_dict(rettv->vval.v_list, d);
}
if (wparg != NULL) {
// found information about a specific window
@@ -11027,7 +10241,7 @@ find_win_by_nr (
tabpage_T *tp /* NULL for current tab page */
)
{
- int nr = get_tv_number_chk(vp, NULL);
+ int nr = (int)tv_get_number_chk(vp, NULL);
if (nr < 0) {
return NULL;
@@ -11062,7 +10276,7 @@ static win_T *find_tabwin(typval_T *wvp, typval_T *tvp)
if (wvp->v_type != VAR_UNKNOWN) {
if (tvp->v_type != VAR_UNKNOWN) {
- long n = get_tv_number(tvp);
+ long n = tv_get_number(tvp);
if (n >= 0) {
tp = find_tabpage(n);
}
@@ -11097,23 +10311,23 @@ getwinvar (
)
{
win_T *win, *oldcurwin;
- char_u *varname;
dictitem_T *v;
tabpage_T *tp = NULL;
tabpage_T *oldtabpage = NULL;
bool done = false;
- if (off == 1)
- tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
- else
+ if (off == 1) {
+ tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
+ } else {
tp = curtab;
+ }
win = find_win_by_nr(&argvars[off], tp);
- varname = get_tv_string_chk(&argvars[off + 1]);
- ++emsg_off;
+ const char *varname = tv_get_string_chk(&argvars[off + 1]);
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
+ emsg_off++;
if (win != NULL && varname != NULL) {
// Set curwin to be our win, temporarily. Also set the tabpage,
// otherwise the window is not valid. Only do this when needed,
@@ -11139,9 +10353,10 @@ getwinvar (
} else {
// Look up the variable.
// Let getwinvar({nr}, "") return the "w:" dictionary.
- v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', varname, FALSE);
+ v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', varname,
+ strlen(varname), false);
if (v != NULL) {
- copy_tv(&v->di_tv, rettv);
+ tv_copy(&v->di_tv, rettv);
done = true;
}
}
@@ -11152,12 +10367,12 @@ getwinvar (
restore_win(oldcurwin, oldtabpage, true);
}
}
+ emsg_off--;
- if (!done && argvars[off + 2].v_type != VAR_UNKNOWN)
- /* use the default return value */
- copy_tv(&argvars[off + 2], rettv);
-
- --emsg_off;
+ if (!done && argvars[off + 2].v_type != VAR_UNKNOWN) {
+ // use the default return value
+ tv_copy(&argvars[off + 2], rettv);
+ }
}
/*
@@ -11167,21 +10382,22 @@ static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int options = WILD_SILENT|WILD_USE_NL;
expand_T xpc;
- int error = FALSE;
+ bool error = false;
/* When the optional second argument is non-zero, don't remove matches
* for 'wildignore' and don't put matches for 'suffixes' at the end. */
rettv->v_type = VAR_STRING;
if (argvars[1].v_type != VAR_UNKNOWN) {
- if (get_tv_number_chk(&argvars[1], &error))
+ if (tv_get_number_chk(&argvars[1], &error)) {
options |= WILD_KEEP_ALL;
+ }
if (argvars[2].v_type != VAR_UNKNOWN) {
- if (get_tv_number_chk(&argvars[2], &error)) {
+ if (tv_get_number_chk(&argvars[2], &error)) {
rettv->v_type = VAR_LIST;
rettv->vval.v_list = NULL;
}
if (argvars[3].v_type != VAR_UNKNOWN
- && get_tv_number_chk(&argvars[3], &error)) {
+ && tv_get_number_chk(&argvars[3], &error)) {
options |= WILD_ALLLINKS;
}
}
@@ -11191,14 +10407,16 @@ static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr)
xpc.xp_context = EXPAND_FILES;
if (p_wic)
options += WILD_ICASE;
- if (rettv->v_type == VAR_STRING)
- rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]),
- NULL, options, WILD_ALL);
- else {
- rettv_list_alloc(rettv);
- ExpandOne(&xpc, get_tv_string(&argvars[0]), NULL, options, WILD_ALL_KEEP);
+ if (rettv->v_type == VAR_STRING) {
+ rettv->vval.v_string = ExpandOne(
+ &xpc, (char_u *)tv_get_string(&argvars[0]), NULL, options, WILD_ALL);
+ } else {
+ tv_list_alloc_ret(rettv);
+ ExpandOne(&xpc, (char_u *)tv_get_string(&argvars[0]), NULL, options,
+ WILD_ALL_KEEP);
for (int i = 0; i < xpc.xp_numfiles; i++) {
- list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1);
+ tv_list_append_string(rettv->vval.v_list, (const char *)xpc.xp_files[i],
+ -1);
}
ExpandCleanup(&xpc);
}
@@ -11210,7 +10428,7 @@ static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int flags = 0; // Flags for globpath.
- int error = false;
+ bool error = false;
// Return a string, or a list if the optional third argument is non-zero.
rettv->v_type = VAR_STRING;
@@ -11218,36 +10436,36 @@ static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (argvars[2].v_type != VAR_UNKNOWN) {
// When the optional second argument is non-zero, don't remove matches
// for 'wildignore' and don't put matches for 'suffixes' at the end.
- if (get_tv_number_chk(&argvars[2], &error)) {
+ if (tv_get_number_chk(&argvars[2], &error)) {
flags |= WILD_KEEP_ALL;
}
if (argvars[3].v_type != VAR_UNKNOWN) {
- if (get_tv_number_chk(&argvars[3], &error)) {
+ if (tv_get_number_chk(&argvars[3], &error)) {
rettv->v_type = VAR_LIST;
rettv->vval.v_list = NULL;
}
if (argvars[4].v_type != VAR_UNKNOWN
- && get_tv_number_chk(&argvars[4], &error)) {
+ && tv_get_number_chk(&argvars[4], &error)) {
flags |= WILD_ALLLINKS;
}
}
}
- char_u buf1[NUMBUFLEN];
- char_u *file = get_tv_string_buf_chk(&argvars[1], buf1);
+ char buf1[NUMBUFLEN];
+ const char *const file = tv_get_string_buf_chk(&argvars[1], buf1);
if (file != NULL && !error) {
garray_T ga;
ga_init(&ga, (int)sizeof(char_u *), 10);
- globpath(get_tv_string(&argvars[0]), file, &ga, flags);
+ globpath((char_u *)tv_get_string(&argvars[0]), (char_u *)file, &ga, flags);
if (rettv->v_type == VAR_STRING) {
rettv->vval.v_string = ga_concat_strings_sep(&ga, "\n");
} else {
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
for (int i = 0; i < ga.ga_len; i++) {
- list_append_string(rettv->vval.v_list,
- ((char_u **)(ga.ga_data))[i], -1);
+ tv_list_append_string(rettv->vval.v_list,
+ ((const char **)(ga.ga_data))[i], -1);
}
}
@@ -11260,18 +10478,19 @@ static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// "glob2regpat()" function
static void f_glob2regpat(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *pat = get_tv_string_chk(&argvars[0]); // NULL on type error
+ const char *const pat = tv_get_string_chk(&argvars[0]); // NULL on type error
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (pat == NULL)
- ? NULL
- : file_pat_to_reg_pat(pat, NULL, NULL, false);
+ rettv->vval.v_string = ((pat == NULL)
+ ? NULL
+ : file_pat_to_reg_pat((char_u *)pat, NULL, NULL,
+ false));
}
/// "has()" function
static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- static char *(has_list[]) = {
+ static const char *const has_list[] = {
#ifdef UNIX
"unix",
#endif
@@ -11322,6 +10541,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
"insert_expand",
"jumplist",
"keymap",
+ "lambda",
"langmap",
"libcall",
"linebreak",
@@ -11338,6 +10558,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
"mouse",
"multi_byte",
"multi_lang",
+ "num64",
"packages",
"path_extra",
"persistent_undo",
@@ -11381,13 +10602,11 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
"winaltkeys",
"writebackup",
"nvim",
- NULL
};
bool n = false;
- char *name = (char *)get_tv_string(&argvars[0]);
-
- for (int i = 0; has_list[i] != NULL; i++) {
+ const char *const name = tv_get_string(&argvars[0]);
+ for (size_t i = 0; i < ARRAY_SIZE(has_list); i++) {
if (STRICMP(name, has_list[i]) == 0) {
n = true;
break;
@@ -11426,6 +10645,10 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
#endif
} else if (STRICMP(name, "syntax_items") == 0) {
n = syntax_present(curwin);
+#ifdef UNIX
+ } else if (STRICMP(name, "unnamedplus") == 0) {
+ n = eval_has_provider("clipboard");
+#endif
}
}
@@ -11448,8 +10671,9 @@ static void f_has_key(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (argvars[0].vval.v_dict == NULL)
return;
- rettv->vval.v_number = dict_find(argvars[0].vval.v_dict,
- get_tv_string(&argvars[1]), -1) != NULL;
+ rettv->vval.v_number = tv_dict_find(argvars[0].vval.v_dict,
+ tv_get_string(&argvars[1]),
+ -1) != NULL;
}
/// `haslocaldir([{win}[, {tab}]])` function
@@ -11541,7 +10765,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
break;
case kCdScopeTab:
assert(tp);
- rettv->vval.v_number = tp->localdir ? 1 : 0;
+ rettv->vval.v_number = tp->tp_localdir ? 1 : 0;
break;
case kCdScopeGlobal:
// The global scope never has a local directory
@@ -11558,24 +10782,24 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_hasmapto(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *name;
- char_u *mode;
- char_u buf[NUMBUFLEN];
- int abbr = FALSE;
-
- name = get_tv_string(&argvars[0]);
- if (argvars[1].v_type == VAR_UNKNOWN)
- mode = (char_u *)"nvo";
- else {
- mode = get_tv_string_buf(&argvars[1], buf);
- if (argvars[2].v_type != VAR_UNKNOWN)
- abbr = get_tv_number(&argvars[2]);
+ const char *mode;
+ const char *const name = tv_get_string(&argvars[0]);
+ bool abbr = false;
+ char buf[NUMBUFLEN];
+ if (argvars[1].v_type == VAR_UNKNOWN) {
+ mode = "nvo";
+ } else {
+ mode = tv_get_string_buf(&argvars[1], buf);
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ abbr = tv_get_number(&argvars[2]);
+ }
}
- if (map_to_exists(name, mode, abbr))
- rettv->vval.v_number = TRUE;
- else
- rettv->vval.v_number = FALSE;
+ if (map_to_exists(name, mode, abbr)) {
+ rettv->vval.v_number = true;
+ } else {
+ rettv->vval.v_number = false;
+ }
}
/*
@@ -11584,20 +10808,19 @@ static void f_hasmapto(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_histadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
HistoryType histype;
- char_u *str;
- char_u buf[NUMBUFLEN];
rettv->vval.v_number = false;
if (check_restricted() || check_secure()) {
return;
}
- str = get_tv_string_chk(&argvars[0]); // NULL on type error
- histype = str != NULL ? get_histtype(str, STRLEN(str), false) : HIST_INVALID;
+ const char *str = tv_get_string_chk(&argvars[0]); // NULL on type error
+ histype = str != NULL ? get_histtype(str, strlen(str), false) : HIST_INVALID;
if (histype != HIST_INVALID) {
- str = get_tv_string_buf(&argvars[1], buf);
+ char buf[NUMBUFLEN];
+ str = tv_get_string_buf(&argvars[1], buf);
if (*str != NUL) {
init_history();
- add_to_history(histype, str, false, NUL);
+ add_to_history(histype, (char_u *)str, false, NUL);
rettv->vval.v_number = true;
return;
}
@@ -11610,23 +10833,21 @@ static void f_histadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_histdel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int n;
- char_u buf[NUMBUFLEN];
- char_u *str;
-
- str = get_tv_string_chk(&argvars[0]); // NULL on type error
+ const char *const str = tv_get_string_chk(&argvars[0]); // NULL on type error
if (str == NULL) {
n = 0;
} else if (argvars[1].v_type == VAR_UNKNOWN) {
// only one argument: clear entire history
- n = clr_history(get_histtype(str, STRLEN(str), false));
+ n = clr_history(get_histtype(str, strlen(str), false));
} else if (argvars[1].v_type == VAR_NUMBER) {
// index given: remove that entry
- n = del_history_idx(get_histtype(str, STRLEN(str), false),
- (int) get_tv_number(&argvars[1]));
+ n = del_history_idx(get_histtype(str, strlen(str), false),
+ (int)tv_get_number(&argvars[1]));
} else {
// string given: remove all matching entries
- n = del_history_entry(get_histtype(str, STRLEN(str), false),
- get_tv_string_buf(&argvars[1], buf));
+ char buf[NUMBUFLEN];
+ n = del_history_entry(get_histtype(str, strlen(str), false),
+ (char_u *)tv_get_string_buf(&argvars[1], buf));
}
rettv->vval.v_number = n;
}
@@ -11638,17 +10859,16 @@ static void f_histget(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
HistoryType type;
int idx;
- char_u *str;
- str = get_tv_string_chk(&argvars[0]); // NULL on type error
+ const char *const str = tv_get_string_chk(&argvars[0]); // NULL on type error
if (str == NULL) {
rettv->vval.v_string = NULL;
} else {
- type = get_histtype(str, STRLEN(str), false);
+ type = get_histtype(str, strlen(str), false);
if (argvars[1].v_type == VAR_UNKNOWN) {
idx = get_history_idx(type);
} else {
- idx = (int)get_tv_number_chk(&argvars[1], NULL);
+ idx = (int)tv_get_number_chk(&argvars[1], NULL);
}
// -1 on type error
rettv->vval.v_string = vim_strsave(get_history_entry(type, idx));
@@ -11663,9 +10883,9 @@ static void f_histnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int i;
- char_u *history = get_tv_string_chk(&argvars[0]);
+ const char *const history = tv_get_string_chk(&argvars[0]);
- i = history == NULL ? HIST_CMD - 1 : get_histtype(history, STRLEN(history),
+ i = history == NULL ? HIST_CMD - 1 : get_histtype(history, strlen(history),
false);
if (i != HIST_INVALID) {
i = get_history_idx(i);
@@ -11680,7 +10900,8 @@ static void f_histnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0]));
+ rettv->vval.v_number = syn_name2id(
+ (const char_u *)tv_get_string(&argvars[0]));
}
/*
@@ -11688,7 +10909,8 @@ static void f_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_hlexists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0]));
+ rettv->vval.v_number = highlight_exists(
+ (const char_u *)tv_get_string(&argvars[0]));
}
/*
@@ -11708,25 +10930,27 @@ static void f_hostname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_iconv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u buf1[NUMBUFLEN];
- char_u buf2[NUMBUFLEN];
- char_u *from, *to, *str;
vimconv_T vimconv;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
- str = get_tv_string(&argvars[0]);
- from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1)));
- to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2)));
+ const char *const str = tv_get_string(&argvars[0]);
+ char buf1[NUMBUFLEN];
+ char_u *const from = enc_canonize(enc_skip(
+ (char_u *)tv_get_string_buf(&argvars[1], buf1)));
+ char buf2[NUMBUFLEN];
+ char_u *const to = enc_canonize(enc_skip(
+ (char_u *)tv_get_string_buf(&argvars[2], buf2)));
vimconv.vc_type = CONV_NONE;
convert_setup(&vimconv, from, to);
- /* If the encodings are equal, no conversion needed. */
- if (vimconv.vc_type == CONV_NONE)
- rettv->vval.v_string = vim_strsave(str);
- else
- rettv->vval.v_string = string_convert(&vimconv, str, NULL);
+ // If the encodings are equal, no conversion needed.
+ if (vimconv.vc_type == CONV_NONE) {
+ rettv->vval.v_string = (char_u *)xstrdup(str);
+ } else {
+ rettv->vval.v_string = string_convert(&vimconv, (char_u *)str, NULL);
+ }
convert_setup(&vimconv, NULL, NULL);
xfree(from);
@@ -11738,13 +10962,12 @@ static void f_iconv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_indent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
-
- lnum = get_tv_lnum(argvars);
- if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
+ const linenr_T lnum = tv_get_lnum(argvars);
+ if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
rettv->vval.v_number = get_indent_lnum(lnum);
- else
+ } else {
rettv->vval.v_number = -1;
+ }
}
/*
@@ -11766,16 +10989,18 @@ static void f_index(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (l != NULL) {
item = l->lv_first;
if (argvars[2].v_type != VAR_UNKNOWN) {
- int error = FALSE;
+ bool error = false;
- /* Start at specified item. Use the cached index that list_find()
- * sets, so that a negative number also works. */
- item = list_find(l, get_tv_number_chk(&argvars[2], &error));
+ // Start at specified item. Use the cached index that tv_list_find()
+ // sets, so that a negative number also works.
+ item = tv_list_find(l, tv_get_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)
+ if (argvars[3].v_type != VAR_UNKNOWN) {
+ ic = tv_get_number_chk(&argvars[3], &error);
+ }
+ if (error) {
item = NULL;
+ }
}
for (; item != NULL; item = item->li_next, ++idx)
@@ -11795,85 +11020,131 @@ static int inputsecret_flag = 0;
* prompt. The third argument to f_inputdialog() specifies the value to return
* when the user cancels the prompt.
*/
-static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog)
+void get_user_input(const typval_T *const argvars,
+ typval_T *const rettv, const bool inputdialog)
+ FUNC_ATTR_NONNULL_ALL
{
- char_u *prompt = get_tv_string_chk(&argvars[0]);
- char_u *p = NULL;
- int c;
- char_u buf[NUMBUFLEN];
- int cmd_silent_save = cmd_silent;
- char_u *defstr = (char_u *)"";
- int xp_type = EXPAND_NOTHING;
- char_u *xp_arg = NULL;
-
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
- cmd_silent = FALSE; /* Want to see the prompt. */
- if (prompt != NULL) {
- /* Only the part of the message after the last NL is considered as
- * prompt for the command line */
- p = vim_strrchr(prompt, '\n');
- if (p == NULL)
- p = prompt;
- else {
- ++p;
- c = *p;
- *p = NUL;
- msg_start();
- msg_clr_eos();
- msg_puts_attr(prompt, echo_attr);
- msg_didout = FALSE;
- msg_starthere();
- *p = c;
+ const char *prompt = "";
+ const char *defstr = "";
+ const char *cancelreturn = NULL;
+ const char *xp_name = NULL;
+ Callback input_callback = { .type = kCallbackNone };
+ char prompt_buf[NUMBUFLEN];
+ char defstr_buf[NUMBUFLEN];
+ char cancelreturn_buf[NUMBUFLEN];
+ char xp_name_buf[NUMBUFLEN];
+ if (argvars[0].v_type == VAR_DICT) {
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ emsgf(_("E5050: {opts} must be the only argument"));
+ return;
+ }
+ dict_T *const dict = argvars[0].vval.v_dict;
+ prompt = tv_dict_get_string_buf_chk(dict, S_LEN("prompt"), prompt_buf, "");
+ if (prompt == NULL) {
+ return;
+ }
+ defstr = tv_dict_get_string_buf_chk(dict, S_LEN("default"), defstr_buf, "");
+ if (defstr == NULL) {
+ return;
+ }
+ char def[1] = { 0 };
+ cancelreturn = tv_dict_get_string_buf_chk(dict, S_LEN("cancelreturn"),
+ cancelreturn_buf, def);
+ if (cancelreturn == NULL) { // error
+ return;
+ }
+ if (*cancelreturn == NUL) {
+ cancelreturn = NULL;
+ }
+ xp_name = tv_dict_get_string_buf_chk(dict, S_LEN("completion"),
+ xp_name_buf, def);
+ if (xp_name == NULL) { // error
+ return;
+ }
+ if (xp_name == def) { // default to NULL
+ xp_name = NULL;
+ }
+ if (!tv_dict_get_callback(dict, S_LEN("highlight"), &input_callback)) {
+ return;
+ }
+ } else {
+ prompt = tv_get_string_buf_chk(&argvars[0], prompt_buf);
+ if (prompt == NULL) {
+ return;
}
- cmdline_row = msg_row;
-
if (argvars[1].v_type != VAR_UNKNOWN) {
- defstr = get_tv_string_buf_chk(&argvars[1], buf);
- if (defstr != NULL)
- stuffReadbuffSpec(defstr);
-
- if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN) {
- char_u *xp_name;
- int xp_namelen;
- uint32_t argt;
-
- /* input() with a third argument: completion */
- rettv->vval.v_string = NULL;
-
- xp_name = get_tv_string_buf_chk(&argvars[2], buf);
- if (xp_name == NULL)
- return;
-
- xp_namelen = (int)STRLEN(xp_name);
-
- if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt,
- &xp_arg) == FAIL)
+ defstr = tv_get_string_buf_chk(&argvars[1], defstr_buf);
+ if (defstr == NULL) {
+ return;
+ }
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ const char *const arg2 = tv_get_string_buf_chk(&argvars[2],
+ cancelreturn_buf);
+ if (arg2 == NULL) {
return;
+ }
+ if (inputdialog) {
+ cancelreturn = arg2;
+ } else {
+ xp_name = arg2;
+ }
}
}
+ }
- if (defstr != NULL) {
- int save_ex_normal_busy = ex_normal_busy;
- ex_normal_busy = 0;
- rettv->vval.v_string =
- getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr,
- xp_type, xp_arg);
- ex_normal_busy = save_ex_normal_busy;
+ int xp_type = EXPAND_NOTHING;
+ char *xp_arg = NULL;
+ if (xp_name != NULL) {
+ // input() with a third argument: completion
+ const int xp_namelen = (int)strlen(xp_name);
+
+ uint32_t argt;
+ if (parse_compl_arg((char_u *)xp_name, xp_namelen, &xp_type,
+ &argt, (char_u **)&xp_arg) == FAIL) {
+ return;
}
- if (inputdialog && rettv->vval.v_string == NULL
- && argvars[1].v_type != VAR_UNKNOWN
- && argvars[2].v_type != VAR_UNKNOWN)
- rettv->vval.v_string = vim_strsave(get_tv_string_buf(
- &argvars[2], buf));
+ }
- xfree(xp_arg);
+ int cmd_silent_save = cmd_silent;
- /* since the user typed this, no need to wait for return */
- need_wait_return = FALSE;
- msg_didout = FALSE;
+ cmd_silent = false; // Want to see the prompt.
+ // Only the part of the message after the last NL is considered as
+ // prompt for the command line.
+ const char *p = strrchr(prompt, '\n');
+ if (p == NULL) {
+ p = prompt;
+ } else {
+ p++;
+ msg_start();
+ msg_clr_eos();
+ msg_puts_attr_len(prompt, p - prompt, echo_attr);
+ msg_didout = false;
+ msg_starthere();
+ }
+ cmdline_row = msg_row;
+
+ stuffReadbuffSpec(defstr);
+
+ const int save_ex_normal_busy = ex_normal_busy;
+ ex_normal_busy = 0;
+ rettv->vval.v_string =
+ (char_u *)getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr,
+ xp_type, xp_arg, input_callback);
+ ex_normal_busy = save_ex_normal_busy;
+ callback_free(&input_callback);
+
+ if (rettv->vval.v_string == NULL && cancelreturn != NULL) {
+ rettv->vval.v_string = (char_u *)xstrdup(cancelreturn);
}
+
+ xfree(xp_arg);
+
+ // Since the user typed this, no need to wait for return.
+ need_wait_return = false;
+ msg_didout = false;
cmd_silent = cmd_silent_save;
}
@@ -11915,7 +11186,7 @@ static void f_inputlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
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_puts(tv_get_string(&li->li_tv));
msg_putchar('\n');
}
@@ -11973,36 +11244,34 @@ static void f_inputsecret(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- long before = 0;
- listitem_T *item;
- list_T *l;
- int error = FALSE;
+ list_T *l;
+ bool error = false;
if (argvars[0].v_type != VAR_LIST) {
EMSG2(_(e_listarg), "insert()");
} else if ((l = argvars[0].vval.v_list) != NULL
- && !tv_check_lock(l->lv_lock,
- (char_u *)N_("insert() argument"), true)) {
+ && !tv_check_lock(l->lv_lock, N_("insert() argument"),
+ TV_TRANSLATE)) {
+ long before = 0;
if (argvars[2].v_type != VAR_UNKNOWN) {
- before = get_tv_number_chk(&argvars[2], &error);
+ before = tv_get_number_chk(&argvars[2], &error);
}
if (error) {
// type error; errmsg already given
return;
}
- if (before == l->lv_len)
- item = NULL;
- else {
- item = list_find(l, before);
+ listitem_T *item = NULL;
+ if (before != l->lv_len) {
+ item = tv_list_find(l, before);
if (item == NULL) {
EMSGN(_(e_listidx), before);
l = NULL;
}
}
if (l != NULL) {
- list_insert_tv(l, &argvars[1], item);
- copy_tv(&argvars[0], rettv);
+ tv_list_insert_tv(l, &argvars[1], item);
+ tv_copy(&argvars[0], rettv);
}
}
}
@@ -12012,7 +11281,7 @@ static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_invert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = ~get_tv_number_chk(&argvars[0], NULL);
+ rettv->vval.v_number = ~tv_get_number_chk(&argvars[0], NULL);
}
/*
@@ -12020,7 +11289,7 @@ static void f_invert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_isdirectory(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = os_isdir(get_tv_string(&argvars[0]));
+ rettv->vval.v_number = os_isdir((const char_u *)tv_get_string(&argvars[0]));
}
/*
@@ -12029,41 +11298,39 @@ static void f_isdirectory(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
lval_T lv;
- char_u *end;
dictitem_T *di;
rettv->vval.v_number = -1;
- end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE,
- GLV_NO_AUTOLOAD, FNE_CHECK_START);
+ const char_u *const end = get_lval((char_u *)tv_get_string(&argvars[0]),
+ NULL,
+ &lv, false, false,
+ GLV_NO_AUTOLOAD|GLV_READ_ONLY,
+ FNE_CHECK_START);
if (end != NULL && lv.ll_name != NULL) {
- if (*end != NUL)
+ if (*end != NUL) {
EMSG(_(e_trailing));
- else {
+ } else {
if (lv.ll_tv == NULL) {
- if (check_changedtick(lv.ll_name))
- rettv->vval.v_number = 1; /* always locked */
- else {
- di = find_var(lv.ll_name, NULL, TRUE);
- if (di != NULL) {
- /* Consider a variable locked when:
- * 1. the variable itself is locked
- * 2. the value of the variable is locked.
- * 3. the List or Dict value is locked.
- */
- rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK)
- || tv_islocked(&di->di_tv));
- }
+ di = find_var((const char *)lv.ll_name, lv.ll_name_len, NULL, true);
+ if (di != NULL) {
+ // Consider a variable locked when:
+ // 1. the variable itself is locked
+ // 2. the value of the variable is locked.
+ // 3. the List or Dict value is locked.
+ rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK)
+ || tv_islocked(&di->di_tv));
}
- } else if (lv.ll_range)
+ } else if (lv.ll_range) {
EMSG(_("E786: Range not allowed"));
- else if (lv.ll_newkey != NULL)
+ } else if (lv.ll_newkey != NULL) {
EMSG2(_(e_dictkey), lv.ll_newkey);
- else if (lv.ll_list != NULL)
- /* List item. */
+ } else if (lv.ll_list != NULL) {
+ // List item.
rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv);
- else
- /* Dictionary item. */
+ } else {
+ // Dictionary item.
rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv);
+ }
}
}
@@ -12071,68 +11338,71 @@ static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
-/*
- * Turn a dict into a list:
- * "what" == 0: list of keys
- * "what" == 1: list of values
- * "what" == 2: list of items
- */
-static void dict_list(typval_T *argvars, typval_T *rettv, int what)
-{
- list_T *l2;
- dictitem_T *di;
- hashitem_T *hi;
- listitem_T *li;
- listitem_T *li2;
- dict_T *d;
- int todo;
-
- if (argvars[0].v_type != VAR_DICT) {
- EMSG(_(e_dictreq));
+/// Turn a dictionary into a list
+///
+/// @param[in] tv Dictionary to convert. Is checked for actually being
+/// a dictionary, will give an error if not.
+/// @param[out] rettv Location where result will be saved.
+/// @param[in] what What to save in rettv.
+static void dict_list(typval_T *const tv, typval_T *const rettv,
+ const DictListType what)
+{
+ if (tv->v_type != VAR_DICT) {
+ emsgf(_(e_dictreq));
return;
}
- if ((d = argvars[0].vval.v_dict) == NULL)
+ if (tv->vval.v_dict == NULL) {
return;
+ }
- rettv_list_alloc(rettv);
-
- 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);
+ tv_list_alloc_ret(rettv);
- li = listitem_alloc();
- list_append(rettv->vval.v_list, li);
+ TV_DICT_ITER(tv->vval.v_dict, di, {
+ listitem_T *const li = tv_list_item_alloc();
+ tv_list_append(rettv->vval.v_list, li);
- if (what == 0) {
- /* keys() */
+ switch (what) {
+ case kDictListKeys: {
li->li_tv.v_type = VAR_STRING;
- li->li_tv.v_lock = 0;
+ li->li_tv.v_lock = VAR_UNLOCKED;
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();
+ break;
+ }
+ case kDictListValues: {
+ tv_copy(&di->di_tv, &li->li_tv);
+ break;
+ }
+ case kDictListItems: {
+ // items()
+ list_T *const sub_l = tv_list_alloc();
li->li_tv.v_type = VAR_LIST;
- li->li_tv.v_lock = 0;
- li->li_tv.vval.v_list = l2;
- ++l2->lv_refcount;
-
- li2 = listitem_alloc();
- list_append(l2, li2);
- li2->li_tv.v_type = VAR_STRING;
- li2->li_tv.v_lock = 0;
- li2->li_tv.vval.v_string = vim_strsave(di->di_key);
-
- li2 = listitem_alloc();
- list_append(l2, li2);
- copy_tv(&di->di_tv, &li2->li_tv);
+ li->li_tv.v_lock = VAR_UNLOCKED;
+ li->li_tv.vval.v_list = sub_l;
+ sub_l->lv_refcount++;
+
+ listitem_T *sub_li = tv_list_item_alloc();
+ tv_list_append(sub_l, sub_li);
+ sub_li->li_tv.v_type = VAR_STRING;
+ sub_li->li_tv.v_lock = VAR_UNLOCKED;
+ sub_li->li_tv.vval.v_string = vim_strsave(di->di_key);
+
+ sub_li = tv_list_item_alloc();
+ tv_list_append(sub_l, sub_li);
+ tv_copy(&di->di_tv, &sub_li->li_tv);
+ break;
}
}
- }
+ });
+}
+
+/// "id()" function
+static void f_id(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const int len = vim_vsnprintf(NULL, 0, "%p", dummy_ap, argvars);
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = xmalloc(len + 1);
+ vim_vsnprintf((char *)rettv->vval.v_string, len + 1, "%p", dummy_ap, argvars);
}
/*
@@ -12263,8 +11533,8 @@ static void f_jobsend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- ssize_t input_len;
- char *input = (char *) save_tv_as_string(&argvars[1], &input_len, false);
+ ptrdiff_t input_len = 0;
+ char *input = save_tv_as_string(&argvars[1], &input_len, false);
if (!input) {
// Either the error has been handled by save_tv_as_string(), or there is no
// input to send.
@@ -12309,10 +11579,10 @@ static void f_jobresize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = 1;
}
-static char **tv_to_argv(typval_T *cmd_tv, char **cmd, bool *executable)
+static char **tv_to_argv(typval_T *cmd_tv, const char **cmd, bool *executable)
{
if (cmd_tv->v_type == VAR_STRING) {
- char *cmd_str = (char *)get_tv_string(cmd_tv);
+ const char *cmd_str = tv_get_string(cmd_tv);
if (cmd) {
*cmd = cmd_str;
}
@@ -12333,8 +11603,8 @@ static char **tv_to_argv(typval_T *cmd_tv, char **cmd, bool *executable)
assert(argl->lv_first);
- const char_u *exe = get_tv_string_chk(&argl->lv_first->li_tv);
- if (!exe || !os_can_exe(exe, NULL, true)) {
+ const char *exe = tv_get_string_chk(&argl->lv_first->li_tv);
+ if (!exe || !os_can_exe((const char_u *)exe, NULL, true)) {
if (exe && executable) {
*executable = false;
}
@@ -12342,16 +11612,16 @@ static char **tv_to_argv(typval_T *cmd_tv, char **cmd, bool *executable)
}
if (cmd) {
- *cmd = (char *)exe;
+ *cmd = exe;
}
// Build the argument vector
int i = 0;
char **argv = xcalloc(argc + 1, sizeof(char *));
for (listitem_T *arg = argl->lv_first; arg != NULL; arg = arg->li_next) {
- char *a = (char *)get_tv_string_chk(&arg->li_tv);
+ const char *a = tv_get_string_chk(&arg->li_tv);
if (!a) {
- // Did emsg in get_tv_string; just deallocate argv.
+ // Did emsg in tv_get_string_chk; just deallocate argv.
shell_free_argv(argv);
return NULL;
}
@@ -12387,23 +11657,26 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
dict_T *job_opts = NULL;
- bool detach = false, rpc = false, pty = false;
- Callback on_stdout = CALLBACK_NONE, on_stderr = CALLBACK_NONE,
- on_exit = CALLBACK_NONE;
+ bool detach = false;
+ bool rpc = false;
+ bool pty = false;
+ Callback on_stdout = CALLBACK_NONE;
+ Callback on_stderr = CALLBACK_NONE;
+ Callback on_exit = CALLBACK_NONE;
char *cwd = NULL;
if (argvars[1].v_type == VAR_DICT) {
job_opts = argvars[1].vval.v_dict;
- detach = get_dict_number(job_opts, "detach") != 0;
- rpc = get_dict_number(job_opts, "rpc") != 0;
- pty = get_dict_number(job_opts, "pty") != 0;
+ detach = tv_dict_get_number(job_opts, "detach") != 0;
+ rpc = tv_dict_get_number(job_opts, "rpc") != 0;
+ pty = tv_dict_get_number(job_opts, "pty") != 0;
if (pty && rpc) {
EMSG2(_(e_invarg2), "job cannot have both 'pty' and 'rpc' options set");
shell_free_argv(argv);
return;
}
- char *new_cwd = (char *)get_dict_string(job_opts, "cwd", false);
+ char *new_cwd = tv_dict_get_string(job_opts, "cwd", false);
if (new_cwd && strlen(new_cwd) > 0) {
cwd = new_cwd;
// The new cwd must be a directory.
@@ -12425,15 +11698,15 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
Process *proc = (Process *)&data->proc;
if (pty) {
- uint16_t width = get_dict_number(job_opts, "width");
+ uint16_t width = (uint16_t)tv_dict_get_number(job_opts, "width");
if (width > 0) {
data->proc.pty.width = width;
}
- uint16_t height = get_dict_number(job_opts, "height");
+ uint16_t height = (uint16_t)tv_dict_get_number(job_opts, "height");
if (height > 0) {
data->proc.pty.height = height;
}
- char *term = (char *)get_dict_string(job_opts, "TERM", true);
+ char *term = tv_dict_get_string(job_opts, "TERM", true);
if (term) {
data->proc.pty.term_name = term;
}
@@ -12493,7 +11766,7 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
list_T *args = argvars[0].vval.v_list;
- list_T *rv = list_alloc();
+ list_T *rv = tv_list_alloc();
ui_busy_start();
MultiQueue *waiting_jobs = multiqueue_new_parent(loop_on_put, &main_loop);
@@ -12504,11 +11777,11 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
TerminalJobData *data = NULL;
if (arg->li_tv.v_type != VAR_NUMBER
|| !(data = find_job(arg->li_tv.vval.v_number))) {
- list_append_number(rv, -3);
+ tv_list_append_number(rv, -3);
} else {
// append the list item and set the status pointer so we'll collect the
// status code when the job exits
- list_append_number(rv, -1);
+ tv_list_append_number(rv, -1);
data->status_ptr = &rv->lv_last->li_tv.vval.v_number;
// Process any pending events for the job because we'll temporarily
// replace the parent queue
@@ -12589,50 +11862,49 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_join(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- garray_T ga;
- char_u *sep;
-
if (argvars[0].v_type != VAR_LIST) {
EMSG(_(e_listreq));
return;
}
- if (argvars[0].vval.v_list == NULL)
+ if (argvars[0].vval.v_list == NULL) {
return;
- if (argvars[1].v_type == VAR_UNKNOWN)
- sep = (char_u *)" ";
- else
- sep = get_tv_string_chk(&argvars[1]);
+ }
+ const char *const sep = (argvars[1].v_type == VAR_UNKNOWN
+ ? " "
+ : tv_get_string_chk(&argvars[1]));
rettv->v_type = VAR_STRING;
if (sep != NULL) {
+ garray_T ga;
ga_init(&ga, (int)sizeof(char), 80);
- list_join(&ga, argvars[0].vval.v_list, (char *) sep);
+ tv_list_join(&ga, argvars[0].vval.v_list, sep);
ga_append(&ga, NUL);
rettv->vval.v_string = (char_u *)ga.ga_data;
- } else
+ } else {
rettv->vval.v_string = NULL;
+ }
}
/// json_decode() function
static void f_json_decode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char numbuf[NUMBUFLEN];
- char *s = NULL;
+ const char *s = NULL;
char *tofree = NULL;
size_t len;
if (argvars[0].v_type == VAR_LIST) {
- if (!encode_vim_list_to_buf(argvars[0].vval.v_list, &len, &s)) {
+ if (!encode_vim_list_to_buf(argvars[0].vval.v_list, &len, &tofree)) {
EMSG(_("E474: Failed to convert list to string"));
return;
}
- tofree = s;
+ s = tofree;
if (s == NULL) {
assert(len == 0);
s = "";
}
} else {
- s = (char *) get_tv_string_buf_chk(&argvars[0], (char_u *) numbuf);
+ s = tv_get_string_buf_chk(&argvars[0], numbuf);
if (s) {
len = strlen(s);
} else {
@@ -12685,24 +11957,28 @@ static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_len(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
switch (argvars[0].v_type) {
- case VAR_STRING:
- case VAR_NUMBER:
- rettv->vval.v_number = (varnumber_T)STRLEN(
- get_tv_string(&argvars[0]));
- break;
- case VAR_LIST:
- rettv->vval.v_number = list_len(argvars[0].vval.v_list);
- break;
- case VAR_DICT:
- rettv->vval.v_number = dict_len(argvars[0].vval.v_dict);
- break;
- case VAR_UNKNOWN:
- case VAR_SPECIAL:
- case VAR_FLOAT:
- case VAR_FUNC:
- case VAR_PARTIAL:
- EMSG(_("E701: Invalid type for len()"));
- break;
+ case VAR_STRING:
+ case VAR_NUMBER: {
+ rettv->vval.v_number = (varnumber_T)strlen(
+ tv_get_string(&argvars[0]));
+ break;
+ }
+ case VAR_LIST: {
+ rettv->vval.v_number = tv_list_len(argvars[0].vval.v_list);
+ break;
+ }
+ case VAR_DICT: {
+ rettv->vval.v_number = tv_dict_len(argvars[0].vval.v_dict);
+ break;
+ }
+ case VAR_UNKNOWN:
+ case VAR_SPECIAL:
+ case VAR_FLOAT:
+ case VAR_PARTIAL:
+ case VAR_FUNC: {
+ EMSG(_("E701: Invalid type for len()"));
+ break;
+ }
}
}
@@ -12787,15 +12063,15 @@ static void f_line(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_line2byte(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
-
- lnum = get_tv_lnum(argvars);
- if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1)
+ const linenr_T lnum = tv_get_lnum(argvars);
+ if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) {
rettv->vval.v_number = -1;
- else
+ } else {
rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL);
- if (rettv->vval.v_number >= 0)
- ++rettv->vval.v_number;
+ }
+ if (rettv->vval.v_number >= 0) {
+ rettv->vval.v_number++;
+ }
}
/*
@@ -12803,17 +12079,15 @@ static void f_line2byte(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_lispindent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- pos_T pos;
- linenr_T lnum;
-
- pos = curwin->w_cursor;
- lnum = get_tv_lnum(argvars);
+ const pos_T pos = curwin->w_cursor;
+ const linenr_T lnum = tv_get_lnum(argvars);
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
curwin->w_cursor.lnum = lnum;
rettv->vval.v_number = get_lisp_indent();
curwin->w_cursor = pos;
- } else
+ } else {
rettv->vval.v_number = -1;
+ }
}
/*
@@ -12827,71 +12101,117 @@ static void f_localtime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
{
- char_u *keys;
- char_u *which;
- char_u buf[NUMBUFLEN];
- char_u *keys_buf = NULL;
- char_u *rhs;
+ char_u *keys_buf = NULL;
+ char_u *rhs;
int mode;
int abbr = FALSE;
int get_dict = FALSE;
mapblock_T *mp;
int buffer_local;
- /* return empty string for failure */
+ // Return empty string for failure.
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
- keys = get_tv_string(&argvars[0]);
- if (*keys == NUL)
+ char_u *keys = (char_u *)tv_get_string(&argvars[0]);
+ if (*keys == NUL) {
return;
+ }
+ char buf[NUMBUFLEN];
+ const char *which;
if (argvars[1].v_type != VAR_UNKNOWN) {
- which = get_tv_string_buf_chk(&argvars[1], buf);
+ which = tv_get_string_buf_chk(&argvars[1], buf);
if (argvars[2].v_type != VAR_UNKNOWN) {
- abbr = get_tv_number(&argvars[2]);
- if (argvars[3].v_type != VAR_UNKNOWN)
- get_dict = get_tv_number(&argvars[3]);
+ abbr = tv_get_number(&argvars[2]);
+ if (argvars[3].v_type != VAR_UNKNOWN) {
+ get_dict = tv_get_number(&argvars[3]);
+ }
}
- } else
- which = (char_u *)"";
- if (which == NULL)
+ } else {
+ which = "";
+ }
+ if (which == NULL) {
return;
+ }
- mode = get_map_mode(&which, 0);
+ mode = get_map_mode((char_u **)&which, 0);
- keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, false,
+ keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, true,
CPO_TO_CPO_FLAGS);
rhs = check_map(keys, mode, exact, false, abbr, &mp, &buffer_local);
xfree(keys_buf);
if (!get_dict) {
- /* Return a string. */
- if (rhs != NULL)
- rettv->vval.v_string = str2special_save(rhs, FALSE);
+ // Return a string.
+ if (rhs != NULL) {
+ rettv->vval.v_string = (char_u *)str2special_save(
+ (const char *)rhs, false, false);
+ }
} else {
- rettv_dict_alloc(rettv);
+ tv_dict_alloc_ret(rettv);
if (rhs != NULL) {
// Return a dictionary.
- char_u *lhs = str2special_save(mp->m_keys, TRUE);
- char_u *mapmode = map_mode_to_chars(mp->m_mode);
- dict_T *dict = rettv->vval.v_dict;
+ mapblock_fill_dict(rettv->vval.v_dict, mp, buffer_local, true);
+ }
+ }
+}
+
+/// luaeval() function implementation
+static void f_luaeval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const char *const str = (const char *)tv_get_string_chk(&argvars[0]);
+ if (str == NULL) {
+ return;
+ }
- 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);
+ executor_eval_lua(cstr_as_string((char *)str), &argvars[1], rettv);
+}
- xfree(lhs);
- xfree(mapmode);
- }
+/// Fill a dictionary with all applicable maparg() like dictionaries
+///
+/// @param dict The dictionary to be filled
+/// @param mp The maphash that contains the mapping information
+/// @param buffer_value The "buffer" value
+/// @param compatible True for compatible with old maparg() dict
+void mapblock_fill_dict(dict_T *const dict,
+ const mapblock_T *const mp,
+ long buffer_value,
+ bool compatible)
+ FUNC_ATTR_NONNULL_ALL
+{
+ char *const lhs = str2special_save((const char *)mp->m_keys,
+ compatible, !compatible);
+ char *const mapmode = map_mode_to_chars(mp->m_mode);
+ varnumber_T noremap_value;
+
+ if (compatible) {
+ // Keep old compatible behavior
+ // This is unable to determine whether a mapping is a <script> mapping
+ noremap_value = !!mp->m_noremap;
+ } else {
+ // Distinguish between <script> mapping
+ // If it's not a <script> mapping, check if it's a noremap
+ noremap_value = mp->m_noremap == REMAP_SCRIPT ? 2 : !!mp->m_noremap;
}
+
+ if (compatible) {
+ tv_dict_add_str(dict, S_LEN("rhs"), (const char *)mp->m_orig_str);
+ } else {
+ tv_dict_add_allocated_str(dict, S_LEN("rhs"),
+ str2special_save((const char *)mp->m_str, false,
+ true));
+ }
+ tv_dict_add_allocated_str(dict, S_LEN("lhs"), lhs);
+ tv_dict_add_nr(dict, S_LEN("noremap"), noremap_value);
+ tv_dict_add_nr(dict, S_LEN("expr"), mp->m_expr ? 1 : 0);
+ tv_dict_add_nr(dict, S_LEN("silent"), mp->m_silent ? 1 : 0);
+ tv_dict_add_nr(dict, S_LEN("sid"), (varnumber_T)mp->m_script_ID);
+ tv_dict_add_nr(dict, S_LEN("buffer"), (varnumber_T)buffer_value);
+ tv_dict_add_nr(dict, S_LEN("nowait"), mp->m_nowait ? 1 : 0);
+ tv_dict_add_allocated_str(dict, S_LEN("mode"), mapmode);
}
/*
@@ -12924,9 +12244,7 @@ static void find_some_match(typval_T *argvars, typval_T *rettv, int type)
char_u *str = NULL;
long len = 0;
char_u *expr = NULL;
- char_u *pat;
regmatch_T regmatch;
- char_u patbuf[NUMBUFLEN];
char_u *save_cpo;
long start = 0;
long nth = 1;
@@ -12945,12 +12263,12 @@ static void find_some_match(typval_T *argvars, typval_T *rettv, int type)
if (type == 3 || type == 4) {
// type 3: return empty list when there are no matches.
// type 4: return ["", -1, -1, -1]
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
if (type == 4) {
- list_append_string(rettv->vval.v_list, (char_u *)"", 0);
- list_append_number(rettv->vval.v_list, (varnumber_T)-1);
- list_append_number(rettv->vval.v_list, (varnumber_T)-1);
- list_append_number(rettv->vval.v_list, (varnumber_T)-1);
+ tv_list_append_string(rettv->vval.v_list, "", 0);
+ tv_list_append_number(rettv->vval.v_list, -1);
+ tv_list_append_number(rettv->vval.v_list, -1);
+ tv_list_append_number(rettv->vval.v_list, -1);
}
} else if (type == 2) {
rettv->v_type = VAR_STRING;
@@ -12962,25 +12280,29 @@ static void find_some_match(typval_T *argvars, typval_T *rettv, int type)
goto theend;
li = l->lv_first;
} else {
- expr = str = get_tv_string(&argvars[0]);
+ expr = str = (char_u *)tv_get_string(&argvars[0]);
len = (long)STRLEN(str);
}
- pat = get_tv_string_buf_chk(&argvars[1], patbuf);
- if (pat == NULL)
+ char patbuf[NUMBUFLEN];
+ const char *const pat = tv_get_string_buf_chk(&argvars[1], patbuf);
+ if (pat == NULL) {
goto theend;
+ }
if (argvars[2].v_type != VAR_UNKNOWN) {
- int error = FALSE;
+ bool error = false;
- start = get_tv_number_chk(&argvars[2], &error);
- if (error)
+ start = tv_get_number_chk(&argvars[2], &error);
+ if (error) {
goto theend;
+ }
if (l != NULL) {
- li = list_find(l, start);
- if (li == NULL)
+ li = tv_list_find(l, start);
+ if (li == NULL) {
goto theend;
- idx = l->lv_idx; /* use the cached index */
+ }
+ idx = l->lv_idx; // Use the cached index.
} else {
if (start < 0)
start = 0;
@@ -12997,13 +12319,15 @@ static void find_some_match(typval_T *argvars, typval_T *rettv, int type)
}
}
- if (argvars[3].v_type != VAR_UNKNOWN)
- nth = get_tv_number_chk(&argvars[3], &error);
- if (error)
+ if (argvars[3].v_type != VAR_UNKNOWN) {
+ nth = tv_get_number_chk(&argvars[3], &error);
+ }
+ if (error) {
goto theend;
+ }
}
- regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
+ regmatch.regprog = vim_regcomp((char_u *)pat, RE_MAGIC + RE_STRING);
if (regmatch.regprog != NULL) {
regmatch.rm_ic = p_ic;
@@ -13062,29 +12386,32 @@ static void find_some_match(typval_T *argvars, typval_T *rettv, int type)
/* return list with matched string and submatches */
for (i = 0; i < NSUBEXP; ++i) {
if (regmatch.endp[i] == NULL) {
- list_append_string(rettv->vval.v_list, (char_u *)"", 0);
+ tv_list_append_string(rettv->vval.v_list, NULL, 0);
} else {
- list_append_string(rettv->vval.v_list,
- regmatch.startp[i],
- (int)(regmatch.endp[i] - regmatch.startp[i]));
+ tv_list_append_string(rettv->vval.v_list,
+ (const char *)regmatch.startp[i],
+ (regmatch.endp[i] - regmatch.startp[i]));
}
}
} 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)
+ // Return matched string.
+ if (l != NULL) {
+ tv_copy(&li->li_tv, rettv);
+ } else {
+ rettv->vval.v_string = (char_u *)xmemdupz(
+ (const char *)regmatch.startp[0],
+ (size_t)(regmatch.endp[0] - regmatch.startp[0]));
+ }
+ } else if (l != NULL) {
rettv->vval.v_number = idx;
- else {
- if (type != 0)
+ } else {
+ if (type != 0) {
rettv->vval.v_number =
(varnumber_T)(regmatch.startp[0] - str);
- else
+ } else {
rettv->vval.v_number =
(varnumber_T)(regmatch.endp[0] - str);
+ }
rettv->vval.v_number += (varnumber_T)(str - expr);
}
}
@@ -13093,7 +12420,8 @@ static void find_some_match(typval_T *argvars, typval_T *rettv, int type)
if (type == 4 && l == NULL) {
// matchstrpos() without a list: drop the second item
- listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first->li_next);
+ tv_list_item_remove(rettv->vval.v_list,
+ rettv->vval.v_list->lv_first->li_next);
}
theend:
@@ -13114,40 +12442,42 @@ static void f_match(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u buf[NUMBUFLEN];
- char_u *grp = get_tv_string_buf_chk(&argvars[0], buf); /* group */
- char_u *pat = get_tv_string_buf_chk(&argvars[1], buf); /* pattern */
- int prio = 10; /* default priority */
+ char grpbuf[NUMBUFLEN];
+ char patbuf[NUMBUFLEN];
+ const char *const grp = tv_get_string_buf_chk(&argvars[0], grpbuf);
+ const char *const pat = tv_get_string_buf_chk(&argvars[1], patbuf);
+ int prio = 10;
int id = -1;
- int error = false;
- char_u *conceal_char = NULL;
+ bool error = false;
+ const char *conceal_char = NULL;
rettv->vval.v_number = -1;
- if (grp == NULL || pat == NULL)
+ if (grp == NULL || pat == NULL) {
return;
+ }
if (argvars[2].v_type != VAR_UNKNOWN) {
- prio = get_tv_number_chk(&argvars[2], &error);
+ prio = tv_get_number_chk(&argvars[2], &error);
if (argvars[3].v_type != VAR_UNKNOWN) {
- id = get_tv_number_chk(&argvars[3], &error);
+ id = tv_get_number_chk(&argvars[3], &error);
if (argvars[4].v_type != VAR_UNKNOWN) {
if (argvars[4].v_type != VAR_DICT) {
EMSG(_(e_dictreq));
return;
}
- if (dict_find(argvars[4].vval.v_dict,
- (char_u *)"conceal", -1) != NULL) {
- conceal_char = get_dict_string(argvars[4].vval.v_dict,
- "conceal", false);
+ dictitem_T *di;
+ if ((di = tv_dict_find(argvars[4].vval.v_dict, S_LEN("conceal")))
+ != NULL) {
+ conceal_char = tv_get_string(&di->di_tv);
}
}
}
}
- if (error == true) {
+ if (error) {
return;
}
if (id >= 1 && id <= 3) {
- EMSGN("E798: ID is reserved for \":match\": %" PRId64, id);
+ EMSGN(_("E798: ID is reserved for \":match\": %" PRId64), id);
return;
}
@@ -13158,10 +12488,9 @@ static void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
-
- char_u buf[NUMBUFLEN];
- char_u *group;
- group = get_tv_string_buf_chk(&argvars[0], buf);
+
+ char buf[NUMBUFLEN];
+ const char *const group = tv_get_string_buf_chk(&argvars[0], buf);
if (group == NULL) {
return;
}
@@ -13177,24 +12506,24 @@ static void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- int error = false;
+ bool error = false;
int prio = 10;
int id = -1;
- char_u *conceal_char = NULL;
+ const char *conceal_char = NULL;
if (argvars[2].v_type != VAR_UNKNOWN) {
- prio = get_tv_number_chk(&argvars[2], &error);
+ prio = tv_get_number_chk(&argvars[2], &error);
if (argvars[3].v_type != VAR_UNKNOWN) {
- id = get_tv_number_chk(&argvars[3], &error);
+ id = tv_get_number_chk(&argvars[3], &error);
if (argvars[4].v_type != VAR_UNKNOWN) {
if (argvars[4].v_type != VAR_DICT) {
EMSG(_(e_dictreq));
return;
}
- if (dict_find(argvars[4].vval.v_dict,
- (char_u *)"conceal", -1) != NULL) {
- conceal_char = get_dict_string(argvars[4].vval.v_dict,
- "conceal", false);
+ dictitem_T *di;
+ if ((di = tv_dict_find(argvars[4].vval.v_dict, S_LEN("conceal")))
+ != NULL) {
+ conceal_char = tv_get_string(&di->di_tv);
}
}
}
@@ -13205,7 +12534,7 @@ static void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// id == 3 is ok because matchaddpos() is supposed to substitute :3match
if (id == 1 || id == 2) {
- EMSGN("E798: ID is reserved for \"match\": %" PRId64, id);
+ EMSGN(_("E798: ID is reserved for \"match\": %" PRId64), id);
return;
}
@@ -13218,19 +12547,20 @@ static void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
- int id = get_tv_number(&argvars[0]);
+ int id = tv_get_number(&argvars[0]);
if (id >= 1 && id <= 3) {
matchitem_T *m;
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);
+ tv_list_append_string(rettv->vval.v_list,
+ (const char *)syn_id2name(m->hlg_id), -1);
+ tv_list_append_string(rettv->vval.v_list, (const char *)m->pattern, -1);
} else {
- list_append_string(rettv->vval.v_list, NULL, -1);
- list_append_string(rettv->vval.v_list, NULL, -1);
+ tv_list_append_string(rettv->vval.v_list, NULL, 0);
+ tv_list_append_string(rettv->vval.v_list, NULL, 0);
}
}
}
@@ -13241,7 +12571,7 @@ static void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_matchdelete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = match_delete(curwin,
- (int)get_tv_number(&argvars[0]), TRUE);
+ (int)tv_get_number(&argvars[0]), true);
}
/*
@@ -13274,54 +12604,53 @@ static void f_matchstrpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
find_some_match(argvars, rettv, 4);
}
-static void max_min(typval_T *argvars, typval_T *rettv, int domax)
+/// Get maximal/minimal number value in a list or dictionary
+///
+/// @param[in] tv List or dictionary to work with. If it contains something
+/// that is not an integer number (or cannot be coerced to
+/// it) error is given.
+/// @param[out] rettv Location where result will be saved. Only assigns
+/// vval.v_number, type is not touched. Returns zero for
+/// empty lists/dictionaries.
+/// @param[in] domax Determines whether maximal or minimal value is desired.
+static void max_min(const typval_T *const tv, typval_T *const rettv,
+ const bool domax)
+ FUNC_ATTR_NONNULL_ALL
{
- long n = 0;
- long i;
- int error = FALSE;
+ varnumber_T n = 0;
+ bool 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;
+ if (tv->v_type == VAR_LIST) {
+ const list_T *const l = tv->vval.v_list;
+ if (tv_list_len(l) != 0) {
+ n = tv_get_number_chk(&l->lv_first->li_tv, &error);
+ for (const listitem_T *li = l->lv_first->li_next; li != NULL && !error;
+ li = li->li_next) {
+ const varnumber_T i = tv_get_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 if (tv->v_type == VAR_DICT) {
+ if (tv->vval.v_dict != NULL) {
+ bool first = true;
+ TV_DICT_ITER(tv->vval.v_dict, di, {
+ const varnumber_T i = tv_get_number_chk(&di->di_tv, &error);
+ if (error) {
+ break;
}
- }
+ if (first) {
+ n = i;
+ first = true;
+ } else if (domax ? i > n : i < n) {
+ n = i;
+ }
+ });
}
- } else
- EMSG(_(e_listdictarg));
+ } else {
+ EMSG2(_(e_listdictarg), domax ? "max()" : "min()");
+ }
rettv->vval.v_number = error ? 0 : n;
}
@@ -13346,28 +12675,29 @@ static void f_min(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *dir;
- char_u buf[NUMBUFLEN];
- int prot = 0755;
+ int prot = 0755; // -V536
rettv->vval.v_number = FAIL;
if (check_restricted() || check_secure())
return;
- dir = get_tv_string_buf(&argvars[0], buf);
- if (*dir == NUL)
+ char buf[NUMBUFLEN];
+ const char *const dir = tv_get_string_buf(&argvars[0], buf);
+ if (*dir == NUL) {
rettv->vval.v_number = FAIL;
- else {
- if (*path_tail(dir) == NUL)
- /* remove trailing slashes */
- *path_tail_with_sep(dir) = NUL;
+ } else {
+ if (*path_tail((char_u *)dir) == NUL) {
+ // Remove trailing slashes.
+ *path_tail_with_sep((char_u *)dir) = NUL;
+ }
if (argvars[1].v_type != VAR_UNKNOWN) {
- if (argvars[2].v_type != VAR_UNKNOWN)
- prot = get_tv_number_chk(&argvars[2], NULL);
- if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) {
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ prot = tv_get_number_chk(&argvars[2], NULL);
+ }
+ if (prot != -1 && strcmp(tv_get_string(&argvars[1]), "p") == 0) {
char *failed_dir;
- int ret = os_mkdir_recurse((char *) dir, prot, &failed_dir);
+ int ret = os_mkdir_recurse(dir, prot, &failed_dir);
if (ret != 0) {
EMSG3(_(e_mkdir), failed_dir, os_strerror(ret));
xfree(failed_dir);
@@ -13383,59 +12713,18 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
-/*
- * "mode()" function
- */
+/// "mode()" function
static void f_mode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u buf[3];
-
- buf[1] = NUL;
- buf[2] = NUL;
+ char *mode = get_mode();
- if (VIsual_active) {
- if (VIsual_select)
- buf[0] = VIsual_mode + 's' - 'v';
- else
- buf[0] = VIsual_mode;
- } else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE
- || State == CONFIRM) {
- buf[0] = 'r';
- if (State == ASKMORE)
- buf[1] = 'm';
- else if (State == CONFIRM)
- buf[1] = '?';
- } else if (State == EXTERNCMD)
- buf[0] = '!';
- else if (State & INSERT) {
- if (State & VREPLACE_FLAG) {
- buf[0] = 'R';
- buf[1] = 'v';
- } else if (State & REPLACE_FLAG)
- buf[0] = 'R';
- else
- buf[0] = 'i';
- } else if (State & CMDLINE) {
- buf[0] = 'c';
- if (exmode_active)
- buf[1] = 'v';
- } else if (exmode_active) {
- buf[0] = 'c';
- buf[1] = 'e';
- } else if (State & TERM_FOCUS) {
- buf[0] = 't';
- } else {
- buf[0] = 'n';
- if (finish_op)
- buf[1] = 'o';
+ // Clear out the minor mode when the argument is not a non-zero number or
+ // non-empty string.
+ if (!non_zero_arg(&argvars[0])) {
+ mode[1] = NUL;
}
- /* Clear out the minor mode when the argument is not a non-zero number or
- * non-empty string. */
- if (!non_zero_arg(&argvars[0]))
- buf[1] = NUL;
-
- rettv->vval.v_string = vim_strsave(buf);
+ rettv->vval.v_string = (char_u *)mode;
rettv->v_type = VAR_STRING;
}
@@ -13447,7 +12736,7 @@ static void f_msgpackdump(typval_T *argvars, typval_T *rettv, FunPtr fptr)
EMSG2(_(e_listarg), "msgpackdump()");
return;
}
- list_T *ret_list = rettv_list_alloc(rettv);
+ list_T *ret_list = tv_list_alloc_ret(rettv);
const list_T *list = argvars[0].vval.v_list;
if (list == NULL) {
return;
@@ -13475,7 +12764,7 @@ static void f_msgpackparse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
EMSG2(_(e_listarg), "msgpackparse()");
return;
}
- list_T *ret_list = rettv_list_alloc(rettv);
+ list_T *ret_list = tv_list_alloc_ret(rettv);
const list_T *list = argvars[0].vval.v_list;
if (list == NULL || list->lv_first == NULL) {
return;
@@ -13520,9 +12809,9 @@ static void f_msgpackparse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
goto f_msgpackparse_exit;
}
if (result == MSGPACK_UNPACK_SUCCESS) {
- listitem_T *li = listitem_alloc();
+ listitem_T *li = tv_list_item_alloc();
li->li_tv.v_type = VAR_UNKNOWN;
- list_append(ret_list, li);
+ tv_list_append(ret_list, li);
if (msgpack_to_vim(unpacked.data, &li->li_tv) == FAIL) {
EMSG2(_(e_invarg2), "Failed to convert msgpack string");
goto f_msgpackparse_exit;
@@ -13553,13 +12842,14 @@ static void f_nextnonblank(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
linenr_T lnum;
- for (lnum = get_tv_lnum(argvars);; ++lnum) {
+ for (lnum = tv_get_lnum(argvars);; lnum++) {
if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) {
lnum = 0;
break;
}
- if (*skipwhite(ml_get(lnum)) != NUL)
+ if (*skipwhite(ml_get(lnum)) != NUL) {
break;
+ }
}
rettv->vval.v_number = lnum;
}
@@ -13569,23 +12859,32 @@ static void f_nextnonblank(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_nr2char(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u buf[NUMBUFLEN];
-
- if (has_mbyte) {
- int utf8 = 0;
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ if (!tv_check_num(&argvars[1])) {
+ return;
+ }
+ }
- if (argvars[1].v_type != VAR_UNKNOWN)
- utf8 = get_tv_number_chk(&argvars[1], NULL);
- if (utf8)
- buf[(*utf_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL;
- else
- buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL;
- } else {
- buf[0] = (char_u)get_tv_number(&argvars[0]);
- buf[1] = NUL;
+ bool error = false;
+ const varnumber_T num = tv_get_number_chk(&argvars[0], &error);
+ if (error) {
+ return;
}
+ if (num < 0) {
+ emsgf(_("E5070: Character number must not be less than zero"));
+ return;
+ }
+ if (num > INT_MAX) {
+ emsgf(_("E5071: Character number must not be greater than INT_MAX (%i)"),
+ INT_MAX);
+ return;
+ }
+
+ char buf[MB_MAXBYTES];
+ const int len = utf_char2bytes((int)num, (char_u *)buf);
+
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = vim_strsave(buf);
+ rettv->vval.v_string = xmemdupz(buf, (size_t)len);
}
/*
@@ -13593,8 +12892,8 @@ static void f_nr2char(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_or(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
- | get_tv_number_chk(&argvars[1], NULL);
+ rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL)
+ | tv_get_number_chk(&argvars[1], NULL);
}
/*
@@ -13603,11 +12902,11 @@ static void f_or(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_pathshorten(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = get_tv_string_chk(&argvars[0]);
- if (!rettv->vval.v_string) {
+ const char *const s = tv_get_string_chk(&argvars[0]);
+ if (!s) {
return;
}
- rettv->vval.v_string = shorten_dir(vim_strsave(rettv->vval.v_string));
+ rettv->vval.v_string = shorten_dir((char_u *)xstrdup(s));
}
/*
@@ -13615,14 +12914,15 @@ static void f_pathshorten(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_pow(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- float_T fx, fy;
+ float_T fx;
+ float_T fy;
rettv->v_type = VAR_FLOAT;
- if (get_float_arg(argvars, &fx) == OK
- && get_float_arg(&argvars[1], &fy) == OK)
+ if (tv_get_float_chk(argvars, &fx) && tv_get_float_chk(&argvars[1], &fy)) {
rettv->vval.v_float = pow(fx, fy);
- else
+ } else {
rettv->vval.v_float = 0.0;
+ }
}
/*
@@ -13630,23 +12930,17 @@ static void f_pow(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_prevnonblank(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
-
- lnum = get_tv_lnum(argvars);
- if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)
+ linenr_T lnum = tv_get_lnum(argvars);
+ if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) {
lnum = 0;
- else
- while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL)
- --lnum;
+ } else {
+ while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) {
+ lnum--;
+ }
+ }
rettv->vval.v_number = lnum;
}
-/* This dummy va_list is here because:
- * - passing a NULL pointer doesn't work when va_list isn't a pointer
- * - locally in the function results in a "used before set" warning
- * - using va_start() to initialize it gives "function with fixed args" error */
-static va_list ap;
-
/*
* "printf()" function
*/
@@ -13655,19 +12949,18 @@ static void f_printf(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
{
- char_u buf[NUMBUFLEN];
int len;
int saved_did_emsg = did_emsg;
- char *fmt;
- /* Get the required length, allocate the buffer and do it for real. */
- did_emsg = FALSE;
- fmt = (char *)get_tv_string_buf(&argvars[0], buf);
- len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1);
+ // Get the required length, allocate the buffer and do it for real.
+ did_emsg = false;
+ char buf[NUMBUFLEN];
+ const char *fmt = tv_get_string_buf(&argvars[0], buf);
+ len = vim_vsnprintf(NULL, 0, fmt, dummy_ap, argvars + 1);
if (!did_emsg) {
char *s = xmalloc(len + 1);
rettv->vval.v_string = (char_u *)s;
- (void)vim_vsnprintf(s, len + 1, fmt, ap, argvars + 1);
+ (void)vim_vsnprintf(s, len + 1, fmt, dummy_ap, argvars + 1);
}
did_emsg |= saved_did_emsg;
}
@@ -13703,32 +12996,34 @@ static void f_py3eval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- long start;
- long end;
- long stride = 1;
- long i;
- int error = FALSE;
+ varnumber_T start;
+ varnumber_T end;
+ varnumber_T stride = 1;
+ varnumber_T i;
+ bool error = false;
- start = get_tv_number_chk(&argvars[0], &error);
+ start = tv_get_number_chk(&argvars[0], &error);
if (argvars[1].v_type == VAR_UNKNOWN) {
end = start - 1;
start = 0;
} else {
- end = get_tv_number_chk(&argvars[1], &error);
- if (argvars[2].v_type != VAR_UNKNOWN)
- stride = get_tv_number_chk(&argvars[2], &error);
+ end = tv_get_number_chk(&argvars[1], &error);
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ stride = tv_get_number_chk(&argvars[2], &error);
+ }
}
- if (error)
- return; /* type error; errmsg already given */
- if (stride == 0)
- EMSG(_("E726: Stride is zero"));
- else if (stride > 0 ? end + 1 < start : end - 1 > start)
- EMSG(_("E727: Start past end"));
- else {
- rettv_list_alloc(rettv);
+ if (error) {
+ return; // Type error; errmsg already given.
+ }
+ if (stride == 0) {
+ emsgf(_("E726: Stride is zero"));
+ } else if (stride > 0 ? end + 1 < start : end - 1 > start) {
+ emsgf(_("E727: Start past end"));
+ } else {
+ tv_list_alloc_ret(rettv);
for (i = start; stride > 0 ? i <= end : i >= end; i += stride) {
- list_append_number(rettv->vval.v_list, (varnumber_T)i);
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)i);
}
}
}
@@ -13738,8 +13033,7 @@ static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int binary = FALSE;
- char_u *fname;
+ bool binary = false;
FILE *fd;
char_u buf[(IOSIZE/256)*256]; /* rounded to avoid odd + 1 */
int io_size = sizeof(buf);
@@ -13753,19 +13047,21 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
char_u *start; /* start of current line */
if (argvars[1].v_type != VAR_UNKNOWN) {
- if (STRCMP(get_tv_string(&argvars[1]), "b") == 0)
- binary = TRUE;
- if (argvars[2].v_type != VAR_UNKNOWN)
- maxline = get_tv_number(&argvars[2]);
+ if (strcmp(tv_get_string(&argvars[1]), "b") == 0) {
+ binary = true;
+ }
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ maxline = tv_get_number(&argvars[2]);
+ }
}
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
- /* Always open the file in binary mode, library functions have a mind of
- * their own about CR-LF conversion. */
- fname = get_tv_string(&argvars[0]);
- if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) {
- EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname);
+ // Always open the file in binary mode, library functions have a mind of
+ // their own about CR-LF conversion.
+ const char *const fname = tv_get_string(&argvars[0]);
+ if (*fname == NUL || (fd = mch_fopen(fname, READBIN)) == NULL) {
+ EMSG2(_(e_notopen), *fname == NUL ? _("<empty>") : fname);
return;
}
@@ -13808,11 +13104,11 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
prevlen = prevsize = 0;
}
- li = listitem_alloc();
+ li = tv_list_item_alloc();
li->li_tv.v_type = VAR_STRING;
li->li_tv.v_lock = 0;
li->li_tv.vval.v_string = s;
- list_append(rettv->vval.v_list, li);
+ tv_list_append(rettv->vval.v_list, li);
start = p + 1; /* step over newline */
if ((++cnt >= maxline && maxline >= 0) || readlen <= 0)
@@ -13842,8 +13138,9 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/* have to shuffle buf to close gap */
int adjust_prevlen = 0;
- if (dest < buf) {
- adjust_prevlen = (int)(buf - dest); /* must be 1 or 2 */
+ if (dest < buf) { // -V782
+ adjust_prevlen = (int)(buf - dest); // -V782
+ // adjust_prevlen must be 1 or 2.
dest = buf;
}
if (readlen > p - buf + 1)
@@ -13887,8 +13184,8 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
if (maxline < 0)
while (cnt > -maxline) {
- listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first);
- --cnt;
+ tv_list_item_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first);
+ cnt--;
}
xfree(prev);
@@ -13910,9 +13207,9 @@ static int list2proftime(typval_T *arg, proftime_T *tm) FUNC_ATTR_NONNULL_ALL
return FAIL;
}
- int error = false;
- varnumber_T n1 = list_find_nr(arg->vval.v_list, 0L, &error);
- varnumber_T n2 = list_find_nr(arg->vval.v_list, 1L, &error);
+ bool error = false;
+ varnumber_T n1 = tv_list_find_nr(arg->vval.v_list, 0L, &error);
+ varnumber_T n2 = tv_list_find_nr(arg->vval.v_list, 1L, &error);
if (error) {
return FAIL;
}
@@ -13920,7 +13217,7 @@ static int list2proftime(typval_T *arg, proftime_T *tm) FUNC_ATTR_NONNULL_ALL
// in f_reltime() we split up the 64-bit proftime_T into two 32-bit
// values, now we combine them again.
union {
- struct { varnumber_T low, high; } split;
+ struct { int32_t low, high; } split;
proftime_T prof;
} u = { .split.high = n1, .split.low = n2 };
@@ -13961,7 +13258,7 @@ static void f_reltime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// (varnumber_T is defined as int). For all our supported platforms, int's
// are at least 32-bits wide. So we'll use two 32-bit values to store it.
union {
- struct { varnumber_T low, high; } split;
+ struct { int32_t low, high; } split;
proftime_T prof;
} u = { .prof = res };
@@ -13971,9 +13268,9 @@ static void f_reltime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
STATIC_ASSERT(sizeof(u.prof) == sizeof(u) && sizeof(u.split) == sizeof(u),
"type punning will produce incorrect results on this platform");
- rettv_list_alloc(rettv);
- list_append_number(rettv->vval.v_list, u.split.high);
- list_append_number(rettv->vval.v_list, u.split.low);
+ tv_list_alloc_ret(rettv);
+ tv_list_append_number(rettv->vval.v_list, u.split.high);
+ tv_list_append_number(rettv->vval.v_list, u.split.low);
}
/// f_reltimestr - return a string that represents the value of {time}
@@ -14003,28 +13300,27 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
listitem_T *li;
long idx;
long end;
- char_u *key;
dict_T *d;
dictitem_T *di;
- char_u *arg_errmsg = (char_u *)N_("remove() argument");
+ const char *const arg_errmsg = N_("remove() argument");
if (argvars[0].v_type == VAR_DICT) {
if (argvars[2].v_type != VAR_UNKNOWN) {
EMSG2(_(e_toomanyarg), "remove()");
} else if ((d = argvars[0].vval.v_dict) != NULL
- && !tv_check_lock(d->dv_lock, arg_errmsg, true)) {
- key = get_tv_string_chk(&argvars[1]);
+ && !tv_check_lock(d->dv_lock, arg_errmsg, TV_TRANSLATE)) {
+ const char *key = tv_get_string_chk(&argvars[1]);
if (key != NULL) {
- di = dict_find(d, key, -1);
+ di = tv_dict_find(d, key, -1);
if (di == NULL) {
EMSG2(_(e_dictkey), key);
- } else if (!var_check_fixed(di->di_flags, arg_errmsg, true)
- && !var_check_ro(di->di_flags, arg_errmsg, true)) {
+ } else if (!var_check_fixed(di->di_flags, arg_errmsg, TV_TRANSLATE)
+ && !var_check_ro(di->di_flags, arg_errmsg, TV_TRANSLATE)) {
*rettv = di->di_tv;
- init_tv(&di->di_tv);
- dictitem_remove(d, di);
- if (is_watched(d)) {
- dictwatcher_notify(d, (char *)key, NULL, rettv);
+ di->di_tv = TV_INITIAL_VALUE;
+ tv_dict_item_remove(d, di);
+ if (tv_dict_is_watched(d)) {
+ tv_dict_watcher_notify(d, key, NULL, rettv);
}
}
}
@@ -14032,28 +13328,28 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} else if (argvars[0].v_type != VAR_LIST) {
EMSG2(_(e_listdictarg), "remove()");
} else if ((l = argvars[0].vval.v_list) != NULL
- && !tv_check_lock(l->lv_lock, arg_errmsg, true)) {
- int error = (int)false;
+ && !tv_check_lock(l->lv_lock, arg_errmsg, TV_TRANSLATE)) {
+ bool 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)
+ idx = tv_get_number_chk(&argvars[1], &error);
+ if (error) {
+ // Type error: do nothing, errmsg already given.
+ } else if ((item = tv_list_find(l, idx)) == NULL) {
EMSGN(_(e_listidx), idx);
- else {
+ } else {
if (argvars[2].v_type == VAR_UNKNOWN) {
// Remove one item, return its value.
- vim_list_remove(l, item, item);
+ tv_list_remove_items(l, item, item);
*rettv = item->li_tv;
xfree(item);
} else {
- /* Remove range of items, return list with values. */
- end = get_tv_number_chk(&argvars[2], &error);
- if (error)
- ; /* type error: do nothing */
- else if ((item2 = list_find(l, end)) == NULL)
+ // Remove range of items, return list with values.
+ end = tv_get_number_chk(&argvars[2], &error);
+ if (error) {
+ // Type error: do nothing.
+ } else if ((item2 = tv_list_find(l, end)) == NULL) {
EMSGN(_(e_listidx), end);
- else {
+ } else {
int cnt = 0;
for (li = item; li != NULL; li = li->li_next) {
@@ -14061,11 +13357,11 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (li == item2)
break;
}
- if (li == NULL) /* didn't find "item2" after "item" */
- EMSG(_(e_invrange));
- else {
- vim_list_remove(l, item, item2);
- l = rettv_list_alloc(rettv);
+ if (li == NULL) { // Didn't find "item2" after "item".
+ emsgf(_(e_invrange));
+ } else {
+ tv_list_remove_items(l, item, item2);
+ l = tv_list_alloc_ret(rettv);
l->lv_first = item;
l->lv_last = item2;
item->li_prev = NULL;
@@ -14083,13 +13379,14 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_rename(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u buf[NUMBUFLEN];
-
- if (check_restricted() || check_secure())
+ if (check_restricted() || check_secure()) {
rettv->vval.v_number = -1;
- else
- rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]),
- get_tv_string_buf(&argvars[1], buf));
+ } else {
+ char buf[NUMBUFLEN];
+ rettv->vval.v_number = vim_rename(
+ (const char_u *)tv_get_string(&argvars[0]),
+ (const char_u *)tv_get_string_buf(&argvars[1], buf));
+ }
}
/*
@@ -14097,32 +13394,37 @@ static void f_rename(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_repeat(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p;
- int n;
-
- n = get_tv_number(&argvars[1]);
+ varnumber_T n = tv_get_number(&argvars[1]);
if (argvars[0].v_type == VAR_LIST) {
- rettv_list_alloc(rettv);
- if (argvars[0].vval.v_list != NULL) {
- while (n-- > 0) {
- list_extend(rettv->vval.v_list, argvars[0].vval.v_list, NULL);
- }
+ tv_list_alloc_ret(rettv);
+ while (n-- > 0) {
+ tv_list_extend(rettv->vval.v_list, argvars[0].vval.v_list, NULL);
}
} else {
- p = get_tv_string(&argvars[0]);
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
+ if (n <= 0) {
+ return;
+ }
- int slen = (int)STRLEN(p);
- int len = slen * n;
- if (len <= 0)
+ const char *const p = tv_get_string(&argvars[0]);
+
+ const size_t slen = strlen(p);
+ if (slen == 0) {
+ return;
+ }
+ const size_t len = slen * n;
+ // Detect overflow.
+ if (len / n != slen) {
return;
+ }
- char_u *r = xmallocz(len);
- for (int i = 0; i < n; i++)
- memmove(r + i * slen, p, (size_t)slen);
+ char *const r = xmallocz(len);
+ for (varnumber_T i = 0; i < n; i++) {
+ memmove(r + i * slen, p, slen);
+ }
- rettv->vval.v_string = r;
+ rettv->vval.v_string = (char_u *)r;
}
}
@@ -14131,61 +13433,49 @@ static void f_repeat(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p;
-#ifdef HAVE_READLINK
- char_u *buf = NULL;
-#endif
-
- p = get_tv_string(&argvars[0]);
+ rettv->v_type = VAR_STRING;
+ const char *fname = tv_get_string(&argvars[0]);
#ifdef WIN32
- {
- char_u *v = NULL;
-
- v = os_resolve_shortcut(p);
- if (v != NULL) {
- rettv->vval.v_string = v;
- } else {
- rettv->vval.v_string = vim_strsave(p);
- }
- }
+ char *const v = os_resolve_shortcut(fname);
+ rettv->vval.v_string = (char_u *)(v == NULL ? xstrdup(fname) : v);
#else
# ifdef HAVE_READLINK
{
- char_u *cpy;
- int len;
- char_u *remain = NULL;
- char_u *q;
- int is_relative_to_current = FALSE;
- int has_trailing_pathsep = FALSE;
+ bool is_relative_to_current = false;
+ bool has_trailing_pathsep = false;
int limit = 100;
- p = vim_strsave(p);
+ char *p = xstrdup(fname);
if (p[0] == '.' && (vim_ispathsep(p[1])
- || (p[1] == '.' && (vim_ispathsep(p[2])))))
- is_relative_to_current = TRUE;
+ || (p[1] == '.' && (vim_ispathsep(p[2]))))) {
+ is_relative_to_current = true;
+ }
- len = STRLEN(p);
- if (len > 0 && after_pathsep((char *)p, (char *)p + len)) {
- has_trailing_pathsep = TRUE;
- p[len - 1] = NUL; /* the trailing slash breaks readlink() */
+ ptrdiff_t len = (ptrdiff_t)strlen(p);
+ if (len > 0 && after_pathsep(p, p + len)) {
+ has_trailing_pathsep = true;
+ p[len - 1] = NUL; // The trailing slash breaks readlink().
}
- q = path_next_component(p);
+ char *q = (char *)path_next_component(p);
+ char *remain = NULL;
if (*q != NUL) {
- /* Separate the first path component in "p", and keep the
- * remainder (beginning with the path separator). */
- remain = vim_strsave(q - 1);
+ // Separate the first path component in "p", and keep the
+ // remainder (beginning with the path separator).
+ remain = xstrdup(q - 1);
q[-1] = NUL;
}
- buf = xmallocz(MAXPATHL);
+ char *const buf = xmallocz(MAXPATHL);
+ char *cpy;
for (;; ) {
for (;; ) {
- len = readlink((char *)p, (char *)buf, MAXPATHL);
- if (len <= 0)
+ len = readlink(p, buf, MAXPATHL);
+ if (len <= 0) {
break;
+ }
buf[len] = NUL;
if (limit-- == 0) {
@@ -14193,66 +13483,72 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
xfree(remain);
EMSG(_("E655: Too many symbolic links (cycle?)"));
rettv->vval.v_string = NULL;
- goto fail;
+ xfree(buf);
+ return;
}
- /* Ensure that the result will have a trailing path separator
- * if the argument has one. */
- if (remain == NULL && has_trailing_pathsep)
- add_pathsep((char *)buf);
+ // Ensure that the result will have a trailing path separator
+ // if the argument has one. */
+ if (remain == NULL && has_trailing_pathsep) {
+ add_pathsep(buf);
+ }
- /* Separate the first path component in the link value and
- * concatenate the remainders. */
- q = path_next_component(vim_ispathsep(*buf) ? buf + 1 : buf);
+ // Separate the first path component in the link value and
+ // concatenate the remainders. */
+ q = (char *)path_next_component(vim_ispathsep(*buf) ? buf + 1 : buf);
if (*q != NUL) {
cpy = remain;
- remain = remain ?
- concat_str(q - 1, remain) : (char_u *) xstrdup((char *)q - 1);
+ remain = (remain
+ ? (char *)concat_str((char_u *)q - 1, (char_u *)remain)
+ : xstrdup(q - 1));
xfree(cpy);
q[-1] = NUL;
}
- q = path_tail(p);
+ q = (char *)path_tail((char_u *)p);
if (q > p && *q == NUL) {
- /* Ignore trailing path separator. */
+ // Ignore trailing path separator.
q[-1] = NUL;
- q = path_tail(p);
+ q = (char *)path_tail((char_u *)p);
}
- if (q > p && !path_is_absolute_path(buf)) {
- /* symlink is relative to directory of argument */
- cpy = xmalloc(STRLEN(p) + STRLEN(buf) + 1);
- STRCPY(cpy, p);
- STRCPY(path_tail(cpy), buf);
- xfree(p);
- p = cpy;
+ if (q > p && !path_is_absolute_path((const char_u *)buf)) {
+ // Symlink is relative to directory of argument. Replace the
+ // symlink with the resolved name in the same directory.
+ const size_t p_len = strlen(p);
+ const size_t buf_len = strlen(buf);
+ p = xrealloc(p, p_len + buf_len + 1);
+ memcpy(path_tail((char_u *)p), buf, buf_len + 1);
} else {
xfree(p);
- p = vim_strsave(buf);
+ p = xstrdup(buf);
}
}
- if (remain == NULL)
+ if (remain == NULL) {
break;
+ }
- /* Append the first path component of "remain" to "p". */
- q = path_next_component(remain + 1);
+ // Append the first path component of "remain" to "p".
+ q = (char *)path_next_component(remain + 1);
len = q - remain - (*q != NUL);
- cpy = vim_strnsave(p, STRLEN(p) + len);
- STRNCAT(cpy, remain, len);
+ const size_t p_len = strlen(p);
+ cpy = xmallocz(p_len + len);
+ memcpy(cpy, p, p_len + 1);
+ xstrlcat(cpy + p_len, remain, len + 1);
xfree(p);
p = cpy;
- /* Shorten "remain". */
- if (*q != NUL)
+ // Shorten "remain".
+ if (*q != NUL) {
STRMOVE(remain, q - 1);
- else {
+ } else {
xfree(remain);
remain = NULL;
}
}
- /* If the result is a relative path name, make it explicitly relative to
- * the current directory if and only if the argument had this form. */
+ // If the result is a relative path name, make it explicitly relative to
+ // the current directory if and only if the argument had this form.
if (!vim_ispathsep(*p)) {
if (is_relative_to_current
&& *p != NUL
@@ -14262,42 +13558,40 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|| (p[1] == '.'
&& (p[2] == NUL
|| vim_ispathsep(p[2])))))) {
- /* Prepend "./". */
- cpy = concat_str((char_u *)"./", p);
+ // Prepend "./".
+ cpy = (char *)concat_str((const char_u *)"./", (const char_u *)p);
xfree(p);
p = cpy;
} else if (!is_relative_to_current) {
- /* Strip leading "./". */
+ // Strip leading "./".
q = p;
- while (q[0] == '.' && vim_ispathsep(q[1]))
+ while (q[0] == '.' && vim_ispathsep(q[1])) {
q += 2;
- if (q > p)
+ }
+ if (q > p) {
STRMOVE(p, p + 2);
+ }
}
}
- /* Ensure that the result will have no trailing path separator
- * if the argument had none. But keep "/" or "//". */
+ // Ensure that the result will have no trailing path separator
+ // if the argument had none. But keep "/" or "//".
if (!has_trailing_pathsep) {
- q = p + STRLEN(p);
- if (after_pathsep((char *)p, (char *)q))
- *path_tail_with_sep(p) = NUL;
+ q = p + strlen(p);
+ if (after_pathsep(p, q)) {
+ *path_tail_with_sep((char_u *)p) = NUL;
+ }
}
- rettv->vval.v_string = p;
+ rettv->vval.v_string = (char_u *)p;
+ xfree(buf);
}
# else
- rettv->vval.v_string = vim_strsave(p);
+ rettv->vval.v_string = (char_u *)xstrdup(p);
# endif
#endif
simplify_filename(rettv->vval.v_string);
-
-#ifdef HAVE_READLINK
-fail:
- xfree(buf);
-#endif
- rettv->v_type = VAR_STRING;
}
/*
@@ -14305,25 +13599,23 @@ fail:
*/
static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- list_T *l;
- listitem_T *li, *ni;
-
+ list_T *l;
if (argvars[0].v_type != VAR_LIST) {
EMSG2(_(e_listarg), "reverse()");
} else if ((l = argvars[0].vval.v_list) != NULL
- && !tv_check_lock(l->lv_lock,
- (char_u *)N_("reverse() argument"), true)) {
- li = l->lv_last;
+ && !tv_check_lock(l->lv_lock, N_("reverse() argument"),
+ TV_TRANSLATE)) {
+ listitem_T *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);
+ listitem_T *const ni = li->li_prev;
+ tv_list_append(l, li);
li = ni;
}
rettv->vval.v_list = l;
rettv->v_type = VAR_LIST;
- ++l->lv_refcount;
+ l->lv_refcount++;
l->lv_idx = l->lv_len - l->lv_idx - 1;
}
}
@@ -14345,40 +13637,45 @@ static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static int get_search_arg(typval_T *varp, int *flagsp)
{
int dir = FORWARD;
- char_u *flags;
- char_u nbuf[NUMBUFLEN];
int mask;
if (varp->v_type != VAR_UNKNOWN) {
- flags = get_tv_string_buf_chk(varp, nbuf);
- if (flags == NULL)
- return 0; /* type error; errmsg already given */
+ char nbuf[NUMBUFLEN];
+ const char *flags = tv_get_string_buf_chk(varp, nbuf);
+ if (flags == NULL) {
+ return 0; // Type error; errmsg already given.
+ }
while (*flags != NUL) {
switch (*flags) {
- case 'b': dir = BACKWARD; break;
- case 'w': p_ws = true; break;
- case 'W': p_ws = false; break;
- default: mask = 0;
- if (flagsp != NULL)
- switch (*flags) {
- case 'c': mask = SP_START; break;
- case 'e': mask = SP_END; break;
- case 'm': mask = SP_RETCOUNT; break;
- case 'n': mask = SP_NOMOVE; break;
- case 'p': mask = SP_SUBPAT; break;
- case 'r': mask = SP_REPEAT; break;
- case 's': mask = SP_SETPCMARK; break;
- case 'z': mask = SP_COLUMN; break;
+ case 'b': dir = BACKWARD; break;
+ case 'w': p_ws = true; break;
+ case 'W': p_ws = false; break;
+ default: {
+ mask = 0;
+ if (flagsp != NULL) {
+ switch (*flags) {
+ case 'c': mask = SP_START; break;
+ case 'e': mask = SP_END; break;
+ case 'm': mask = SP_RETCOUNT; break;
+ case 'n': mask = SP_NOMOVE; break;
+ case 'p': mask = SP_SUBPAT; break;
+ case 'r': mask = SP_REPEAT; break;
+ case 's': mask = SP_SETPCMARK; break;
+ case 'z': mask = SP_COLUMN; break;
+ }
}
- if (mask == 0) {
- EMSG2(_(e_invarg2), flags);
- dir = 0;
- } else
- *flagsp |= mask;
+ if (mask == 0) {
+ emsgf(_(e_invarg2), flags);
+ dir = 0;
+ } else {
+ *flagsp |= mask;
+ }
+ }
}
- if (dir == 0)
+ if (dir == 0) {
break;
- ++flags;
+ }
+ flags++;
}
}
return dir;
@@ -14388,7 +13685,6 @@ static int get_search_arg(typval_T *varp, int *flagsp)
static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
{
int flags;
- char_u *pat;
pos_T pos;
pos_T save_cursor;
bool save_p_ws = p_ws;
@@ -14400,10 +13696,11 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
int options = SEARCH_KEEP;
int subpatnum;
- pat = get_tv_string(&argvars[0]);
- dir = get_search_arg(&argvars[1], flagsp); /* may set p_ws */
- if (dir == 0)
+ const char *const pat = tv_get_string(&argvars[0]);
+ dir = get_search_arg(&argvars[1], flagsp); // May set p_ws.
+ if (dir == 0) {
goto theend;
+ }
flags = *flagsp;
if (flags & SP_START) {
options |= SEARCH_START;
@@ -14417,13 +13714,15 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
/* Optional arguments: line number to stop searching and timeout. */
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) {
- lnum_stop = get_tv_number_chk(&argvars[2], NULL);
- if (lnum_stop < 0)
+ lnum_stop = tv_get_number_chk(&argvars[2], NULL);
+ if (lnum_stop < 0) {
goto theend;
+ }
if (argvars[3].v_type != VAR_UNKNOWN) {
- time_limit = get_tv_number_chk(&argvars[3], NULL);
- if (time_limit < 0)
+ time_limit = tv_get_number_chk(&argvars[3], NULL);
+ if (time_limit < 0) {
goto theend;
+ }
}
}
@@ -14438,13 +13737,13 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
*/
if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0)
|| ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) {
- EMSG2(_(e_invarg2), get_tv_string(&argvars[1]));
+ EMSG2(_(e_invarg2), tv_get_string(&argvars[1]));
goto theend;
}
pos = save_cursor = curwin->w_cursor;
- subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L,
- options, RE_SEARCH, (linenr_T)lnum_stop, &tm);
+ subpatnum = searchit(curwin, curbuf, &pos, dir, (char_u *)pat, 1,
+ options, RE_SEARCH, (linenr_T)lnum_stop, &tm);
if (subpatnum != FAIL) {
if (flags & SP_SUBPAT)
retval = subpatnum;
@@ -14501,7 +13800,7 @@ static void f_rpcnotify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (!channel_send_event((uint64_t)argvars[0].vval.v_number,
- (char *)get_tv_string(&argvars[1]),
+ tv_get_string(&argvars[1]),
args)) {
EMSG2(_(e_invarg2), "Channel doesn't exist");
return;
@@ -14568,7 +13867,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
Error err = ERROR_INIT;
Object result = channel_send_call((uint64_t)argvars[0].vval.v_number,
- (char *)get_tv_string(&argvars[1]),
+ tv_get_string(&argvars[1]),
args,
&err);
@@ -14583,7 +13882,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
restore_funccal(save_funccalp);
}
- if (err.set) {
+ if (ERROR_SET(&err)) {
nvim_err_writeln(cstr_as_string(err.msg));
goto end;
}
@@ -14594,6 +13893,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
end:
api_free_object(result);
+ api_clear_error(&err);
}
// "rpcstart()" function (DEPRECATED)
@@ -14643,7 +13943,7 @@ static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// Copy arguments to the vector
if (argsl > 0) {
for (listitem_T *arg = args->lv_first; arg != NULL; arg = arg->li_next) {
- argv[i++] = xstrdup((char *) get_tv_string(&arg->li_tv));
+ argv[i++] = xstrdup(tv_get_string(&arg->li_tv));
}
}
@@ -14685,17 +13985,16 @@ static void f_rpcstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_screenattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int row;
- int col;
int c;
- row = get_tv_number_chk(&argvars[0], NULL) - 1;
- col = get_tv_number_chk(&argvars[1], NULL) - 1;
+ const int row = (int)tv_get_number_chk(&argvars[0], NULL) - 1;
+ const int col = (int)tv_get_number_chk(&argvars[1], NULL) - 1;
if (row < 0 || row >= screen_Rows
- || col < 0 || col >= screen_Columns)
+ || col < 0 || col >= screen_Columns) {
c = -1;
- else
+ } else {
c = ScreenAttrs[LineOffset[row] + col];
+ }
rettv->vval.v_number = c;
}
@@ -14704,17 +14003,15 @@ static void f_screenattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_screenchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int row;
- int col;
int off;
int c;
- row = get_tv_number_chk(&argvars[0], NULL) - 1;
- col = get_tv_number_chk(&argvars[1], NULL) - 1;
+ const int row = tv_get_number_chk(&argvars[0], NULL) - 1;
+ const int col = tv_get_number_chk(&argvars[1], NULL) - 1;
if (row < 0 || row >= screen_Rows
- || col < 0 || col >= screen_Columns)
+ || col < 0 || col >= screen_Columns) {
c = -1;
- else {
+ } else {
off = LineOffset[row] + col;
if (enc_utf8 && ScreenLinesUC[off] != 0)
c = ScreenLinesUC[off];
@@ -14759,19 +14056,21 @@ static void f_searchdecl(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int locally = 1;
int thisblock = 0;
- int error = FALSE;
+ bool error = false;
rettv->vval.v_number = 1; /* default: FAIL */
- char_u *name = get_tv_string_chk(&argvars[0]);
+ const char *const name = tv_get_string_chk(&argvars[0]);
if (argvars[1].v_type != VAR_UNKNOWN) {
- locally = get_tv_number_chk(&argvars[1], &error) == 0;
- if (!error && argvars[2].v_type != VAR_UNKNOWN)
- thisblock = get_tv_number_chk(&argvars[2], &error) != 0;
+ locally = tv_get_number_chk(&argvars[1], &error) == 0;
+ if (!error && argvars[2].v_type != VAR_UNKNOWN) {
+ thisblock = tv_get_number_chk(&argvars[2], &error) != 0;
+ }
}
- if (!error && name != NULL)
- rettv->vval.v_number = find_decl(name, STRLEN(name), locally,
+ if (!error && name != NULL) {
+ rettv->vval.v_number = find_decl((char_u *)name, strlen(name), locally,
thisblock, SEARCH_KEEP) == FAIL;
+ }
}
/*
@@ -14779,65 +14078,70 @@ static void f_searchdecl(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static int searchpair_cmn(typval_T *argvars, pos_T *match_pos)
{
- char_u *spat, *mpat, *epat;
- char_u *skip;
bool save_p_ws = p_ws;
int dir;
int flags = 0;
- char_u nbuf1[NUMBUFLEN];
- char_u nbuf2[NUMBUFLEN];
- char_u nbuf3[NUMBUFLEN];
- int retval = 0; /* default: FAIL */
+ int retval = 0; // default: FAIL
long lnum_stop = 0;
long time_limit = 0;
- /* Get the three pattern arguments: start, middle, end. */
- spat = get_tv_string_chk(&argvars[0]);
- mpat = get_tv_string_buf_chk(&argvars[1], nbuf1);
- epat = get_tv_string_buf_chk(&argvars[2], nbuf2);
- if (spat == NULL || mpat == NULL || epat == NULL)
- goto theend; /* type error */
+ // Get the three pattern arguments: start, middle, end.
+ char nbuf1[NUMBUFLEN];
+ char nbuf2[NUMBUFLEN];
+ char nbuf3[NUMBUFLEN];
+ const char *spat = tv_get_string_chk(&argvars[0]);
+ const char *mpat = tv_get_string_buf_chk(&argvars[1], nbuf1);
+ const char *epat = tv_get_string_buf_chk(&argvars[2], nbuf2);
+ if (spat == NULL || mpat == NULL || epat == NULL) {
+ goto theend; // Type error.
+ }
- /* Handle the optional fourth argument: flags */
- dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */
- if (dir == 0)
+ // Handle the optional fourth argument: flags.
+ dir = get_search_arg(&argvars[3], &flags); // may set p_ws.
+ if (dir == 0) {
goto theend;
+ }
- /* Don't accept SP_END or SP_SUBPAT.
- * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set.
- */
+ // Don't accept SP_END or SP_SUBPAT.
+ // Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set.
if ((flags & (SP_END | SP_SUBPAT)) != 0
|| ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) {
- EMSG2(_(e_invarg2), get_tv_string(&argvars[3]));
+ EMSG2(_(e_invarg2), tv_get_string(&argvars[3]));
goto theend;
}
- /* Using 'r' implies 'W', otherwise it doesn't work. */
- if (flags & SP_REPEAT)
+ // Using 'r' implies 'W', otherwise it doesn't work.
+ if (flags & SP_REPEAT) {
p_ws = false;
+ }
- /* Optional fifth argument: skip expression */
+ // Optional fifth argument: skip expression.
+ const char *skip;
if (argvars[3].v_type == VAR_UNKNOWN
- || argvars[4].v_type == VAR_UNKNOWN)
- skip = (char_u *)"";
- else {
- skip = get_tv_string_buf_chk(&argvars[4], nbuf3);
+ || argvars[4].v_type == VAR_UNKNOWN) {
+ skip = "";
+ } else {
+ skip = tv_get_string_buf_chk(&argvars[4], nbuf3);
+ if (skip == NULL) {
+ goto theend; // Type error.
+ }
if (argvars[5].v_type != VAR_UNKNOWN) {
- lnum_stop = get_tv_number_chk(&argvars[5], NULL);
- if (lnum_stop < 0)
+ lnum_stop = tv_get_number_chk(&argvars[5], NULL);
+ if (lnum_stop < 0) {
goto theend;
+ }
if (argvars[6].v_type != VAR_UNKNOWN) {
- time_limit = get_tv_number_chk(&argvars[6], NULL);
- if (time_limit < 0)
+ time_limit = tv_get_number_chk(&argvars[6], NULL);
+ if (time_limit < 0) {
goto theend;
+ }
}
}
}
- if (skip == NULL)
- goto theend; /* type error */
- retval = do_searchpair(spat, mpat, epat, dir, skip, flags,
- match_pos, lnum_stop, time_limit);
+ retval = do_searchpair(
+ (char_u *)spat, (char_u *)mpat, (char_u *)epat, dir, (char_u *)skip,
+ flags, match_pos, lnum_stop, time_limit);
theend:
p_ws = save_p_ws;
@@ -14862,15 +14166,15 @@ static void f_searchpairpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int lnum = 0;
int col = 0;
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
if (searchpair_cmn(argvars, &match_pos) > 0) {
lnum = match_pos.lnum;
col = match_pos.col;
}
- list_append_number(rettv->vval.v_list, (varnumber_T)lnum);
- list_append_number(rettv->vval.v_list, (varnumber_T)col);
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)lnum);
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)col);
}
/*
@@ -14902,9 +14206,10 @@ do_searchpair (
int n;
int r;
int nest = 1;
- int err;
int options = SEARCH_KEEP;
proftime_T tm;
+ size_t pat2_len;
+ size_t pat3_len;
/* Make 'cpoptions' empty, the 'l' flag should not be used here. */
save_cpo = p_cpo;
@@ -14913,18 +14218,22 @@ do_searchpair (
/* Set the time limit, if there is one. */
tm = profile_setlimit(time_limit);
- /* Make two search patterns: start/end (pat2, for in nested pairs) and
- * start/middle/end (pat3, for the top pair). */
- pat2 = xmalloc(STRLEN(spat) + STRLEN(epat) + 15);
- pat3 = xmalloc(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23);
- sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
- if (*mpat == NUL)
+ // Make two search patterns: start/end (pat2, for in nested pairs) and
+ // start/middle/end (pat3, for the top pair).
+ pat2_len = STRLEN(spat) + STRLEN(epat) + 17;
+ pat2 = xmalloc(pat2_len);
+ pat3_len = STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 25;
+ pat3 = xmalloc(pat3_len);
+ snprintf((char *)pat2, pat2_len, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
+ if (*mpat == NUL) {
STRCPY(pat3, pat2);
- else
- sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
- spat, epat, mpat);
- if (flags & SP_START)
+ } else {
+ snprintf((char *)pat3, pat3_len,
+ "\\m\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat, mpat);
+ }
+ if (flags & SP_START) {
options |= SEARCH_START;
+ }
save_cursor = curwin->w_cursor;
pos = curwin->w_cursor;
@@ -14958,7 +14267,8 @@ do_searchpair (
if (*skip != NUL) {
save_pos = curwin->w_cursor;
curwin->w_cursor = pos;
- r = eval_to_bool(skip, &err, NULL, FALSE);
+ bool err;
+ r = eval_to_bool(skip, &err, NULL, false);
curwin->w_cursor = save_pos;
if (err) {
/* Evaluating {skip} caused an error, break here. */
@@ -15029,7 +14339,7 @@ static void f_searchpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int n;
int flags = 0;
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
n = search_cmn(argvars, &match_pos, &flags);
if (n > 0) {
@@ -15037,10 +14347,11 @@ static void f_searchpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
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);
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)lnum);
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)col);
+ if (flags & SP_SUBPAT) {
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)n);
+ }
}
/// "serverlist()" function
@@ -15050,13 +14361,13 @@ static void f_serverlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
char **addrs = server_address_list(&n);
// Copy addrs into a linked list.
- list_T *l = rettv_list_alloc(rettv);
+ list_T *l = tv_list_alloc_ret(rettv);
for (size_t i = 0; i < n; i++) {
- listitem_T *li = listitem_alloc();
+ listitem_T *li = tv_list_item_alloc();
li->li_tv.v_type = VAR_STRING;
li->li_tv.v_lock = 0;
- li->li_tv.vval.v_string = (char_u *) addrs[i];
- list_append(l, li);
+ li->li_tv.vval.v_string = (char_u *)addrs[i];
+ tv_list_append(l, li);
}
xfree(addrs);
}
@@ -15071,22 +14382,39 @@ static void f_serverstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
+ char *address;
// If the user supplied an address, use it, otherwise use a temp.
if (argvars[0].v_type != VAR_UNKNOWN) {
if (argvars[0].v_type != VAR_STRING) {
EMSG(_(e_invarg));
return;
} else {
- rettv->vval.v_string = vim_strsave(get_tv_string(argvars));
+ address = xstrdup(tv_get_string(argvars));
}
} else {
- rettv->vval.v_string = (char_u *)server_address_new();
+ address = server_address_new();
}
- int result = server_start((char *) rettv->vval.v_string);
+ int result = server_start(address);
+ xfree(address);
+
if (result != 0) {
- EMSG2("Failed to start server: %s", uv_strerror(result));
+ EMSG2("Failed to start server: %s",
+ result > 0 ? "Unknown system error" : uv_strerror(result));
+ return;
+ }
+
+ // Since it's possible server_start adjusted the given {address} (e.g.,
+ // "localhost:" will now have a port), return the final value to the user.
+ size_t n;
+ char **addrs = server_address_list(&n);
+ rettv->vval.v_string = (char_u *)addrs[n - 1];
+
+ n--;
+ for (size_t i = 0; i < n; i++) {
+ xfree(addrs[i]);
}
+ xfree(addrs);
}
/// "serverstop()" function
@@ -15096,7 +14424,7 @@ static void f_serverstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- if (argvars[0].v_type == VAR_UNKNOWN || argvars[0].v_type != VAR_STRING) {
+ if (argvars[0].v_type != VAR_STRING) {
EMSG(_(e_invarg));
return;
}
@@ -15111,44 +14439,43 @@ static void f_serverstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
- char_u *varname, *bufvarname;
- typval_T *varp;
- char_u nbuf[NUMBUFLEN];
-
- if (check_restricted() || check_secure())
+ if (check_restricted()
+ || check_secure()
+ || !tv_check_str_or_nr(&argvars[0])) {
return;
- (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */
- varname = get_tv_string_chk(&argvars[1]);
- buf = get_buf_tv(&argvars[0], FALSE);
- varp = &argvars[2];
+ }
+ const char *varname = tv_get_string_chk(&argvars[1]);
+ buf_T *const buf = get_buf_tv(&argvars[0], false);
+ typval_T *varp = &argvars[2];
- if (buf != NULL && varname != NULL && varp != NULL) {
+ if (buf != NULL && varname != NULL) {
if (*varname == '&') {
long numval;
- char_u *strval;
- int error = false;
- aco_save_T aco;
+ bool error = false;
+ aco_save_T aco;
// set curbuf to be our buf, temporarily
aucmd_prepbuf(&aco, buf);
- ++varname;
- numval = get_tv_number_chk(varp, &error);
- strval = get_tv_string_buf_chk(varp, nbuf);
- if (!error && strval != NULL)
+ varname++;
+ numval = tv_get_number_chk(varp, &error);
+ char nbuf[NUMBUFLEN];
+ const char *const strval = tv_get_string_buf_chk(varp, nbuf);
+ if (!error && strval != NULL) {
set_option_value(varname, numval, strval, OPT_LOCAL);
+ }
// reset notion of buffer
aucmd_restbuf(&aco);
} else {
buf_T *save_curbuf = curbuf;
- bufvarname = xmalloc(STRLEN(varname) + 3);
+ const size_t varname_len = STRLEN(varname);
+ char *const bufvarname = xmalloc(varname_len + 3);
curbuf = buf;
- STRCPY(bufvarname, "b:");
- STRCPY(bufvarname + 2, varname);
- set_var(bufvarname, varp, TRUE);
+ memcpy(bufvarname, "b:", 2);
+ memcpy(bufvarname + 2, varname, varname_len + 1);
+ set_var(bufvarname, varname_len + 2, varp, true);
xfree(bufvarname);
curbuf = save_curbuf;
}
@@ -15159,7 +14486,6 @@ static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_T *d;
dictitem_T *di;
- char_u *csearch;
if (argvars[0].v_type != VAR_DICT) {
EMSG(_(e_dictreq));
@@ -15167,7 +14493,7 @@ static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if ((d = argvars[0].vval.v_dict) != NULL) {
- csearch = get_dict_string(d, "char", false);
+ char_u *const csearch = (char_u *)tv_dict_get_string(d, "char", false);
if (csearch != NULL) {
if (enc_utf8) {
int pcc[MAX_MCO];
@@ -15179,13 +14505,15 @@ static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
csearch, MB_PTR2LEN(csearch));
}
- di = dict_find(d, (char_u *)"forward", -1);
- if (di != NULL)
- set_csearch_direction(get_tv_number(&di->di_tv) ? FORWARD : BACKWARD);
+ di = tv_dict_find(d, S_LEN("forward"));
+ if (di != NULL) {
+ set_csearch_direction(tv_get_number(&di->di_tv) ? FORWARD : BACKWARD);
+ }
- di = dict_find(d, (char_u *)"until", -1);
- if (di != NULL)
- set_csearch_until(!!get_tv_number(&di->di_tv));
+ di = tv_dict_find(d, S_LEN("until"));
+ if (di != NULL) {
+ set_csearch_until(!!tv_get_number(&di->di_tv));
+ }
}
}
@@ -15194,10 +14522,11 @@ static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_setcmdpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int pos = (int)get_tv_number(&argvars[0]) - 1;
+ const int pos = (int)tv_get_number(&argvars[0]) - 1;
- if (pos >= 0)
+ if (pos >= 0) {
rettv->vval.v_number = set_cmdline_pos(pos);
+ }
}
@@ -15206,17 +14535,17 @@ static void f_setfperm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = 0;
- char_u *fname = get_tv_string_chk(&argvars[0]);
+ const char *const fname = tv_get_string_chk(&argvars[0]);
if (fname == NULL) {
return;
}
- char_u modebuf[NUMBUFLEN];
- char_u *mode_str = get_tv_string_buf_chk(&argvars[1], modebuf);
+ char modebuf[NUMBUFLEN];
+ const char *const mode_str = tv_get_string_buf_chk(&argvars[1], modebuf);
if (mode_str == NULL) {
return;
}
- if (STRLEN(mode_str) != 9) {
+ if (strlen(mode_str) != 9) {
EMSG2(_(e_invarg2), mode_str);
return;
}
@@ -15237,27 +14566,28 @@ static void f_setfperm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_setline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
- char_u *line = NULL;
list_T *l = NULL;
listitem_T *li = NULL;
long added = 0;
linenr_T lcount = curbuf->b_ml.ml_line_count;
- lnum = get_tv_lnum(&argvars[0]);
+ linenr_T lnum = tv_get_lnum(&argvars[0]);
+ const char *line = NULL;
if (argvars[1].v_type == VAR_LIST) {
l = argvars[1].vval.v_list;
li = l->lv_first;
- } else
- line = get_tv_string_chk(&argvars[1]);
+ } else {
+ line = tv_get_string_chk(&argvars[1]);
+ }
/* default result is zero == OK */
for (;; ) {
if (l != NULL) {
- /* list argument, get next string */
- if (li == NULL)
+ // List argument, get next string.
+ if (li == NULL) {
break;
- line = get_tv_string_chk(&li->li_tv);
+ }
+ line = tv_get_string_chk(&li->li_tv);
li = li->li_next;
}
@@ -15273,18 +14603,20 @@ static void f_setline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (lnum <= curbuf->b_ml.ml_line_count) {
- /* existing line, replace it */
- if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) {
+ // Existing line, replace it.
+ if (u_savesub(lnum) == OK
+ && ml_replace(lnum, (char_u *)line, true) == OK) {
changed_bytes(lnum, 0);
if (lnum == curwin->w_cursor.lnum)
check_cursor_col();
rettv->vval.v_number = 0; /* OK */
}
} else if (added > 0 || u_save(lnum - 1, lnum) == OK) {
- /* lnum is one past the last line, append the line */
- ++added;
- if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK)
- rettv->vval.v_number = 0; /* OK */
+ // lnum is one past the last line, append the line.
+ added++;
+ if (ml_append(lnum - 1, (char_u *)line, 0, false) == OK) {
+ rettv->vval.v_number = 0; // OK
+ }
}
if (l == NULL) /* only one string argument */
@@ -15299,7 +14631,7 @@ static void f_setline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// Create quickfix/location list from VimL values
///
/// Used by `setqflist()` and `setloclist()` functions. Accepts invalid
-/// list_arg, action_arg and title_arg arguments in which case errors out,
+/// list_arg, action_arg and what_arg arguments in which case errors out,
/// including VAR_UNKNOWN parameters.
///
/// @param[in,out] wp Window to create location list for. May be NULL in
@@ -15313,9 +14645,10 @@ static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv)
FUNC_ATTR_NONNULL_ARG(2, 3)
{
static char *e_invact = N_("E927: Invalid action: '%s'");
- char_u *title = NULL;
+ const char *title = NULL;
int action = ' ';
rettv->vval.v_number = -1;
+ dict_T *d = NULL;
typval_T *list_arg = &args[0];
if (list_arg->v_type != VAR_LIST) {
@@ -15331,7 +14664,7 @@ static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv)
EMSG(_(e_stringreq));
return;
}
- char_u *act = get_tv_string_chk(action_arg);
+ const char *const act = tv_get_string_chk(action_arg);
if ((*act == 'a' || *act == 'r' || *act == ' ') && act[1] == NUL) {
action = *act;
} else {
@@ -15343,20 +14676,26 @@ static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv)
if (title_arg->v_type == VAR_UNKNOWN) {
// Option argument was not given.
goto skip_args;
- }
- title = get_tv_string_chk(title_arg);
- if (!title) {
- // Type error. Error already printed by get_tv_string_chk().
+ } else if (title_arg->v_type == VAR_STRING) {
+ title = tv_get_string_chk(title_arg);
+ if (!title) {
+ // Type error. Error already printed by tv_get_string_chk().
+ return;
+ }
+ } else if (title_arg->v_type == VAR_DICT) {
+ d = title_arg->vval.v_dict;
+ } else {
+ emsgf(_(e_dictreq));
return;
}
skip_args:
if (!title) {
- title = (char_u*)(wp ? "setloclist()" : "setqflist()");
+ title = (wp ? "setloclist()" : "setqflist()");
}
list_T *l = list_arg->vval.v_list;
- if (l && set_errorlist(wp, l, action, title) == OK) {
+ if (l && set_errorlist(wp, l, action, (char_u *)title, d) == OK) {
rettv->vval.v_number = 0;
}
}
@@ -15402,11 +14741,11 @@ static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
EMSG(_(e_invarg));
return;
}
- if (!(dict_find(d, (char_u *)"group", -1) != NULL
- && (dict_find(d, (char_u *)"pattern", -1) != NULL
- || dict_find(d, (char_u *)"pos1", -1) != NULL)
- && dict_find(d, (char_u *)"priority", -1) != NULL
- && dict_find(d, (char_u *)"id", -1) != NULL)) {
+ if (!(tv_dict_find(d, S_LEN("group")) != NULL
+ && (tv_dict_find(d, S_LEN("pattern")) != NULL
+ || tv_dict_find(d, S_LEN("pos1")) != NULL)
+ && tv_dict_find(d, S_LEN("priority")) != NULL
+ && tv_dict_find(d, S_LEN("id")) != NULL)) {
EMSG(_(e_invarg));
return;
}
@@ -15415,29 +14754,31 @@ static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
clear_matches(curwin);
li = l->lv_first;
+ bool match_add_failed = false;
while (li != NULL) {
int i = 0;
- char_u buf[5];
- dictitem_T *di;
d = li->li_tv.vval.v_dict;
- if (dict_find(d, (char_u *)"pattern", -1) == NULL) {
+ dictitem_T *const di = tv_dict_find(d, S_LEN("pattern"));
+ if (di == NULL) {
if (s == NULL) {
- s = list_alloc();
+ s = tv_list_alloc();
if (s == NULL) {
return;
}
}
// match from matchaddpos()
- for (i = 1; i < 9; ++i) {
- snprintf((char *)buf, sizeof(buf), (char *)"pos%d", i);
- if ((di = dict_find(d, (char_u *)buf, -1)) != NULL) {
- if (di->di_tv.v_type != VAR_LIST) {
+ for (i = 1; i < 9; i++) {
+ char buf[5];
+ snprintf(buf, sizeof(buf), "pos%d", i);
+ dictitem_T *const pos_di = tv_dict_find(d, buf, -1);
+ if (pos_di != NULL) {
+ if (pos_di->di_tv.v_type != VAR_LIST) {
return;
}
- list_append_tv(s, &di->di_tv);
+ tv_list_append_tv(s, &pos_di->di_tv);
s->lv_refcount++;
} else {
break;
@@ -15445,25 +14786,39 @@ static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
- char_u *group = get_dict_string(d, "group", false);
- int priority = get_dict_number(d, "priority");
- int id = get_dict_number(d, "id");
- char_u *conceal = dict_find(d, (char_u *)"conceal", -1) != NULL
- ? get_dict_string(d, "conceal",
- false)
- : NULL;
+ // Note: there are three number buffers involved:
+ // - group_buf below.
+ // - numbuf in tv_dict_get_string().
+ // - mybuf in tv_get_string().
+ //
+ // If you change this code make sure that buffers will not get
+ // accidentally reused.
+ char group_buf[NUMBUFLEN];
+ const char *const group = tv_dict_get_string_buf(d, "group", group_buf);
+ const int priority = (int)tv_dict_get_number(d, "priority");
+ const int id = (int)tv_dict_get_number(d, "id");
+ dictitem_T *const conceal_di = tv_dict_find(d, S_LEN("conceal"));
+ const char *const conceal = (conceal_di != NULL
+ ? tv_get_string(&conceal_di->di_tv)
+ : NULL);
if (i == 0) {
- match_add(curwin, group,
- get_dict_string(d, "pattern", false),
- priority, id, NULL, conceal);
+ if (match_add(curwin, group,
+ tv_dict_get_string(d, "pattern", false),
+ priority, id, NULL, conceal) != id) {
+ match_add_failed = true;
+ }
} else {
- match_add(curwin, group, NULL, priority, id, s, conceal);
- list_unref(s);
+ if (match_add(curwin, group, NULL, priority, id, s, conceal) != id) {
+ match_add_failed = true;
+ }
+ tv_list_unref(s);
s = NULL;
}
li = li->li_next;
}
- rettv->vval.v_number = 0;
+ if (!match_add_failed) {
+ rettv->vval.v_number = 0;
+ }
}
}
@@ -15474,11 +14829,10 @@ static void f_setpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
pos_T pos;
int fnum;
- char_u *name;
colnr_T curswant = -1;
rettv->vval.v_number = -1;
- name = get_tv_string_chk(argvars);
+ const char *const name = tv_get_string_chk(argvars);
if (name != NULL) {
if (list2fpos(&argvars[1], &pos, &fnum, &curswant) == OK) {
if (--pos.col < 0) {
@@ -15499,7 +14853,7 @@ static void f_setpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
} else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) {
// set mark
- if (setmark_pos(name[1], &pos, fnum) == OK) {
+ if (setmark_pos((uint8_t)name[1], &pos, fnum) == OK) {
rettv->vval.v_number = 0;
}
} else {
@@ -15523,8 +14877,6 @@ static void f_setqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int regname;
- char_u *strregname;
- char_u *stropt;
bool append = false;
MotionType yank_type;
long block_len;
@@ -15532,39 +14884,52 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
block_len = -1;
yank_type = kMTUnknown;
- strregname = get_tv_string_chk(argvars);
- rettv->vval.v_number = 1; /* FAIL is default */
+ rettv->vval.v_number = 1; // FAIL is default.
- if (strregname == NULL)
- return; /* type error; errmsg already given */
- regname = *strregname;
- if (regname == 0 || regname == '@')
+ const char *const strregname = tv_get_string_chk(argvars);
+ if (strregname == NULL) {
+ return; // Type error; errmsg already given.
+ }
+ regname = (uint8_t)(*strregname);
+ if (regname == 0 || regname == '@') {
regname = '"';
+ }
+ bool set_unnamed = false;
if (argvars[2].v_type != VAR_UNKNOWN) {
- stropt = get_tv_string_chk(&argvars[2]);
- if (stropt == NULL)
- return; /* type error */
- for (; *stropt != NUL; ++stropt)
+ const char *stropt = tv_get_string_chk(&argvars[2]);
+ if (stropt == NULL) {
+ return; // Type error.
+ }
+ for (; *stropt != NUL; stropt++) {
switch (*stropt) {
- case 'a': case 'A': // append
- append = true;
- break;
- case 'v': case 'c': // character-wise selection
- yank_type = kMTCharWise;
- break;
- case 'V': case 'l': // line-wise selection
- yank_type = kMTLineWise;
- break;
- case 'b': case Ctrl_V: // block-wise selection
- yank_type = kMTBlockWise;
- if (ascii_isdigit(stropt[1])) {
- ++stropt;
- block_len = getdigits_long(&stropt) - 1;
- --stropt;
+ case 'a': case 'A': { // append
+ append = true;
+ break;
+ }
+ case 'v': case 'c': { // character-wise selection
+ yank_type = kMTCharWise;
+ break;
+ }
+ case 'V': case 'l': { // line-wise selection
+ yank_type = kMTLineWise;
+ break;
+ }
+ case 'b': case Ctrl_V: { // block-wise selection
+ yank_type = kMTBlockWise;
+ if (ascii_isdigit(stropt[1])) {
+ stropt++;
+ block_len = getdigits_long((char_u **)&stropt) - 1;
+ stropt--;
+ }
+ break;
+ }
+ case 'u': case '"': { // unnamed register
+ set_unnamed = true;
+ break;
}
- break;
}
+ }
}
if (argvars[1].v_type == VAR_LIST) {
@@ -15574,45 +14939,52 @@ static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// First half: use for pointers to result lines; second half: use for
// pointers to allocated copies.
- char_u **lstval = xmalloc(sizeof(char_u *) * ((len + 1) * 2));
- char_u **curval = lstval;
- char_u **allocval = lstval + len + 2;
- char_u **curallocval = allocval;
+ char **lstval = xmalloc(sizeof(char *) * ((len + 1) * 2));
+ const char **curval = (const char **)lstval;
+ char **allocval = lstval + len + 2;
+ char **curallocval = allocval;
- char_u buf[NUMBUFLEN];
for (listitem_T *li = ll == NULL ? NULL : ll->lv_first;
li != NULL;
li = li->li_next) {
- char_u *strval = get_tv_string_buf_chk(&li->li_tv, buf);
- if (strval == NULL) {
+ char buf[NUMBUFLEN];
+ *curval = tv_get_string_buf_chk(&li->li_tv, buf);
+ if (*curval == NULL) {
goto free_lstval;
}
- if (strval == buf) {
+ if (*curval == buf) {
// Need to make a copy,
- // next get_tv_string_buf_chk() will overwrite the string.
- strval = vim_strsave(buf);
- *curallocval++ = strval;
+ // next tv_get_string_buf_chk() will overwrite the string.
+ *curallocval = xstrdup(*curval);
+ *curval = *curallocval;
+ curallocval++;
}
- *curval++ = strval;
+ curval++;
}
*curval++ = NULL;
- write_reg_contents_lst(regname, lstval, STRLEN(lstval),
- append, yank_type, block_len);
+ write_reg_contents_lst(regname, (char_u **)lstval, append, yank_type,
+ block_len);
free_lstval:
- while (curallocval > allocval)
- xfree(*--curallocval);
+ while (curallocval > allocval) {
+ xfree(*--curallocval);
+ }
xfree(lstval);
} else {
- char_u *strval = get_tv_string_chk(&argvars[1]);
+ const char *strval = tv_get_string_chk(&argvars[1]);
if (strval == NULL) {
return;
}
- write_reg_contents_ex(regname, strval, STRLEN(strval),
+ write_reg_contents_ex(regname, (const char_u *)strval, STRLEN(strval),
append, yank_type, block_len);
}
rettv->vval.v_number = 0;
+
+ if (set_unnamed) {
+ // Discard the result. We already handle the error case.
+ if (op_register_set_previous(regname)) { }
+ }
}
/*
@@ -15620,35 +14992,31 @@ free_lstval:
*/
static void f_settabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- tabpage_T *save_curtab;
- tabpage_T *tp;
- char_u *varname, *tabvarname;
- typval_T *varp;
-
rettv->vval.v_number = 0;
- if (check_restricted() || check_secure())
+ if (check_restricted() || check_secure()) {
return;
+ }
- tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
- varname = get_tv_string_chk(&argvars[1]);
- varp = &argvars[2];
+ tabpage_T *const tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
+ const char *const varname = tv_get_string_chk(&argvars[1]);
+ typval_T *const varp = &argvars[2];
- if (varname != NULL && varp != NULL
- && tp != NULL
- ) {
- save_curtab = curtab;
- goto_tabpage_tp(tp, FALSE, FALSE);
+ if (varname != NULL && tp != NULL) {
+ tabpage_T *const save_curtab = curtab;
+ goto_tabpage_tp(tp, false, false);
- tabvarname = xmalloc(STRLEN(varname) + 3);
- STRCPY(tabvarname, "t:");
- STRCPY(tabvarname + 2, varname);
- set_var(tabvarname, varp, TRUE);
+ const size_t varname_len = strlen(varname);
+ char *const tabvarname = xmalloc(varname_len + 3);
+ memcpy(tabvarname, "t:", 2);
+ memcpy(tabvarname + 2, varname, varname_len + 1);
+ set_var(tabvarname, varname_len + 2, varp, true);
xfree(tabvarname);
- /* Restore current tabpage */
- if (valid_tabpage(save_curtab))
- goto_tabpage_tp(save_curtab, FALSE, FALSE);
+ // Restore current tabpage.
+ if (valid_tabpage(save_curtab)) {
+ goto_tabpage_tp(save_curtab, false, false);
+ }
}
}
@@ -15674,45 +15042,43 @@ static void f_setwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void setwinvar(typval_T *argvars, typval_T *rettv, int off)
{
- win_T *win;
- win_T *save_curwin;
- tabpage_T *save_curtab;
- char_u *varname, *winvarname;
- typval_T *varp;
- char_u nbuf[NUMBUFLEN];
- tabpage_T *tp = NULL;
-
- if (check_restricted() || check_secure())
+ if (check_restricted() || check_secure()) {
return;
+ }
- if (off == 1)
- tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
- else
+ tabpage_T *tp = NULL;
+ if (off == 1) {
+ tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
+ } else {
tp = curtab;
- win = find_win_by_nr(&argvars[off], tp);
- varname = get_tv_string_chk(&argvars[off + 1]);
- varp = &argvars[off + 2];
+ }
+ win_T *const win = find_win_by_nr(&argvars[off], tp);
+ const char *varname = tv_get_string_chk(&argvars[off + 1]);
+ typval_T *varp = &argvars[off + 2];
if (win != NULL && varname != NULL && varp != NULL) {
+ win_T *save_curwin;
+ tabpage_T *save_curtab;
bool need_switch_win = tp != curtab || win != curwin;
if (!need_switch_win
|| switch_win(&save_curwin, &save_curtab, win, tp, true) == OK) {
if (*varname == '&') {
long numval;
- char_u *strval;
- int error = false;
+ bool error = false;
- ++varname;
- numval = get_tv_number_chk(varp, &error);
- strval = get_tv_string_buf_chk(varp, nbuf);
+ varname++;
+ numval = tv_get_number_chk(varp, &error);
+ char nbuf[NUMBUFLEN];
+ const char *const strval = tv_get_string_buf_chk(varp, nbuf);
if (!error && strval != NULL) {
set_option_value(varname, numval, strval, OPT_LOCAL);
}
} else {
- winvarname = xmalloc(STRLEN(varname) + 3);
- STRCPY(winvarname, "w:");
- STRCPY(winvarname + 2, varname);
- set_var(winvarname, varp, true);
+ const size_t varname_len = strlen(varname);
+ char *const winvarname = xmalloc(varname_len + 3);
+ memcpy(winvarname, "w:", 2);
+ memcpy(winvarname + 2, varname, varname_len + 1);
+ set_var(winvarname, varname_len + 2, varp, true);
xfree(winvarname);
}
}
@@ -15725,11 +15091,11 @@ static void setwinvar(typval_T *argvars, typval_T *rettv, int off)
/// f_sha256 - sha256({string}) function
static void f_sha256(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p = get_tv_string(&argvars[0]);
- const char_u *hash = sha256_bytes(p, (int) STRLEN(p) , NULL, 0);
+ const char *p = tv_get_string(&argvars[0]);
+ const char *hash = sha256_bytes((const uint8_t *)p, strlen(p) , NULL, 0);
// make a copy of the hash (sha256_bytes returns a static buffer)
- rettv->vval.v_string = (char_u *) xstrdup((char *) hash);
+ rettv->vval.v_string = (char_u *)xstrdup(hash);
rettv->v_type = VAR_STRING;
}
@@ -15739,7 +15105,8 @@ static void f_sha256(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_shellescape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_string = vim_strsave_shellescape(
- get_tv_string(&argvars[0]), non_zero_arg(&argvars[1]), true);
+ (const char_u *)tv_get_string(&argvars[0]), non_zero_arg(&argvars[1]),
+ true);
rettv->v_type = VAR_STRING;
}
@@ -15756,14 +15123,61 @@ static void f_shiftwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_simplify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p;
-
- p = get_tv_string(&argvars[0]);
- rettv->vval.v_string = vim_strsave(p);
- simplify_filename(rettv->vval.v_string); /* simplify in place */
+ const char *const p = tv_get_string(&argvars[0]);
+ rettv->vval.v_string = (char_u *)xstrdup(p);
+ simplify_filename(rettv->vval.v_string); // Simplify in place.
rettv->v_type = VAR_STRING;
}
+/// "sockconnect()" function
+static void f_sockconnect(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ if (argvars[0].v_type != VAR_STRING || argvars[1].v_type != VAR_STRING) {
+ EMSG(_(e_invarg));
+ return;
+ }
+ if (argvars[2].v_type != VAR_DICT && argvars[2].v_type != VAR_UNKNOWN) {
+ // Wrong argument types
+ EMSG2(_(e_invarg2), "expected dictionary");
+ return;
+ }
+
+ const char *mode = tv_get_string(&argvars[0]);
+ const char *address = tv_get_string(&argvars[1]);
+
+ bool tcp;
+ if (strcmp(mode, "tcp") == 0) {
+ tcp = true;
+ } else if (strcmp(mode, "pipe") == 0) {
+ tcp = false;
+ } else {
+ EMSG2(_(e_invarg2), "invalid mode");
+ return;
+ }
+
+ bool rpc = false;
+ if (argvars[2].v_type == VAR_DICT) {
+ dict_T *opts = argvars[2].vval.v_dict;
+ rpc = tv_dict_get_number(opts, "rpc") != 0;
+ }
+
+ if (!rpc) {
+ EMSG2(_(e_invarg2), "rpc option must be true");
+ return;
+ }
+
+ const char *error = NULL;
+ eval_format_source_name_line((char *)IObuff, sizeof(IObuff));
+ uint64_t id = channel_connect(tcp, address, 50, (char *)IObuff, &error);
+
+ if (error) {
+ EMSG2(_("connection failed: %s"), error);
+ }
+
+ rettv->vval.v_number = (varnumber_T)id;
+ rettv->v_type = VAR_NUMBER;
+}
+
/// struct used in the array that's given to qsort()
typedef struct {
listitem_T *item;
@@ -15776,10 +15190,10 @@ typedef struct {
bool item_compare_numeric;
bool item_compare_numbers;
bool item_compare_float;
- char_u *item_compare_func;
+ const char *item_compare_func;
partial_T *item_compare_partial;
dict_T *item_compare_selfdict;
- int item_compare_func_err;
+ bool item_compare_func_err;
} sortinfo_T;
static sortinfo_T *sortinfo = NULL;
@@ -15790,58 +15204,61 @@ static sortinfo_T *sortinfo = NULL;
*/
static int item_compare(const void *s1, const void *s2, bool keep_zero)
{
- sortItem_T *si1, *si2;
- char_u *p1;
- char_u *p2;
- char_u *tofree1 = NULL;
- char_u *tofree2 = NULL;
- int res;
+ sortItem_T *const si1 = (sortItem_T *)s1;
+ sortItem_T *const si2 = (sortItem_T *)s2;
- si1 = (sortItem_T *)s1;
- si2 = (sortItem_T *)s2;
- typval_T *tv1 = &si1->item->li_tv;
- typval_T *tv2 = &si2->item->li_tv;
+ typval_T *const tv1 = &si1->item->li_tv;
+ typval_T *const tv2 = &si2->item->li_tv;
+
+ int res;
if (sortinfo->item_compare_numbers) {
- long v1 = get_tv_number(tv1);
- long v2 = get_tv_number(tv2);
+ const varnumber_T v1 = tv_get_number(tv1);
+ const varnumber_T v2 = tv_get_number(tv2);
- return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
+ res = v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
+ goto item_compare_end;
}
if (sortinfo->item_compare_float) {
- float_T v1 = get_tv_float(tv1);
- float_T v2 = get_tv_float(tv2);
+ const float_T v1 = tv_get_float(tv1);
+ const float_T v2 = tv_get_float(tv2);
- return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
+ res = v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
+ goto item_compare_end;
}
+ char *tofree1 = NULL;
+ char *tofree2 = NULL;
+ char *p1;
+ char *p2;
+
// encode_tv2string() puts quotes around a string and allocates memory. Don't
// do that for string variables. Use a single quote when comparing with
// a non-string to do what the docs promise.
if (tv1->v_type == VAR_STRING) {
if (tv2->v_type != VAR_STRING || sortinfo->item_compare_numeric) {
- p1 = (char_u *)"'";
+ p1 = "'";
} else {
- p1 = tv1->vval.v_string;
+ p1 = (char *)tv1->vval.v_string;
}
} else {
- tofree1 = p1 = (char_u *) encode_tv2string(tv1, NULL);
+ tofree1 = p1 = encode_tv2string(tv1, NULL);
}
if (tv2->v_type == VAR_STRING) {
if (tv1->v_type != VAR_STRING || sortinfo->item_compare_numeric) {
- p2 = (char_u *)"'";
+ p2 = "'";
} else {
- p2 = tv2->vval.v_string;
+ p2 = (char *)tv2->vval.v_string;
}
} else {
- tofree2 = p2 = (char_u *) encode_tv2string(tv2, NULL);
+ tofree2 = p2 = encode_tv2string(tv2, NULL);
}
if (p1 == NULL) {
- p1 = (char_u *)"";
+ p1 = "";
}
if (p2 == NULL) {
- p2 = (char_u *)"";
+ p2 = "";
}
if (!sortinfo->item_compare_numeric) {
if (sortinfo->item_compare_ic) {
@@ -15851,19 +15268,20 @@ static int item_compare(const void *s1, const void *s2, bool keep_zero)
}
} else {
double n1, n2;
- n1 = strtod((char *)p1, (char **)&p1);
- n2 = strtod((char *)p2, (char **)&p2);
+ n1 = strtod(p1, &p1);
+ n2 = strtod(p2, &p2);
res = n1 == n2 ? 0 : n1 > n2 ? 1 : -1;
}
+ xfree(tofree1);
+ xfree(tofree2);
+
+item_compare_end:
// When the result would be zero, compare the item indexes. Makes the
// sort stable.
if (res == 0 && !keep_zero) {
res = si1->idx > si2->idx ? 1 : -1;
}
-
- xfree(tofree1);
- xfree(tofree2);
return res;
}
@@ -15884,7 +15302,7 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero)
typval_T rettv;
typval_T argv[3];
int dummy;
- char_u *func_name;
+ const char *func_name;
partial_T *partial = sortinfo->item_compare_partial;
// shortcut after failure in previous call; compare all items equal
@@ -15898,30 +15316,31 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero)
if (partial == NULL) {
func_name = sortinfo->item_compare_func;
} else {
- func_name = partial->pt_name;
+ func_name = (const char *)partial_name(partial);
}
+
// Copy the values. This is needed to be able to set v_lock to VAR_FIXED
// in the copy without changing the original list items.
- copy_tv(&si1->item->li_tv, &argv[0]);
- copy_tv(&si2->item->li_tv, &argv[1]);
+ tv_copy(&si1->item->li_tv, &argv[0]);
+ tv_copy(&si2->item->li_tv, &argv[1]);
- rettv.v_type = VAR_UNKNOWN; // clear_tv() uses this
- res = call_func(func_name,
+ rettv.v_type = VAR_UNKNOWN; // tv_clear() uses this
+ res = call_func((const char_u *)func_name,
(int)STRLEN(func_name),
- &rettv, 2, argv, 0L, 0L, &dummy, true,
+ &rettv, 2, argv, NULL, 0L, 0L, &dummy, true,
partial, sortinfo->item_compare_selfdict);
- clear_tv(&argv[0]);
- clear_tv(&argv[1]);
+ tv_clear(&argv[0]);
+ tv_clear(&argv[1]);
if (res == FAIL) {
res = ITEM_COMPARE_FAIL;
} else {
- res = get_tv_number_chk(&rettv, &sortinfo->item_compare_func_err);
+ res = tv_get_number_chk(&rettv, &sortinfo->item_compare_func_err);
}
if (sortinfo->item_compare_func_err) {
res = ITEM_COMPARE_FAIL; // return value has wrong type
}
- clear_tv(&rettv);
+ tv_clear(&rettv);
// When the result would be zero, compare the pointers themselves. Makes
// the sort stable.
@@ -15959,23 +15378,22 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
sortinfo_T *old_sortinfo = sortinfo;
sortinfo = &info;
+ const char *const arg_errmsg = (sort
+ ? N_("sort() argument")
+ : N_("uniq() argument"));
+
if (argvars[0].v_type != VAR_LIST) {
EMSG2(_(e_listarg), sort ? "sort()" : "uniq()");
} else {
l = argvars[0].vval.v_list;
- if (l == NULL
- || tv_check_lock(l->lv_lock,
- (char_u *)(sort
- ? N_("sort() argument")
- : N_("uniq() argument")),
- true)) {
+ if (l == NULL || tv_check_lock(l->lv_lock, arg_errmsg, TV_TRANSLATE)) {
goto theend;
}
rettv->vval.v_list = l;
rettv->v_type = VAR_LIST;
++l->lv_refcount;
- len = list_len(l);
+ len = tv_list_len(l);
if (len <= 1) {
goto theend; // short list sorts pretty quickly
}
@@ -15991,20 +15409,20 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
if (argvars[1].v_type != VAR_UNKNOWN) {
/* optional second argument: {func} */
if (argvars[1].v_type == VAR_FUNC) {
- info.item_compare_func = argvars[1].vval.v_string;
+ info.item_compare_func = (const char *)argvars[1].vval.v_string;
} else if (argvars[1].v_type == VAR_PARTIAL) {
info.item_compare_partial = argvars[1].vval.v_partial;
} else {
- int error = FALSE;
+ bool error = false;
- i = get_tv_number_chk(&argvars[1], &error);
+ i = tv_get_number_chk(&argvars[1], &error);
if (error) {
goto theend; // type error; errmsg already given
}
if (i == 1) {
info.item_compare_ic = true;
} else if (argvars[1].v_type != VAR_NUMBER) {
- info.item_compare_func = get_tv_string(&argvars[1]);
+ info.item_compare_func = tv_get_string(&argvars[1]);
} else if (i != 0) {
EMSG(_(e_invarg));
goto theend;
@@ -16013,16 +15431,16 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
if (*info.item_compare_func == NUL) {
// empty string means default sort
info.item_compare_func = NULL;
- } else if (STRCMP(info.item_compare_func, "n") == 0) {
+ } else if (strcmp(info.item_compare_func, "n") == 0) {
info.item_compare_func = NULL;
info.item_compare_numeric = true;
- } else if (STRCMP(info.item_compare_func, "N") == 0) {
+ } else if (strcmp(info.item_compare_func, "N") == 0) {
info.item_compare_func = NULL;
info.item_compare_numbers = true;
- } else if (STRCMP(info.item_compare_func, "f") == 0) {
+ } else if (strcmp(info.item_compare_func, "f") == 0) {
info.item_compare_func = NULL;
info.item_compare_float = true;
- } else if (STRCMP(info.item_compare_func, "i") == 0) {
+ } else if (strcmp(info.item_compare_func, "i") == 0) {
info.item_compare_func = NULL;
info.item_compare_ic = true;
}
@@ -16074,7 +15492,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
l->lv_len = 0;
for (i = 0; i < len; i++) {
- list_append(l, ptrs[i].item);
+ tv_list_append(l, ptrs[i].item);
}
}
}
@@ -16110,8 +15528,8 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
} else {
l->lv_last = ptrs[i].item;
}
- list_fix_watch(l, li);
- listitem_free(li);
+ tv_list_watch_fix(l, li);
+ tv_list_item_free(li);
l->lv_len--;
}
}
@@ -16156,11 +15574,9 @@ static void f_reltimefloat(typval_T *argvars , typval_T *rettv, FunPtr fptr)
*/
static void f_soundfold(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *s;
-
rettv->v_type = VAR_STRING;
- s = get_tv_string(&argvars[0]);
- rettv->vval.v_string = eval_soundfold(s);
+ const char *const s = tv_get_string(&argvars[0]);
+ rettv->vval.v_string = (char_u *)eval_soundfold(s);
}
/*
@@ -16168,25 +15584,26 @@ static void f_soundfold(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_spellbadword(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *word = (char_u *)"";
+ const char *word = "";
hlf_T attr = HLF_COUNT;
size_t len = 0;
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
if (argvars[0].v_type == VAR_UNKNOWN) {
- /* Find the start and length of the badly spelled word. */
- len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr);
- if (len != 0)
- word = get_cursor_pos_ptr();
+ // Find the start and length of the badly spelled word.
+ len = spell_move_to(curwin, FORWARD, true, true, &attr);
+ if (len != 0) {
+ word = (char *)get_cursor_pos_ptr();
+ }
} else if (curwin->w_p_spell && *curbuf->b_s.b_p_spl != NUL) {
- char_u *str = get_tv_string_chk(&argvars[0]);
+ const char *str = tv_get_string_chk(&argvars[0]);
int capcol = -1;
if (str != NULL) {
- /* Check the argument for spelling. */
+ // Check the argument for spelling.
while (*str != NUL) {
- len = spell_check(curwin, str, &attr, &capcol, false);
+ len = spell_check(curwin, (char_u *)str, &attr, &capcol, false);
if (attr != HLF_COUNT) {
word = str;
break;
@@ -16197,14 +15614,13 @@ static void f_spellbadword(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
assert(len <= INT_MAX);
- list_append_string(rettv->vval.v_list, word, (int)len);
- list_append_string(rettv->vval.v_list,
- (char_u *)(attr == HLF_SPB ? "bad" :
- attr == HLF_SPR ? "rare" :
- attr == HLF_SPL ? "local" :
- attr == HLF_SPC ? "caps" :
- ""),
- -1);
+ tv_list_append_string(rettv->vval.v_list, word, len);
+ tv_list_append_string(rettv->vval.v_list,
+ (attr == HLF_SPB ? "bad"
+ : attr == HLF_SPR ? "rare"
+ : attr == HLF_SPL ? "local"
+ : attr == HLF_SPC ? "caps"
+ : NULL), -1);
}
/*
@@ -16212,39 +15628,40 @@ static void f_spellbadword(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_spellsuggest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *str;
- int typeerr = FALSE;
+ bool typeerr = false;
int maxcount;
garray_T ga;
listitem_T *li;
bool need_capital = false;
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
if (curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL) {
- str = get_tv_string(&argvars[0]);
+ const char *const str = tv_get_string(&argvars[0]);
if (argvars[1].v_type != VAR_UNKNOWN) {
- maxcount = get_tv_number_chk(&argvars[1], &typeerr);
- if (maxcount <= 0)
+ maxcount = tv_get_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)
+ need_capital = tv_get_number_chk(&argvars[2], &typeerr);
+ if (typeerr) {
return;
+ }
}
} else
maxcount = 25;
- spell_suggest_list(&ga, str, maxcount, need_capital, false);
+ spell_suggest_list(&ga, (char_u *)str, maxcount, need_capital, false);
- for (int i = 0; i < ga.ga_len; ++i) {
- str = ((char_u **)ga.ga_data)[i];
+ for (int i = 0; i < ga.ga_len; i++) {
+ char *p = ((char **)ga.ga_data)[i];
- li = listitem_alloc();
+ li = tv_list_item_alloc();
li->li_tv.v_type = VAR_STRING;
li->li_tv.v_lock = 0;
- li->li_tv.vval.v_string = str;
- list_append(rettv->vval.v_list, li);
+ li->li_tv.vval.v_string = (char_u *)p;
+ tv_list_append(rettv->vval.v_list, li);
}
ga_clear(&ga);
}
@@ -16252,64 +15669,69 @@ static void f_spellsuggest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *str;
- char_u *end;
- char_u *pat = NULL;
regmatch_T regmatch;
- char_u patbuf[NUMBUFLEN];
char_u *save_cpo;
int match;
colnr_T col = 0;
- int keepempty = FALSE;
- int typeerr = FALSE;
+ bool keepempty = false;
+ bool typeerr = false;
/* Make 'cpoptions' empty, the 'l' flag should not be used here. */
save_cpo = p_cpo;
p_cpo = (char_u *)"";
- str = get_tv_string(&argvars[0]);
+ const char *str = tv_get_string(&argvars[0]);
+ const char *pat = NULL;
+ char patbuf[NUMBUFLEN];
if (argvars[1].v_type != VAR_UNKNOWN) {
- pat = get_tv_string_buf_chk(&argvars[1], patbuf);
- if (pat == NULL)
- typeerr = TRUE;
- if (argvars[2].v_type != VAR_UNKNOWN)
- keepempty = get_tv_number_chk(&argvars[2], &typeerr);
+ pat = tv_get_string_buf_chk(&argvars[1], patbuf);
+ if (pat == NULL) {
+ typeerr = true;
+ }
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ keepempty = (bool)tv_get_number_chk(&argvars[2], &typeerr);
+ }
+ }
+ if (pat == NULL || *pat == NUL) {
+ pat = "[\\x01- ]\\+";
}
- if (pat == NULL || *pat == NUL)
- pat = (char_u *)"[\\x01- ]\\+";
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
if (typeerr)
return;
- regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
+ regmatch.regprog = vim_regcomp((char_u *)pat, RE_MAGIC + RE_STRING);
if (regmatch.regprog != NULL) {
regmatch.rm_ic = 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 (*str == NUL) {
+ match = false; // Empty item at the end.
+ } else {
+ match = vim_regexec_nl(&regmatch, (char_u *)str, col);
+ }
+ const char *end;
+ if (match) {
+ end = (const char *)regmatch.startp[0];
+ } else {
+ end = str + strlen(str);
+ }
if (keepempty || end > str || (rettv->vval.v_list->lv_len > 0
- && *str != NUL && match && end <
- regmatch.endp[0])) {
- list_append_string(rettv->vval.v_list, str, (int)(end - str));
+ && *str != NUL
+ && match
+ && end < (const char *)regmatch.endp[0])) {
+ tv_list_append_string(rettv->vval.v_list, str, end - str);
}
if (!match)
break;
- /* Advance to just after the match. */
- if (regmatch.endp[0] > str)
+ // Advance to just after the match.
+ if (regmatch.endp[0] > (char_u *)str) {
col = 0;
- else {
- /* Don't get stuck at the same match. */
+ } else {
+ // Don't get stuck at the same match.
col = (*mb_ptr2len)(regmatch.endp[0]);
}
- str = regmatch.endp[0];
+ str = (const char *)regmatch.endp[0];
}
vim_regfree(regmatch.regprog);
@@ -16323,11 +15745,16 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_str2float(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p = skipwhite(get_tv_string(&argvars[0]));
+ char_u *p = skipwhite((const char_u *)tv_get_string(&argvars[0]));
+ bool isneg = (*p == '-');
- if (*p == '+')
+ if (*p == '+' || *p == '-') {
p = skipwhite(p + 1);
- (void) string2float((char *) p, &rettv->vval.v_float);
+ }
+ (void)string2float((char *)p, &rettv->vval.v_float);
+ if (isneg) {
+ rettv->vval.v_float *= -1;
+ }
rettv->v_type = VAR_FLOAT;
}
@@ -16335,37 +15762,45 @@ static void f_str2float(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int base = 10;
- char_u *p;
- long n;
+ varnumber_T n;
int what;
if (argvars[1].v_type != VAR_UNKNOWN) {
- base = get_tv_number(&argvars[1]);
+ base = tv_get_number(&argvars[1]);
if (base != 2 && base != 8 && base != 10 && base != 16) {
EMSG(_(e_invarg));
return;
}
}
- p = skipwhite(get_tv_string(&argvars[0]));
- if (*p == '+') {
+ char_u *p = skipwhite((const char_u *)tv_get_string(&argvars[0]));
+ bool isneg = (*p == '-');
+ if (*p == '+' || *p == '-') {
p = skipwhite(p + 1);
}
switch (base) {
- case 2:
- what = STR2NR_BIN + STR2NR_FORCE;
+ case 2: {
+ what = STR2NR_BIN | STR2NR_FORCE;
break;
- case 8:
- what = STR2NR_OCT + STR2NR_FORCE;
+ }
+ case 8: {
+ what = STR2NR_OCT | STR2NR_FORCE;
break;
- case 16:
- what = STR2NR_HEX + STR2NR_FORCE;
+ }
+ case 16: {
+ what = STR2NR_HEX | STR2NR_FORCE;
break;
- default:
+ }
+ default: {
what = 0;
+ }
}
vim_str2nr(p, NULL, NULL, what, &n, NULL, 0);
- rettv->vval.v_number = n;
+ if (isneg) {
+ rettv->vval.v_number = -n;
+ } else {
+ rettv->vval.v_number = n;
+ }
}
/*
@@ -16373,17 +15808,16 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u result_buf[256];
time_t seconds;
- char_u *p;
rettv->v_type = VAR_STRING;
- p = get_tv_string(&argvars[0]);
- if (argvars[1].v_type == VAR_UNKNOWN)
+ char *p = (char *)tv_get_string(&argvars[0]);
+ if (argvars[1].v_type == VAR_UNKNOWN) {
seconds = time(NULL);
- else
- seconds = (time_t)get_tv_number(&argvars[1]);
+ } else {
+ seconds = (time_t)tv_get_number(&argvars[1]);
+ }
struct tm curtime;
struct tm *curtime_ptr = os_localtime_r(&seconds, &curtime);
@@ -16397,23 +15831,27 @@ static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
conv.vc_type = CONV_NONE;
enc = enc_locale();
convert_setup(&conv, p_enc, enc);
- if (conv.vc_type != CONV_NONE)
- p = string_convert(&conv, p, NULL);
- if (p != NULL)
- (void)strftime((char *)result_buf, sizeof(result_buf),
- (char *)p, curtime_ptr);
- else
+ if (conv.vc_type != CONV_NONE) {
+ p = (char *)string_convert(&conv, (char_u *)p, NULL);
+ }
+ char result_buf[256];
+ if (p != NULL) {
+ (void)strftime(result_buf, sizeof(result_buf), p, curtime_ptr);
+ } else {
result_buf[0] = NUL;
+ }
- if (conv.vc_type != CONV_NONE)
+ if (conv.vc_type != CONV_NONE) {
xfree(p);
+ }
convert_setup(&conv, enc, p_enc);
- if (conv.vc_type != CONV_NONE)
- rettv->vval.v_string = string_convert(&conv, result_buf, NULL);
- else
- rettv->vval.v_string = vim_strsave(result_buf);
+ if (conv.vc_type != CONV_NONE) {
+ rettv->vval.v_string = string_convert(&conv, (char_u *)result_buf, NULL);
+ } else {
+ rettv->vval.v_string = (char_u *)xstrdup(result_buf);
+ }
- /* Release conversion descriptors */
+ // Release conversion descriptors.
convert_setup(&conv, NULL, NULL);
xfree(enc);
}
@@ -16422,33 +15860,28 @@ static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// "strgetchar()" function
static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *str;
- int len;
- int error = false;
- int charidx;
-
rettv->vval.v_number = -1;
- str = get_tv_string_chk(&argvars[0]);
+
+ const char *const str = tv_get_string_chk(&argvars[0]);
if (str == NULL) {
return;
}
- len = (int)STRLEN(str);
- charidx = get_tv_number_chk(&argvars[1], &error);
+ bool error = false;
+ varnumber_T charidx = tv_get_number_chk(&argvars[1], &error);
if (error) {
return;
}
- {
- int byteidx = 0;
+ const size_t len = STRLEN(str);
+ size_t byteidx = 0;
- while (charidx >= 0 && byteidx < len) {
- if (charidx == 0) {
- rettv->vval.v_number = mb_ptr2char(str + byteidx);
- break;
- }
- charidx--;
- byteidx += mb_cptr2len(str + byteidx);
+ while (charidx >= 0 && byteidx < len) {
+ if (charidx == 0) {
+ rettv->vval.v_number = mb_ptr2char((const char_u *)str + byteidx);
+ break;
}
+ charidx--;
+ byteidx += MB_CPTR2LEN((const char_u *)str + byteidx);
}
}
@@ -16457,32 +15890,33 @@ static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_stridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u buf[NUMBUFLEN];
- char_u *needle;
- char_u *haystack;
- char_u *save_haystack;
- char_u *pos;
- int start_idx;
-
- needle = get_tv_string_chk(&argvars[1]);
- save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf);
rettv->vval.v_number = -1;
- if (needle == NULL || haystack == NULL)
- return; /* type error; errmsg already given */
+
+ char buf[NUMBUFLEN];
+ const char *const needle = tv_get_string_chk(&argvars[1]);
+ const char *haystack = tv_get_string_buf_chk(&argvars[0], buf);
+ const char *const haystack_start = haystack;
+ if (needle == NULL || haystack == NULL) {
+ return; // Type error; errmsg already given.
+ }
if (argvars[2].v_type != VAR_UNKNOWN) {
- int error = FALSE;
+ bool error = false;
- start_idx = get_tv_number_chk(&argvars[2], &error);
- if (error || start_idx >= (int)STRLEN(haystack))
+ const ptrdiff_t start_idx = (ptrdiff_t)tv_get_number_chk(&argvars[2],
+ &error);
+ if (error || start_idx >= (ptrdiff_t)strlen(haystack)) {
return;
- if (start_idx >= 0)
+ }
+ if (start_idx >= 0) {
haystack += start_idx;
+ }
}
- pos = (char_u *)strstr((char *)haystack, (char *)needle);
- if (pos != NULL)
- rettv->vval.v_number = (varnumber_T)(pos - save_haystack);
+ const char *pos = strstr(haystack, needle);
+ if (pos != NULL) {
+ rettv->vval.v_number = (varnumber_T)(pos - haystack_start);
+ }
}
/*
@@ -16499,8 +15933,7 @@ static void f_string(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_strlen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = (varnumber_T)(STRLEN(
- get_tv_string(&argvars[0])));
+ rettv->vval.v_number = (varnumber_T)strlen(tv_get_string(&argvars[0]));
}
/*
@@ -16508,21 +15941,21 @@ static void f_strlen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_strchars(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *s = get_tv_string(&argvars[0]);
+ const char *s = tv_get_string(&argvars[0]);
int skipcc = 0;
varnumber_T len = 0;
- int (*func_mb_ptr2char_adv)(char_u **pp);
+ int (*func_mb_ptr2char_adv)(const char_u **pp);
if (argvars[1].v_type != VAR_UNKNOWN) {
- skipcc = get_tv_number_chk(&argvars[1], NULL);
+ skipcc = tv_get_number_chk(&argvars[1], NULL);
}
if (skipcc < 0 || skipcc > 1) {
EMSG(_(e_invarg));
} else {
func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv;
while (*s != NUL) {
- func_mb_ptr2char_adv(&s);
- ++len;
+ func_mb_ptr2char_adv((const char_u **)&s);
+ len++;
}
rettv->vval.v_number = len;
}
@@ -16533,13 +15966,14 @@ static void f_strchars(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *s = get_tv_string(&argvars[0]);
+ const char *const s = tv_get_string(&argvars[0]);
int col = 0;
- if (argvars[1].v_type != VAR_UNKNOWN)
- col = get_tv_number(&argvars[1]);
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ col = tv_get_number(&argvars[1]);
+ }
- rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, s) - col);
+ rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, (char_u *)s) - col);
}
/*
@@ -16547,44 +15981,40 @@ static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_strwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *s = get_tv_string(&argvars[0]);
+ const char *const s = tv_get_string(&argvars[0]);
- rettv->vval.v_number = (varnumber_T) mb_string2cells(s);
+ rettv->vval.v_number = (varnumber_T)mb_string2cells((const char_u *)s);
}
// "strcharpart()" function
-static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) {
- char_u *p;
- int nchar;
- int nbyte = 0;
- int charlen;
- int len = 0;
- int slen;
- int error = false;
-
- p = get_tv_string(&argvars[0]);
- slen = (int)STRLEN(p);
+static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ const char *const p = tv_get_string(&argvars[0]);
+ const size_t slen = STRLEN(p);
- nchar = get_tv_number_chk(&argvars[1], &error);
+ int nbyte = 0;
+ bool error = false;
+ varnumber_T nchar = tv_get_number_chk(&argvars[1], &error);
if (!error) {
if (nchar > 0) {
- while (nchar > 0 && nbyte < slen) {
- nbyte += mb_cptr2len(p + nbyte);
+ while (nchar > 0 && (size_t)nbyte < slen) {
+ nbyte += MB_CPTR2LEN((const char_u *)p + nbyte);
nchar--;
}
} else {
nbyte = nchar;
}
}
+ int len = 0;
if (argvars[2].v_type != VAR_UNKNOWN) {
- charlen = get_tv_number(&argvars[2]);
- while (charlen > 0 && nbyte + len < slen) {
+ int charlen = tv_get_number(&argvars[2]);
+ while (charlen > 0 && nbyte + len < (int)slen) {
int off = nbyte + len;
if (off < 0) {
len += 1;
} else {
- len += mb_cptr2len(p + off);
+ len += (size_t)MB_CPTR2LEN((const char_u *)p + off);
}
charlen--;
}
@@ -16597,17 +16027,17 @@ static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) {
if (nbyte < 0) {
len += nbyte;
nbyte = 0;
- } else if (nbyte > slen) {
+ } else if ((size_t)nbyte > slen) {
nbyte = slen;
}
if (len < 0) {
len = 0;
- } else if (nbyte + len > slen) {
+ } else if (nbyte + len > (int)slen) {
len = slen - nbyte;
}
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = vim_strnsave(p + nbyte, len);
+ rettv->vval.v_string = (char_u *)xstrndup(p + nbyte, (size_t)len);
}
/*
@@ -16615,39 +16045,37 @@ static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) {
*/
static void f_strpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p;
- int n;
- int len;
- int slen;
- int error = FALSE;
+ bool error = false;
- p = get_tv_string(&argvars[0]);
- slen = (int)STRLEN(p);
+ const char *const p = tv_get_string(&argvars[0]);
+ const size_t slen = strlen(p);
- n = get_tv_number_chk(&argvars[1], &error);
- if (error)
+ varnumber_T n = tv_get_number_chk(&argvars[1], &error);
+ varnumber_T len;
+ if (error) {
len = 0;
- else if (argvars[2].v_type != VAR_UNKNOWN)
- len = get_tv_number(&argvars[2]);
- else
- len = slen - n; /* default len: all bytes that are available. */
+ } else if (argvars[2].v_type != VAR_UNKNOWN) {
+ len = tv_get_number(&argvars[2]);
+ } else {
+ len = slen - n; // Default len: all bytes that are available.
+ }
- /*
- * Only return the overlap between the specified part and the actual
- * string.
- */
+ // Only return the overlap between the specified part and the actual
+ // string.
if (n < 0) {
len += n;
n = 0;
- } else if (n > slen)
+ } else if (n > (varnumber_T)slen) {
n = slen;
- if (len < 0)
+ }
+ if (len < 0) {
len = 0;
- else if (n + len > slen)
+ } else if (n + len > (varnumber_T)slen) {
len = slen - n;
+ }
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = vim_strnsave(p + n, len);
+ rettv->vval.v_string = (char_u *)xmemdupz(p + n, (size_t)len);
}
/*
@@ -16655,45 +16083,46 @@ static void f_strpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_strridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u buf[NUMBUFLEN];
- char_u *needle;
- char_u *haystack;
- char_u *rest;
- char_u *lastmatch = NULL;
- int haystack_len, end_idx;
-
- needle = get_tv_string_chk(&argvars[1]);
- haystack = get_tv_string_buf_chk(&argvars[0], buf);
+ char buf[NUMBUFLEN];
+ const char *const needle = tv_get_string_chk(&argvars[1]);
+ const char *const haystack = tv_get_string_buf_chk(&argvars[0], buf);
rettv->vval.v_number = -1;
- if (needle == NULL || haystack == NULL)
- return; /* type error; errmsg already given */
+ if (needle == NULL || haystack == NULL) {
+ return; // Type error; errmsg already given.
+ }
- haystack_len = (int)STRLEN(haystack);
+ const size_t haystack_len = STRLEN(haystack);
+ ptrdiff_t end_idx;
if (argvars[2].v_type != VAR_UNKNOWN) {
- /* Third argument: upper limit for index */
- end_idx = get_tv_number_chk(&argvars[2], NULL);
- if (end_idx < 0)
- return; /* can never find a match */
- } else
- end_idx = haystack_len;
+ // Third argument: upper limit for index.
+ end_idx = (ptrdiff_t)tv_get_number_chk(&argvars[2], NULL);
+ if (end_idx < 0) {
+ return; // Can never find a match.
+ }
+ } else {
+ end_idx = (ptrdiff_t)haystack_len;
+ }
+ const char *lastmatch = NULL;
if (*needle == NUL) {
- /* Empty string matches past the end. */
+ // Empty string matches past the end.
lastmatch = haystack + end_idx;
} else {
- for (rest = haystack; *rest != NUL; ++rest) {
- rest = (char_u *)strstr((char *)rest, (char *)needle);
- if (rest == NULL || rest > haystack + end_idx)
+ for (const char *rest = haystack; *rest != NUL; rest++) {
+ rest = strstr(rest, needle);
+ if (rest == NULL || rest > haystack + end_idx) {
break;
+ }
lastmatch = rest;
}
}
- if (lastmatch == NULL)
+ if (lastmatch == NULL) {
rettv->vval.v_number = -1;
- else
+ } else {
rettv->vval.v_number = (varnumber_T)(lastmatch - haystack);
+ }
}
/*
@@ -16702,7 +16131,7 @@ static void f_strridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_strtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = transstr(get_tv_string(&argvars[0]));
+ rettv->vval.v_string = transstr((char_u *)tv_get_string(&argvars[0]));
}
/*
@@ -16710,18 +16139,22 @@ static void f_strtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_submatch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int error = FALSE;
- int no = (int)get_tv_number_chk(&argvars[0], &error);
+ bool error = false;
+ int no = (int)tv_get_number_chk(&argvars[0], &error);
if (error) {
return;
}
+ if (no < 0 || no >= NSUBEXP) {
+ EMSGN(_("E935: invalid submatch number: %d"), no);
+ return;
+ }
int retList = 0;
if (argvars[1].v_type != VAR_UNKNOWN) {
- retList = get_tv_number_chk(&argvars[1], &error);
+ retList = tv_get_number_chk(&argvars[1], &error);
if (error) {
- return;
+ return;
}
}
@@ -16739,40 +16172,47 @@ static void f_submatch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_substitute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u patbuf[NUMBUFLEN];
- char_u subbuf[NUMBUFLEN];
- char_u flagsbuf[NUMBUFLEN];
+ char patbuf[NUMBUFLEN];
+ char subbuf[NUMBUFLEN];
+ char flagsbuf[NUMBUFLEN];
+
+ const char *const str = tv_get_string_chk(&argvars[0]);
+ const char *const pat = tv_get_string_buf_chk(&argvars[1], patbuf);
+ const char *sub = NULL;
+ const char *const flg = tv_get_string_buf_chk(&argvars[3], flagsbuf);
- char_u *str = get_tv_string_chk(&argvars[0]);
- char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf);
- char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf);
- char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf);
+ typval_T *expr = NULL;
+ if (tv_is_func(argvars[2])) {
+ expr = &argvars[2];
+ } else {
+ sub = tv_get_string_buf_chk(&argvars[2], subbuf);
+ }
rettv->v_type = VAR_STRING;
- if (str == NULL || pat == NULL || sub == NULL || flg == NULL)
+ if (str == NULL || pat == NULL || (sub == NULL && expr == NULL)
+ || flg == NULL) {
rettv->vval.v_string = NULL;
- else
- rettv->vval.v_string = do_string_sub(str, pat, sub, flg);
+ } else {
+ rettv->vval.v_string = do_string_sub((char_u *)str, (char_u *)pat,
+ (char_u *)sub, expr, (char_u *)flg);
+ }
}
-/*
- * "synID(lnum, col, trans)" function
- */
+/// "synID(lnum, col, trans)" function
static void f_synID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int id = 0;
- long lnum;
- long col;
- int trans;
- int transerr = FALSE;
+ // -1 on type error (both)
+ const linenr_T lnum = tv_get_lnum(argvars);
+ const colnr_T col = (colnr_T)tv_get_number(&argvars[1]) - 1;
- lnum = get_tv_lnum(argvars); /* -1 on type error */
- col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */
- trans = get_tv_number_chk(&argvars[2], &transerr);
+ bool transerr = false;
+ const int trans = tv_get_number_chk(&argvars[2], &transerr);
+ int id = 0;
if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count
- && col >= 0 && col < (long)STRLEN(ml_get(lnum)))
- id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL, FALSE);
+ && col >= 0 && (size_t)col < STRLEN(ml_get(lnum))) {
+ id = syn_get_id(curwin, lnum, col, trans, NULL, false);
+ }
rettv->vval.v_number = id;
}
@@ -16782,20 +16222,16 @@ static void f_synID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p = NULL;
- int id;
- char_u *what;
- char_u *mode;
- char_u modebuf[NUMBUFLEN];
+ const int id = (int)tv_get_number(&argvars[0]);
+ const char *const what = tv_get_string(&argvars[1]);
int modec;
-
- id = get_tv_number(&argvars[0]);
- what = get_tv_string(&argvars[1]);
if (argvars[2].v_type != VAR_UNKNOWN) {
- mode = get_tv_string_buf(&argvars[2], modebuf);
+ char modebuf[NUMBUFLEN];
+ const char *const mode = tv_get_string_buf(&argvars[2], modebuf);
modec = TOLOWER_ASC(mode[0]);
- if (modec != 'c' && modec != 'g')
- modec = 0; /* replace invalid with current */
+ if (modec != 'c' && modec != 'g') {
+ modec = 0; // Replace invalid with current.
+ }
} else if (ui_rgb_attached()) {
modec = 'g';
} else {
@@ -16803,54 +16239,56 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
+ const char *p = NULL;
switch (TOLOWER_ASC(what[0])) {
- case 'b':
- if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */
+ case 'b': {
+ if (TOLOWER_ASC(what[1]) == 'g') { // bg[#]
+ p = highlight_color(id, what, modec);
+ } else { // bold
+ p = highlight_has_attr(id, HL_BOLD, modec);
+ }
+ break;
+ }
+ case 'f': { // fg[#] or font
p = highlight_color(id, what, modec);
- else /* bold */
- p = highlight_has_attr(id, HL_BOLD, modec);
- break;
-
- case 'f': /* fg[#] or font */
- p = highlight_color(id, what, modec);
- break;
-
- case 'i':
- if (TOLOWER_ASC(what[1]) == 'n') /* inverse */
+ break;
+ }
+ case 'i': {
+ if (TOLOWER_ASC(what[1]) == 'n') { // inverse
+ p = highlight_has_attr(id, HL_INVERSE, modec);
+ } else { // italic
+ p = highlight_has_attr(id, HL_ITALIC, modec);
+ }
+ break;
+ }
+ case 'n': { // name
+ p = get_highlight_name(NULL, id - 1);
+ break;
+ }
+ case 'r': { // reverse
p = highlight_has_attr(id, HL_INVERSE, modec);
- else /* italic */
- p = highlight_has_attr(id, HL_ITALIC, modec);
- break;
-
- case 'n': /* name */
- p = get_highlight_name(NULL, id - 1);
- break;
-
- case 'r': /* reverse */
- p = highlight_has_attr(id, HL_INVERSE, modec);
- break;
-
- case 's':
- if (TOLOWER_ASC(what[1]) == 'p') /* sp[#] */
- p = highlight_color(id, what, modec);
- else /* standout */
- p = highlight_has_attr(id, HL_STANDOUT, modec);
- break;
-
- case 'u':
- if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c')
- /* underline */
- p = highlight_has_attr(id, HL_UNDERLINE, modec);
- else
- /* undercurl */
- p = highlight_has_attr(id, HL_UNDERCURL, modec);
- break;
+ break;
+ }
+ case 's': {
+ if (TOLOWER_ASC(what[1]) == 'p') { // sp[#]
+ p = highlight_color(id, what, modec);
+ } else { // standout
+ p = highlight_has_attr(id, HL_STANDOUT, modec);
+ }
+ break;
+ }
+ case 'u': {
+ if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') { // underline
+ p = highlight_has_attr(id, HL_UNDERLINE, modec);
+ } else { // undercurl
+ p = highlight_has_attr(id, HL_UNDERCURL, modec);
+ }
+ break;
+ }
}
- if (p != NULL)
- p = vim_strsave(p);
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = p;
+ rettv->vval.v_string = (char_u *)(p == NULL ? p : xstrdup(p));
}
/*
@@ -16858,14 +16296,13 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_synIDtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int id;
+ int id = tv_get_number(&argvars[0]);
- id = get_tv_number(&argvars[0]);
-
- if (id > 0)
+ if (id > 0) {
id = syn_get_final_id(id);
- else
+ } else {
id = 0;
+ }
rettv->vval.v_number = id;
}
@@ -16875,8 +16312,6 @@ static void f_synIDtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- long lnum;
- long col;
int syntax_flags = 0;
int cchar;
int matchid = 0;
@@ -16885,15 +16320,16 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
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 */
+ // -1 on type error (both)
+ const linenr_T lnum = tv_get_lnum(argvars);
+ const colnr_T col = (colnr_T)tv_get_number(&argvars[1]) - 1;
memset(str, NUL, sizeof(str));
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count && col >= 0
- && col <= (long)STRLEN(ml_get(lnum)) && curwin->w_p_cole > 0) {
- (void)syn_get_id(curwin, lnum, col, FALSE, NULL, FALSE);
+ && (size_t)col <= STRLEN(ml_get(lnum)) && curwin->w_p_cole > 0) {
+ (void)syn_get_id(curwin, lnum, col, false, NULL, false);
syntax_flags = get_syntax_info(&matchid);
// get the conceal character
@@ -16911,10 +16347,10 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
- list_append_number(rettv->vval.v_list, (syntax_flags & HL_CONCEAL) != 0);
+ tv_list_append_number(rettv->vval.v_list, (syntax_flags & HL_CONCEAL) != 0);
// -1 to auto-determine strlen
- list_append_string(rettv->vval.v_list, str, -1);
- list_append_number(rettv->vval.v_list, matchid);
+ tv_list_append_string(rettv->vval.v_list, (const char *)str, -1);
+ tv_list_append_number(rettv->vval.v_list, matchid);
}
/*
@@ -16922,56 +16358,35 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_synstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- long lnum;
- long col;
-
rettv->v_type = VAR_LIST;
rettv->vval.v_list = NULL;
- lnum = get_tv_lnum(argvars); /* -1 on type error */
- col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */
+ // -1 on type error (both)
+ const linenr_T lnum = tv_get_lnum(argvars);
+ const colnr_T col = (colnr_T)tv_get_number(&argvars[1]) - 1;
if (lnum >= 1
&& lnum <= curbuf->b_ml.ml_line_count
&& col >= 0
- && col <= (long)STRLEN(ml_get(lnum))) {
- rettv_list_alloc(rettv);
- (void)syn_get_id(curwin, lnum, (colnr_T)col, FALSE, NULL, TRUE);
+ && (size_t)col <= STRLEN(ml_get(lnum))) {
+ tv_list_alloc_ret(rettv);
+ (void)syn_get_id(curwin, lnum, col, false, NULL, true);
int id;
int i = 0;
while ((id = syn_get_stack_item(i++)) >= 0) {
- list_append_number(rettv->vval.v_list, id);
+ tv_list_append_number(rettv->vval.v_list, id);
}
}
}
-static list_T* string_to_list(char_u *str, size_t len, bool keepempty)
+static list_T *string_to_list(const char *str, size_t len, const bool keepempty)
{
- list_T *list = list_alloc();
-
- // Copy each line to a list element using NL as the delimiter.
- for (size_t i = 0; i < len; i++) {
- char_u *start = str + i;
- size_t line_len = (char_u *) xmemscan(start, NL, len - i) - start;
- i += line_len;
-
- // Don't use a str function to copy res as it may contains NULs.
- char_u *s = xmemdupz(start, line_len);
- memchrsub(s, NUL, NL, line_len); // Replace NUL with NL to avoid truncation
-
- listitem_T *li = listitem_alloc();
- li->li_tv.v_type = VAR_STRING;
- li->li_tv.v_lock = 0;
- li->li_tv.vval.v_string = s;
- list_append(list, li);
- }
-
- // Optionally retain final newline, if present
- if (keepempty && str[len-1] == NL) {
- list_append_string(list, (char_u*)"", 0);
+ if (!keepempty && str[len - 1] == NL) {
+ len--;
}
-
+ list_T *const list = tv_list_alloc();
+ encode_list_write(list, str, len);
return list;
}
@@ -16986,16 +16401,20 @@ static void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
}
// get input to the shell command (if any), and its length
- ssize_t input_len;
- char *input = (char *) save_tv_as_string(&argvars[1], &input_len, false);
+ ptrdiff_t input_len;
+ char *input = save_tv_as_string(&argvars[1], &input_len, false);
if (input_len < 0) {
assert(input == NULL);
return;
}
// get shell command to execute
- char **argv = tv_to_argv(&argvars[0], NULL, NULL);
+ bool executable = true;
+ char **argv = tv_to_argv(&argvars[0], NULL, &executable);
if (!argv) {
+ if (!executable) {
+ set_vim_var_nr(VV_SHELL_ERROR, (long)-1);
+ }
xfree(input);
return; // Already did emsg.
}
@@ -17012,7 +16431,7 @@ static void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
if (res == NULL) {
if (retlist) {
// return an empty list when there's no output
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
} else {
rettv->vval.v_string = (char_u *) xstrdup("");
}
@@ -17022,9 +16441,9 @@ static void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
if (retlist) {
int keepempty = 0;
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) {
- keepempty = get_tv_number(&argvars[2]);
+ keepempty = tv_get_number(&argvars[2]);
}
- rettv->vval.v_list = string_to_list((char_u *) res, nread, keepempty != 0);
+ rettv->vval.v_list = string_to_list(res, nread, (bool)keepempty);
rettv->vval.v_list->lv_refcount++;
rettv->v_type = VAR_LIST;
@@ -17067,20 +16486,20 @@ static void f_systemlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- tabpage_T *tp;
win_T *wp = NULL;
- if (argvars[0].v_type == VAR_UNKNOWN)
+ if (argvars[0].v_type == VAR_UNKNOWN) {
wp = firstwin;
- else {
- tp = find_tabpage((int)get_tv_number(&argvars[0]));
- if (tp != NULL)
+ } else {
+ tabpage_T *const tp = find_tabpage((int)tv_get_number(&argvars[0]));
+ if (tp != NULL) {
wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
+ }
}
if (wp != NULL) {
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
while (wp != NULL) {
- list_append_number(rettv->vval.v_list, wp->w_buffer->b_fnum);
+ tv_list_append_number(rettv->vval.v_list, wp->w_buffer->b_fnum);
wp = wp->w_next;
}
}
@@ -17093,19 +16512,20 @@ static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_tabpagenr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int nr = 1;
- char_u *arg;
if (argvars[0].v_type != VAR_UNKNOWN) {
- arg = get_tv_string_chk(&argvars[0]);
+ const char *const arg = tv_get_string_chk(&argvars[0]);
nr = 0;
if (arg != NULL) {
- if (STRCMP(arg, "$") == 0)
+ if (strcmp(arg, "$") == 0) {
nr = tabpage_index(NULL) - 1;
- else
+ } else {
EMSG2(_(e_invexpr2), arg);
+ }
}
- } else
+ } else {
nr = tabpage_index(curtab);
+ }
rettv->vval.v_number = nr;
}
@@ -17119,19 +16539,19 @@ static int get_winnr(tabpage_T *tp, typval_T *argvar)
win_T *twin;
int nr = 1;
win_T *wp;
- char_u *arg;
twin = (tp == curtab) ? curwin : tp->tp_curwin;
if (argvar->v_type != VAR_UNKNOWN) {
- arg = get_tv_string_chk(argvar);
- if (arg == NULL)
- nr = 0; /* type error; errmsg already given */
- else if (STRCMP(arg, "$") == 0)
+ const char *const arg = tv_get_string_chk(argvar);
+ if (arg == NULL) {
+ nr = 0; // Type error; errmsg already given.
+ } else if (strcmp(arg, "$") == 0) {
twin = (tp == curtab) ? lastwin : tp->tp_lastwin;
- else if (STRCMP(arg, "#") == 0) {
+ } else if (strcmp(arg, "#") == 0) {
twin = (tp == curtab) ? prevwin : tp->tp_prevwin;
- if (twin == NULL)
+ if (twin == NULL) {
nr = 0;
+ }
} else {
EMSG2(_(e_invexpr2), arg);
nr = 0;
@@ -17157,13 +16577,12 @@ static int get_winnr(tabpage_T *tp, typval_T *argvar)
static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int nr = 1;
- tabpage_T *tp;
-
- tp = find_tabpage((int)get_tv_number(&argvars[0]));
- if (tp == NULL)
+ tabpage_T *const tp = find_tabpage((int)tv_get_number(&argvars[0]));
+ if (tp == NULL) {
nr = 0;
- else
+ } else {
nr = get_winnr(tp, &argvars[1]);
+ }
rettv->vval.v_number = nr;
}
@@ -17173,16 +16592,16 @@ static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_tagfiles(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *fname;
+ char *fname;
tagname_T tn;
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
fname = xmalloc(MAXPATHL);
- int first = TRUE;
- while (get_tagfname(&tn, first, fname) == OK) {
- list_append_string(rettv->vval.v_list, fname, -1);
- first = FALSE;
+ bool first = true;
+ while (get_tagfname(&tn, first, (char_u *)fname) == OK) {
+ tv_list_append_string(rettv->vval.v_list, fname, -1);
+ first = false;
}
tagname_free(&tn);
@@ -17194,15 +16613,19 @@ static void f_tagfiles(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_taglist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *tag_pattern;
-
- tag_pattern = get_tv_string(&argvars[0]);
+ const char *const tag_pattern = tv_get_string(&argvars[0]);
- rettv->vval.v_number = FALSE;
- if (*tag_pattern == NUL)
+ rettv->vval.v_number = false;
+ if (*tag_pattern == NUL) {
return;
+ }
- (void)get_tags(rettv_list_alloc(rettv), tag_pattern);
+ const char *fname = NULL;
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ fname = tv_get_string(&argvars[1]);
+ }
+ (void)get_tags(tv_list_alloc_ret(rettv), (char_u *)tag_pattern,
+ (char_u *)fname);
}
/*
@@ -17226,7 +16649,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- char *cmd;
+ const char *cmd;
bool executable = true;
char **argv = tv_to_argv(&argvars[0], &cmd, &executable);
if (!argv) {
@@ -17244,15 +16667,15 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
Callback on_stdout = CALLBACK_NONE, on_stderr = CALLBACK_NONE,
on_exit = CALLBACK_NONE;
dict_T *job_opts = NULL;
- char *cwd = ".";
+ const char *cwd = ".";
if (argvars[1].v_type == VAR_DICT) {
job_opts = argvars[1].vval.v_dict;
- char *new_cwd = (char *)get_dict_string(job_opts, "cwd", false);
- if (new_cwd && strlen(new_cwd) > 0) {
+ const char *const new_cwd = tv_dict_get_string(job_opts, "cwd", false);
+ if (new_cwd && *new_cwd != NUL) {
cwd = new_cwd;
// The new cwd must be a directory.
- if (!os_isdir((char_u *)cwd)) {
+ if (!os_isdir((const char_u *)cwd)) {
EMSG2(_(e_invarg2), "expected valid directory");
shell_free_argv(argv);
return;
@@ -17289,13 +16712,15 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// at this point the buffer has no terminal instance associated yet, so unset
// the 'swapfile' option to ensure no swap file will be created
curbuf->b_p_swf = false;
- (void)setfname(curbuf, (uint8_t *)buf, NULL, true);
+ (void)setfname(curbuf, (char_u *)buf, NULL, true);
// Save the job id and pid in b:terminal_job_{id,pid}
- Error err;
- dict_set_value(curbuf->b_vars, cstr_as_string("terminal_job_id"),
- INTEGER_OBJ(rettv->vval.v_number), false, false, &err);
- dict_set_value(curbuf->b_vars, cstr_as_string("terminal_job_pid"),
- INTEGER_OBJ(pid), false, false, &err);
+ Error err = ERROR_INIT;
+ dict_set_var(curbuf->b_vars, cstr_as_string("terminal_job_id"),
+ INTEGER_OBJ(rettv->vval.v_number), false, false, &err);
+ api_clear_error(&err);
+ dict_set_var(curbuf->b_vars, cstr_as_string("terminal_job_pid"),
+ INTEGER_OBJ(pid), false, false, &err);
+ api_clear_error(&err);
Terminal *term = terminal_open(topts);
data->term = term;
@@ -17304,7 +16729,17 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
-static bool callback_from_typval(Callback *callback, typval_T *arg)
+// "test_garbagecollect_now()" function
+static void f_test_garbagecollect_now(typval_T *argvars,
+ typval_T *rettv, FunPtr fptr)
+{
+ // This is dangerous, any Lists and Dicts used internally may be freed
+ // while still in use.
+ garbage_collect(true);
+}
+
+bool callback_from_typval(Callback *const callback, typval_T *const arg)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL) {
callback->data.partial = arg->vval.v_partial;
@@ -17324,53 +16759,33 @@ static bool callback_from_typval(Callback *callback, typval_T *arg)
return true;
}
-
/// Unref/free callback
-static void callback_free(Callback *callback)
+void callback_free(Callback *const callback)
+ FUNC_ATTR_NONNULL_ALL
{
switch (callback->type) {
- case kCallbackFuncref:
+ case kCallbackFuncref: {
func_unref(callback->data.funcref);
xfree(callback->data.funcref);
break;
-
- case kCallbackPartial:
+ }
+ case kCallbackPartial: {
partial_unref(callback->data.partial);
break;
-
- case kCallbackNone:
+ }
+ case kCallbackNone: {
break;
-
- default:
+ }
+ default: {
abort();
+ }
}
callback->type = kCallbackNone;
}
-static bool callback_equal(Callback *cb1, Callback *cb2)
-{
- if (cb1->type != cb2->type) {
- return false;
- }
- switch (cb1->type) {
- case kCallbackFuncref:
- return STRCMP(cb1->data.funcref, cb2->data.funcref) == 0;
-
- case kCallbackPartial:
- // FIXME: this is inconsistent with tv_equal but is needed for precision
- // maybe change dictwatcheradd to return a watcher id instead?
- return cb1->data.partial == cb2->data.partial;
-
- case kCallbackNone:
- return true;
-
- default:
- abort();
- }
-}
-
-static bool callback_call(Callback *callback, int argcount_in,
- typval_T *argvars_in, typval_T *rettv)
+bool callback_call(Callback *const callback, const int argcount_in,
+ typval_T *const argvars_in, typval_T *const rettv)
+ FUNC_ATTR_NONNULL_ALL
{
partial_T *partial;
char_u *name;
@@ -17382,7 +16797,7 @@ static bool callback_call(Callback *callback, int argcount_in,
case kCallbackPartial:
partial = callback->data.partial;
- name = partial->pt_name;
+ name = partial_name(partial);
break;
case kCallbackNone:
@@ -17395,7 +16810,7 @@ static bool callback_call(Callback *callback, int argcount_in,
int dummy;
return call_func(name, (int)STRLEN(name), rettv, argcount_in, argvars_in,
- curwin->w_cursor.lnum, curwin->w_cursor.lnum, &dummy,
+ NULL, curwin->w_cursor.lnum, curwin->w_cursor.lnum, &dummy,
true, partial, NULL);
}
@@ -17422,11 +16837,82 @@ static bool set_ref_in_callback(Callback *callback, int copyID,
return false;
}
+static void add_timer_info(typval_T *rettv, timer_T *timer)
+{
+ list_T *list = rettv->vval.v_list;
+ dict_T *dict = tv_dict_alloc();
+
+ tv_list_append_dict(list, dict);
+ tv_dict_add_nr(dict, S_LEN("id"), timer->timer_id);
+ tv_dict_add_nr(dict, S_LEN("time"), timer->timeout);
+ tv_dict_add_nr(dict, S_LEN("paused"), timer->paused);
+
+ tv_dict_add_nr(dict, S_LEN("repeat"),
+ (timer->repeat_count < 0 ? -1 : timer->repeat_count));
+
+ dictitem_T *di = tv_dict_item_alloc("callback");
+ if (tv_dict_add(dict, di) == FAIL) {
+ xfree(di);
+ return;
+ }
+
+ if (timer->callback.type == kCallbackPartial) {
+ di->di_tv.v_type = VAR_PARTIAL;
+ di->di_tv.vval.v_partial = timer->callback.data.partial;
+ timer->callback.data.partial->pt_refcount++;
+ } else if (timer->callback.type == kCallbackFuncref) {
+ di->di_tv.v_type = VAR_FUNC;
+ di->di_tv.vval.v_string = vim_strsave(timer->callback.data.funcref);
+ }
+ di->di_tv.v_lock = 0;
+}
+
+static void add_timer_info_all(typval_T *rettv)
+{
+ timer_T *timer;
+ map_foreach_value(timers, timer, {
+ if (!timer->stopped) {
+ add_timer_info(rettv, timer);
+ }
+ })
+}
+
+/// "timer_info([timer])" function
+static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ tv_list_alloc_ret(rettv);
+ if (argvars[0].v_type != VAR_UNKNOWN) {
+ if (argvars[0].v_type != VAR_NUMBER) {
+ EMSG(_(e_number_exp));
+ return;
+ }
+ timer_T *timer = pmap_get(uint64_t)(timers, tv_get_number(&argvars[0]));
+ if (timer != NULL && !timer->stopped) {
+ add_timer_info(rettv, timer);
+ }
+ } else {
+ add_timer_info_all(rettv);
+ }
+}
+
+/// "timer_pause(timer, paused)" function
+static void f_timer_pause(typval_T *argvars, typval_T *unused, FunPtr fptr)
+{
+ if (argvars[0].v_type != VAR_NUMBER) {
+ EMSG(_(e_number_exp));
+ return;
+ }
+ int paused = (bool)tv_get_number(&argvars[1]);
+ timer_T *timer = pmap_get(uint64_t)(timers, tv_get_number(&argvars[0]));
+ if (timer != NULL) {
+ timer->paused = paused;
+ }
+}
/// "timer_start(timeout, callback, opts)" function
static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- long timeout = get_tv_number(&argvars[0]);
+ const long timeout = tv_get_number(&argvars[0]);
timer_T *timer;
int repeat = 1;
dict_T *dict;
@@ -17436,11 +16922,12 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (argvars[2].v_type != VAR_UNKNOWN) {
if (argvars[2].v_type != VAR_DICT
|| (dict = argvars[2].vval.v_dict) == NULL) {
- EMSG2(_(e_invarg2), get_tv_string(&argvars[2]));
+ EMSG2(_(e_invarg2), tv_get_string(&argvars[2]));
return;
}
- if (dict_find(dict, (char_u *)"repeat", -1) != NULL) {
- repeat = get_dict_number(dict, "repeat");
+ dictitem_T *const di = tv_dict_find(dict, S_LEN("repeat"));
+ if (di != NULL) {
+ repeat = tv_get_number(&di->di_tv);
if (repeat == 0) {
repeat = 1;
}
@@ -17455,6 +16942,7 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr)
timer = xmalloc(sizeof *timer);
timer->refcount = 1;
timer->stopped = false;
+ timer->paused = false;
timer->repeat_count = repeat;
timer->timeout = timeout;
timer->timer_id = last_timer_id++;
@@ -17464,8 +16952,7 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr)
timer->tw.events = multiqueue_new_child(main_loop.events);
// if main loop is blocked, don't queue up multiple events
timer->tw.blockable = true;
- time_watcher_start(&timer->tw, timer_due_cb, timeout,
- timeout * (repeat != 1));
+ time_watcher_start(&timer->tw, timer_due_cb, timeout, timeout);
pmap_put(uint64_t)(timers, timer->timer_id, timer);
rettv->vval.v_number = timer->timer_id;
@@ -17480,7 +16967,7 @@ static void f_timer_stop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- timer_T *timer = pmap_get(uint64_t)(timers, get_tv_number(&argvars[0]));
+ timer_T *timer = pmap_get(uint64_t)(timers, tv_get_number(&argvars[0]));
if (timer == NULL) {
return;
@@ -17489,28 +16976,32 @@ static void f_timer_stop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
timer_stop(timer);
}
+static void f_timer_stopall(typval_T *argvars, typval_T *unused, FunPtr fptr)
+{
+ timer_stop_all();
+}
+
// invoked on the main loop
static void timer_due_cb(TimeWatcher *tw, void *data)
{
timer_T *timer = (timer_T *)data;
- if (timer->stopped) {
+ if (timer->stopped || timer->paused) {
return;
}
+
timer->refcount++;
// if repeat was negative repeat forever
if (timer->repeat_count >= 0 && --timer->repeat_count == 0) {
timer_stop(timer);
}
- typval_T argv[2];
- init_tv(argv);
+ typval_T argv[2] = { TV_INITIAL_VALUE, TV_INITIAL_VALUE };
argv[0].v_type = VAR_NUMBER;
argv[0].vval.v_number = timer->timer_id;
- typval_T rettv;
+ typval_T rettv = TV_INITIAL_VALUE;
- init_tv(&rettv);
callback_call(&timer->callback, 1, argv, &rettv);
- clear_tv(&rettv);
+ tv_clear(&rettv);
if (!timer->stopped && timer->timeout == 0) {
// special case: timeout=0 means the callback will be
@@ -17550,7 +17041,7 @@ static void timer_decref(timer_T *timer)
}
}
-void timer_teardown(void)
+static void timer_stop_all(void)
{
timer_T *timer;
map_foreach_value(timers, timer, {
@@ -17558,35 +17049,19 @@ void timer_teardown(void)
})
}
+void timer_teardown(void)
+{
+ timer_stop_all();
+}
+
/*
* "tolower(string)" function
*/
static void f_tolower(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p = vim_strsave(get_tv_string(&argvars[0]));
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = p;
-
- while (*p != NUL) {
- int l;
-
- if (enc_utf8) {
- int c, lc;
-
- c = utf_ptr2char(p);
- lc = utf_tolower(c);
- l = utf_ptr2len(p);
- /* TODO: reallocate string when byte count changes. */
- if (utf_char2len(lc) == l)
- utf_char2bytes(lc, p);
- p += l;
- } else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
- p += l; /* skip multi-byte character */
- else {
- *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */
- ++p;
- }
- }
+ rettv->vval.v_string = (char_u *)strcase_save(tv_get_string(&argvars[0]),
+ false);
}
/*
@@ -17595,7 +17070,8 @@ static void f_tolower(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_toupper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = strup_save(get_tv_string(&argvars[0]));
+ rettv->vval.v_string = (char_u *)strcase_save(tv_get_string(&argvars[0]),
+ true);
}
/*
@@ -17603,77 +17079,71 @@ static void f_toupper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_tr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *in_str;
- char_u *fromstr;
- char_u *tostr;
- char_u *p;
- int inlen;
- int fromlen;
- int tolen;
- int idx;
- char_u *cpstr;
- int cplen;
- int first = TRUE;
- char_u buf[NUMBUFLEN];
- char_u buf2[NUMBUFLEN];
- garray_T ga;
+ char buf[NUMBUFLEN];
+ char buf2[NUMBUFLEN];
- in_str = get_tv_string(&argvars[0]);
- fromstr = get_tv_string_buf_chk(&argvars[1], buf);
- tostr = get_tv_string_buf_chk(&argvars[2], buf2);
+ const char *in_str = tv_get_string(&argvars[0]);
+ const char *fromstr = tv_get_string_buf_chk(&argvars[1], buf);
+ const char *tostr = tv_get_string_buf_chk(&argvars[2], buf2);
- /* Default return value: empty string. */
+ // Default return value: empty string.
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
- if (fromstr == NULL || tostr == NULL)
- return; /* type error; errmsg already given */
+ if (fromstr == NULL || tostr == NULL) {
+ return; // Type error; errmsg already given.
+ }
+ garray_T ga;
ga_init(&ga, (int)sizeof(char), 80);
- if (!has_mbyte)
- /* not multi-byte: fromstr and tostr must be the same length */
- if (STRLEN(fromstr) != STRLEN(tostr)) {
-error:
- EMSG2(_(e_invarg2), fromstr);
- ga_clear(&ga);
- return;
+ if (!has_mbyte) {
+ // Not multi-byte: fromstr and tostr must be the same length.
+ if (strlen(fromstr) != strlen(tostr)) {
+ goto error;
}
+ }
- /* fromstr and tostr have to contain the same number of chars */
+ // fromstr and tostr have to contain the same number of chars.
+ bool first = true;
while (*in_str != NUL) {
if (has_mbyte) {
- inlen = (*mb_ptr2len)(in_str);
- cpstr = in_str;
- cplen = inlen;
- idx = 0;
- for (p = fromstr; *p != NUL; p += fromlen) {
- fromlen = (*mb_ptr2len)(p);
+ const char *cpstr = in_str;
+ const int inlen = (*mb_ptr2len)((const char_u *)in_str);
+ int cplen = inlen;
+ int idx = 0;
+ int fromlen;
+ for (const char *p = fromstr; *p != NUL; p += fromlen) {
+ fromlen = (*mb_ptr2len)((const char_u *)p);
if (fromlen == inlen && STRNCMP(in_str, p, inlen) == 0) {
+ int tolen;
for (p = tostr; *p != NUL; p += tolen) {
- tolen = (*mb_ptr2len)(p);
+ tolen = (*mb_ptr2len)((const char_u *)p);
if (idx-- == 0) {
cplen = tolen;
- cpstr = p;
+ cpstr = (char *)p;
break;
}
}
- if (*p == NUL) /* tostr is shorter than fromstr */
+ if (*p == NUL) { // tostr is shorter than fromstr.
goto error;
+ }
break;
}
- ++idx;
+ idx++;
}
if (first && cpstr == in_str) {
- /* Check that fromstr and tostr have the same number of
- * (multi-byte) characters. Done only once when a character
- * of in_str doesn't appear in fromstr. */
- first = FALSE;
- for (p = tostr; *p != NUL; p += tolen) {
- tolen = (*mb_ptr2len)(p);
- --idx;
+ // Check that fromstr and tostr have the same number of
+ // (multi-byte) characters. Done only once when a character
+ // of in_str doesn't appear in fromstr.
+ first = false;
+ int tolen;
+ for (const char *p = tostr; *p != NUL; p += tolen) {
+ tolen = (*mb_ptr2len)((const char_u *)p);
+ idx--;
}
- if (idx != 0)
+ if (idx != 0) {
goto error;
+ }
}
ga_grow(&ga, cplen);
@@ -17682,13 +17152,14 @@ error:
in_str += inlen;
} else {
- /* When not using multi-byte chars we can do it faster. */
- p = vim_strchr(fromstr, *in_str);
- if (p != NULL)
+ // When not using multi-byte chars we can do it faster.
+ const char *const p = strchr(fromstr, *in_str);
+ if (p != NULL) {
ga_append(&ga, tostr[p - fromstr]);
- else
+ } else {
ga_append(&ga, *in_str);
- ++in_str;
+ }
+ in_str++;
}
}
@@ -17696,6 +17167,11 @@ error:
ga_append(&ga, NUL);
rettv->vval.v_string = ga.ga_data;
+ return;
+error:
+ EMSG2(_(e_invarg2), fromstr);
+ ga_clear(&ga);
+ return;
}
/*
@@ -17741,20 +17217,18 @@ static void f_type(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_undofile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- {
- char_u *fname = get_tv_string(&argvars[0]);
+ const char *const fname = tv_get_string(&argvars[0]);
- if (*fname == NUL) {
- /* If there is no file name there will be no undo file. */
- rettv->vval.v_string = NULL;
- } else {
- char *ffname = FullName_save((char *)fname, false);
+ if (*fname == NUL) {
+ // If there is no file name there will be no undo file.
+ rettv->vval.v_string = NULL;
+ } else {
+ char *ffname = FullName_save(fname, false);
- if (ffname != NULL) {
- rettv->vval.v_string = (char_u *)u_get_undo_file_name(ffname, false);
- }
- xfree(ffname);
+ if (ffname != NULL) {
+ rettv->vval.v_string = (char_u *)u_get_undo_file_name(ffname, false);
}
+ xfree(ffname);
}
}
@@ -17763,22 +17237,22 @@ static void f_undofile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_undotree(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv_dict_alloc(rettv);
+ tv_dict_alloc_ret(rettv);
dict_T *dict = rettv->vval.v_dict;
list_T *list;
- dict_add_nr_str(dict, "synced", (long)curbuf->b_u_synced, NULL);
- dict_add_nr_str(dict, "seq_last", curbuf->b_u_seq_last, NULL);
- dict_add_nr_str(dict, "save_last",
- (long)curbuf->b_u_save_nr_last, NULL);
- dict_add_nr_str(dict, "seq_cur", curbuf->b_u_seq_cur, NULL);
- dict_add_nr_str(dict, "time_cur", (long)curbuf->b_u_time_cur, NULL);
- dict_add_nr_str(dict, "save_cur", (long)curbuf->b_u_save_nr_cur, NULL);
+ tv_dict_add_nr(dict, S_LEN("synced"), (varnumber_T)curbuf->b_u_synced);
+ tv_dict_add_nr(dict, S_LEN("seq_last"), (varnumber_T)curbuf->b_u_seq_last);
+ tv_dict_add_nr(dict, S_LEN("save_last"),
+ (varnumber_T)curbuf->b_u_save_nr_last);
+ tv_dict_add_nr(dict, S_LEN("seq_cur"), (varnumber_T)curbuf->b_u_seq_cur);
+ tv_dict_add_nr(dict, S_LEN("time_cur"), (varnumber_T)curbuf->b_u_time_cur);
+ tv_dict_add_nr(dict, S_LEN("save_cur"), (varnumber_T)curbuf->b_u_save_nr_cur);
- list = list_alloc();
+ list = tv_list_alloc();
u_eval_tree(curbuf->b_u_oldhead, list);
- dict_add_list(dict, "entries", list);
+ tv_dict_add_list(dict, S_LEN("entries"), list);
}
/*
@@ -17837,7 +17311,7 @@ static void f_wildmenumode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// "win_findbuf()" function
static void f_win_findbuf(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
win_findbuf(argvars, rettv->vval.v_list);
}
@@ -17856,7 +17330,7 @@ static void f_win_gotoid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// "win_id2tabwin()" function
static void f_win_id2tabwin(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv);
win_id2tabwin(argvars, rettv->vval.v_list);
}
@@ -17951,36 +17425,37 @@ static void f_winrestcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_winrestview(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- dict_T *dict;
+ dict_T *dict;
if (argvars[0].v_type != VAR_DICT
- || (dict = argvars[0].vval.v_dict) == NULL)
- EMSG(_(e_invarg));
- else {
- if (dict_find(dict, (char_u *)"lnum", -1) != NULL) {
- curwin->w_cursor.lnum = get_dict_number(dict, "lnum");
+ || (dict = argvars[0].vval.v_dict) == NULL) {
+ emsgf(_(e_invarg));
+ } else {
+ dictitem_T *di;
+ if ((di = tv_dict_find(dict, S_LEN("lnum"))) != NULL) {
+ curwin->w_cursor.lnum = tv_get_number(&di->di_tv);
}
- if (dict_find(dict, (char_u *)"col", -1) != NULL) {
- curwin->w_cursor.col = get_dict_number(dict, "col");
+ if ((di = tv_dict_find(dict, S_LEN("col"))) != NULL) {
+ curwin->w_cursor.col = tv_get_number(&di->di_tv);
}
- if (dict_find(dict, (char_u *)"coladd", -1) != NULL) {
- curwin->w_cursor.coladd = get_dict_number(dict, "coladd");
+ if ((di = tv_dict_find(dict, S_LEN("coladd"))) != NULL) {
+ curwin->w_cursor.coladd = tv_get_number(&di->di_tv);
}
- if (dict_find(dict, (char_u *)"curswant", -1) != NULL) {
- curwin->w_curswant = get_dict_number(dict, "curswant");
+ if ((di = tv_dict_find(dict, S_LEN("curswant"))) != NULL) {
+ curwin->w_curswant = tv_get_number(&di->di_tv);
curwin->w_set_curswant = false;
}
- if (dict_find(dict, (char_u *)"topline", -1) != NULL) {
- set_topline(curwin, get_dict_number(dict, "topline"));
+ if ((di = tv_dict_find(dict, S_LEN("topline"))) != NULL) {
+ set_topline(curwin, tv_get_number(&di->di_tv));
}
- if (dict_find(dict, (char_u *)"topfill", -1) != NULL) {
- curwin->w_topfill = get_dict_number(dict, "topfill");
+ if ((di = tv_dict_find(dict, S_LEN("topfill"))) != NULL) {
+ curwin->w_topfill = tv_get_number(&di->di_tv);
}
- if (dict_find(dict, (char_u *)"leftcol", -1) != NULL) {
- curwin->w_leftcol = get_dict_number(dict, "leftcol");
+ if ((di = tv_dict_find(dict, S_LEN("leftcol"))) != NULL) {
+ curwin->w_leftcol = tv_get_number(&di->di_tv);
}
- if (dict_find(dict, (char_u *)"skipcol", -1) != NULL) {
- curwin->w_skipcol = get_dict_number(dict, "skipcol");
+ if ((di = tv_dict_find(dict, S_LEN("skipcol"))) != NULL) {
+ curwin->w_skipcol = tv_get_number(&di->di_tv);
}
check_cursor();
@@ -18003,45 +17478,103 @@ static void f_winsaveview(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_T *dict;
- rettv_dict_alloc(rettv);
+ tv_dict_alloc_ret(rettv);
dict = rettv->vval.v_dict;
- dict_add_nr_str(dict, "lnum", (long)curwin->w_cursor.lnum, NULL);
- dict_add_nr_str(dict, "col", (long)curwin->w_cursor.col, NULL);
- dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL);
+ tv_dict_add_nr(dict, S_LEN("lnum"), (varnumber_T)curwin->w_cursor.lnum);
+ tv_dict_add_nr(dict, S_LEN("col"), (varnumber_T)curwin->w_cursor.col);
+ tv_dict_add_nr(dict, S_LEN("coladd"), (varnumber_T)curwin->w_cursor.coladd);
update_curswant();
- dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL);
+ tv_dict_add_nr(dict, S_LEN("curswant"), (varnumber_T)curwin->w_curswant);
- dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL);
- dict_add_nr_str(dict, "topfill", (long)curwin->w_topfill, NULL);
- dict_add_nr_str(dict, "leftcol", (long)curwin->w_leftcol, NULL);
- dict_add_nr_str(dict, "skipcol", (long)curwin->w_skipcol, NULL);
+ tv_dict_add_nr(dict, S_LEN("topline"), (varnumber_T)curwin->w_topline);
+ tv_dict_add_nr(dict, S_LEN("topfill"), (varnumber_T)curwin->w_topfill);
+ tv_dict_add_nr(dict, S_LEN("leftcol"), (varnumber_T)curwin->w_leftcol);
+ tv_dict_add_nr(dict, S_LEN("skipcol"), (varnumber_T)curwin->w_skipcol);
}
/// Writes list of strings to file
-static bool write_list(FILE *fd, list_T *list, bool binary)
+///
+/// @param fp File to write to.
+/// @param[in] list List to write.
+/// @param[in] binary Whether to write in binary mode.
+///
+/// @return true in case of success, false otherwise.
+static bool write_list(FileDescriptor *const fp, const list_T *const list,
+ const bool binary)
{
- int ret = true;
-
- for (listitem_T *li = list->lv_first; li != NULL; li = li->li_next) {
- for (char_u *s = get_tv_string(&li->li_tv); *s != NUL; ++s) {
- if (putc(*s == '\n' ? NUL : *s, fd) == EOF) {
- ret = false;
- break;
+ int error = 0;
+ for (const listitem_T *li = list->lv_first; li != NULL; li = li->li_next) {
+ const char *const s = tv_get_string_chk(&li->li_tv);
+ if (s == NULL) {
+ return false;
+ }
+ const char *hunk_start = s;
+ for (const char *p = hunk_start;; p++) {
+ if (*p == NUL || *p == NL) {
+ if (p != hunk_start) {
+ const ptrdiff_t written = file_write(fp, hunk_start,
+ (size_t)(p - hunk_start));
+ if (written < 0) {
+ error = (int)written;
+ goto write_list_error;
+ }
+ }
+ if (*p == NUL) {
+ break;
+ } else {
+ hunk_start = p + 1;
+ const ptrdiff_t written = file_write(fp, (char[]){ NUL }, 1);
+ if (written < 0) {
+ error = (int)written;
+ break;
+ }
+ }
}
}
if (!binary || li->li_next != NULL) {
- if (putc('\n', fd) == EOF) {
- ret = false;
- break;
+ const ptrdiff_t written = file_write(fp, "\n", 1);
+ if (written < 0) {
+ error = (int)written;
+ goto write_list_error;
}
}
- if (ret == false) {
- EMSG(_(e_write));
- break;
+ }
+ if ((error = file_flush(fp)) != 0) {
+ goto write_list_error;
+ }
+ return true;
+write_list_error:
+ emsgf(_("E80: Error while writing: %s"), os_strerror(error));
+ return false;
+}
+
+/// Initializes a static list with 10 items.
+void init_static_list(staticList10_T *sl)
+{
+ list_T *l = &sl->sl_list;
+
+ memset(sl, 0, sizeof(staticList10_T));
+ l->lv_first = &sl->sl_items[0];
+ l->lv_last = &sl->sl_items[9];
+ l->lv_refcount = DO_NOT_FREE_CNT;
+ l->lv_lock = VAR_FIXED;
+ sl->sl_list.lv_len = 10;
+
+ for (int i = 0; i < 10; i++) {
+ listitem_T *li = &sl->sl_items[i];
+
+ if (i == 0) {
+ li->li_prev = NULL;
+ } else {
+ li->li_prev = li - 1;
+ }
+ if (i == 9) {
+ li->li_next = NULL;
+ } else {
+ li->li_next = li + 1;
}
}
- return ret;
}
/// Saves a typval_T as a string.
@@ -18053,7 +17586,7 @@ static bool write_list(FILE *fd, list_T *list, bool binary)
/// @param[in] endnl If true, the output will end in a newline (if a list).
/// @returns an allocated string if `tv` represents a VimL string, list, or
/// number; NULL otherwise.
-static char_u *save_tv_as_string(typval_T *tv, ssize_t *len, bool endnl)
+static char *save_tv_as_string(typval_T *tv, ptrdiff_t *const len, bool endnl)
FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
if (tv->v_type == VAR_UNKNOWN) {
@@ -18061,34 +17594,33 @@ static char_u *save_tv_as_string(typval_T *tv, ssize_t *len, bool endnl)
return NULL;
}
- // For types other than list, let get_tv_string_buf_chk() get the value or
+ // For types other than list, let tv_get_string_buf_chk() get the value or
// print an error.
if (tv->v_type != VAR_LIST) {
- char_u *ret = get_tv_string_chk(tv);
- if (ret && (*len = STRLEN(ret))) {
- ret = vim_strsave(ret);
+ const char *ret = tv_get_string_chk(tv);
+ if (ret && (*len = strlen(ret))) {
+ return xmemdupz(ret, (size_t)(*len));
} else {
- ret = NULL;
*len = -1;
+ return NULL;
}
- return ret;
}
// Pre-calculate the resulting length.
*len = 0;
list_T *list = tv->vval.v_list;
for (listitem_T *li = list->lv_first; li != NULL; li = li->li_next) {
- *len += STRLEN(get_tv_string(&li->li_tv)) + 1;
+ *len += strlen(tv_get_string(&li->li_tv)) + 1;
}
if (*len == 0) {
return NULL;
}
- char_u *ret = xmalloc(*len + endnl);
- char_u *end = ret;
+ char *ret = xmalloc(*len + endnl);
+ char *end = ret;
for (listitem_T *li = list->lv_first; li != NULL; li = li->li_next) {
- for (char_u *s = get_tv_string(&li->li_tv); *s != NUL; s++) {
+ for (const char *s = tv_get_string(&li->li_tv); *s != NUL; s++) {
*end++ = (*s == '\n') ? NUL : *s;
}
if (endnl || li->li_next != NULL) {
@@ -18117,7 +17649,7 @@ static void f_winwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/// "wordcount()" function
static void f_wordcount(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv_dict_alloc(rettv);
+ tv_dict_alloc_ret(rettv);
cursor_pos_info(rettv->vval.v_dict);
}
@@ -18140,28 +17672,50 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
bool binary = false;
bool append = false;
+ bool do_fsync = !!p_fs;
if (argvars[2].v_type != VAR_UNKNOWN) {
- if (vim_strchr(get_tv_string(&argvars[2]), 'b')) {
- binary = true;
+ const char *const flags = tv_get_string_chk(&argvars[2]);
+ if (flags == NULL) {
+ return;
}
- if (vim_strchr(get_tv_string(&argvars[2]), 'a')) {
- append = true;
+ for (const char *p = flags; *p; p++) {
+ switch (*p) {
+ case 'b': { binary = true; break; }
+ case 'a': { append = true; break; }
+ case 's': { do_fsync = true; break; }
+ case 'S': { do_fsync = false; break; }
+ default: {
+ // Using %s, p and not %c, *p to preserve multibyte characters
+ emsgf(_("E5060: Unknown flag: %s"), p);
+ return;
+ }
+ }
}
}
- // Always open the file in binary mode, library functions have a mind of
- // their own about CR-LF conversion.
- char_u *fname = get_tv_string(&argvars[1]);
- FILE *fd;
- if (*fname == NUL || (fd = mch_fopen((char *)fname,
- append ? APPENDBIN : WRITEBIN)) == NULL) {
- EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname);
- rettv->vval.v_number = -1;
+ char buf[NUMBUFLEN];
+ const char *const fname = tv_get_string_buf_chk(&argvars[1], buf);
+ if (fname == NULL) {
+ return;
+ }
+ FileDescriptor fp;
+ int error;
+ rettv->vval.v_number = -1;
+ if (*fname == NUL) {
+ EMSG(_("E482: Can't open file with an empty name"));
+ } else if ((error = file_open(&fp, fname,
+ ((append ? kFileAppend : kFileTruncate)
+ | kFileCreate), 0666)) != 0) {
+ emsgf(_("E482: Can't open file %s for writing: %s"),
+ fname, os_strerror(error));
} else {
- if (write_list(fd, argvars[0].vval.v_list, binary) == false) {
- rettv->vval.v_number = -1;
+ if (write_list(&fp, argvars[0].vval.v_list, binary)) {
+ rettv->vval.v_number = 0;
+ }
+ if ((error = file_close(&fp, do_fsync)) != 0) {
+ emsgf(_("E80: Error when closing file %s: %s"),
+ fname, os_strerror(error));
}
- fclose(fd);
}
}
/*
@@ -18169,82 +17723,96 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_xor(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
- ^ get_tv_number_chk(&argvars[1], NULL);
+ rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL)
+ ^ tv_get_number_chk(&argvars[1], NULL);
}
-/*
- * Translate a String variable into a position.
- * Returns NULL when there is an error.
- */
-static pos_T *
-var2fpos (
- typval_T *varp,
- int dollar_lnum, /* TRUE when $ is last line */
- int *fnum /* set to fnum for '0, 'A, etc. */
-)
+/// Translate a VimL object into a position
+///
+/// Accepts VAR_LIST and VAR_STRING objects. Does not give an error for invalid
+/// type.
+///
+/// @param[in] tv Object to translate.
+/// @param[in] dollar_lnum True when "$" is last line.
+/// @param[out] ret_fnum Set to fnum for marks.
+///
+/// @return Pointer to position or NULL in case of error (e.g. invalid type).
+pos_T *var2fpos(const typval_T *const tv, const int dollar_lnum,
+ int *const ret_fnum)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- char_u *name;
static pos_T pos;
pos_T *pp;
- /* Argument can be [lnum, col, coladd]. */
- if (varp->v_type == VAR_LIST) {
+ // Argument can be [lnum, col, coladd].
+ if (tv->v_type == VAR_LIST) {
list_T *l;
int len;
- int error = FALSE;
- listitem_T *li;
+ bool error = false;
+ listitem_T *li;
- l = varp->vval.v_list;
- if (l == NULL)
+ l = tv->vval.v_list;
+ if (l == NULL) {
return NULL;
+ }
- /* Get the line number */
- pos.lnum = list_find_nr(l, 0L, &error);
- if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count)
- return NULL; /* invalid line number */
+ // Get the line number.
+ pos.lnum = tv_list_find_nr(l, 0L, &error);
+ if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count) {
+ // Invalid line number.
+ return NULL;
+ }
- /* Get the column number */
- pos.col = list_find_nr(l, 1L, &error);
- if (error)
+ // Get the column number.
+ pos.col = tv_list_find_nr(l, 1L, &error);
+ if (error) {
return NULL;
+ }
len = (long)STRLEN(ml_get(pos.lnum));
- /* We accept "$" for the column number: last column. */
- li = list_find(l, 1L);
+ // We accept "$" for the column number: last column.
+ li = tv_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)
+ && 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;
+ // Accept a position up to the NUL after the line.
+ if (pos.col == 0 || (int)pos.col > len + 1) {
+ // Invalid column number.
+ return NULL;
+ }
+ pos.col--;
- /* Get the virtual offset. Defaults to zero. */
- pos.coladd = list_find_nr(l, 2L, &error);
- if (error)
+ // Get the virtual offset. Defaults to zero.
+ pos.coladd = tv_list_find_nr(l, 2L, &error);
+ if (error) {
pos.coladd = 0;
+ }
return &pos;
}
- name = get_tv_string_chk(varp);
- if (name == NULL)
+ const char *const name = tv_get_string_chk(tv);
+ if (name == NULL) {
return NULL;
- if (name[0] == '.') /* cursor */
+ }
+ if (name[0] == '.') { // Cursor.
return &curwin->w_cursor;
- if (name[0] == 'v' && name[1] == NUL) { /* Visual start */
- if (VIsual_active)
+ }
+ if (name[0] == 'v' && name[1] == NUL) { // Visual start.
+ if (VIsual_active) {
return &VIsual;
+ }
return &curwin->w_cursor;
}
- if (name[0] == '\'') { /* mark */
- pp = getmark_buf_fnum(curbuf, name[1], FALSE, fnum);
- if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0)
+ if (name[0] == '\'') { // Mark.
+ pp = getmark_buf_fnum(curbuf, (uint8_t)name[1], false, ret_fnum);
+ if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) {
return NULL;
+ }
return pp;
}
@@ -18297,32 +17865,37 @@ static int list2fpos(typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp)
return FAIL;
if (fnump != NULL) {
- n = list_find_nr(l, i++, NULL); /* fnum */
- if (n < 0)
+ n = tv_list_find_nr(l, i++, NULL); // fnum
+ if (n < 0) {
return FAIL;
- if (n == 0)
- n = curbuf->b_fnum; /* current buffer */
+ }
+ if (n == 0) {
+ n = curbuf->b_fnum; // Current buffer.
+ }
*fnump = n;
}
- n = list_find_nr(l, i++, NULL); /* lnum */
- if (n < 0)
+ n = tv_list_find_nr(l, i++, NULL); // lnum
+ if (n < 0) {
return FAIL;
+ }
posp->lnum = n;
- n = list_find_nr(l, i++, NULL); /* col */
- if (n < 0)
+ n = tv_list_find_nr(l, i++, NULL); // col
+ if (n < 0) {
return FAIL;
+ }
posp->col = n;
- n = list_find_nr(l, i, NULL); // off
- if (n < 0)
+ n = tv_list_find_nr(l, i, NULL); // off
+ if (n < 0) {
posp->coladd = 0;
- else
+ } else {
posp->coladd = n;
+ }
if (curswantp != NULL) {
- *curswantp = list_find_nr(l, i + 1, NULL); // curswant
+ *curswantp = tv_list_find_nr(l, i + 1, NULL); // curswant
}
return OK;
@@ -18333,15 +17906,16 @@ static int list2fpos(typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp)
* Advance "arg" to the first character after the name.
* Return 0 for error.
*/
-static int get_env_len(char_u **arg)
+static int get_env_len(const char_u **arg)
{
- char_u *p;
int len;
- for (p = *arg; vim_isIDc(*p); ++p)
- ;
- if (p == *arg) /* no name found */
+ const char_u *p;
+ for (p = *arg; vim_isIDc(*p); p++) {
+ }
+ if (p == *arg) { // No name found.
return 0;
+ }
len = (int)(p - *arg);
*arg = p;
@@ -18351,11 +17925,12 @@ static int get_env_len(char_u **arg)
// Get the length of the name of a function or internal variable.
// "arg" is advanced to the first non-white character after the name.
// Return 0 if something is wrong.
-static int get_id_len(char_u **arg) {
- char_u *p;
+static int get_id_len(const char **const arg)
+{
int len;
// Find the end of the name.
+ const char *p;
for (p = *arg; eval_isnamec(*p); p++) {
if (*p == ':') {
// "s:" is start of "s:var", but "n:" is not and can be used in
@@ -18372,7 +17947,7 @@ static int get_id_len(char_u **arg) {
}
len = (int)(p - *arg);
- *arg = skipwhite(p);
+ *arg = (const char *)skipwhite((const char_u *)p);
return len;
}
@@ -18386,18 +17961,18 @@ static int get_id_len(char_u **arg) {
* If the name contains 'magic' {}'s, expand them and return the
* expanded name in an allocated string via 'alias' - caller must free.
*/
-static int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose)
+static int get_name_len(const char **const arg,
+ char **alias,
+ int evaluate,
+ int verbose)
{
int len;
- char_u *p;
- char_u *expr_start;
- char_u *expr_end;
*alias = NULL; /* default to no alias */
- if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA
- && (*arg)[2] == (int)KE_SNR) {
- /* hard coded <SNR>, already translated */
+ if ((*arg)[0] == (char)K_SPECIAL && (*arg)[1] == (char)KS_EXTRA
+ && (*arg)[2] == (char)KE_SNR) {
+ // Hard coded <SNR>, already translated.
*arg += 3;
return get_id_len(arg) + 3;
}
@@ -18407,17 +17982,17 @@ static int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose)
*arg += len;
}
- /*
- * Find the end of the name; check for {} construction.
- */
- p = find_name_end(*arg, &expr_start, &expr_end,
- len > 0 ? 0 : FNE_CHECK_START);
+ // Find the end of the name; check for {} construction.
+ char_u *expr_start;
+ char_u *expr_end;
+ const char *p = (const char *)find_name_end((char_u *)(*arg),
+ (const char_u **)&expr_start,
+ (const char_u **)&expr_end,
+ len > 0 ? 0 : FNE_CHECK_START);
if (expr_start != NULL) {
- char_u *temp_string;
-
if (!evaluate) {
len += (int)(p - *arg);
- *arg = skipwhite(p);
+ *arg = (const char *)skipwhite((const char_u *)p);
return len;
}
@@ -18425,11 +18000,13 @@ static int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose)
* Include any <SID> etc in the expanded string:
* Thus the -len here.
*/
- temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p);
- if (temp_string == NULL)
+ char_u *temp_string = make_expanded_name((char_u *)(*arg) - len, expr_start,
+ expr_end, (char_u *)p);
+ if (temp_string == NULL) {
return -1;
- *alias = temp_string;
- *arg = skipwhite(p);
+ }
+ *alias = (char *)temp_string;
+ *arg = (const char *)skipwhite((const char_u *)p);
return (int)STRLEN(temp_string);
}
@@ -18446,12 +18023,11 @@ static int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose)
// "flags" can have FNE_INCL_BR and FNE_CHECK_START.
// Return a pointer to just after the name. Equal to "arg" if there is no
// valid name.
-static char_u *find_name_end(char_u *arg, char_u **expr_start,
- char_u **expr_end, int flags)
+static const char_u *find_name_end(const char_u *arg, const char_u **expr_start,
+ const char_u **expr_end, int flags)
{
int mb_nest = 0;
int br_nest = 0;
- char_u *p;
int len;
if (expr_start != NULL) {
@@ -18464,6 +18040,7 @@ static char_u *find_name_end(char_u *arg, char_u **expr_start,
return arg;
}
+ const char_u *p;
for (p = arg; *p != NUL
&& (eval_isnamec(*p)
|| *p == '{'
@@ -18535,7 +18112,8 @@ static char_u *find_name_end(char_u *arg, char_u **expr_start,
* Returns a new allocated string, which the caller must free.
* Returns NULL for failure.
*/
-static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)
+static char_u *make_expanded_name(const char_u *in_start, char_u *expr_start,
+ char_u *expr_end, char_u *in_end)
{
char_u c1;
char_u *retval = NULL;
@@ -18564,7 +18142,9 @@ static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *
*expr_end = '}';
if (retval != NULL) {
- temp_result = find_name_end(retval, &expr_start, &expr_end, 0);
+ temp_result = (char_u *)find_name_end(retval,
+ (const char_u **)&expr_start,
+ (const char_u **)&expr_end, 0);
if (expr_start != NULL) {
/* Further expansion! */
temp_result = make_expanded_name(retval, expr_start,
@@ -18598,7 +18178,7 @@ static int eval_isnamec1(int c)
/*
* Get number v: variable value.
*/
-long get_vim_var_nr(int idx) FUNC_ATTR_PURE
+varnumber_T get_vim_var_nr(int idx) FUNC_ATTR_PURE
{
return vimvars[idx].vv_nr;
}
@@ -18608,7 +18188,7 @@ long get_vim_var_nr(int idx) FUNC_ATTR_PURE
*/
char_u *get_vim_var_str(int idx) FUNC_ATTR_PURE FUNC_ATTR_NONNULL_RET
{
- return get_tv_string(&vimvars[idx].vv_tv);
+ return (char_u *)tv_get_string(&vimvars[idx].vv_tv);
}
/*
@@ -18661,7 +18241,7 @@ void set_vcount(long count, long count1, int set_prevcount)
/// @param[in] val Value to set to.
void set_vim_var_nr(const VimVarIndex idx, const varnumber_T val)
{
- clear_tv(&vimvars[idx].vv_tv);
+ tv_clear(&vimvars[idx].vv_tv);
vimvars[idx].vv_type = VAR_NUMBER;
vimvars[idx].vv_nr = val;
}
@@ -18672,7 +18252,7 @@ void set_vim_var_nr(const VimVarIndex idx, const varnumber_T val)
/// @param[in] val Value to set to.
void set_vim_var_special(const VimVarIndex idx, const SpecialVarValue val)
{
- clear_tv(&vimvars[idx].vv_tv);
+ tv_clear(&vimvars[idx].vv_tv);
vimvars[idx].vv_type = VAR_SPECIAL;
vimvars[idx].vv_special = val;
}
@@ -18686,7 +18266,7 @@ void set_vim_var_special(const VimVarIndex idx, const SpecialVarValue val)
void set_vim_var_string(const VimVarIndex idx, const char *const val,
const ptrdiff_t len)
{
- clear_tv(&vimvars[idx].vv_di.di_tv);
+ tv_clear(&vimvars[idx].vv_di.di_tv);
vimvars[idx].vv_type = VAR_STRING;
if (val == NULL) {
vimvars[idx].vv_str = NULL;
@@ -18703,7 +18283,7 @@ void set_vim_var_string(const VimVarIndex idx, const char *const val,
/// @param[in,out] val Value to set to. Reference count will be incremented.
void set_vim_var_list(const VimVarIndex idx, list_T *const val)
{
- clear_tv(&vimvars[idx].vv_di.di_tv);
+ tv_clear(&vimvars[idx].vv_di.di_tv);
vimvars[idx].vv_type = VAR_LIST;
vimvars[idx].vv_list = val;
if (val != NULL) {
@@ -18718,14 +18298,14 @@ void set_vim_var_list(const VimVarIndex idx, list_T *const val)
/// Also keys of the dictionary will be made read-only.
void set_vim_var_dict(const VimVarIndex idx, dict_T *const val)
{
- clear_tv(&vimvars[idx].vv_di.di_tv);
+ tv_clear(&vimvars[idx].vv_di.di_tv);
vimvars[idx].vv_type = VAR_DICT;
vimvars[idx].vv_dict = val;
if (val != NULL) {
val->dv_refcount++;
// Set readonly
- dict_set_keys_readonly(val);
+ tv_dict_set_keys_readonly(val);
}
}
@@ -18843,9 +18423,8 @@ char_u *set_cmdarg(exarg_T *eap, char_u *oldarg)
* Get the value of internal variable "name".
* Return OK or FAIL.
*/
-static int
-get_var_tv (
- char_u *name,
+static int get_var_tv(
+ const char *name,
int len, // length of "name"
typval_T *rettv, // NULL when only checking existence
dictitem_T **dip, // non-NULL when typval's dict item is needed
@@ -18855,55 +18434,52 @@ get_var_tv (
{
int ret = OK;
typval_T *tv = NULL;
- typval_T atv;
dictitem_T *v;
- int cc;
-
- /* truncate the name, so that we can use strcmp() */
- cc = name[len];
- name[len] = NUL;
- /*
- * Check for "b:changedtick".
- */
- if (STRCMP(name, "b:changedtick") == 0) {
- atv.v_type = VAR_NUMBER;
- atv.vval.v_number = curbuf->b_changedtick;
- tv = &atv;
- }
- /*
- * Check for user-defined variables.
- */
- else {
- v = find_var(name, NULL, no_autoload);
- if (v != NULL) {
- tv = &v->di_tv;
- if (dip != NULL) {
- *dip = v;
- }
+ v = find_var(name, (size_t)len, NULL, no_autoload);
+ if (v != NULL) {
+ tv = &v->di_tv;
+ if (dip != NULL) {
+ *dip = v;
}
}
if (tv == NULL) {
- if (rettv != NULL && verbose)
- EMSG2(_(e_undefvar), name);
+ if (rettv != NULL && verbose) {
+ emsgf(_("E121: Undefined variable: %.*s"), len, name);
+ }
ret = FAIL;
- } else if (rettv != NULL)
- copy_tv(tv, rettv);
-
- name[len] = cc;
+ } else if (rettv != NULL) {
+ tv_copy(tv, rettv);
+ }
return ret;
}
-/*
- * Handle expr[expr], expr[expr:expr] subscript and .name lookup.
- * Also handle function call with Funcref variable: func(expr)
- * Can all be combined: dict.func(expr)[idx]['func'](expr)
- */
-static int
-handle_subscript (
- char_u **arg,
+/// Check if variable "name[len]" is a local variable or an argument.
+/// If so, "*eval_lavars_used" is set to TRUE.
+static void check_vars(const char *name, size_t len)
+{
+ if (eval_lavars_used == NULL) {
+ return;
+ }
+
+ const char *varname;
+ hashtab_T *ht = find_var_ht(name, len, &varname);
+
+ if (ht == get_funccal_local_ht() || ht == get_funccal_args_ht()) {
+ if (find_var(name, len, NULL, true) != NULL) {
+ *eval_lavars_used = true;
+ }
+ }
+}
+
+/// Handle expr[expr], expr[expr:expr] subscript and .name lookup.
+/// Also handle function call with Funcref variable: func(expr)
+/// Can all be combined: dict.func(expr)[idx]['func'](expr)
+static int
+handle_subscript(
+ const char **const arg,
typval_T *rettv,
int evaluate, /* do more than finding the end */
int verbose /* give error messages */
@@ -18918,8 +18494,7 @@ handle_subscript (
while (ret == OK
&& (**arg == '['
|| (**arg == '.' && rettv->v_type == VAR_DICT)
- || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC
- || rettv->v_type == VAR_PARTIAL)))
+ || (**arg == '(' && (!evaluate || tv_is_func(*rettv))))
&& !ascii_iswhite(*(*arg - 1))) {
if (**arg == '(') {
partial_T *pt = NULL;
@@ -18931,59 +18506,59 @@ handle_subscript (
// Invoke the function. Recursive!
if (functv.v_type == VAR_PARTIAL) {
pt = functv.vval.v_partial;
- s = pt->pt_name;
+ s = partial_name(pt);
} else {
s = functv.vval.v_string;
}
} else {
s = (char_u *)"";
}
- ret = get_func_tv(s, (int)STRLEN(s), rettv, arg,
+ ret = get_func_tv(s, (int)STRLEN(s), rettv, (char_u **)arg,
curwin->w_cursor.lnum, curwin->w_cursor.lnum,
&len, evaluate, pt, selfdict);
- /* Clear the funcref afterwards, so that deleting it while
- * evaluating the arguments is possible (see test55). */
- if (evaluate)
- clear_tv(&functv);
+ // Clear the funcref afterwards, so that deleting it while
+ // evaluating the arguments is possible (see test55).
+ if (evaluate) {
+ tv_clear(&functv);
+ }
/* Stop the expression evaluation when immediately aborting on
* error, or when an interrupt occurred or an exception was thrown
* but not caught. */
if (aborting()) {
- if (ret == OK)
- clear_tv(rettv);
+ if (ret == OK) {
+ tv_clear(rettv);
+ }
ret = FAIL;
}
- dict_unref(selfdict);
+ tv_dict_unref(selfdict);
selfdict = NULL;
- } else { /* **arg == '[' || **arg == '.' */
- dict_unref(selfdict);
+ } else { // **arg == '[' || **arg == '.'
+ tv_dict_unref(selfdict);
if (rettv->v_type == VAR_DICT) {
selfdict = rettv->vval.v_dict;
if (selfdict != NULL)
++selfdict->dv_refcount;
} else
selfdict = NULL;
- if (eval_index(arg, rettv, evaluate, verbose) == FAIL) {
- clear_tv(rettv);
+ if (eval_index((char_u **)arg, rettv, evaluate, verbose) == FAIL) {
+ tv_clear(rettv);
ret = FAIL;
}
}
}
// Turn "dict.Func" into a partial for "Func" bound to "dict".
- if (selfdict != NULL
- && (rettv->v_type == VAR_FUNC
- || rettv->v_type == VAR_PARTIAL)) {
+ if (selfdict != NULL && tv_is_func(*rettv)) {
set_selfdict(rettv, selfdict);
}
- dict_unref(selfdict);
+ tv_dict_unref(selfdict);
return ret;
}
-static void set_selfdict(typval_T *rettv, dict_T *selfdict)
+void set_selfdict(typval_T *rettv, dict_T *selfdict)
{
// Don't do this when "dict.Func" is already a partial that was bound
// explicitly (pt_auto is false).
@@ -18991,19 +18566,23 @@ static void set_selfdict(typval_T *rettv, dict_T *selfdict)
&& rettv->vval.v_partial->pt_dict != NULL) {
return;
}
- char_u *fname = rettv->v_type == VAR_FUNC || rettv->v_type == VAR_STRING
- ? rettv->vval.v_string
- : rettv->vval.v_partial->pt_name;
+ char_u *fname;
char_u *tofree = NULL;
ufunc_T *fp;
char_u fname_buf[FLEN_FIXED + 1];
int error;
- // Translate "s:func" to the stored function name.
- fname = fname_trans_sid(fname, fname_buf, &tofree, &error);
-
- fp = find_func(fname);
- xfree(tofree);
+ if (rettv->v_type == VAR_PARTIAL && rettv->vval.v_partial->pt_func != NULL) {
+ fp = rettv->vval.v_partial->pt_func;
+ } else {
+ fname = rettv->v_type == VAR_FUNC || rettv->v_type == VAR_STRING
+ ? rettv->vval.v_string
+ : rettv->vval.v_partial->pt_name;
+ // Translate "s:func" to the stored function name.
+ fname = fname_trans_sid(fname, fname_buf, &tofree, &error);
+ fp = find_func(fname);
+ xfree(tofree);
+ }
// Turn "dict.Func" into a partial for "Func" with "dict".
if (fp != NULL && (fp->uf_flags & FC_DICT)) {
@@ -19024,8 +18603,13 @@ static void set_selfdict(typval_T *rettv, dict_T *selfdict)
// Partial: copy the function name, use selfdict and copy
// args. Can't take over name or args, the partial might
// be referenced elsewhere.
- pt->pt_name = vim_strsave(ret_pt->pt_name);
- func_ref(pt->pt_name);
+ if (ret_pt->pt_name != NULL) {
+ pt->pt_name = vim_strsave(ret_pt->pt_name);
+ func_ref(pt->pt_name);
+ } else {
+ pt->pt_func = ret_pt->pt_func;
+ func_ptr_ref(pt->pt_func);
+ }
if (ret_pt->pt_argc > 0) {
size_t arg_size = sizeof(typval_T) * ret_pt->pt_argc;
pt->pt_argv = (typval_T *)xmalloc(arg_size);
@@ -19035,7 +18619,7 @@ static void set_selfdict(typval_T *rettv, dict_T *selfdict)
} else {
pt->pt_argc = ret_pt->pt_argc;
for (i = 0; i < pt->pt_argc; i++) {
- copy_tv(&ret_pt->pt_argv[i], &pt->pt_argv[i]);
+ tv_copy(&ret_pt->pt_argv[i], &pt->pt_argv[i]);
}
}
}
@@ -19047,546 +18631,90 @@ static void set_selfdict(typval_T *rettv, dict_T *selfdict)
}
}
-/*
- * Free the memory for a variable type-value.
- */
-void free_tv(typval_T *varp)
+// Find variable "name" in the list of variables.
+// Return a pointer to it if found, NULL if not found.
+// Careful: "a:0" variables don't have a name.
+// When "htp" is not NULL we are writing to the variable, set "htp" to the
+// hashtab_T used.
+static dictitem_T *find_var(const char *const name, const size_t name_len,
+ hashtab_T **htp, int no_autoload)
{
- if (varp != NULL) {
- switch (varp->v_type) {
- case VAR_FUNC:
- func_unref(varp->vval.v_string);
- // FALLTHROUGH
- case VAR_STRING:
- xfree(varp->vval.v_string);
- break;
- case VAR_PARTIAL:
- partial_unref(varp->vval.v_partial);
- break;
- case VAR_LIST:
- list_unref(varp->vval.v_list);
- break;
- case VAR_DICT:
- dict_unref(varp->vval.v_dict);
- break;
- case VAR_SPECIAL:
- case VAR_NUMBER:
- case VAR_FLOAT:
- case VAR_UNKNOWN:
- break;
- }
- xfree(varp);
+ const char *varname;
+ hashtab_T *const ht = find_var_ht(name, name_len, &varname);
+ if (htp != NULL) {
+ *htp = ht;
}
-}
-
-#define TYPVAL_ENCODE_ALLOW_SPECIALS false
-
-#define TYPVAL_ENCODE_CONV_NIL(tv) \
- do { \
- tv->vval.v_special = kSpecialVarFalse; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
- TYPVAL_ENCODE_CONV_NIL(tv)
-
-#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
- do { \
- (void)num; \
- tv->vval.v_number = 0; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num)
-
-#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
- do { \
- tv->vval.v_float = 0; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
- do { \
- xfree(buf); \
- tv->vval.v_string = NULL; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len)
-
-#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type)
-
-static inline int _nothing_conv_func_start(typval_T *const tv,
- char_u *const fun)
- FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ARG(1)
-{
- tv->v_lock = VAR_UNLOCKED;
- if (tv->v_type == VAR_PARTIAL) {
- partial_T *const pt_ = tv->vval.v_partial;
- if (pt_ != NULL && pt_->pt_refcount > 1) {
- pt_->pt_refcount--;
- tv->vval.v_partial = NULL;
- return OK;
- }
- } else {
- func_unref(fun);
- if (fun != empty_string) {
- xfree(fun);
- }
- tv->vval.v_string = NULL;
+ if (ht == NULL) {
+ return NULL;
}
- return NOTDONE;
-}
-#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
- do { \
- if (_nothing_conv_func_start(tv, fun) != NOTDONE) { \
- return OK; \
- } \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
-#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
-
-static inline void _nothing_conv_func_end(typval_T *const tv, const int copyID)
- FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
-{
- if (tv->v_type == VAR_PARTIAL) {
- partial_T *const pt = tv->vval.v_partial;
- if (pt == NULL) {
- return;
- }
- // Dictionary should already be freed by the time.
- // If it was not freed then it is a part of the reference cycle.
- assert(pt->pt_dict == NULL || pt->pt_dict->dv_copyID == copyID);
- pt->pt_dict = NULL;
- // As well as all arguments.
- pt->pt_argc = 0;
- assert(pt->pt_refcount <= 1);
- partial_unref(pt);
- tv->vval.v_partial = NULL;
- assert(tv->v_lock == VAR_UNLOCKED);
- }
-}
-#define TYPVAL_ENCODE_CONV_FUNC_END(tv) _nothing_conv_func_end(tv, copyID)
-
-#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
- do { \
- list_unref(tv->vval.v_list); \
- tv->vval.v_list = NULL; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
- do { \
- assert((void *)&dict != (void *)&TYPVAL_ENCODE_NODICT_VAR); \
- dict_unref((dict_T *)dict); \
- *((dict_T **)&dict) = NULL; \
- if (tv != NULL) { \
- ((typval_T *)tv)->v_lock = VAR_UNLOCKED; \
- } \
- } while (0)
-
-static inline int _nothing_conv_real_list_after_start(
- typval_T *const tv, MPConvStackVal *const mpsv)
- FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
-{
- assert(tv != NULL);
- tv->v_lock = VAR_UNLOCKED;
- if (tv->vval.v_list->lv_refcount > 1) {
- tv->vval.v_list->lv_refcount--;
- tv->vval.v_list = NULL;
- mpsv->data.l.li = NULL;
- return OK;
+ dictitem_T *const ret = find_var_in_ht(ht, *name,
+ varname,
+ name_len - (size_t)(varname - name),
+ no_autoload || htp != NULL);
+ if (ret != NULL) {
+ return ret;
}
- return NOTDONE;
-}
-#define TYPVAL_ENCODE_CONV_LIST_START(tv, len)
-
-#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv) \
- do { \
- if (_nothing_conv_real_list_after_start(tv, &mpsv) != NOTDONE) { \
- goto typval_encode_stop_converting_one_item; \
- } \
- } while (0)
-#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv)
-
-static inline void _nothing_conv_list_end(typval_T *const tv)
- FUNC_ATTR_ALWAYS_INLINE
-{
- if (tv == NULL) {
- return;
- }
- assert(tv->v_type == VAR_LIST);
- list_T *const list = tv->vval.v_list;
- list_unref(list);
- tv->vval.v_list = NULL;
+ // Search in parent scope for lambda
+ return find_var_in_scoped_ht(name, name_len, no_autoload || htp != NULL);
}
-#define TYPVAL_ENCODE_CONV_LIST_END(tv) _nothing_conv_list_end(tv)
-static inline int _nothing_conv_real_dict_after_start(
- typval_T *const tv, dict_T **const dictp, const void *const nodictvar,
- MPConvStackVal *const mpsv)
- FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
-{
- if (tv != NULL) {
- tv->v_lock = VAR_UNLOCKED;
- }
- if ((const void *)dictp != nodictvar && (*dictp)->dv_refcount > 1) {
- (*dictp)->dv_refcount--;
- *dictp = NULL;
- mpsv->data.d.todo = 0;
- return OK;
- }
- return NOTDONE;
-}
-#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len)
-
-#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv) \
- do { \
- if (_nothing_conv_real_dict_after_start( \
- tv, (dict_T **)&dict, (void *)&TYPVAL_ENCODE_NODICT_VAR, \
- &mpsv) != NOTDONE) { \
- goto typval_encode_stop_converting_one_item; \
- } \
- } while (0)
-
-#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(tv, dict)
-#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict)
-#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict)
-
-static inline void _nothing_conv_dict_end(typval_T *const tv,
- dict_T **const dictp,
- const void *const nodictvar)
- FUNC_ATTR_ALWAYS_INLINE
-{
- if ((const void *)dictp != nodictvar) {
- dict_unref(*dictp);
- *dictp = NULL;
- }
-}
-#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
- _nothing_conv_dict_end(tv, (dict_T **)&dict, \
- (void *)&TYPVAL_ENCODE_NODICT_VAR)
-
-#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type)
-
-#define TYPVAL_ENCODE_SCOPE static
-#define TYPVAL_ENCODE_NAME nothing
-#define TYPVAL_ENCODE_FIRST_ARG_TYPE const void *const
-#define TYPVAL_ENCODE_FIRST_ARG_NAME ignored
-#include "nvim/eval/typval_encode.c.h"
-#undef TYPVAL_ENCODE_SCOPE
-#undef TYPVAL_ENCODE_NAME
-#undef TYPVAL_ENCODE_FIRST_ARG_TYPE
-#undef TYPVAL_ENCODE_FIRST_ARG_NAME
-
-#undef TYPVAL_ENCODE_ALLOW_SPECIALS
-#undef TYPVAL_ENCODE_CONV_NIL
-#undef TYPVAL_ENCODE_CONV_BOOL
-#undef TYPVAL_ENCODE_CONV_NUMBER
-#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
-#undef TYPVAL_ENCODE_CONV_FLOAT
-#undef TYPVAL_ENCODE_CONV_STRING
-#undef TYPVAL_ENCODE_CONV_STR_STRING
-#undef TYPVAL_ENCODE_CONV_EXT_STRING
-#undef TYPVAL_ENCODE_CONV_FUNC_START
-#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS
-#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF
-#undef TYPVAL_ENCODE_CONV_FUNC_END
-#undef TYPVAL_ENCODE_CONV_EMPTY_LIST
-#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
-#undef TYPVAL_ENCODE_CONV_LIST_START
-#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
-#undef TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
-#undef TYPVAL_ENCODE_CONV_LIST_END
-#undef TYPVAL_ENCODE_CONV_DICT_START
-#undef TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START
-#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
-#undef TYPVAL_ENCODE_CONV_DICT_AFTER_KEY
-#undef TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS
-#undef TYPVAL_ENCODE_CONV_DICT_END
-#undef TYPVAL_ENCODE_CONV_RECURSE
-
-/// Free memory for a variable value and set the value to NULL or 0
+/// Find variable in hashtab
///
-/// @param[in,out] varp Value to free.
-void clear_tv(typval_T *varp)
-{
- if (varp != NULL && varp->v_type != VAR_UNKNOWN) {
- const int evn_ret = encode_vim_to_nothing(varp, varp, "clear_tv argument");
- (void)evn_ret;
- assert(evn_ret == OK);
- }
-}
-
-/*
- * Set the value of a variable to NULL without freeing items.
- */
-static void init_tv(typval_T *varp)
-{
- if (varp != NULL)
- memset(varp, 0, sizeof(typval_T));
-}
-
-/*
- * 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.
- */
-long get_tv_number(typval_T *varp)
-{
- int error = FALSE;
-
- return get_tv_number_chk(varp, &error); /* return 0L on error */
-}
-
-long get_tv_number_chk(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:
- case VAR_PARTIAL:
- EMSG(_("E703: Using a Funcref as a Number"));
- break;
- case VAR_STRING:
- if (varp->vval.v_string != NULL) {
- vim_str2nr(varp->vval.v_string, NULL, NULL,
- STR2NR_ALL, &n, NULL, 0);
- }
- return n;
- case VAR_LIST:
- EMSG(_("E745: Using a List as a Number"));
- break;
- case VAR_DICT:
- EMSG(_("E728: Using a Dictionary as a Number"));
- break;
- case VAR_SPECIAL:
- switch (varp->vval.v_special) {
- case kSpecialVarTrue: {
- return 1;
- }
- case kSpecialVarFalse:
- case kSpecialVarNull: {
- return 0;
- }
- }
- break;
- case VAR_UNKNOWN:
- EMSG2(_(e_intern2), "get_tv_number(UNKNOWN)");
- break;
- }
- if (denote == NULL) {
- // useful for values that must be unsigned
- n = -1;
- } else {
- *denote = true;
- }
- return n;
-}
-
-static float_T get_tv_float(typval_T *varp)
-{
- switch (varp->v_type) {
- case VAR_NUMBER:
- return (float_T)(varp->vval.v_number);
- case VAR_FLOAT:
- return varp->vval.v_float;
- break;
- case VAR_FUNC:
- case VAR_PARTIAL:
- EMSG(_("E891: Using a Funcref as a Float"));
- break;
- case VAR_STRING:
- EMSG(_("E892: Using a String as a Float"));
- break;
- case VAR_LIST:
- EMSG(_("E893: Using a List as a Float"));
- break;
- case VAR_DICT:
- EMSG(_("E894: Using a Dictionary as a Float"));
- break;
- default:
- EMSG2(_(e_intern2), "get_tv_float()");
- break;
- }
- return 0;
-}
-
-/*
- * Get the lnum from the first argument.
- * Also accepts ".", "$", etc., but that only works for the current buffer.
- * Returns -1 on error.
- */
-static linenr_T get_tv_lnum(typval_T *argvars)
-{
- typval_T rettv;
- linenr_T lnum;
-
- lnum = get_tv_number_chk(&argvars[0], NULL);
- if (lnum == 0) { /* no valid number, try using line() */
- rettv.v_type = VAR_NUMBER;
- f_line(argvars, &rettv, NULL);
- 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(typval_T *argvars, buf_T *buf)
-{
- if (argvars[0].v_type == VAR_STRING
- && argvars[0].vval.v_string != NULL
- && argvars[0].vval.v_string[0] == '$'
- && buf != NULL)
- return buf->b_ml.ml_line_count;
- return get_tv_number_chk(&argvars[0], NULL);
-}
-
-/*
- * Get the string value of a variable.
- * If it is a Number variable, the number is converted into a string.
- * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE!
- * get_tv_string_buf() uses a given buffer.
- * If the String variable has never been set, return an empty string.
- * Never returns NULL;
- * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return
- * NULL on error.
- */
-static char_u *get_tv_string(const typval_T *varp)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
-{
- static char_u mybuf[NUMBUFLEN];
-
- return get_tv_string_buf(varp, mybuf);
-}
-
-static char_u *get_tv_string_buf(const typval_T *varp, char_u *buf)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
-{
- char_u *res = get_tv_string_buf_chk(varp, buf);
-
- return res != NULL ? res : (char_u *)"";
-}
-
-/// Careful: This uses a single, static buffer. YOU CAN ONLY USE IT ONCE!
-char_u *get_tv_string_chk(const typval_T *varp)
- FUNC_ATTR_NONNULL_ALL
-{
- static char_u mybuf[NUMBUFLEN];
-
- return get_tv_string_buf_chk(varp, mybuf);
-}
-
-static char_u *get_tv_string_buf_chk(const typval_T *varp, char_u *buf)
- FUNC_ATTR_NONNULL_ALL
-{
- switch (varp->v_type) {
- case VAR_NUMBER:
- sprintf((char *)buf, "%" PRId64, (int64_t)varp->vval.v_number);
- return buf;
- case VAR_FUNC:
- case VAR_PARTIAL:
- EMSG(_("E729: using Funcref as a String"));
- break;
- case VAR_LIST:
- EMSG(_("E730: using List as a String"));
- break;
- case VAR_DICT:
- EMSG(_("E731: using Dictionary as a String"));
- break;
- case VAR_FLOAT:
- EMSG(_(e_float_as_string));
- break;
- case VAR_STRING:
- if (varp->vval.v_string != NULL)
- return varp->vval.v_string;
- return (char_u *)"";
- case VAR_SPECIAL:
- STRCPY(buf, encode_special_var_names[varp->vval.v_special]);
- return buf;
- case VAR_UNKNOWN:
- EMSG(_("E908: using an invalid value as a String"));
- break;
- }
- return NULL;
-}
-
-/*
- * Find variable "name" in the list of variables.
- * Return a pointer to it if found, NULL if not found.
- * Careful: "a:0" variables don't have a name.
- * When "htp" is not NULL we are writing to the variable, set "htp" to the
- * hashtab_T used.
- */
-static dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload)
-{
- char_u *varname;
- hashtab_T *ht;
-
- ht = find_var_ht(name, &varname);
- if (htp != NULL)
- *htp = ht;
- if (ht == NULL)
- return NULL;
- return find_var_in_ht(ht, *name, varname, no_autoload || htp != NULL);
-}
-
-/// Find variable "varname" in hashtab "ht" with name "htname".
-/// Returns NULL if not found.
-static dictitem_T *find_var_in_ht(hashtab_T *ht, int htname,
- char_u *varname, bool no_autoload)
+/// @param[in] ht Hashtab to find variable in.
+/// @param[in] htname Hashtab name (first character).
+/// @param[in] varname Variable name.
+/// @param[in] varname_len Variable name length.
+/// @param[in] no_autoload If true then autoload scripts will not be sourced
+/// if autoload variable was not found.
+///
+/// @return pointer to the dictionary item with the found variable or NULL if it
+/// was not found.
+static dictitem_T *find_var_in_ht(hashtab_T *const ht,
+ int htname,
+ const char *const varname,
+ const size_t varname_len,
+ int no_autoload)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
hashitem_T *hi;
- if (*varname == NUL) {
- /* Must be something like "s:", otherwise "ht" would be NULL. */
+ if (varname_len == 0) {
+ // Must be something like "s:", otherwise "ht" would be NULL.
switch (htname) {
- case 's': return &SCRIPT_SV(current_SID)->sv_var;
- case 'g': return &globvars_var;
- case 'v': return &vimvars_var;
- case 'b': return &curbuf->b_bufvar;
- case 'w': return &curwin->w_winvar;
- case 't': return &curtab->tp_winvar;
- case 'l': return current_funccal == NULL
- ? NULL : &current_funccal->l_vars_var;
- case 'a': return current_funccal == NULL
- ? NULL : &current_funccal->l_avars_var;
+ case 's': return (dictitem_T *)&SCRIPT_SV(current_SID)->sv_var;
+ case 'g': return (dictitem_T *)&globvars_var;
+ case 'v': return (dictitem_T *)&vimvars_var;
+ case 'b': return (dictitem_T *)&curbuf->b_bufvar;
+ case 'w': return (dictitem_T *)&curwin->w_winvar;
+ case 't': return (dictitem_T *)&curtab->tp_winvar;
+ case 'l': return (current_funccal == NULL
+ ? NULL : (dictitem_T *)&current_funccal->l_vars_var);
+ case 'a': return (current_funccal == NULL
+ ? NULL : (dictitem_T *)&current_funccal->l_avars_var);
}
return NULL;
}
- hi = hash_find(ht, varname);
+ hi = hash_find_len(ht, varname, varname_len);
if (HASHITEM_EMPTY(hi)) {
- /* For global variables we may try auto-loading the script. If it
- * worked find the variable again. Don't auto-load a script if it was
- * loaded already, otherwise it would be loaded every time when
- * checking if a function name is a Funcref variable. */
+ // For global variables we may try auto-loading the script. If it
+ // worked find the variable again. Don't auto-load a script if it was
+ // loaded already, otherwise it would be loaded every time when
+ // checking if a function name is a Funcref variable.
if (ht == &globvarht && !no_autoload) {
- /* Note: script_autoload() may make "hi" invalid. It must either
- * be obtained again or not used. */
- if (!script_autoload(varname, FALSE) || aborting())
+ // Note: script_autoload() may make "hi" invalid. It must either
+ // be obtained again or not used.
+ if (!script_autoload(varname, varname_len, false) || aborting()) {
return NULL;
- hi = hash_find(ht, varname);
+ }
+ hi = hash_find_len(ht, varname, varname_len);
}
- if (HASHITEM_EMPTY(hi))
+ if (HASHITEM_EMPTY(hi)) {
return NULL;
+ }
}
- return HI2DI(hi);
+ return TV_DICT_HI2DI(hi);
}
// Get function call environment based on backtrace debug level
@@ -19608,17 +18736,45 @@ static funccall_T *get_funccal(void)
return funccal;
}
-// Find the dict and hashtable used for a variable name. Set "varname" to the
-// start of name without ':'.
-static hashtab_T *find_var_ht_dict(char_u *name, uint8_t **varname, dict_T **d)
+/// Return the hashtable used for argument in the current funccal.
+/// Return NULL if there is no current funccal.
+static hashtab_T *get_funccal_args_ht(void)
{
- hashitem_T *hi;
+ if (current_funccal == NULL) {
+ return NULL;
+ }
+ return &get_funccal()->l_avars.dv_hashtab;
+}
+
+/// Return the hashtable used for local variables in the current funccal.
+/// Return NULL if there is no current funccal.
+static hashtab_T *get_funccal_local_ht(void)
+{
+ if (current_funccal == NULL) {
+ return NULL;
+ }
+ return &get_funccal()->l_vars.dv_hashtab;
+}
+
+/// Find the dict and hashtable used for a variable
+///
+/// @param[in] name Variable name, possibly with scope prefix.
+/// @param[in] name_len Variable name length.
+/// @param[out] varname Will be set to the start of the name without scope
+/// prefix.
+/// @param[out] d Scope dictionary.
+///
+/// @return Scope hashtab, NULL if name is not valid.
+static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len,
+ const char **varname, dict_T **d)
+{
+ hashitem_T *hi;
*d = NULL;
- if (name[0] == NUL) {
+ if (name_len == 0) {
return NULL;
}
- if (name[1] != ':') {
+ if (name_len == 1 || (name_len >= 2 && name[1] != ':')) {
// name has implicit scope
if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) {
// The name must not start with a colon or #.
@@ -19627,7 +18783,7 @@ static hashtab_T *find_var_ht_dict(char_u *name, uint8_t **varname, dict_T **d)
*varname = name;
// "version" is "v:version" in all scopes
- hi = hash_find(&compat_hashtab, name);
+ hi = hash_find_len(&compat_hashtab, name, name_len);
if (!HASHITEM_EMPTY(hi)) {
return &compat_hashtab;
}
@@ -19643,26 +18799,27 @@ static hashtab_T *find_var_ht_dict(char_u *name, uint8_t **varname, dict_T **d)
*varname = name + 2;
if (*name == 'g') { // global variable
*d = &globvardict;
- } else if (vim_strchr(name + 2, ':') != NULL
- || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) {
+ } else if (name_len > 2
+ && (memchr(name + 2, ':', name_len - 2) != NULL
+ || memchr(name + 2, AUTOLOAD_CHAR, name_len - 2) != NULL)) {
// There must be no ':' or '#' in the rest of the name if g: was not used
return NULL;
}
- if (*name == 'b') { // buffer variable
+ if (*name == 'b') { // buffer variable
*d = curbuf->b_vars;
- } else if (*name == 'w') { // window variable
+ } else if (*name == 'w') { // window variable
*d = curwin->w_vars;
- } else if (*name == 't') { // tab page variable
+ } else if (*name == 't') { // tab page variable
*d = curtab->tp_vars;
- } else if (*name == 'v') { // v: variable
+ } else if (*name == 'v') { // v: variable
*d = &vimvardict;
} else if (*name == 'a' && current_funccal != NULL) { // function argument
*d = &get_funccal()->l_avars;
} else if (*name == 'l' && current_funccal != NULL) { // local variable
*d = &get_funccal()->l_vars;
- } else if (*name == 's' // script variable
- && current_SID > 0 && current_SID <= ga_scripts.ga_len) {
+ } else if (*name == 's' // script variable
+ && current_SID > 0 && current_SID <= ga_scripts.ga_len) {
*d = &SCRIPT_SV(current_SID)->sv_dict;
}
@@ -19670,28 +18827,35 @@ end:
return *d ? &(*d)->dv_hashtab : NULL;
}
-// Find the hashtab used for a variable name.
-// Return NULL if the name is not valid.
-// Set "varname" to the start of name without ':'.
-static hashtab_T *find_var_ht(uint8_t *name, uint8_t **varname)
+/// Find the hashtable used for a variable
+///
+/// @param[in] name Variable name, possibly with scope prefix.
+/// @param[in] name_len Variable name length.
+/// @param[out] varname Will be set to the start of the name without scope
+/// prefix.
+///
+/// @return Scope hashtab, NULL if name is not valid.
+static hashtab_T *find_var_ht(const char *name, const size_t name_len,
+ const char **varname)
{
dict_T *d;
- return find_var_ht_dict(name, varname, &d);
+ return find_var_ht_dict(name, name_len, varname, &d);
}
/*
* Get the string value of a (global/local) variable.
- * Note: see get_tv_string() for how long the pointer remains valid.
+ * Note: see tv_get_string() for how long the pointer remains valid.
* Returns NULL when it doesn't exist.
*/
-char_u *get_var_value(char_u *name)
+char_u *get_var_value(const char *const name)
{
dictitem_T *v;
- v = find_var(name, NULL, FALSE);
- if (v == NULL)
+ v = find_var(name, strlen(name), NULL, false);
+ if (v == NULL) {
return NULL;
- return get_tv_string(&v->di_tv);
+ }
+ return (char_u *)tv_get_string(&v->di_tv);
}
/*
@@ -19728,10 +18892,10 @@ void new_script_vars(scid_T id)
* Initialize dictionary "dict" as a scope and set variable "dict_var" to
* point to it.
*/
-void init_var_dict(dict_T *dict, dictitem_T *dict_var, int scope)
+void init_var_dict(dict_T *dict, ScopeDictDictItem *dict_var, int scope)
{
hash_init(&dict->dv_hashtab);
- dict->dv_lock = 0;
+ dict->dv_lock = VAR_UNLOCKED;
dict->dv_scope = scope;
dict->dv_refcount = DO_NOT_FREE_CNT;
dict->dv_copyID = 0;
@@ -19751,7 +18915,7 @@ void unref_var_dict(dict_T *dict)
/* Now the dict needs to be freed if no one else is using it, go back to
* normal reference counting. */
dict->dv_refcount -= DO_NOT_FREE_CNT - 1;
- dict_unref(dict);
+ tv_dict_unref(dict);
}
/*
@@ -19782,9 +18946,9 @@ static void vars_clear_ext(hashtab_T *ht, int free_val)
// Free the variable. Don't remove it from the hashtab,
// ht_array might change then. hash_clear() takes care of it
// later.
- v = HI2DI(hi);
+ v = TV_DICT_HI2DI(hi);
if (free_val) {
- clear_tv(&v->di_tv);
+ tv_clear(&v->di_tv);
}
if (v->di_flags & DI_FLAGS_ALLOC) {
xfree(v);
@@ -19801,38 +18965,37 @@ static void vars_clear_ext(hashtab_T *ht, int free_val)
*/
static void delete_var(hashtab_T *ht, hashitem_T *hi)
{
- dictitem_T *di = HI2DI(hi);
+ dictitem_T *di = TV_DICT_HI2DI(hi);
hash_remove(ht, hi);
- clear_tv(&di->di_tv);
+ tv_clear(&di->di_tv);
xfree(di);
}
/*
* List the value of one internal variable.
*/
-static void list_one_var(dictitem_T *v, char_u *prefix, int *first)
+static void list_one_var(dictitem_T *v, const char *prefix, int *first)
{
- char_u *s = (char_u *) encode_tv2echo(&v->di_tv, NULL);
- list_one_var_a(prefix, v->di_key, v->di_tv.v_type,
- s == NULL ? (char_u *)"" : s, first);
+ char *const s = encode_tv2echo(&v->di_tv, NULL);
+ list_one_var_a(prefix, (const char *)v->di_key, STRLEN(v->di_key),
+ v->di_tv.v_type, (s == NULL ? "" : s), first);
xfree(s);
}
-static void
-list_one_var_a (
- char_u *prefix,
- char_u *name,
- int type,
- char_u *string,
- int *first /* when TRUE clear rest of screen and set to FALSE */
-)
+/// @param[in] name_len Length of the name. May be -1, in this case strlen()
+/// will be used.
+/// @param[in,out] first When true clear rest of screen and set to false.
+static void list_one_var_a(const char *prefix, const char *name,
+ const ptrdiff_t name_len, const int type,
+ const char *string, int *first)
{
- /* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */
+ // don't use msg() or msg_attr() to avoid overwriting "v:statusmsg"
msg_start();
msg_puts(prefix);
- if (name != NULL) /* "a:" vars don't have a name stored */
- msg_puts(name);
+ if (name != NULL) { // "a:" vars don't have a name stored
+ msg_puts_attr_len(name, name_len, 0);
+ }
msg_putchar(' ');
msg_advance(22);
if (type == VAR_NUMBER) {
@@ -19850,10 +19013,10 @@ list_one_var_a (
} else
msg_putchar(' ');
- msg_outtrans(string);
+ msg_outtrans((char_u *)string);
if (type == VAR_FUNC || type == VAR_PARTIAL) {
- msg_puts((char_u *)"()");
+ msg_puts("()");
}
if (*first) {
msg_clr_eos();
@@ -19861,46 +19024,47 @@ list_one_var_a (
}
}
-/*
- * Set variable "name" to value in "tv".
- * If the variable already exists, the value is updated.
- * Otherwise the variable is created.
- */
-static void
-set_var (
- char_u *name,
- typval_T *tv,
- int copy /* make copy of value in "tv" */
-)
+/// Set variable to the given value
+///
+/// If the variable already exists, the value is updated. Otherwise the variable
+/// is created.
+///
+/// @param[in] name Variable name to set.
+/// @param[in] name_len Length of the variable name.
+/// @param tv Variable value.
+/// @param[in] copy True if value in tv is to be copied.
+static void set_var(const char *name, const size_t name_len, typval_T *const tv,
+ const bool copy)
+ FUNC_ATTR_NONNULL_ALL
{
dictitem_T *v;
- char_u *varname;
hashtab_T *ht;
- typval_T oldtv;
dict_T *dict;
- ht = find_var_ht_dict(name, &varname, &dict);
- bool watched = is_watched(dict);
-
- if (watched) {
- init_tv(&oldtv);
- }
+ const char *varname;
+ ht = find_var_ht_dict(name, name_len, &varname, &dict);
+ const bool watched = tv_dict_is_watched(dict);
if (ht == NULL || *varname == NUL) {
EMSG2(_(e_illvar), name);
return;
}
- v = find_var_in_ht(ht, 0, varname, TRUE);
+ v = find_var_in_ht(ht, 0, varname, name_len - (size_t)(varname - name), true);
- if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL)
- && var_check_func_name(name, v == NULL)) {
+ // Search in parent scope which is possible to reference from lambda
+ if (v == NULL) {
+ v = find_var_in_scoped_ht((const char *)name, name_len, true);
+ }
+
+ if (tv_is_func(*tv) && !var_check_func_name(name, v == NULL)) {
return;
}
+ typval_T oldtv = TV_INITIAL_VALUE;
if (v != NULL) {
// existing variable, need to clear the value
- if (var_check_ro(v->di_flags, name, false)
- || tv_check_lock(v->di_tv.v_lock, name, false)) {
+ if (var_check_ro(v->di_flags, name, name_len)
+ || tv_check_lock(v->di_tv.v_lock, name, name_len)) {
return;
}
@@ -19909,19 +19073,19 @@ set_var (
if (ht == &vimvarht) {
if (v->di_tv.v_type == VAR_STRING) {
xfree(v->di_tv.vval.v_string);
- if (copy || tv->v_type != VAR_STRING)
- v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv));
- else {
+ if (copy || tv->v_type != VAR_STRING) {
+ v->di_tv.vval.v_string = (char_u *)xstrdup(tv_get_string(tv));
+ } else {
// Take over the string to avoid an extra alloc/free.
v->di_tv.vval.v_string = tv->vval.v_string;
tv->vval.v_string = NULL;
}
return;
} else if (v->di_tv.v_type == VAR_NUMBER) {
- v->di_tv.vval.v_number = get_tv_number(tv);
- if (STRCMP(varname, "searchforward") == 0)
+ v->di_tv.vval.v_number = tv_get_number(tv);
+ if (strcmp(varname, "searchforward") == 0) {
set_search_direction(v->di_tv.vval.v_number ? '/' : '?');
- else if (STRCMP(varname, "hlsearch") == 0) {
+ } else if (strcmp(varname, "hlsearch") == 0) {
no_hlsearch = !v->di_tv.vval.v_number;
redraw_all_later(SOME_VALID);
}
@@ -19932,23 +19096,24 @@ set_var (
}
if (watched) {
- copy_tv(&v->di_tv, &oldtv);
+ tv_copy(&v->di_tv, &oldtv);
}
- clear_tv(&v->di_tv);
- } else { /* add a new variable */
- /* Can't add "v:" variable. */
+ tv_clear(&v->di_tv);
+ } else { // Add a new variable.
+ // Can't add "v:" variable.
if (ht == &vimvarht) {
- EMSG2(_(e_illvar), name);
+ emsgf(_(e_illvar), name);
return;
}
- /* Make sure the variable name is valid. */
- if (!valid_varname(varname))
+ // Make sure the variable name is valid.
+ if (!valid_varname(varname)) {
return;
+ }
- v = xmalloc(sizeof(dictitem_T) + STRLEN(varname));
+ v = xmalloc(sizeof(dictitem_T) + strlen(varname));
STRCPY(v->di_key, varname);
- if (hash_add(ht, DI2HIKEY(v)) == FAIL) {
+ if (tv_dict_add(dict, v) == FAIL) {
xfree(v);
return;
}
@@ -19956,167 +19121,153 @@ set_var (
}
if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT) {
- copy_tv(tv, &v->di_tv);
+ tv_copy(tv, &v->di_tv);
} else {
v->di_tv = *tv;
v->di_tv.v_lock = 0;
- init_tv(tv);
+ tv_init(tv);
}
if (watched) {
if (oldtv.v_type == VAR_UNKNOWN) {
- dictwatcher_notify(dict, (char *)v->di_key, &v->di_tv, NULL);
+ tv_dict_watcher_notify(dict, (char *)v->di_key, &v->di_tv, NULL);
} else {
- dictwatcher_notify(dict, (char *)v->di_key, &v->di_tv, &oldtv);
- clear_tv(&oldtv);
+ tv_dict_watcher_notify(dict, (char *)v->di_key, &v->di_tv, &oldtv);
+ tv_clear(&oldtv);
}
}
}
-// Return true if di_flags "flags" indicates variable "name" is read-only.
-// Also give an error message.
-static bool var_check_ro(int flags, char_u *name, bool use_gettext)
+/// Check whether variable is read-only (DI_FLAGS_RO, DI_FLAGS_RO_SBX)
+///
+/// Also gives an error message.
+///
+/// @param[in] flags di_flags attribute value.
+/// @param[in] name Variable name, for use in error message.
+/// @param[in] name_len Variable name length. Use #TV_TRANSLATE to translate
+/// variable name and compute the length. Use #TV_CSTRING
+/// to compute the length with strlen() without
+/// translating.
+///
+/// Both #TV_… values are used for optimization purposes:
+/// variable name with its length is needed only in case
+/// of error, when no error occurs computing them is
+/// a waste of CPU resources. This especially applies to
+/// gettext.
+///
+/// @return True if variable is read-only: either always or in sandbox when
+/// sandbox is enabled, false otherwise.
+bool var_check_ro(const int flags, const char *name,
+ size_t name_len)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
+ const char *error_message = NULL;
if (flags & DI_FLAGS_RO) {
- EMSG2(_(e_readonlyvar), use_gettext ? (char_u *)_(name) : name);
- return true;
+ error_message = N_(e_readonlyvar);
+ } else if ((flags & DI_FLAGS_RO_SBX) && sandbox) {
+ error_message = N_("E794: Cannot set variable in the sandbox: \"%.*s\"");
}
- if ((flags & DI_FLAGS_RO_SBX) && sandbox) {
- EMSG2(_(e_readonlysbx), use_gettext ? (char_u *)_(name) : name);
- return true;
+
+ if (error_message == NULL) {
+ return false;
}
- return false;
+ if (name_len == TV_TRANSLATE) {
+ name = _(name);
+ name_len = strlen(name);
+ } else if (name_len == TV_CSTRING) {
+ name_len = strlen(name);
+ }
+
+ emsgf(_(error_message), (int)name_len, name);
+
+ return true;
}
-// Return true if di_flags "flags" indicates variable "name" is fixed.
-// Also give an error message.
-static bool var_check_fixed(int flags, char_u *name, bool use_gettext)
+/// Check whether variable is fixed (DI_FLAGS_FIX)
+///
+/// Also gives an error message.
+///
+/// @param[in] flags di_flags attribute value.
+/// @param[in] name Variable name, for use in error message.
+/// @param[in] name_len Variable name length. Use #TV_TRANSLATE to translate
+/// variable name and compute the length. Use #TV_CSTRING
+/// to compute the length with strlen() without
+/// translating.
+///
+/// Both #TV_… values are used for optimization purposes:
+/// variable name with its length is needed only in case
+/// of error, when no error occurs computing them is
+/// a waste of CPU resources. This especially applies to
+/// gettext.
+///
+/// @return True if variable is fixed, false otherwise.
+static bool var_check_fixed(const int flags, const char *name,
+ size_t name_len)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
if (flags & DI_FLAGS_FIX) {
- EMSG2(_("E795: Cannot delete variable %s"),
- use_gettext ? (char_u *)_(name) : name);
+ if (name_len == TV_TRANSLATE) {
+ name = _(name);
+ name_len = strlen(name);
+ } else if (name_len == TV_CSTRING) {
+ name_len = strlen(name);
+ }
+ emsgf(_("E795: Cannot delete variable %.*s"), (int)name_len, name);
return true;
}
return false;
}
-/*
- * Check if a funcref is assigned to a valid variable name.
- * Return TRUE and give an error if not.
- */
-static int
-var_check_func_name (
- char_u *name, /* points to start of variable name */
- int new_var /* TRUE when creating the variable */
-)
+// TODO(ZyX-I): move to eval/expressions
+
+/// Check if name is a valid name to assign funcref to
+///
+/// @param[in] name Possible function/funcref name.
+/// @param[in] new_var True if it is a name for a variable.
+///
+/// @return false in case of error, true in case of success. Also gives an
+/// error message if appropriate.
+bool var_check_func_name(const char *const name, const bool new_var)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
// Allow for w: b: s: and t:.
if (!(vim_strchr((char_u *)"wbst", name[0]) != NULL && name[1] == ':')
&& !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') ? name[2]
: name[0])) {
EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name);
- return TRUE;
+ return false;
}
- /* Don't allow hiding a function. When "v" is not NULL we might be
- * assigning another function to the same var, the type is checked
- * below. */
- if (new_var && function_exists(name)) {
+ // Don't allow hiding a function. When "v" is not NULL we might be
+ // assigning another function to the same var, the type is checked
+ // below.
+ if (new_var && function_exists((const char *)name, false)) {
EMSG2(_("E705: Variable name conflicts with existing function: %s"),
- name);
- return TRUE;
+ name);
+ return false;
}
- return FALSE;
+ return true;
}
-/*
- * Check if a variable name is valid.
- * Return FALSE and give an error if not.
- */
-static int valid_varname(char_u *varname)
-{
- char_u *p;
+// TODO(ZyX-I): move to eval/expressions
- for (p = varname; *p != NUL; ++p)
- if (!eval_isnamec1(*p) && (p == varname || !ascii_isdigit(*p))
+/// Check if a variable name is valid
+///
+/// @param[in] varname Variable name to check.
+///
+/// @return false when variable name is not valid, true when it is. Also gives
+/// an error message if appropriate.
+bool valid_varname(const char *varname)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ for (const char *p = varname; *p != NUL; p++) {
+ if (!eval_isnamec1((int)(uint8_t)(*p))
+ && (p == varname || !ascii_isdigit(*p))
&& *p != AUTOLOAD_CHAR) {
- EMSG2(_(e_illvar), varname);
- return FALSE;
+ emsgf(_(e_illvar), varname);
+ return false;
}
- return TRUE;
-}
-
-// Return true if typeval "tv" is set to be locked (immutable).
-// Also give an error message, using "name" or _("name") when use_gettext is
-// true.
-static bool tv_check_lock(int lock, char_u *name, bool use_gettext)
-{
- if (lock & VAR_LOCKED) {
- EMSG2(_("E741: Value is locked: %s"),
- name == NULL
- ? (char_u *)_("Unknown")
- : use_gettext ? (char_u *)_(name)
- : name);
- return true;
- }
- if (lock & VAR_FIXED) {
- EMSG2(_("E742: Cannot change value of %s"),
- name == NULL
- ? (char_u *)_("Unknown")
- : use_gettext ? (char_u *)_(name)
- : name);
- return true;
- }
- return false;
-}
-
-/*
- * Copy the values from typval_T "from" to typval_T "to".
- * When needed allocates string or increases reference count.
- * Does not make a copy of a list or dict but copies the reference!
- * It is OK for "from" and "to" to point to the same item. This is used to
- * make a copy later.
- */
-void copy_tv(typval_T *from, typval_T *to)
-{
- to->v_type = from->v_type;
- to->v_lock = 0;
- memmove(&to->vval, &from->vval, sizeof(to->vval));
- switch (from->v_type) {
- case VAR_NUMBER:
- case VAR_FLOAT:
- case VAR_SPECIAL:
- break;
- case VAR_STRING:
- case VAR_FUNC:
- if (from->vval.v_string != NULL) {
- to->vval.v_string = vim_strsave(from->vval.v_string);
- if (from->v_type == VAR_FUNC) {
- func_ref(to->vval.v_string);
- }
- }
- break;
- case VAR_PARTIAL:
- if (from->vval.v_partial == NULL) {
- to->vval.v_partial = NULL;
- } else {
- to->vval.v_partial = from->vval.v_partial;
- (to->vval.v_partial->pt_refcount)++;
- }
- break;
- case VAR_LIST:
- if (from->vval.v_list != NULL) {
- to->vval.v_list->lv_refcount++;
- }
- break;
- case VAR_DICT:
- if (from->vval.v_dict != NULL) {
- to->vval.v_dict->dv_refcount++;
- }
- break;
- case VAR_UNKNOWN:
- EMSG2(_(e_intern2), "copy_tv(UNKNOWN)");
- break;
}
+ return true;
}
/// Make a copy of an item
@@ -20134,7 +19285,7 @@ void copy_tv(typval_T *from, typval_T *to)
/// list[1]`) var_item_copy with zero copyID will emit
/// a copy with (`copy[0] isnot copy[1]`), with non-zero it
/// will emit a copy with (`copy[0] is copy[1]`) like in the
-/// original list. Not use when deep is false.
+/// original list. Not used when deep is false.
int var_item_copy(const vimconv_T *const conv,
typval_T *const from,
typval_T *const to,
@@ -20157,11 +19308,12 @@ int var_item_copy(const vimconv_T *const conv,
case VAR_FUNC:
case VAR_PARTIAL:
case VAR_SPECIAL:
- copy_tv(from, to);
+ tv_copy(from, to);
break;
case VAR_STRING:
- if (conv == NULL || conv->vc_type == CONV_NONE) {
- copy_tv(from, to);
+ if (conv == NULL || conv->vc_type == CONV_NONE
+ || from->vval.v_string == NULL) {
+ tv_copy(from, to);
} else {
to->v_type = VAR_STRING;
to->v_lock = 0;
@@ -20183,10 +19335,11 @@ int var_item_copy(const vimconv_T *const conv,
to->vval.v_list = from->vval.v_list->lv_copylist;
++to->vval.v_list->lv_refcount;
} else {
- to->vval.v_list = list_copy(conv, from->vval.v_list, deep, copyID);
+ to->vval.v_list = tv_list_copy(conv, from->vval.v_list, deep, copyID);
}
- if (to->vval.v_list == NULL)
+ if (to->vval.v_list == NULL && from->vval.v_list != NULL) {
ret = FAIL;
+ }
break;
case VAR_DICT:
to->v_type = VAR_DICT;
@@ -20198,10 +19351,11 @@ int var_item_copy(const vimconv_T *const conv,
to->vval.v_dict = from->vval.v_dict->dv_copydict;
++to->vval.v_dict->dv_refcount;
} else {
- to->vval.v_dict = dict_copy(conv, from->vval.v_dict, deep, copyID);
+ to->vval.v_dict = tv_dict_copy(conv, from->vval.v_dict, deep, copyID);
}
- if (to->vval.v_dict == NULL)
+ if (to->vval.v_dict == NULL && from->vval.v_dict != NULL) {
ret = FAIL;
+ }
break;
case VAR_UNKNOWN:
EMSG2(_(e_intern2), "var_item_copy(UNKNOWN)");
@@ -20220,7 +19374,6 @@ void ex_echo(exarg_T *eap)
{
char_u *arg = eap->arg;
typval_T rettv;
- char_u *p;
bool needclr = true;
bool atstart = true;
@@ -20231,19 +19384,20 @@ void ex_echo(exarg_T *eap)
* still need to be cleared. E.g., "echo 22,44". */
need_clr_eos = needclr;
- p = arg;
- if (eval1(&arg, &rettv, !eap->skip) == FAIL) {
- /*
- * Report the invalid expression unless the expression evaluation
- * has been cancelled due to an aborting error, an interrupt, or an
- * exception.
- */
- if (!aborting())
- EMSG2(_(e_invexpr2), p);
- need_clr_eos = FALSE;
- break;
+ {
+ char_u *p = arg;
+ if (eval1(&arg, &rettv, !eap->skip) == FAIL) {
+ // Report the invalid expression unless the expression evaluation
+ // has been cancelled due to an aborting error, an interrupt, or an
+ // exception.
+ if (!aborting()) {
+ EMSG2(_(e_invexpr2), p);
+ }
+ need_clr_eos = false;
+ break;
+ }
+ need_clr_eos = false;
}
- need_clr_eos = FALSE;
if (!eap->skip) {
if (atstart) {
@@ -20257,9 +19411,11 @@ void ex_echo(exarg_T *eap)
msg_sb_eol();
msg_start();
}
- } else if (eap->cmdidx == CMD_echo)
- msg_puts_attr((char_u *)" ", echo_attr);
- char_u *tofree = p = (char_u *) encode_tv2echo(&rettv, NULL);
+ } else if (eap->cmdidx == CMD_echo) {
+ msg_puts_attr(" ", echo_attr);
+ }
+ char *tofree = encode_tv2echo(&rettv, NULL);
+ const char *p = tofree;
if (p != NULL) {
for (; *p != NUL && !got_int; ++p) {
if (*p == '\n' || *p == '\r' || *p == TAB) {
@@ -20268,21 +19424,22 @@ void ex_echo(exarg_T *eap)
msg_clr_eos();
needclr = false;
}
- msg_putchar_attr(*p, echo_attr);
+ msg_putchar_attr((uint8_t)(*p), echo_attr);
} else {
if (has_mbyte) {
- int i = (*mb_ptr2len)(p);
+ int i = (*mb_ptr2len)((const char_u *)p);
- (void)msg_outtrans_len_attr(p, i, echo_attr);
+ (void)msg_outtrans_len_attr((char_u *)p, i, echo_attr);
p += i - 1;
- } else
- (void)msg_outtrans_len_attr(p, 1, echo_attr);
+ } else {
+ (void)msg_outtrans_len_attr((char_u *)p, 1, echo_attr);
+ }
}
}
}
xfree(tofree);
}
- clear_tv(&rettv);
+ tv_clear(&rettv);
arg = skipwhite(arg);
}
eap->nextcmd = check_nextcmd(arg);
@@ -20326,7 +19483,6 @@ void ex_execute(exarg_T *eap)
int ret = OK;
char_u *p;
garray_T ga;
- int len;
int save_did_emsg;
ga_init(&ga, 1, 80);
@@ -20348,16 +19504,17 @@ void ex_execute(exarg_T *eap)
}
if (!eap->skip) {
- p = get_tv_string(&rettv);
- len = (int)STRLEN(p);
+ const char *const argstr = tv_get_string(&rettv);
+ const size_t len = strlen(argstr);
ga_grow(&ga, len + 2);
- if (!GA_EMPTY(&ga))
+ if (!GA_EMPTY(&ga)) {
((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
- STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p);
+ }
+ memcpy((char_u *)(ga.ga_data) + ga.ga_len, argstr, len + 1);
ga.ga_len += len;
}
- clear_tv(&rettv);
+ tv_clear(&rettv);
arg = skipwhite(arg);
}
@@ -20390,9 +19547,9 @@ void ex_execute(exarg_T *eap)
* Returns NULL when no option name found. Otherwise pointer to the char
* after the option name.
*/
-static char_u *find_option_end(char_u **arg, int *opt_flags)
+static const char *find_option_end(const char **const arg, int *const opt_flags)
{
- char_u *p = *arg;
+ const char *p = *arg;
++p;
if (*p == 'g' && p[1] == ':') {
@@ -20401,18 +19558,22 @@ static char_u *find_option_end(char_u **arg, int *opt_flags)
} else if (*p == 'l' && p[1] == ':') {
*opt_flags = OPT_LOCAL;
p += 2;
- } else
+ } else {
*opt_flags = 0;
+ }
- if (!ASCII_ISALPHA(*p))
+ if (!ASCII_ISALPHA(*p)) {
return NULL;
+ }
*arg = p;
- if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL)
- p += 4; /* termcap option */
- else
- while (ASCII_ISALPHA(*p))
- ++p;
+ if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) {
+ p += 4; // t_xx/termcap option
+ } else {
+ while (ASCII_ISALPHA(*p)) {
+ p++;
+ }
+ }
return p;
}
@@ -20431,10 +19592,10 @@ void ex_function(exarg_T *eap)
char_u *line_arg = NULL;
garray_T newargs;
garray_T newlines;
- int varargs = FALSE;
- int mustend = FALSE;
+ int varargs = false;
int flags = 0;
ufunc_T *fp;
+ bool overwrite = false;
int indent;
int nesting;
char_u *skip_until = NULL;
@@ -20457,8 +19618,9 @@ void ex_function(exarg_T *eap)
if (!HASHITEM_EMPTY(hi)) {
--todo;
fp = HI2UF(hi);
- if (!isdigit(*fp->uf_name))
- list_func_head(fp, FALSE);
+ if (!func_name_refcount(fp->uf_name)) {
+ list_func_head(fp, false);
+ }
}
}
}
@@ -20524,8 +19686,9 @@ void ex_function(exarg_T *eap)
* interrupt, or an exception.
*/
if (!aborting()) {
- if (!eap->skip && fudi.fd_newkey != NULL)
+ if (fudi.fd_newkey != NULL) {
EMSG2(_(e_dictkey), fudi.fd_newkey);
+ }
xfree(fudi.fd_newkey);
return;
} else
@@ -20567,7 +19730,7 @@ void ex_function(exarg_T *eap)
}
if (!got_int) {
msg_putchar('\n');
- msg_puts((char_u *)" endfunction");
+ msg_puts(" endfunction");
}
} else
emsg_funcname(N_("E123: Undefined function: %s"), name);
@@ -20600,9 +19763,7 @@ void ex_function(exarg_T *eap)
arg = name;
else
arg = fudi.fd_newkey;
- if (arg != NULL && (fudi.fd_di == NULL
- || (fudi.fd_di->di_tv.v_type != VAR_FUNC
- && fudi.fd_di->di_tv.v_type != VAR_PARTIAL))) {
+ if (arg != NULL && (fudi.fd_di == NULL || !tv_is_func(fudi.fd_di->di_tv))) {
int j = (*arg == K_SPECIAL) ? 3 : 0;
while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j])
: eval_isnamec(arg[j])))
@@ -20615,59 +19776,11 @@ void ex_function(exarg_T *eap)
EMSG(_("E862: Cannot use g: here"));
}
- /*
- * Isolate the arguments: "arg1, arg2, ...)"
- */
- while (*p != ')') {
- if (p[0] == '.' && p[1] == '.' && p[2] == '.') {
- varargs = TRUE;
- p += 3;
- mustend = TRUE;
- } else {
- arg = p;
- while (ASCII_ISALNUM(*p) || *p == '_')
- ++p;
- if (arg == p || isdigit(*arg)
- || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0)
- || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) {
- if (!eap->skip)
- EMSG2(_("E125: Illegal argument: %s"), arg);
- break;
- }
- ga_grow(&newargs, 1);
- c = *p;
- *p = NUL;
- arg = vim_strsave(arg);
-
- /* Check for duplicate argument name. */
- for (int i = 0; i < newargs.ga_len; ++i)
- if (STRCMP(((char_u **)(newargs.ga_data))[i], arg) == 0) {
- EMSG2(_("E853: Duplicate argument name: %s"), arg);
- xfree(arg);
- goto erret;
- }
-
- ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg;
- *p = c;
- newargs.ga_len++;
- if (*p == ',')
- ++p;
- else
- mustend = TRUE;
- }
- p = skipwhite(p);
- if (mustend && *p != ')') {
- if (!eap->skip)
- EMSG2(_(e_invarg2), eap->arg);
- break;
- }
- }
- if (*p != ')') {
- goto erret;
+ if (get_function_args(&p, ')', &newargs, &varargs, eap->skip) == FAIL) {
+ goto errret_2;
}
- ++p; // skip the ')'
- /* find extra arguments "range", "dict" and "abort" */
+ // find extra arguments "range", "dict", "abort" and "closure"
for (;; ) {
p = skipwhite(p);
if (STRNCMP(p, "range", 5) == 0) {
@@ -20679,16 +19792,28 @@ void ex_function(exarg_T *eap)
} else if (STRNCMP(p, "abort", 5) == 0) {
flags |= FC_ABORT;
p += 5;
- } else
+ } else if (STRNCMP(p, "closure", 7) == 0) {
+ flags |= FC_CLOSURE;
+ p += 7;
+ if (current_funccal == NULL) {
+ emsg_funcname(N_
+ ("E932: Closure function should not be at top level: %s"),
+ name == NULL ? (char_u *)"" : name);
+ goto erret;
+ }
+ } else {
break;
+ }
}
/* When there is a line break use what follows for the function body.
* Makes 'exe "func Test()\n...\nendfunc"' work. */
- if (*p == '\n')
+ const char *const end = (const char *)p + STRLEN(p);
+ if (*p == '\n') {
line_arg = p + 1;
- else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg)
- EMSG(_(e_trailing));
+ } else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) {
+ emsgf(_(e_trailing));
+ }
/*
* Read the body of the function, until ":endfunction" is found.
@@ -20762,8 +19887,30 @@ void ex_function(exarg_T *eap)
/* Check for "endfunction". */
if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) {
- if (line_arg == NULL)
+ if (*p == '!') {
+ p++;
+ }
+ const char *const comment_start = strchr((const char *)p, '"');
+ const char *const endfunc_end = (comment_start
+ ? strchr(comment_start, '\n')
+ : strpbrk((const char *)p, "\n|"));
+ p = (endfunc_end
+ ? (char_u *)endfunc_end
+ : p + STRLEN(p));
+ if (*p == '|') {
+ emsgf(_(e_trailing2), p);
+ if (line_arg == NULL) {
+ xfree(theline);
+ }
+ goto erret;
+ }
+ if (line_arg == NULL) {
xfree(theline);
+ } else {
+ if ((const char *)p < end) {
+ eap->nextcmd = p + 1;
+ }
+ }
break;
}
@@ -20782,7 +19929,7 @@ void ex_function(exarg_T *eap)
if (*p == '!') {
p = skipwhite(p + 1);
}
- p += eval_fname_script(p);
+ p += eval_fname_script((const char *)p);
xfree(trans_function_name(&p, true, 0, NULL, NULL));
if (*skipwhite(p) == '(') {
nesting++;
@@ -20790,9 +19937,15 @@ void ex_function(exarg_T *eap)
}
}
- /* Check for ":append" or ":insert". */
+ // Check for ":append", ":change", ":insert".
p = skip_range(p, NULL);
if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p'))
+ || (p[0] == 'c'
+ && (!ASCII_ISALPHA(p[1])
+ || (p[1] == 'h' && (!ASCII_ISALPHA(p[2])
+ || (p[2] == 'a'
+ && (STRNCMP(&p[3], "nge", 3) != 0
+ || !ASCII_ISALPHA(p[6])))))))
|| (p[0] == 'i'
&& (!ASCII_ISALPHA(p[1]) || (p[1] == 'n'
&& (!ASCII_ISALPHA(p[2])
@@ -20857,7 +20010,7 @@ void ex_function(exarg_T *eap)
* If there are no errors, add the function
*/
if (fudi.fd_dict == NULL) {
- v = find_var(name, &ht, FALSE);
+ v = find_var((const char *)name, STRLEN(name), &ht, false);
if (v != NULL && v->di_tv.v_type == VAR_FUNC) {
emsg_funcname(N_("E707: Function name conflicts with variable: %s"),
name);
@@ -20870,16 +20023,25 @@ void ex_function(exarg_T *eap)
emsg_funcname(e_funcexts, name);
goto erret;
}
- if (fp->uf_refcount > 1 || fp->uf_calls > 0) {
+ if (fp->uf_calls > 0) {
emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"),
name);
goto erret;
}
- /* redefine existing function */
- ga_clear_strings(&(fp->uf_args));
- ga_clear_strings(&(fp->uf_lines));
- xfree(name);
- name = NULL;
+ if (fp->uf_refcount > 1) {
+ // This function is referenced somewhere, don't redefine it but
+ // create a new one.
+ (fp->uf_refcount)--;
+ fp->uf_flags |= FC_REMOVED;
+ fp = NULL;
+ overwrite = true;
+ } else {
+ // redefine existing function
+ ga_clear_strings(&(fp->uf_args));
+ ga_clear_strings(&(fp->uf_lines));
+ xfree(name);
+ name = NULL;
+ }
}
} else {
char numbuf[20];
@@ -20890,11 +20052,13 @@ void ex_function(exarg_T *eap)
goto erret;
}
if (fudi.fd_di == NULL) {
- if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg, false)) {
+ if (tv_check_lock(fudi.fd_dict->dv_lock, (const char *)eap->arg,
+ TV_CSTRING)) {
// Can't add a function to a locked dictionary
goto erret;
}
- } else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg, false)) {
+ } else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, (const char *)eap->arg,
+ TV_CSTRING)) {
// Can't change an existing function if it is locked
goto erret;
}
@@ -20914,7 +20078,7 @@ void ex_function(exarg_T *eap)
/* Check that the autoload name matches the script name. */
int j = FAIL;
if (sourcing_name != NULL) {
- scriptname = autoload_name(name);
+ scriptname = (char_u *)autoload_name((const char *)name, STRLEN(name));
p = vim_strchr(scriptname, '/');
plen = (int)STRLEN(p);
slen = (int)STRLEN(sourcing_name);
@@ -20931,20 +20095,21 @@ void ex_function(exarg_T *eap)
}
}
- fp = xmalloc(sizeof(ufunc_T) + STRLEN(name));
+ fp = xcalloc(1, sizeof(ufunc_T) + STRLEN(name));
if (fudi.fd_dict != NULL) {
if (fudi.fd_di == NULL) {
- /* add new dict entry */
- fudi.fd_di = dictitem_alloc(fudi.fd_newkey);
- if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) {
+ // Add new dict entry
+ fudi.fd_di = tv_dict_item_alloc((const char *)fudi.fd_newkey);
+ if (tv_dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) {
xfree(fudi.fd_di);
xfree(fp);
goto erret;
}
- } else
- /* overwrite existing dict entry */
- clear_tv(&fudi.fd_di->di_tv);
+ } else {
+ // Overwrite existing dict entry.
+ tv_clear(&fudi.fd_di->di_tv);
+ }
fudi.fd_di->di_tv.v_type = VAR_FUNC;
fudi.fd_di->di_tv.v_lock = 0;
fudi.fd_di->di_tv.vval.v_string = vim_strsave(name);
@@ -20955,14 +20120,22 @@ void ex_function(exarg_T *eap)
/* insert the new function in the function list */
STRCPY(fp->uf_name, name);
- if (hash_add(&func_hashtab, UF2HIKEY(fp)) == FAIL) {
- xfree(fp);
- goto erret;
+ if (overwrite) {
+ hi = hash_find(&func_hashtab, name);
+ hi->hi_key = UF2HIKEY(fp);
+ } else if (hash_add(&func_hashtab, UF2HIKEY(fp)) == FAIL) {
+ xfree(fp);
+ goto erret;
}
+ fp->uf_refcount = 1;
}
- fp->uf_refcount = 1;
fp->uf_args = newargs;
fp->uf_lines = newlines;
+ if ((flags & FC_CLOSURE) != 0) {
+ register_closure(fp);
+ } else {
+ fp->uf_scoped = NULL;
+ }
fp->uf_tml_count = NULL;
fp->uf_tml_total = NULL;
fp->uf_tml_self = NULL;
@@ -20977,6 +20150,7 @@ void ex_function(exarg_T *eap)
erret:
ga_clear_strings(&newargs);
+errret_2:
ga_clear_strings(&newlines);
ret_free:
xfree(skip_until);
@@ -20986,30 +20160,29 @@ ret_free:
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).
- */
+/// Get a function name, translating "<SID>" and "<SNR>".
+/// Also handles a Funcref in a List or Dictionary.
+/// flags:
+/// TFN_INT: internal function name OK
+/// TFN_QUIET: be quiet
+/// TFN_NO_AUTOLOAD: do not use script autoloading
+/// TFN_NO_DEREF: do not dereference a Funcref
+/// Advances "pp" to just after the function name (if no error).
+///
+/// @return the function name in allocated memory, or NULL for failure.
static char_u *
-trans_function_name (
+trans_function_name(
char_u **pp,
- int skip, /* only find the end, don't evaluate */
+ int skip, // only find the end, don't evaluate
int flags,
funcdict_T *fdp, // return: info about dictionary used
partial_T **partial // return: partial of a FuncRef
)
{
char_u *name = NULL;
- char_u *start;
- char_u *end;
+ const char_u *start;
+ const char_u *end;
int lead;
- char_u sid_buf[20];
int len;
lval_T lv;
@@ -21022,19 +20195,20 @@ trans_function_name (
if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA
&& (*pp)[2] == (int)KE_SNR) {
*pp += 3;
- len = get_id_len(pp) + 3;
- return vim_strnsave(start, len);
+ len = get_id_len((const char **)pp) + 3;
+ return (char_u *)xmemdupz(start, len);
}
/* A name starting with "<SID>" or "<SNR>" is local to a script. But
* don't skip over "s:", get_lval() needs it for "s:dict.func". */
- lead = eval_fname_script(start);
- if (lead > 2)
+ lead = eval_fname_script((const char *)start);
+ if (lead > 2) {
start += lead;
+ }
- /* Note that TFN_ flags use the same values as GLV_ flags. */
- end = get_lval(start, NULL, &lv, FALSE, skip, flags,
- lead > 2 ? 0 : FNE_CHECK_START);
+ // Note that TFN_ flags use the same values as GLV_ flags.
+ end = get_lval((char_u *)start, NULL, &lv, false, skip, flags,
+ lead > 2 ? 0 : FNE_CHECK_START);
if (end == start) {
if (!skip)
EMSG(_("E129: Function name required"));
@@ -21047,10 +20221,12 @@ trans_function_name (
* interrupt, or an exception.
*/
if (!aborting()) {
- if (end != NULL)
- EMSG2(_(e_invarg2), start);
- } else
- *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR);
+ if (end != NULL) {
+ emsgf(_(e_invarg2), start);
+ }
+ } else {
+ *pp = (char_u *)find_name_end(start, NULL, NULL, FNE_INCL_BR);
+ }
goto theend;
}
@@ -21063,11 +20239,11 @@ trans_function_name (
}
if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) {
name = vim_strsave(lv.ll_tv->vval.v_string);
- *pp = end;
+ *pp = (char_u *)end;
} else if (lv.ll_tv->v_type == VAR_PARTIAL
&& lv.ll_tv->vval.v_partial != NULL) {
- name = vim_strsave(lv.ll_tv->vval.v_partial->pt_name);
- *pp = end;
+ name = vim_strsave(partial_name(lv.ll_tv->vval.v_partial));
+ *pp = (char_u *)end;
if (partial != NULL) {
*partial = lv.ll_tv->vval.v_partial;
}
@@ -21077,7 +20253,7 @@ trans_function_name (
|| fdp->fd_newkey == NULL)) {
EMSG(_(e_funcref));
} else {
- *pp = end;
+ *pp = (char_u *)end;
}
name = NULL;
}
@@ -21085,29 +20261,30 @@ trans_function_name (
}
if (lv.ll_name == NULL) {
- /* Error found, but continue after the function name. */
- *pp = end;
+ // Error found, but continue after the function name.
+ *pp = (char_u *)end;
goto theend;
}
/* Check if the name is a Funcref. If so, use the value. */
if (lv.ll_exp_name != NULL) {
- len = (int)STRLEN(lv.ll_exp_name);
+ len = (int)strlen(lv.ll_exp_name);
name = deref_func_name(lv.ll_exp_name, &len, partial,
flags & TFN_NO_AUTOLOAD);
- if (name == lv.ll_exp_name) {
+ if ((const char *)name == lv.ll_exp_name) {
name = NULL;
}
- } else {
+ } else if (!(flags & TFN_NO_DEREF)) {
len = (int)(end - *pp);
- name = deref_func_name(*pp, &len, partial, flags & TFN_NO_AUTOLOAD);
+ name = deref_func_name((const char *)(*pp), &len, partial,
+ flags & TFN_NO_AUTOLOAD);
if (name == *pp) {
name = NULL;
}
}
if (name != NULL) {
name = vim_strsave(name);
- *pp = end;
+ *pp = (char_u *)end;
if (strncmp((char *)name, "<SNR>", 5) == 0) {
// Change "<SNR>" to the byte sequence.
name[0] = K_SPECIAL;
@@ -21119,12 +20296,13 @@ trans_function_name (
}
if (lv.ll_exp_name != NULL) {
- len = (int)STRLEN(lv.ll_exp_name);
+ len = (int)strlen(lv.ll_exp_name);
if (lead <= 2 && lv.ll_name == lv.ll_exp_name
- && STRNCMP(lv.ll_name, "s:", 2) == 0) {
- /* When there was "s:" already or the name expanded to get a
- * leading "s:" then remove it. */
+ && lv.ll_name_len >= 2 && memcmp(lv.ll_name, "s:", 2) == 0) {
+ // When there was "s:" already or the name expanded to get a
+ // leading "s:" then remove it.
lv.ll_name += 2;
+ lv.ll_name_len -= 2;
len -= 2;
lead = 2;
}
@@ -21132,37 +20310,41 @@ trans_function_name (
// Skip over "s:" and "g:".
if (lead == 2 || (lv.ll_name[0] == 'g' && lv.ll_name[1] == ':')) {
lv.ll_name += 2;
+ lv.ll_name_len -= 2;
}
- len = (int)(end - lv.ll_name);
+ len = (int)((const char *)end - lv.ll_name);
}
- /*
- * Copy the function name to allocated memory.
- * Accept <SID>name() inside a script, translate into <SNR>123_name().
- * Accept <SNR>123_name() outside a script.
- */
- if (skip)
- lead = 0; /* do nothing */
- else if (lead > 0) {
+ size_t sid_buf_len = 0;
+ char sid_buf[20];
+
+ // Copy the function name to allocated memory.
+ // Accept <SID>name() inside a script, translate into <SNR>123_name().
+ // Accept <SNR>123_name() outside a script.
+ if (skip) {
+ lead = 0; // do nothing
+ } else if (lead > 0) {
lead = 3;
if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name))
- || eval_fname_sid(*pp)) {
- /* It's "s:" or "<SID>" */
+ || eval_fname_sid((const char *)(*pp))) {
+ // It's "s:" or "<SID>".
if (current_SID <= 0) {
EMSG(_(e_usingsid));
goto theend;
}
- sprintf((char *)sid_buf, "%" PRId64 "_", (int64_t)current_SID);
- lead += (int)STRLEN(sid_buf);
+ sid_buf_len = snprintf(sid_buf, sizeof(sid_buf),
+ "%" PRIdSCID "_", current_SID);
+ lead += sid_buf_len;
}
- } else if (!(flags & TFN_INT) && builtin_function(lv.ll_name, len)) {
+ } else if (!(flags & TFN_INT)
+ && builtin_function(lv.ll_name, lv.ll_name_len)) {
EMSG2(_("E128: Function name must start with a capital or \"s:\": %s"),
start);
goto theend;
}
- if (!skip && !(flags & TFN_QUIET)) {
- char_u *cp = vim_strchr(lv.ll_name, ':');
+ if (!skip && !(flags & TFN_QUIET) && !(flags & TFN_NO_DEREF)) {
+ char_u *cp = xmemrchr(lv.ll_name, ':', lv.ll_name_len);
if (cp != NULL && cp < end) {
EMSG2(_("E884: Function name cannot contain a colon: %s"), start);
@@ -21175,12 +20357,13 @@ trans_function_name (
name[0] = K_SPECIAL;
name[1] = KS_EXTRA;
name[2] = (int)KE_SNR;
- if (lead > 3) /* If it's "<SID>" */
- STRCPY(name + 3, sid_buf);
+ if (sid_buf_len > 0) { // If it's "<SID>"
+ memcpy(name + 3, sid_buf, sid_buf_len);
+ }
}
- memmove(name + lead, lv.ll_name, (size_t)len);
+ memmove(name + lead, lv.ll_name, len);
name[lead + len] = NUL;
- *pp = end;
+ *pp = (char_u *)end;
theend:
clear_lval(&lv);
@@ -21192,12 +20375,13 @@ theend:
* Return 2 if "p" starts with "s:".
* Return 0 otherwise.
*/
-static int eval_fname_script(char_u *p)
+static int eval_fname_script(const char *const p)
{
- // Use mb_stricmp() because in Turkish comparing the "I" may not work with
+ // Use mb_strnicmp() because in Turkish comparing the "I" may not work with
// the standard library function.
- if (p[0] == '<' && (mb_strnicmp(p + 1, (char_u *)"SID>", 4) == 0
- || mb_strnicmp(p + 1, (char_u *)"SNR>", 4) == 0)) {
+ if (p[0] == '<'
+ && (mb_strnicmp((char_u *)p + 1, (char_u *)"SID>", 4) == 0
+ || mb_strnicmp((char_u *)p + 1, (char_u *)"SNR>", 4) == 0)) {
return 5;
}
if (p[0] == 's' && p[1] == ':') {
@@ -21206,13 +20390,19 @@ static int eval_fname_script(char_u *p)
return 0;
}
-/*
- * Return TRUE if "p" starts with "<SID>" or "s:".
- * Only works if eval_fname_script() returned non-zero for "p"!
- */
-static int eval_fname_sid(char_u *p)
+/// Check whether function name starts with <SID> or s:
+///
+/// @warning Only works for names previously checked by eval_fname_script(), if
+/// it returned non-zero.
+///
+/// @param[in] name Name to check.
+///
+/// @return true if it starts with <SID> or s:, false otherwise.
+static inline bool eval_fname_sid(const char *const name)
+ FUNC_ATTR_PURE FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
+ FUNC_ATTR_NONNULL_ALL
{
- return *p == 's' || TOUPPER_ASC(p[2]) == 'I';
+ return *name == 's' || TOUPPER_ASC(name[2]) == 'I';
}
/*
@@ -21226,38 +20416,45 @@ static void list_func_head(ufunc_T *fp, int indent)
MSG_PUTS("function ");
if (fp->uf_name[0] == K_SPECIAL) {
MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8));
- msg_puts(fp->uf_name + 3);
- } else
- msg_puts(fp->uf_name);
+ msg_puts((const char *)fp->uf_name + 3);
+ } else {
+ msg_puts((const char *)fp->uf_name);
+ }
msg_putchar('(');
int j;
- for (j = 0; j < fp->uf_args.ga_len; ++j) {
- if (j)
- MSG_PUTS(", ");
- msg_puts(FUNCARG(fp, j));
+ for (j = 0; j < fp->uf_args.ga_len; j++) {
+ if (j) {
+ msg_puts(", ");
+ }
+ msg_puts((const char *)FUNCARG(fp, j));
}
if (fp->uf_varargs) {
- if (j)
- MSG_PUTS(", ");
- MSG_PUTS("...");
+ if (j) {
+ msg_puts(", ");
+ }
+ msg_puts("...");
}
msg_putchar(')');
- if (fp->uf_flags & FC_ABORT)
- MSG_PUTS(" abort");
- if (fp->uf_flags & FC_RANGE)
- MSG_PUTS(" range");
- if (fp->uf_flags & FC_DICT)
- MSG_PUTS(" dict");
+ if (fp->uf_flags & FC_ABORT) {
+ msg_puts(" abort");
+ }
+ if (fp->uf_flags & FC_RANGE) {
+ msg_puts(" range");
+ }
+ if (fp->uf_flags & FC_DICT) {
+ msg_puts(" dict");
+ }
+ if (fp->uf_flags & FC_CLOSURE) {
+ msg_puts(" closure");
+ }
msg_clr_eos();
if (p_verbose > 0)
last_set_msg(fp->uf_script_ID);
}
-/*
- * Find a function by name, return pointer to it in ufuncs.
- * Return NULL for unknown function.
- */
-static ufunc_T *find_func(char_u *name)
+/// Find a function by name, return pointer to it in ufuncs.
+/// @return NULL for unknown function.
+static ufunc_T *find_func(const char_u *name)
{
hashitem_T *hi;
@@ -21271,61 +20468,118 @@ static ufunc_T *find_func(char_u *name)
void free_all_functions(void)
{
hashitem_T *hi;
+ ufunc_T *fp;
+ uint64_t skipped = 0;
+ uint64_t todo = 1;
+ uint64_t used;
+
+ // First clear what the functions contain. Since this may lower the
+ // reference count of a function, it may also free a function and change
+ // the hash table. Restart if that happens.
+ while (todo > 0) {
+ todo = func_hashtab.ht_used;
+ for (hi = func_hashtab.ht_array; todo > 0; hi++) {
+ if (!HASHITEM_EMPTY(hi)) {
+ // Only free functions that are not refcounted, those are
+ // supposed to be freed when no longer referenced.
+ fp = HI2UF(hi);
+ if (func_name_refcount(fp->uf_name)) {
+ skipped++;
+ } else {
+ used = func_hashtab.ht_used;
+ func_clear(fp, true);
+ if (used != func_hashtab.ht_used) {
+ skipped = 0;
+ break;
+ }
+ }
+ todo--;
+ }
+ }
+ }
- /* Need to start all over every time, because func_free() may change the
- * hash table. */
- while (func_hashtab.ht_used > 0)
- for (hi = func_hashtab.ht_array;; ++hi)
+ // Now actually free the functions. Need to start all over every time,
+ // because func_free() may change the hash table.
+ skipped = 0;
+ while (func_hashtab.ht_used > skipped) {
+ todo = func_hashtab.ht_used;
+ for (hi = func_hashtab.ht_array; todo > 0; hi++) {
if (!HASHITEM_EMPTY(hi)) {
- func_free(HI2UF(hi));
- break;
+ todo--;
+ // Only free functions that are not refcounted, those are
+ // supposed to be freed when no longer referenced.
+ fp = HI2UF(hi);
+ if (func_name_refcount(fp->uf_name)) {
+ skipped++;
+ } else {
+ func_free(fp);
+ skipped = 0;
+ break;
+ }
}
+ }
+ }
+ if (skipped == 0) {
+ hash_clear(&func_hashtab);
+ }
}
#endif
-int translated_function_exists(char_u *name)
+bool translated_function_exists(const char *name)
{
if (builtin_function(name, -1)) {
return find_internal_func((char *)name) != NULL;
}
- return find_func(name) != NULL;
+ return find_func((const char_u *)name) != NULL;
}
-/*
- * Return TRUE if a function "name" exists.
- */
-static int function_exists(char_u *name)
+/// Check whether function with the given name exists
+///
+/// @param[in] name Function name.
+/// @param[in] no_deref Whether to dereference a Funcref.
+///
+/// @return True if it exists, false otherwise.
+static bool function_exists(const char *const name, bool no_deref)
{
- char_u *nm = name;
- char_u *p;
- int n = FALSE;
+ const char_u *nm = (const char_u *)name;
+ bool n = false;
+ int flag = TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD;
- p = trans_function_name(&nm, false, TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD,
- NULL, NULL);
+ if (no_deref) {
+ flag |= TFN_NO_DEREF;
+ }
+ char *const p = (char *)trans_function_name((char_u **)&nm, false, flag, NULL,
+ NULL);
nm = skipwhite(nm);
/* Only accept "funcname", "funcname ", "funcname (..." and
* "funcname(...", not "funcname!...". */
- if (p != NULL && (*nm == NUL || *nm == '('))
+ if (p != NULL && (*nm == NUL || *nm == '(')) {
n = translated_function_exists(p);
+ }
xfree(p);
return n;
}
-/// Return TRUE if "name" looks like a builtin function name: starts with a
+/// Checks if a builtin function with the given name exists.
+///
+/// @param[in] name name of the builtin function to check.
+/// @param[in] len length of "name", or -1 for NUL terminated.
+///
+/// @return true if "name" looks like a builtin function name: starts with a
/// lower case letter and doesn't contain AUTOLOAD_CHAR.
-/// "len" is the length of "name", or -1 for NUL terminated.
-static bool builtin_function(char_u *name, int len)
+static bool builtin_function(const char *name, int len)
{
if (!ASCII_ISLOWER(name[0])) {
- return FALSE;
+ return false;
}
- char_u *p = vim_strchr(name, AUTOLOAD_CHAR);
+ const char *p = (len == -1
+ ? strchr(name, AUTOLOAD_CHAR)
+ : memchr(name, AUTOLOAD_CHAR, (size_t)len));
- return p == NULL
- || (len > 0 && p > name + len);
+ return p == NULL;
}
/*
@@ -21491,44 +20745,45 @@ static int prof_self_cmp(const void *s1, const void *s2)
}
-/*
- * If "name" has a package name try autoloading the script for it.
- * Return TRUE if a package was loaded.
- */
-static int
-script_autoload (
- char_u *name,
- int reload /* load script again when already loaded */
-)
+/// If name has a package name try autoloading the script for it
+///
+/// @param[in] name Variable/function name.
+/// @param[in] name_len Name length.
+/// @param[in] reload If true, load script again when already loaded.
+///
+/// @return true if a package was loaded.
+static bool script_autoload(const char *const name, const size_t name_len,
+ const bool reload)
{
- char_u *p;
- char_u *scriptname, *tofree;
- int ret = FALSE;
- int i;
-
- /* If there is no '#' after name[0] there is no package name. */
- p = vim_strchr(name, AUTOLOAD_CHAR);
- if (p == NULL || p == name)
- return FALSE;
+ // If there is no '#' after name[0] there is no package name.
+ const char *p = memchr(name, AUTOLOAD_CHAR, name_len);
+ if (p == NULL || p == name) {
+ return false;
+ }
- tofree = scriptname = autoload_name(name);
+ bool ret = false;
+ char *tofree = autoload_name(name, name_len);
+ char *scriptname = tofree;
- /* Find the name in the list of previously loaded package names. Skip
- * "autoload/", it's always the same. */
- for (i = 0; i < ga_loaded.ga_len; ++i)
- if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0)
+ // Find the name in the list of previously loaded package names. Skip
+ // "autoload/", it's always the same.
+ int i = 0;
+ for (; i < ga_loaded.ga_len; i++) {
+ if (STRCMP(((char **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) {
break;
- if (!reload && i < ga_loaded.ga_len)
- ret = FALSE; /* was loaded already */
- else {
- /* Remember the name if it wasn't loaded already. */
+ }
+ }
+ if (!reload && i < ga_loaded.ga_len) {
+ ret = false; // Was loaded already.
+ } else {
+ // Remember the name if it wasn't loaded already.
if (i == ga_loaded.ga_len) {
- GA_APPEND(char_u *, &ga_loaded, scriptname);
+ GA_APPEND(char *, &ga_loaded, scriptname);
tofree = NULL;
}
// Try loading the package from $VIMRUNTIME/autoload/<name>.vim
- if (source_runtime(scriptname, 0) == OK) {
+ if (source_runtime((char_u *)scriptname, 0) == OK) {
ret = true;
}
}
@@ -21537,21 +20792,29 @@ script_autoload (
return ret;
}
-/*
- * Return the autoload script name for a function or variable name.
- */
-static char_u *autoload_name(char_u *name)
+/// Return the autoload script name for a function or variable name
+///
+/// @param[in] name Variable/function name.
+/// @param[in] name_len Name length.
+///
+/// @return [allocated] autoload script name.
+static char *autoload_name(const char *const name, const size_t name_len)
+ FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
{
- /* Get the script file name: replace '#' with '/', append ".vim". */
- char_u *scriptname = xmalloc(STRLEN(name) + 14);
- STRCPY(scriptname, "autoload/");
- STRCAT(scriptname, name);
- *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL;
- STRCAT(scriptname, ".vim");
-
- char_u *p;
- while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL)
- *p = '/';
+ // Get the script file name: replace '#' with '/', append ".vim".
+ char *const scriptname = xmalloc(name_len + sizeof("autoload/.vim"));
+ memcpy(scriptname, "autoload/", sizeof("autoload/") - 1);
+ memcpy(scriptname + sizeof("autoload/") - 1, name, name_len);
+ size_t auchar_idx = 0;
+ for (size_t i = sizeof("autoload/") - 1;
+ i - sizeof("autoload/") + 1 < name_len;
+ i++) {
+ if (scriptname[i] == AUTOLOAD_CHAR) {
+ scriptname[i] = '/';
+ auchar_idx = i;
+ }
+ }
+ memcpy(scriptname + auchar_idx, ".vim", sizeof(".vim"));
return scriptname;
}
@@ -21579,8 +20842,10 @@ char_u *get_user_func_name(expand_T *xp, int idx)
++hi;
fp = HI2UF(hi);
- if (fp->uf_flags & FC_DICT)
- return (char_u *)""; /* don't show dict functions */
+ if ((fp->uf_flags & FC_DICT)
+ || STRNCMP(fp->uf_name, "<lambda>", 8) == 0) {
+ return (char_u *)""; // don't show dict and lambda functions
+ }
if (STRLEN(fp->uf_name) + 4 >= IOSIZE)
return fp->uf_name; /* prevents overflow */
@@ -21611,9 +20876,18 @@ static void cat_func_name(char_u *buf, ufunc_T *fp)
STRCPY(buf, fp->uf_name);
}
-/*
- * ":delfunction {name}"
- */
+/// There are two kinds of function names:
+/// 1. ordinary names, function defined with :function
+/// 2. numbered functions and lambdas
+/// For the first we only count the name stored in func_hashtab as a reference,
+/// using function() does not count as a reference, because the function is
+/// looked up by name.
+static bool func_name_refcount(char_u *name)
+{
+ return isdigit(*name) || *name == '<';
+}
+
+/// ":delfunction {name}"
void ex_delfunction(exarg_T *eap)
{
ufunc_T *fp = NULL;
@@ -21660,102 +20934,172 @@ void ex_delfunction(exarg_T *eap)
}
if (fudi.fd_dict != NULL) {
- /* Delete the dict item that refers to the function, it will
- * invoke func_unref() and possibly delete the function. */
- dictitem_remove(fudi.fd_dict, fudi.fd_di);
- } else
- func_free(fp);
+ // Delete the dict item that refers to the function, it will
+ // invoke func_unref() and possibly delete the function.
+ tv_dict_item_remove(fudi.fd_dict, fudi.fd_di);
+ } else {
+ // A normal function (not a numbered function or lambda) has a
+ // refcount of 1 for the entry in the hashtable. When deleting
+ // it and the refcount is more than one, it should be kept.
+ // A numbered function or lambda should be kept if the refcount is
+ // one or more.
+ if (fp->uf_refcount > (func_name_refcount(fp->uf_name) ? 0 : 1)) {
+ // Function is still referenced somewhere. Don't free it but
+ // do remove it from the hashtable.
+ if (func_remove(fp)) {
+ fp->uf_refcount--;
+ }
+ fp->uf_flags |= FC_DELETED;
+ } else {
+ func_clear_free(fp, false);
+ }
+ }
}
}
-/*
- * Free a function and remove it from the list of functions.
- */
-static void func_free(ufunc_T *fp)
+/// Remove the function from the function hashtable. If the function was
+/// deleted while it still has references this was already done.
+///
+/// @return true if the entry was deleted, false if it wasn't found.
+static bool func_remove(ufunc_T *fp)
{
- hashitem_T *hi;
+ hashitem_T *hi = hash_find(&func_hashtab, UF2HIKEY(fp));
+
+ if (!HASHITEM_EMPTY(hi)) {
+ hash_remove(&func_hashtab, hi);
+ return true;
+ }
+
+ return false;
+}
- /* clear this function */
+/// Free all things that a function contains. Does not free the function
+/// itself, use func_free() for that.
+///
+/// param[in] force When true, we are exiting.
+static void func_clear(ufunc_T *fp, bool force)
+{
+ if (fp->uf_cleared) {
+ return;
+ }
+ fp->uf_cleared = true;
+
+ // clear this function
ga_clear_strings(&(fp->uf_args));
ga_clear_strings(&(fp->uf_lines));
xfree(fp->uf_tml_count);
xfree(fp->uf_tml_total);
xfree(fp->uf_tml_self);
+ funccal_unref(fp->uf_scoped, fp, force);
+}
- /* remove the function from the function hashtable */
- hi = hash_find(&func_hashtab, UF2HIKEY(fp));
- if (HASHITEM_EMPTY(hi))
- EMSG2(_(e_intern2), "func_free()");
- else
- hash_remove(&func_hashtab, hi);
-
+/// Free a function and remove it from the list of functions. Does not free
+/// what a function contains, call func_clear() first.
+///
+/// param[in] fp The function to free.
+static void func_free(ufunc_T *fp)
+{
+ // only remove it when not done already, otherwise we would remove a newer
+ // version of the function
+ if ((fp->uf_flags & (FC_DELETED | FC_REMOVED)) == 0) {
+ func_remove(fp);
+ }
xfree(fp);
}
+/// Free all things that a function contains and free the function itself.
+///
+/// param[in] force When true, we are exiting.
+static void func_clear_free(ufunc_T *fp, bool force)
+{
+ func_clear(fp, force);
+ func_free(fp);
+}
+
/*
* Unreference a Function: decrement the reference count and free it when it
- * becomes zero. Only for numbered functions.
+ * becomes zero.
*/
void func_unref(char_u *name)
{
- ufunc_T *fp;
+ ufunc_T *fp = NULL;
- if (name != NULL && isdigit(*name)) {
- fp = find_func(name);
- if (fp == NULL) {
+ if (name == NULL || !func_name_refcount(name)) {
+ return;
+ }
+
+ fp = find_func(name);
+ if (fp == NULL && isdigit(*name)) {
#ifdef EXITFREE
- if (!entered_free_all_mem) {
- EMSG2(_(e_intern2), "func_unref()");
- }
+ if (!entered_free_all_mem) {
+ EMSG2(_(e_intern2), "func_unref()");
+ abort();
+ }
#else
EMSG2(_(e_intern2), "func_unref()");
+ abort();
#endif
- } else {
- user_func_unref(fp);
- }
}
+ func_ptr_unref(fp);
}
-static void user_func_unref(ufunc_T *fp)
+/// Unreference a Function: decrement the reference count and free it when it
+/// becomes zero.
+/// Unreference user function, freeing it if needed
+///
+/// Decrements the reference count and frees when it becomes zero.
+///
+/// @param fp Function to unreference.
+void func_ptr_unref(ufunc_T *fp)
{
- if (--fp->uf_refcount <= 0) {
- // Only delete it when it's not being used. Otherwise it's done
+ if (fp != NULL && --fp->uf_refcount <= 0) {
+ // Only delete it when it's not being used. Otherwise it's done
// when "uf_calls" becomes zero.
if (fp->uf_calls == 0) {
- func_free(fp);
+ func_clear_free(fp, false);
}
}
}
-/*
- * Count a reference to a Function.
- */
+/// Count a reference to a Function.
void func_ref(char_u *name)
{
ufunc_T *fp;
- if (name != NULL && isdigit(*name)) {
- fp = find_func(name);
- if (fp == NULL)
- EMSG2(_(e_intern2), "func_ref()");
- else
- ++fp->uf_refcount;
+ if (name == NULL || !func_name_refcount(name)) {
+ return;
+ }
+ fp = find_func(name);
+ if (fp != NULL) {
+ (fp->uf_refcount)++;
+ } else if (isdigit(*name)) {
+ // Only give an error for a numbered function.
+ // Fail silently, when named or lambda function isn't found.
+ EMSG2(_(e_intern2), "func_ref()");
}
}
-/*
- * Call a user function.
- */
-static void
-call_user_func (
- ufunc_T *fp, /* pointer to function */
- int argcount, /* nr of args */
- typval_T *argvars, /* arguments */
- typval_T *rettv, /* return value */
- linenr_T firstline, /* first line of range */
- linenr_T lastline, /* last line of range */
- dict_T *selfdict /* Dictionary for "self" */
-)
+/// Count a reference to a Function.
+void func_ptr_ref(ufunc_T *fp)
+{
+ if (fp != NULL) {
+ (fp->uf_refcount)++;
+ }
+}
+
+/// Call a user function
+///
+/// @param fp Function to call.
+/// @param[in] argcount Number of arguments.
+/// @param argvars Arguments.
+/// @param[out] rettv Return value.
+/// @param[in] firstline First line of range.
+/// @param[in] lastline Last line of range.
+/// @param selfdict Dictionary for "self" for dictionary functions.
+void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
+ typval_T *rettv, linenr_T firstline, linenr_T lastline,
+ dict_T *selfdict)
+ FUNC_ATTR_NONNULL_ARG(1, 3, 4)
{
char_u *save_sourcing_name;
linenr_T save_sourcing_lnum;
@@ -21766,6 +21110,7 @@ call_user_func (
dictitem_T *v;
int fixvar_idx = 0; /* index in fixvar[] */
int ai;
+ bool islambda = false;
char_u numbuf[NUMBUFLEN];
char_u *name;
proftime_T wait_start;
@@ -21803,25 +21148,32 @@ call_user_func (
fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0);
fc->dbg_tick = debug_tick;
- /*
- * Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables
- * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free
- * each argument variable and saves a lot of time.
- */
- /*
- * Init l: variables.
- */
+ // Set up fields for closure.
+ fc->fc_refcount = 0;
+ fc->fc_copyID = 0;
+ ga_init(&fc->fc_funcs, sizeof(ufunc_T *), 1);
+ func_ptr_ref(fp);
+
+ if (STRNCMP(fp->uf_name, "<lambda>", 8) == 0) {
+ islambda = true;
+ }
+
+ // Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables
+ // with names up to VAR_SHORT_LEN long. This avoids having to alloc/free
+ // each argument variable and saves a lot of time.
+ //
+ // Init l: variables.
init_var_dict(&fc->l_vars, &fc->l_vars_var, VAR_DEF_SCOPE);
if (selfdict != NULL) {
- /* Set l:self to "selfdict". Use "name" to avoid a warning from
- * some compiler that checks the destination size. */
- v = &fc->fixvar[fixvar_idx++].var;
+ // Set l:self to "selfdict". Use "name" to avoid a warning from
+ // some compiler that checks the destination size.
+ v = (dictitem_T *)&fc->fixvar[fixvar_idx++];
#ifndef __clang_analyzer__
name = v->di_key;
STRCPY(name, "self");
#endif
v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX;
- hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v));
+ tv_dict_add(&fc->l_vars, v);
v->di_tv.v_type = VAR_DICT;
v->di_tv.v_lock = 0;
v->di_tv.vval.v_dict = selfdict;
@@ -21834,17 +21186,17 @@ call_user_func (
* Set a:000 to a list with room for the "..." arguments.
*/
init_var_dict(&fc->l_avars, &fc->l_avars_var, VAR_SCOPE);
- add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0",
- (varnumber_T)(argcount - fp->uf_args.ga_len));
- /* Use "name" to avoid a warning from some compiler that checks the
- * destination size. */
- v = &fc->fixvar[fixvar_idx++].var;
+ add_nr_var(&fc->l_avars, (dictitem_T *)&fc->fixvar[fixvar_idx++], "0",
+ (varnumber_T)(argcount - fp->uf_args.ga_len));
+ // Use "name" to avoid a warning from some compiler that checks the
+ // destination size.
+ v = (dictitem_T *)&fc->fixvar[fixvar_idx++];
#ifndef __clang_analyzer__
name = v->di_key;
STRCPY(name, "000");
#endif
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
- hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v));
+ tv_dict_add(&fc->l_avars, v);
v->di_tv.v_type = VAR_LIST;
v->di_tv.v_lock = VAR_FIXED;
v->di_tv.vval.v_list = &fc->l_varlist;
@@ -21852,42 +21204,53 @@ call_user_func (
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 (int i = 0; i < argcount; ++i) {
+ // Set a:firstline to "firstline" and a:lastline to "lastline".
+ // Set a:name to named arguments.
+ // Set a:N to the "..." arguments.
+ add_nr_var(&fc->l_avars, (dictitem_T *)&fc->fixvar[fixvar_idx++],
+ "firstline", (varnumber_T)firstline);
+ add_nr_var(&fc->l_avars, (dictitem_T *)&fc->fixvar[fixvar_idx++],
+ "lastline", (varnumber_T)lastline);
+ for (int i = 0; i < argcount; i++) {
+ bool addlocal = false;
+
ai = i - fp->uf_args.ga_len;
- if (ai < 0)
- /* named argument a:name */
+ if (ai < 0) {
+ // named argument a:name
name = FUNCARG(fp, i);
- else {
- /* "..." argument a:1, a:2, etc. */
- sprintf((char *)numbuf, "%d", ai + 1);
+ if (islambda) {
+ addlocal = true;
+ }
+ } else {
+ // "..." argument a:1, a:2, etc.
+ snprintf((char *)numbuf, sizeof(numbuf), "%d", ai + 1);
name = numbuf;
}
if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) {
- v = &fc->fixvar[fixvar_idx++].var;
+ v = (dictitem_T *)&fc->fixvar[fixvar_idx++];
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
} else {
v = xmalloc(sizeof(dictitem_T) + STRLEN(name));
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX | DI_FLAGS_ALLOC;
}
STRCPY(v->di_key, name);
- hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v));
- /* Note: the values are copied directly to avoid alloc/free.
- * "argvars" must have VAR_FIXED for v_lock. */
+ // Note: the values are copied directly to avoid alloc/free.
+ // "argvars" must have VAR_FIXED for v_lock.
v->di_tv = argvars[i];
v->di_tv.v_lock = VAR_FIXED;
+ if (addlocal) {
+ // Named arguments can be accessed without the "a:" prefix in lambda
+ // expressions. Add to the l: dict.
+ tv_copy(&v->di_tv, &v->di_tv);
+ tv_dict_add(&fc->l_vars, v);
+ } else {
+ tv_dict_add(&fc->l_avars, v);
+ }
+
if (ai >= 0 && ai < MAX_FUNC_ARGS) {
- list_append(&fc->l_varlist, &fc->l_listitems[ai]);
+ tv_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;
}
@@ -21925,24 +21288,24 @@ call_user_func (
smsg(_("calling %s"), sourcing_name);
if (p_verbose >= 14) {
- char_u buf[MSG_BUF_LEN];
-
- msg_puts((char_u *)"(");
- for (int i = 0; i < argcount; ++i) {
+ msg_puts("(");
+ for (int i = 0; i < argcount; i++) {
if (i > 0) {
- msg_puts((char_u *)", ");
+ msg_puts(", ");
}
if (argvars[i].v_type == VAR_NUMBER) {
msg_outnum((long)argvars[i].vval.v_number);
} else {
// Do not want errors such as E724 here.
emsg_off++;
- char_u *s = (char_u *) encode_tv2string(&argvars[i], NULL);
- char_u *tofree = s;
+ char *tofree = encode_tv2string(&argvars[i], NULL);
emsg_off--;
- if (s != NULL) {
- if (vim_strsize(s) > MSG_BUF_CLEN) {
- trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
+ if (tofree != NULL) {
+ char *s = tofree;
+ char buf[MSG_BUF_LEN];
+ if (vim_strsize((char_u *)s) > MSG_BUF_CLEN) {
+ trunc_string((char_u *)s, (char_u *)buf, MSG_BUF_CLEN,
+ sizeof(buf));
s = buf;
}
msg_puts(s);
@@ -21950,9 +21313,9 @@ call_user_func (
}
}
}
- msg_puts((char_u *)")");
+ msg_puts(")");
}
- msg_puts((char_u *)"\n"); /* don't overwrite this either */
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
--no_wait_return;
@@ -21995,14 +21358,14 @@ call_user_func (
// when the function was aborted because of an error, return -1
if ((did_emsg
&& (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) {
- clear_tv(rettv);
+ tv_clear(rettv);
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = -1;
}
if (func_or_func_caller_profiling) {
call_start = profile_end(call_start);
- call_start = profile_sub_wait(wait_start, call_start);
+ call_start = profile_sub_wait(wait_start, call_start); // -V614
fp->uf_tm_total = profile_add(fp->uf_tm_total, call_start);
fp->uf_tm_self = profile_self(fp->uf_tm_self, call_start,
fp->uf_tm_children);
@@ -22043,7 +21406,7 @@ call_user_func (
xfree(tofree);
}
}
- msg_puts((char_u *)"\n"); /* don't overwrite this either */
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
--no_wait_return;
@@ -22061,7 +21424,7 @@ call_user_func (
verbose_enter_scroll();
smsg(_("continuing in %s"), sourcing_name);
- msg_puts((char_u *)"\n"); /* don't overwrite this either */
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
--no_wait_return;
@@ -22071,41 +21434,35 @@ call_user_func (
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 the a:000 list and the l: and a: dicts are not referenced and there
+ // is no closure using it, we can free the funccall_T and what's in it.
if (fc->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);
+ && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT
+ && fc->fc_refcount <= 0) {
+ 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" is still in use. This can happen when returning "a:000",
+ // assigning "l:" to a global variable or defining a closure.
+ // Link "fc" in the list for garbage collection later.
fc->caller = previous_funccal;
previous_funccal = fc;
- /* Make a copy of the a: variables, since we didn't do that above. */
- 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: variables, since we didn't do that above.
+ TV_DICT_ITER(&fc->l_avars, di, {
+ tv_copy(&di->di_tv, &di->di_tv);
+ });
- /* Make a copy of the a:000 items, since we didn't do that above. */
- for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next)
- copy_tv(&li->li_tv, &li->li_tv);
+ // Make a copy of the a:000 items, since we didn't do that above.
+ for (listitem_T *li = fc->l_varlist.lv_first; li != NULL;
+ li = li->li_next) {
+ tv_copy(&li->li_tv, &li->li_tv);
+ }
}
- if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) && fp->uf_refcount <= 0) {
+ if (--fp->uf_calls <= 0 && fp->uf_refcount <= 0) {
// Function was unreferenced while being used, free it now.
- func_free(fp);
+ func_clear_free(fp, false);
}
// restore search patterns and redo buffer
if (did_save_redo) {
@@ -22114,15 +21471,46 @@ call_user_func (
restore_search_patterns();
}
-/*
- * Return TRUE if items in "fc" do not have "copyID". That means they are not
- * referenced from anywhere that is in use.
- */
+/// Unreference "fc": decrement the reference count and free it when it
+/// becomes zero. "fp" is detached from "fc".
+///
+/// @param[in] force When true, we are exiting.
+static void funccal_unref(funccall_T *fc, ufunc_T *fp, bool force)
+{
+ funccall_T **pfc;
+ int i;
+
+ if (fc == NULL) {
+ return;
+ }
+
+ if (--fc->fc_refcount <= 0 && (force || (
+ 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))) {
+ for (pfc = &previous_funccal; *pfc != NULL; pfc = &(*pfc)->caller) {
+ if (fc == *pfc) {
+ *pfc = fc->caller;
+ free_funccal(fc, true);
+ return;
+ }
+ }
+ }
+ for (i = 0; i < fc->fc_funcs.ga_len; i++) {
+ if (((ufunc_T **)(fc->fc_funcs.ga_data))[i] == fp) {
+ ((ufunc_T **)(fc->fc_funcs.ga_data))[i] = NULL;
+ }
+ }
+}
+
+/// @return true if items in "fc" do not have "copyID". That means they are not
+/// referenced from anywhere that is in use.
static int can_free_funccal(funccall_T *fc, int copyID)
{
return fc->l_varlist.lv_copyID != copyID
&& fc->l_vars.dv_copyID != copyID
- && fc->l_avars.dv_copyID != copyID;
+ && fc->l_avars.dv_copyID != copyID
+ && fc->fc_copyID != copyID;
}
/*
@@ -22136,18 +21524,34 @@ free_funccal (
{
listitem_T *li;
- /* The a: variables typevals may not have been allocated, only free the
- * allocated variables. */
+ for (int i = 0; i < fc->fc_funcs.ga_len; i++) {
+ ufunc_T *fp = ((ufunc_T **)(fc->fc_funcs.ga_data))[i];
+
+ // When garbage collecting a funccall_T may be freed before the
+ // function that references it, clear its uf_scoped field.
+ // The function may have been redefined and point to another
+ // funccal_T, don't clear it then.
+ if (fp != NULL && fp->uf_scoped == fc) {
+ fp->uf_scoped = NULL;
+ }
+ }
+ ga_clear(&fc->fc_funcs);
+
+ // The a: variables typevals may not have been allocated, only free the
+ // allocated variables.
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);
+ // 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) {
+ tv_clear(&li->li_tv);
+ }
+ }
+ func_ptr_unref(fc->func);
xfree(fc);
}
@@ -22160,7 +21564,7 @@ static void add_nr_var(dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)
STRCPY(v->di_key, name);
#endif
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
- hash_add(&dp->dv_hashtab, DI2HIKEY(v));
+ tv_dict_add(dp, v);
v->di_tv.v_type = VAR_NUMBER;
v->di_tv.v_lock = VAR_FIXED;
v->di_tv.vval.v_number = nr;
@@ -22186,10 +21590,11 @@ void ex_return(exarg_T *eap)
eap->nextcmd = NULL;
if ((*arg != NUL && *arg != '|' && *arg != '\n')
&& eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) {
- if (!eap->skip)
- returning = do_return(eap, FALSE, TRUE, &rettv);
- else
- clear_tv(&rettv);
+ if (!eap->skip) {
+ returning = do_return(eap, false, true, &rettv);
+ } else {
+ tv_clear(&rettv);
+ }
}
/* It's safer to return also on error. */
else if (!eap->skip) {
@@ -22276,7 +21681,7 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
* a return immediately after reanimation, the value is already
* there. */
if (!reanimate && rettv != NULL) {
- clear_tv(current_funccal->rettv);
+ tv_clear(current_funccal->rettv);
*current_funccal->rettv = *(typval_T *)rettv;
if (!is_cmd)
xfree(rettv);
@@ -22287,14 +21692,6 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
}
/*
- * Free the variable with a pending return value.
- */
-void discard_pending_return(void *rettv)
-{
- free_tv((typval_T *)rettv);
-}
-
-/*
* Generate a return command for producing the value of "rettv". The result
* is an allocated string. Used by report_pending() for verbose messages.
*/
@@ -22311,7 +21708,7 @@ char_u *get_return_cmd(void *rettv)
}
STRCPY(IObuff, ":return ");
- STRNCPY(IObuff + 8, s, IOSIZE - 8);
+ STRLCPY(IObuff + 8, s, IOSIZE - 8);
if (STRLEN(s) + 8 >= IOSIZE)
STRCPY(IObuff + IOSIZE - 4, "...");
xfree(tofree);
@@ -22466,6 +21863,72 @@ static var_flavour_T var_flavour(char_u *varname)
}
}
+/// Search hashitem in parent scope.
+hashitem_T *find_hi_in_scoped_ht(const char *name, hashtab_T **pht)
+{
+ if (current_funccal == NULL || current_funccal->func->uf_scoped == NULL) {
+ return NULL;
+ }
+
+ funccall_T *old_current_funccal = current_funccal;
+ hashitem_T *hi = NULL;
+ const size_t namelen = strlen(name);
+ const char *varname;
+
+ // Search in parent scope which is possible to reference from lambda
+ current_funccal = current_funccal->func->uf_scoped;
+ while (current_funccal != NULL) {
+ hashtab_T *ht = find_var_ht(name, namelen, &varname);
+ if (ht != NULL && *varname != NUL) {
+ hi = hash_find_len(ht, varname, namelen - (varname - name));
+ if (!HASHITEM_EMPTY(hi)) {
+ *pht = ht;
+ break;
+ }
+ }
+ if (current_funccal == current_funccal->func->uf_scoped) {
+ break;
+ }
+ current_funccal = current_funccal->func->uf_scoped;
+ }
+ current_funccal = old_current_funccal;
+
+ return hi;
+}
+
+/// Search variable in parent scope.
+dictitem_T *find_var_in_scoped_ht(const char *name, const size_t namelen,
+ int no_autoload)
+{
+ if (current_funccal == NULL || current_funccal->func->uf_scoped == NULL) {
+ return NULL;
+ }
+
+ dictitem_T *v = NULL;
+ funccall_T *old_current_funccal = current_funccal;
+ const char *varname;
+
+ // Search in parent scope which is possible to reference from lambda
+ current_funccal = current_funccal->func->uf_scoped;
+ while (current_funccal) {
+ hashtab_T *ht = find_var_ht(name, namelen, &varname);
+ if (ht != NULL && *varname != NUL) {
+ v = find_var_in_ht(ht, *name, varname,
+ namelen - (size_t)(varname - name), no_autoload);
+ if (v != NULL) {
+ break;
+ }
+ }
+ if (current_funccal == current_funccal->func->uf_scoped) {
+ break;
+ }
+ current_funccal = current_funccal->func->uf_scoped;
+ }
+ current_funccal = old_current_funccal;
+
+ return v;
+}
+
/// Iterate over global variables
///
/// @warning No modifications to global variable dictionary must be performed
@@ -22489,7 +21952,7 @@ const void *var_shada_iter(const void *const iter, const char **const name,
hi = globvarht.ht_array;
while ((size_t) (hi - hifirst) < hinum
&& (HASHITEM_EMPTY(hi)
- || var_flavour(HI2DI(hi)->di_key) != VAR_FLAVOUR_SHADA)) {
+ || var_flavour(hi->hi_key) != VAR_FLAVOUR_SHADA)) {
hi++;
}
if ((size_t) (hi - hifirst) == hinum) {
@@ -22498,11 +21961,10 @@ const void *var_shada_iter(const void *const iter, const char **const name,
} else {
hi = (const hashitem_T *) iter;
}
- *name = (char *) HI2DI(hi)->di_key;
- copy_tv(&(HI2DI(hi)->di_tv), rettv);
- while ((size_t) (++hi - hifirst) < hinum) {
- if (!HASHITEM_EMPTY(hi)
- && var_flavour(HI2DI(hi)->di_key) == VAR_FLAVOUR_SHADA) {
+ *name = (char *)TV_DICT_HI2DI(hi)->di_key;
+ tv_copy(&TV_DICT_HI2DI(hi)->di_tv, rettv);
+ while ((size_t)(++hi - hifirst) < hinum) {
+ if (!HASHITEM_EMPTY(hi) && var_flavour(hi->hi_key) == VAR_FLAVOUR_SHADA) {
return hi;
}
}
@@ -22513,62 +21975,55 @@ void var_set_global(const char *const name, typval_T vartv)
{
funccall_T *const saved_current_funccal = current_funccal;
current_funccal = NULL;
- set_var((char_u *) name, &vartv, false);
+ set_var(name, strlen(name), &vartv, false);
current_funccal = saved_current_funccal;
}
int store_session_globals(FILE *fd)
{
- hashitem_T *hi;
- dictitem_T *this_var;
- int todo;
- char_u *p, *t;
-
- todo = (int)globvarht.ht_used;
- for (hi = globvarht.ht_array; todo > 0; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- --todo;
- this_var = HI2DI(hi);
- if ((this_var->di_tv.v_type == VAR_NUMBER
- || this_var->di_tv.v_type == VAR_STRING)
- && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) {
- /* Escape special characters with a backslash. Turn a LF and
- * CR into \n and \r. */
- p = vim_strsave_escaped(get_tv_string(&this_var->di_tv),
- (char_u *)"\\\"\n\r");
- for (t = p; *t != NUL; ++t)
- if (*t == '\n')
- *t = 'n';
- else if (*t == '\r')
- *t = 'r';
- if ((fprintf(fd, "let %s = %c%s%c",
- this_var->di_key,
- (this_var->di_tv.v_type == VAR_STRING) ? '"'
- : ' ',
- p,
- (this_var->di_tv.v_type == VAR_STRING) ? '"'
- : ' ') < 0)
- || put_eol(fd) == FAIL) {
- xfree(p);
- return FAIL;
+ TV_DICT_ITER(&globvardict, this_var, {
+ if ((this_var->di_tv.v_type == VAR_NUMBER
+ || this_var->di_tv.v_type == VAR_STRING)
+ && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) {
+ // Escape special characters with a backslash. Turn a LF and
+ // CR into \n and \r.
+ char_u *const p = vim_strsave_escaped(
+ (const char_u *)tv_get_string(&this_var->di_tv),
+ (const char_u *)"\\\"\n\r");
+ for (char_u *t = p; *t != NUL; t++) {
+ if (*t == '\n') {
+ *t = 'n';
+ } else if (*t == '\r') {
+ *t = 'r';
}
+ }
+ if ((fprintf(fd, "let %s = %c%s%c",
+ this_var->di_key,
+ ((this_var->di_tv.v_type == VAR_STRING) ? '"'
+ : ' '),
+ p,
+ ((this_var->di_tv.v_type == VAR_STRING) ? '"'
+ : ' ')) < 0)
+ || put_eol(fd) == FAIL) {
xfree(p);
- } else if (this_var->di_tv.v_type == VAR_FLOAT
- && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) {
- float_T f = this_var->di_tv.vval.v_float;
- int sign = ' ';
-
- if (f < 0) {
- f = -f;
- sign = '-';
- }
- if ((fprintf(fd, "let %s = %c%f",
- this_var->di_key, sign, f) < 0)
- || put_eol(fd) == FAIL)
- return FAIL;
+ return FAIL;
+ }
+ xfree(p);
+ } else if (this_var->di_tv.v_type == VAR_FLOAT
+ && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) {
+ float_T f = this_var->di_tv.vval.v_float;
+ int sign = ' ';
+
+ if (f < 0) {
+ f = -f;
+ sign = '-';
+ }
+ if ((fprintf(fd, "let %s = %c%f", this_var->di_key, sign, f) < 0)
+ || put_eol(fd) == FAIL) {
+ return FAIL;
}
}
- }
+ });
return OK;
}
@@ -22588,51 +22043,6 @@ void last_set_msg(scid_T scriptID)
}
}
-/*
- * List v:oldfiles in a nice way.
- */
-void ex_oldfiles(exarg_T *eap)
-{
- list_T *l = get_vim_var_list(VV_OLDFILES);
- listitem_T *li;
- long nr = 0;
-
- if (l == NULL)
- msg((char_u *)_("No old files"));
- else {
- msg_start();
- msg_scroll = TRUE;
- for (li = l->lv_first; li != NULL && !got_int; li = li->li_next) {
- msg_outnum(++nr);
- MSG_PUTS(": ");
- msg_outtrans(get_tv_string(&li->li_tv));
- msg_putchar('\n');
- ui_flush(); /* output one line at a time */
- os_breakcheck();
- }
- /* Assume "got_int" was set to truncate the listing. */
- got_int = FALSE;
-
- // File selection prompt on ":browse oldfiles"
- if (cmdmod.browse) {
- quit_more = false;
- nr = prompt_for_number(false);
- msg_starthere();
- if (nr > 0 && nr <= l->lv_len) {
- char_u *p = list_find_str(l, nr);
- if (p == NULL) {
- return;
- }
- p = expand_env_save(p);
- eap->arg = p;
- eap->cmdidx = CMD_edit;
- do_exedit(eap, NULL);
- xfree(p);
- }
- }
- }
-}
-
// reset v:option_new, v:option_old and v:option_type
void reset_v_option_vars(void)
{
@@ -22865,7 +22275,7 @@ repeat:
sub = vim_strnsave(s, (int)(p - s));
str = vim_strnsave(*fnamep, *fnamelen);
*usedlen = (size_t)(p + 1 - src);
- s = do_string_sub(str, pat, sub, flags);
+ s = do_string_sub(str, pat, sub, NULL, flags);
*fnamep = s;
*fnamelen = STRLEN(s);
xfree(*bufp);
@@ -22901,12 +22311,12 @@ repeat:
return valid;
}
-/*
- * Perform a substitution on "str" with pattern "pat" and substitute "sub".
- * "flags" can be "g" to do a global substitute.
- * Returns an allocated string, NULL for error.
- */
-char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, char_u *flags)
+/// Perform a substitution on "str" with pattern "pat" and substitute "sub".
+/// When "sub" is NULL "expr" is used, must be a VAR_FUNC or VAR_PARTIAL.
+/// "flags" can be "g" to do a global substitute.
+/// Returns an allocated string, NULL for error.
+char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub,
+ typval_T *expr, char_u *flags)
{
int sublen;
regmatch_T regmatch;
@@ -22944,23 +22354,21 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, char_u *flags)
zero_width = regmatch.startp[0];
}
- /*
- * Get some space for a temporary buffer to do the substitution
- * into. It will contain:
- * - The text up to where the match is.
- * - The substituted text.
- * - The text after the match.
- */
- sublen = vim_regsub(&regmatch, sub, tail, FALSE, TRUE, FALSE);
+ // Get some space for a temporary buffer to do the substitution
+ // into. It will contain:
+ // - The text up to where the match is.
+ // - The substituted text.
+ // - The text after the match.
+ sublen = vim_regsub(&regmatch, sub, expr, tail, false, true, false);
ga_grow(&ga, (int)((end - tail) + sublen -
(regmatch.endp[0] - regmatch.startp[0])));
/* copy the text up to where the match is */
int i = (int)(regmatch.startp[0] - tail);
memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i);
- /* add the substituted text */
- (void)vim_regsub(&regmatch, sub, (char_u *)ga.ga_data
- + ga.ga_len + i, TRUE, TRUE, FALSE);
+ // add the substituted text
+ (void)vim_regsub(&regmatch, sub, expr, (char_u *)ga.ga_data
+ + ga.ga_len + i, true, true, false);
ga.ga_len += i + sublen - 1;
tail = regmatch.endp[0];
if (*tail == NUL)
@@ -22977,11 +22385,12 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, char_u *flags)
char_u *ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data);
ga_clear(&ga);
- if (p_cpo == empty_option)
+ if (p_cpo == empty_option) {
p_cpo = save_cpo;
- else
- /* Darn, evaluating {sub} expression changed the value. */
+ } else {
+ // Darn, evaluating {sub} expression or {expr} changed the value.
free_string_option(save_cpo);
+ }
return ret;
}
@@ -22993,7 +22402,7 @@ static inline TerminalJobData *common_job_init(char **argv,
bool pty,
bool rpc,
bool detach,
- char *cwd)
+ const char *cwd)
{
TerminalJobData *data = xcalloc(1, sizeof(TerminalJobData));
data->stopped = false;
@@ -23027,9 +22436,9 @@ static inline TerminalJobData *common_job_init(char **argv,
static inline bool common_job_callbacks(dict_T *vopts, Callback *on_stdout,
Callback *on_stderr, Callback *on_exit)
{
- if (get_dict_callback(vopts, "on_stdout", on_stdout)
- && get_dict_callback(vopts, "on_stderr", on_stderr)
- && get_dict_callback(vopts, "on_exit", on_exit)) {
+ if (tv_dict_get_callback(vopts, S_LEN("on_stdout"), on_stdout)
+ &&tv_dict_get_callback(vopts, S_LEN("on_stderr"), on_stderr)
+ && tv_dict_get_callback(vopts, S_LEN("on_exit"), on_exit)) {
vopts->dv_refcount++;
return true;
}
@@ -23056,8 +22465,9 @@ static inline bool common_job_start(TerminalJobData *data, typval_T *rettv)
data->refcount++;
char *cmd = xstrdup(proc->argv[0]);
- if (!process_spawn(proc)) {
- EMSG2(_(e_jobspawn), cmd);
+ int status = process_spawn(proc);
+ if (status) {
+ EMSG3(_(e_jobspawn), os_strerror(status), cmd);
xfree(cmd);
if (proc->type == kProcessTypePty) {
xfree(data->proc.pty.term_name);
@@ -23070,8 +22480,9 @@ static inline bool common_job_start(TerminalJobData *data, typval_T *rettv)
if (data->rpc) {
- // the rpc channel takes over the in and out streams
- channel_from_process(proc, data->id);
+ eval_format_source_name_line((char *)IObuff, sizeof(IObuff));
+ // RPC channel takes over the in/out streams.
+ channel_from_process(proc, data->id, (char *)IObuff);
} else {
wstream_init(proc->in, 0);
if (proc->out) {
@@ -23115,7 +22526,7 @@ static inline void process_job_event(TerminalJobData *data, Callback *callback,
JobEvent event_data;
event_data.received = NULL;
if (buf) {
- event_data.received = list_alloc();
+ event_data.received = tv_list_alloc();
char *ptr = buf;
size_t remaining = count;
size_t off = 0;
@@ -23123,7 +22534,7 @@ static inline void process_job_event(TerminalJobData *data, Callback *callback,
while (off < remaining) {
// append the line
if (ptr[off] == NL) {
- list_append_string(event_data.received, (uint8_t *)ptr, off);
+ tv_list_append_string(event_data.received, ptr, off);
size_t skip = off + 1;
ptr += skip;
remaining -= skip;
@@ -23136,7 +22547,7 @@ static inline void process_job_event(TerminalJobData *data, Callback *callback,
}
off++;
}
- list_append_string(event_data.received, (uint8_t *)ptr, off);
+ tv_list_append_string(event_data.received, ptr, off);
} else {
event_data.status = status;
}
@@ -23179,11 +22590,10 @@ static void on_job_output(Stream *stream, TerminalJobData *data, RBuffer *buf,
terminal_receive(data->term, ptr, count);
}
+ rbuffer_consumed(buf, count);
if (callback->type != kCallbackNone) {
process_job_event(data, callback, type, ptr, count, 0);
}
-
- rbuffer_consumed(buf, count);
}
static void eval_job_process_exit_cb(Process *proc, int status, void *d)
@@ -23283,10 +22693,9 @@ static void on_job_event(JobEvent *ev)
argv[2].v_lock = 0;
argv[2].vval.v_string = (uint8_t *)ev->type;
- typval_T rettv;
- init_tv(&rettv);
+ typval_T rettv = TV_INITIAL_VALUE;
callback_call(ev->callback, 3, argv, &rettv);
- clear_tv(&rettv);
+ tv_clear(&rettv);
}
static TerminalJobData *find_job(uint64_t id)
@@ -23309,8 +22718,8 @@ static void script_host_eval(char *name, typval_T *argvars, typval_T *rettv)
return;
}
- list_T *args = list_alloc();
- list_append_string(args, argvars[0].vval.v_string, -1);
+ list_T *args = tv_list_alloc();
+ tv_list_append_string(args, (const char *)argvars[0].vval.v_string, -1);
*rettv = eval_call_provider(name, "eval", args);
}
@@ -23342,11 +22751,12 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments)
arguments->lv_refcount++;
int dummy;
- (void)call_func((uint8_t *)func,
+ (void)call_func((const char_u *)func,
name_len,
&rettv,
2,
argvars,
+ NULL,
curwin->w_cursor.lnum,
curwin->w_cursor.lnum,
&dummy,
@@ -23354,7 +22764,7 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments)
NULL,
NULL);
- list_unref(arguments);
+ tv_list_unref(arguments);
// Restore caller scope information
restore_funccal(provider_caller_scope.funccalp);
provider_caller_scope = saved_provider_caller_scope;
@@ -23363,14 +22773,16 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments)
return rettv;
}
-bool eval_has_provider(char *name)
+bool eval_has_provider(const char *name)
{
-#define check_provider(name) \
+#define CHECK_PROVIDER(name) \
if (has_##name == -1) { \
- has_##name = !!find_func((uint8_t *)"provider#" #name "#Call"); \
+ has_##name = !!find_func((char_u *)"provider#" #name "#Call"); \
if (!has_##name) { \
- script_autoload((uint8_t *)"provider#" #name "#Call", false); \
- has_##name = !!find_func((uint8_t *)"provider#" #name "#Call"); \
+ script_autoload("provider#" #name "#Call", \
+ sizeof("provider#" #name "#Call") - 1, \
+ false); \
+ has_##name = !!find_func((char_u *)"provider#" #name "#Call"); \
} \
}
@@ -23379,107 +22791,27 @@ bool eval_has_provider(char *name)
static int has_python3 = -1;
static int has_ruby = -1;
- if (!strcmp(name, "clipboard")) {
- check_provider(clipboard);
+ if (strequal(name, "clipboard")) {
+ CHECK_PROVIDER(clipboard);
return has_clipboard;
- } else if (!strcmp(name, "python3")) {
- check_provider(python3);
+ } else if (strequal(name, "python3")) {
+ CHECK_PROVIDER(python3);
return has_python3;
- } else if (!strcmp(name, "python")) {
- check_provider(python);
+ } else if (strequal(name, "python")) {
+ CHECK_PROVIDER(python);
return has_python;
- } else if (!strcmp(name, "ruby")) {
- check_provider(ruby);
+ } else if (strequal(name, "ruby")) {
+ CHECK_PROVIDER(ruby);
return has_ruby;
}
return false;
}
-// Compute the `DictWatcher` address from a QUEUE node. This only exists for
-// .asan-blacklist (ASAN doesn't handle QUEUE_DATA pointer arithmetic).
-static DictWatcher *dictwatcher_node_data(QUEUE *q)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
-{
- return QUEUE_DATA(q, DictWatcher, node);
-}
-
-// Send a change notification to all `dict` watchers that match `key`.
-static void dictwatcher_notify(dict_T *dict, const char *key, typval_T *newtv,
- typval_T *oldtv)
- FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_NONNULL_ARG(2)
-{
- typval_T argv[4];
- for (size_t i = 0; i < ARRAY_SIZE(argv); i++) {
- init_tv(argv + i);
- }
-
- argv[0].v_type = VAR_DICT;
- argv[0].vval.v_dict = dict;
- argv[1].v_type = VAR_STRING;
- argv[1].vval.v_string = (char_u *)xstrdup(key);
- argv[2].v_type = VAR_DICT;
- argv[2].vval.v_dict = dict_alloc();
- argv[2].vval.v_dict->dv_refcount++;
-
- if (newtv) {
- dictitem_T *v = dictitem_alloc((char_u *)"new");
- copy_tv(newtv, &v->di_tv);
- dict_add(argv[2].vval.v_dict, v);
- }
-
- if (oldtv) {
- dictitem_T *v = dictitem_alloc((char_u *)"old");
- copy_tv(oldtv, &v->di_tv);
- dict_add(argv[2].vval.v_dict, v);
- }
-
- typval_T rettv;
-
- QUEUE *w;
- QUEUE_FOREACH(w, &dict->watchers) {
- DictWatcher *watcher = dictwatcher_node_data(w);
- if (!watcher->busy && dictwatcher_matches(watcher, key)) {
- init_tv(&rettv);
- watcher->busy = true;
- callback_call(&watcher->callback, 3, argv, &rettv);
- watcher->busy = false;
- clear_tv(&rettv);
- }
- }
-
- for (size_t i = 1; i < ARRAY_SIZE(argv); i++) {
- clear_tv(argv + i);
- }
-}
-
-// Test if `key` matches with with `watcher->key_pattern`
-static bool dictwatcher_matches(DictWatcher *watcher, const char *key)
- FUNC_ATTR_NONNULL_ALL
-{
- // For now only allow very simple globbing in key patterns: a '*' at the end
- // of the string means it should match everything up to the '*' instead of the
- // whole string.
- char *nul = strchr(watcher->key_pattern, NUL);
- size_t len = nul - watcher->key_pattern;
- if (*(nul - 1) == '*') {
- return !strncmp(key, watcher->key_pattern, len - 1);
- } else {
- return !strcmp(key, watcher->key_pattern);
- }
-}
-
-// Perform all necessary cleanup for a `DictWatcher` instance.
-static void dictwatcher_free(DictWatcher *watcher)
- FUNC_ATTR_NONNULL_ALL
-{
- callback_free(&watcher->callback);
- xfree(watcher->key_pattern);
- xfree(watcher);
-}
-
-// Check if `d` has at least one watcher.
-static bool is_watched(dict_T *d)
+/// Writes "<sourcing_name>:<sourcing_lnum>" to `buf[bufsize]`.
+void eval_format_source_name_line(char *buf, size_t bufsize)
{
- return d && !QUEUE_EMPTY(&d->watchers);
+ snprintf(buf, bufsize, "%s:%" PRIdLINENR,
+ (sourcing_name ? sourcing_name : (char_u *)"?"),
+ (sourcing_name ? sourcing_lnum : 0));
}
diff --git a/src/nvim/eval.h b/src/nvim/eval.h
index 630e309442..070bc35bd5 100644
--- a/src/nvim/eval.h
+++ b/src/nvim/eval.h
@@ -1,11 +1,12 @@
#ifndef NVIM_EVAL_H
#define NVIM_EVAL_H
-#include "nvim/profile.h"
#include "nvim/hashtab.h" // For hashtab_T
-#include "nvim/garray.h" // For garray_T
-#include "nvim/buffer_defs.h" // For scid_T
+#include "nvim/buffer_defs.h"
#include "nvim/ex_cmds_defs.h" // For exarg_T
+#include "nvim/eval/typval.h"
+#include "nvim/profile.h"
+#include "nvim/garray.h"
#define COPYID_INC 2
#define COPYID_MASK (~0x1)
@@ -13,42 +14,10 @@
// All user-defined functions are found in this hashtable.
extern hashtab_T func_hashtab;
-// Structure to hold info for a user function.
-typedef struct ufunc ufunc_T;
-
-struct ufunc {
- int uf_varargs; ///< variable nr of arguments
- int uf_flags;
- int uf_calls; ///< nr of active calls
- garray_T uf_args; ///< arguments
- garray_T uf_lines; ///< function lines
- int uf_profiling; ///< true when func is being profiled
- // Profiling the function as a whole.
- int uf_tm_count; ///< nr of calls
- proftime_T uf_tm_total; ///< time spent in function + children
- proftime_T uf_tm_self; ///< time spent in function itself
- proftime_T uf_tm_children; ///< time spent in children this call
- // Profiling the function per line.
- int *uf_tml_count; ///< nr of times line was executed
- proftime_T *uf_tml_total; ///< time spent in a line + children
- proftime_T *uf_tml_self; ///< time spent in a line itself
- proftime_T uf_tml_start; ///< start time for current line
- proftime_T uf_tml_children; ///< time spent in children for this line
- proftime_T uf_tml_wait; ///< start wait time for current line
- int uf_tml_idx; ///< index of line being timed; -1 if none
- int uf_tml_execed; ///< line being timed was executed
- scid_T uf_script_ID; ///< ID of script where function was defined,
- // used for s: variables
- int uf_refcount; ///< for numbered function: reference count
- char_u uf_name[1]; ///< name of function (actually longer); can
- // start with <SNR>123_ (<SNR> is K_SPECIAL
- // KS_EXTRA KE_SNR)
-};
-
// From user function to hashitem and back.
EXTERN ufunc_T dumuf;
#define UF2HIKEY(fp) ((fp)->uf_name)
-#define HIKEY2UF(p) ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf)))
+#define HIKEY2UF(p) ((ufunc_T *)(p - offsetof(ufunc_T, uf_name)))
#define HI2UF(hi) HIKEY2UF((hi)->hi_key)
/// Defines for Vim variables
@@ -127,6 +96,7 @@ typedef enum {
VV__NULL_LIST, // List with NULL value. For test purposes only.
VV__NULL_DICT, // Dictionary with NULL value. For test purposes only.
VV_VIM_DID_ENTER,
+ VV_TESTING,
VV_TYPE_NUMBER,
VV_TYPE_STRING,
VV_TYPE_FUNC,
@@ -156,8 +126,8 @@ extern const list_T *eval_msgpack_type_lists[LAST_MSGPACK_TYPE + 1];
#undef LAST_MSGPACK_TYPE
-/// Maximum number of function arguments
-#define MAX_FUNC_ARGS 20
+typedef int (*ArgvFunc)(int current_argcount, typval_T *argv,
+ int called_func_argcount);
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval.h.generated.h"
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index e0b72feb19..0e359fb61c 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -2,10 +2,10 @@
--
-- Keys:
--
--- args Number of arguments, list with maximum and minimum number of arguments
--- or list with a minimum number of arguments only. Defaults to zero
+-- args Number of arguments, list with maximum and minimum number of arguments
+-- or list with a minimum number of arguments only. Defaults to zero
-- arguments.
--- func Name of the C function which implements the VimL function. Defaults to
+-- func Name of the C function which implements the VimL function. Defaults to
-- `f_{funcname}`.
local varargs = function(nr)
@@ -29,9 +29,11 @@ return {
assert_exception={args={1, 2}},
assert_fails={args={1, 2}},
assert_false={args={1, 2}},
+ assert_inrange={args={3, 4}},
assert_match={args={2, 3}},
assert_notequal={args={2, 3}},
assert_notmatch={args={2, 3}},
+ assert_report={args=1},
assert_true={args={1, 2}},
atan={args=1, func="float_op_wrapper", data="&atan"},
atan2={args=2},
@@ -103,6 +105,7 @@ return {
foldtext={},
foldtextresult={args=1},
foreground={},
+ funcref={args={1, 3}},
['function']={args={1, 3}},
garbagecollect={args={0, 1}},
get={args={2, 3}},
@@ -125,11 +128,11 @@ return {
getftime={args=1},
getftype={args=1},
getline={args={1, 2}},
- getloclist={args=1, func='f_getqflist'},
+ getloclist={args={1, 2}},
getmatches={},
getpid={},
getpos={args=1},
- getqflist={},
+ getqflist={args={0, 1}},
getreg={args={0, 3}},
getregtype={args={0, 1}},
gettabinfo={args={0, 1}},
@@ -168,6 +171,7 @@ return {
invert={args=1},
isdirectory={args=1},
islocked={args=1},
+ id={args=1},
items={args=1},
jobclose={args={1, 2}},
jobpid={args=1},
@@ -190,6 +194,7 @@ return {
localtime={},
log={args=1, func="float_op_wrapper", data="&log"},
log10={args=1, func="float_op_wrapper", data="&log10"},
+ luaeval={args={1, 2}},
map={args=2},
maparg={args={1, 4}},
mapcheck={args={1, 3}},
@@ -203,6 +208,7 @@ return {
matchstr={args={2, 4}},
matchstrpos={args={2,4}},
max={args=1},
+ menu_get={args={1, 2}},
min={args=1},
mkdir={args={1, 3}},
mode={args={0, 1}},
@@ -264,6 +270,7 @@ return {
simplify={args=1},
sin={args=1, func="float_op_wrapper", data="&sin"},
sinh={args=1, func="float_op_wrapper", data="&sinh"},
+ sockconnect={args={2,3}},
sort={args={1, 3}},
soundfold={args=1},
spellbadword={args={0, 1}},
@@ -297,13 +304,17 @@ return {
tabpagenr={args={0, 1}},
tabpagewinnr={args={1, 2}},
tagfiles={},
- taglist={args=1},
+ taglist={args={1, 2}},
tan={args=1, func="float_op_wrapper", data="&tan"},
tanh={args=1, func="float_op_wrapper", data="&tanh"},
tempname={},
termopen={args={1, 2}},
+ test_garbagecollect_now={},
+ timer_info={args={0,1}},
+ timer_pause={args=2},
timer_start={args={2,3}},
timer_stop={args=1},
+ timer_stopall={args=0},
tolower={args=1},
toupper={args=1},
tr={args=3},
diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c
index 43e9f76c0f..9c9c2c2dc8 100644
--- a/src/nvim/eval/decode.c
+++ b/src/nvim/eval/decode.c
@@ -1,12 +1,17 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <stddef.h>
#include <msgpack.h>
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
#include "nvim/eval.h"
#include "nvim/eval/encode.h"
#include "nvim/ascii.h"
+#include "nvim/macros.h"
#include "nvim/message.h"
+#include "nvim/globals.h"
#include "nvim/charset.h" // vim_str2nr
#include "nvim/lib/kvec.h"
#include "nvim/vim.h" // OK, FAIL
@@ -51,16 +56,16 @@ static inline void create_special_dict(typval_T *const rettv,
typval_T val)
FUNC_ATTR_NONNULL_ALL
{
- dict_T *const dict = dict_alloc();
- dictitem_T *const type_di = dictitem_alloc((char_u *) "_TYPE");
+ dict_T *const dict = tv_dict_alloc();
+ dictitem_T *const type_di = tv_dict_item_alloc_len(S_LEN("_TYPE"));
type_di->di_tv.v_type = VAR_LIST;
type_di->di_tv.v_lock = VAR_UNLOCKED;
type_di->di_tv.vval.v_list = (list_T *) eval_msgpack_type_lists[type];
type_di->di_tv.vval.v_list->lv_refcount++;
- dict_add(dict, type_di);
- dictitem_T *const val_di = dictitem_alloc((char_u *) "_VAL");
+ tv_dict_add(dict, type_di);
+ dictitem_T *const val_di = tv_dict_item_alloc_len(S_LEN("_VAL"));
val_di->di_tv = val;
- dict_add(dict, val_di);
+ tv_dict_add(dict, val_di);
dict->dv_refcount++;
*rettv = (typval_T) {
.v_type = VAR_DICT,
@@ -118,18 +123,18 @@ static inline int json_decoder_pop(ValuesStackItem obj,
if (last_container.container.vval.v_list->lv_len != 0
&& !obj.didcomma) {
EMSG2(_("E474: Expected comma before list item: %s"), val_location);
- clear_tv(&obj.val);
+ tv_clear(&obj.val);
return FAIL;
}
assert(last_container.special_val == NULL);
- listitem_T *obj_li = listitem_alloc();
+ listitem_T *obj_li = tv_list_item_alloc();
obj_li->li_tv = obj.val;
- list_append(last_container.container.vval.v_list, obj_li);
+ tv_list_append(last_container.container.vval.v_list, obj_li);
} else if (last_container.stack_index == kv_size(*stack) - 2) {
if (!obj.didcolon) {
EMSG2(_("E474: Expected colon before dictionary value: %s"),
val_location);
- clear_tv(&obj.val);
+ tv_clear(&obj.val);
return FAIL;
}
ValuesStackItem key = kv_pop(*stack);
@@ -138,34 +143,35 @@ static inline int json_decoder_pop(ValuesStackItem obj,
assert(!(key.is_special_string
|| key.val.vval.v_string == NULL
|| *key.val.vval.v_string == NUL));
- dictitem_T *obj_di = dictitem_alloc(key.val.vval.v_string);
- clear_tv(&key.val);
- if (dict_add(last_container.container.vval.v_dict, obj_di)
+ dictitem_T *const obj_di = tv_dict_item_alloc(
+ (const char *)key.val.vval.v_string);
+ tv_clear(&key.val);
+ if (tv_dict_add(last_container.container.vval.v_dict, obj_di)
== FAIL) {
assert(false);
}
obj_di->di_tv = obj.val;
} else {
- list_T *const kv_pair = list_alloc();
- list_append_list(last_container.special_val, kv_pair);
- listitem_T *const key_li = listitem_alloc();
+ list_T *const kv_pair = tv_list_alloc();
+ tv_list_append_list(last_container.special_val, kv_pair);
+ listitem_T *const key_li = tv_list_item_alloc();
key_li->li_tv = key.val;
- list_append(kv_pair, key_li);
- listitem_T *const val_li = listitem_alloc();
+ tv_list_append(kv_pair, key_li);
+ listitem_T *const val_li = tv_list_item_alloc();
val_li->li_tv = obj.val;
- list_append(kv_pair, val_li);
+ tv_list_append(kv_pair, val_li);
}
} else {
// Object with key only
if (!obj.is_special_string && obj.val.v_type != VAR_STRING) {
EMSG2(_("E474: Expected string key: %s"), *pp);
- clear_tv(&obj.val);
+ tv_clear(&obj.val);
return FAIL;
} else if (!obj.didcomma
&& (last_container.special_val == NULL
&& (DICT_LEN(last_container.container.vval.v_dict) != 0))) {
EMSG2(_("E474: Expected comma before dictionary key: %s"), val_location);
- clear_tv(&obj.val);
+ tv_clear(&obj.val);
return FAIL;
}
// Handle empty key and key represented as special dictionary
@@ -173,16 +179,16 @@ static inline int json_decoder_pop(ValuesStackItem obj,
&& (obj.is_special_string
|| obj.val.vval.v_string == NULL
|| *obj.val.vval.v_string == NUL
- || dict_find(last_container.container.vval.v_dict,
- obj.val.vval.v_string, -1))) {
- clear_tv(&obj.val);
+ || tv_dict_find(last_container.container.vval.v_dict,
+ (const char *)obj.val.vval.v_string, -1))) {
+ tv_clear(&obj.val);
// Restart
(void) kv_pop(*container_stack);
ValuesStackItem last_container_val =
kv_A(*stack, last_container.stack_index);
while (kv_size(*stack) > last_container.stack_index) {
- clear_tv(&(kv_pop(*stack).val));
+ tv_clear(&(kv_pop(*stack).val));
}
*pp = last_container.s;
*didcomma = last_container_val.didcomma;
@@ -218,10 +224,80 @@ static inline int json_decoder_pop(ValuesStackItem obj,
} \
} while (0)
+/// Create a new special dictionary that ought to represent a MAP
+///
+/// @param[out] ret_tv Address where new special dictionary is saved.
+///
+/// @return [allocated] list which should contain key-value pairs. Return value
+/// may be safely ignored.
+list_T *decode_create_map_special_dict(typval_T *const ret_tv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ list_T *const list = tv_list_alloc();
+ list->lv_refcount++;
+ create_special_dict(ret_tv, kMPMap, ((typval_T) {
+ .v_type = VAR_LIST,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_list = list },
+ }));
+ return list;
+}
+
+/// Convert char* string to typval_T
+///
+/// Depending on whether string has (no) NUL bytes, it may use a special
+/// dictionary or decode string to VAR_STRING.
+///
+/// @param[in] s String to decode.
+/// @param[in] len String length.
+/// @param[in] hasnul Whether string has NUL byte, not or it was not yet
+/// determined.
+/// @param[in] binary If true, save special string type as kMPBinary,
+/// otherwise kMPString.
+/// @param[in] s_allocated If true, then `s` was allocated and can be saved in
+/// a returned structure. If it is not saved there, it
+/// will be freed.
+///
+/// @return Decoded string.
+typval_T decode_string(const char *const s, const size_t len,
+ const TriState hasnul, const bool binary,
+ const bool s_allocated)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ assert(s != NULL || len == 0);
+ const bool really_hasnul = (hasnul == kNone
+ ? memchr(s, NUL, len) != NULL
+ : (bool)hasnul);
+ if (really_hasnul) {
+ list_T *const list = tv_list_alloc();
+ list->lv_refcount++;
+ typval_T tv;
+ create_special_dict(&tv, binary ? kMPBinary : kMPString, ((typval_T) {
+ .v_type = VAR_LIST,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_list = list },
+ }));
+ const int elw_ret = encode_list_write((void *)list, s, len);
+ if (s_allocated) {
+ xfree((void *)s);
+ }
+ if (elw_ret == -1) {
+ tv_clear(&tv);
+ return (typval_T) { .v_type = VAR_UNKNOWN, .v_lock = VAR_UNLOCKED };
+ }
+ return tv;
+ } else {
+ return (typval_T) {
+ .v_type = VAR_STRING,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_string = (char_u *)(
+ s_allocated ? (char *)s : xmemdupz(s, len)) },
+ };
+ }
+}
+
/// Parse JSON double-quoted string
///
-/// @param[in] conv Defines conversion necessary to convert UTF-8 string to
-/// &encoding.
/// @param[in] buf Buffer being converted.
/// @param[in] buf_len Length of the buffer.
/// @param[in,out] pp Pointer to the start of the string. Must point to '"'.
@@ -238,8 +314,7 @@ static inline int json_decoder_pop(ValuesStackItem obj,
/// value when decoder is restarted, otherwise unused.
///
/// @return OK in case of success, FAIL in case of error.
-static inline int parse_json_string(vimconv_T *const conv,
- const char *const buf, const size_t buf_len,
+static inline int parse_json_string(const char *const buf, const size_t buf_len,
const char **const pp,
ValuesStack *const stack,
ContainerStack *const container_stack,
@@ -360,8 +435,8 @@ static inline int parse_json_string(vimconv_T *const conv,
case 'u': {
const char ubuf[] = { t[1], t[2], t[3], t[4] };
t += 4;
- unsigned long ch;
- vim_str2nr((char_u *) ubuf, NULL, NULL,
+ uvarnumber_T ch;
+ vim_str2nr((char_u *)ubuf, NULL, NULL,
STR2NR_HEX | STR2NR_FORCE, NULL, &ch, 4);
if (ch == 0) {
hasnul = true;
@@ -414,43 +489,13 @@ static inline int parse_json_string(vimconv_T *const conv,
}
PUT_FST_IN_PAIR(fst_in_pair, str_end);
#undef PUT_FST_IN_PAIR
- if (conv->vc_type != CONV_NONE) {
- size_t str_len = (size_t) (str_end - str);
- char *const new_str = (char *) string_convert(conv, (char_u *) str,
- &str_len);
- if (new_str == NULL) {
- emsgf(_("E474: Failed to convert string \"%.*s\" from UTF-8"),
- (int) str_len, str);
- xfree(str);
- goto parse_json_string_fail;
- }
- xfree(str);
- str = new_str;
- str_end = new_str + str_len;
- }
- if (hasnul) {
- typval_T obj;
- list_T *const list = list_alloc();
- list->lv_refcount++;
- create_special_dict(&obj, kMPString, ((typval_T) {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- }));
- if (encode_list_write((void *) list, str, (size_t) (str_end - str))
- == -1) {
- clear_tv(&obj);
- goto parse_json_string_fail;
- }
- xfree(str);
- POP(obj, true);
- } else {
- *str_end = NUL;
- POP(((typval_T) {
- .v_type = VAR_STRING,
- .vval = { .v_string = (char_u *) str },
- }), false);
+ *str_end = NUL;
+ typval_T obj = decode_string(
+ str, (size_t)(str_end - str), hasnul ? kTrue : kFalse, false, true);
+ if (obj.v_type == VAR_UNKNOWN) {
+ goto parse_json_string_fail;
}
+ POP(obj, obj.v_type != VAR_STRING);
goto parse_json_string_ret;
parse_json_string_fail:
ret = FAIL;
@@ -564,7 +609,7 @@ parse_json_number_check:
tv.v_type = VAR_FLOAT;
} else {
// Convert integer
- long nr;
+ varnumber_T nr;
int num_len;
vim_str2nr((char_u *) s, NULL, &num_len, 0, &nr, NULL, (int) (p - s));
if ((int) exp_num_len != num_len) {
@@ -572,7 +617,7 @@ parse_json_number_check:
"to integer vim_str2nr consumed %i bytes in place of %zu"),
(int) exp_num_len, s, num_len, exp_num_len);
}
- tv.vval.v_number = (varnumber_T) nr;
+ tv.vval.v_number = nr;
}
if (json_decoder_pop(OBJ(tv, false, *didcomma, *didcolon),
stack, container_stack,
@@ -624,9 +669,6 @@ int json_decode_string(const char *const buf, const size_t buf_len,
EMSG(_("E474: Attempt to decode a blank string"));
return FAIL;
}
- vimconv_T conv = { .vc_type = CONV_NONE };
- convert_setup(&conv, (char_u *) "utf-8", p_enc);
- conv.vc_fail = true;
int ret = OK;
ValuesStack stack = KV_INITIAL_VALUE;
ContainerStack container_stack = KV_INITIAL_VALUE;
@@ -772,7 +814,7 @@ json_decode_string_cycle_start:
break;
}
case '"': {
- if (parse_json_string(&conv, buf, buf_len, &p, &stack, &container_stack,
+ if (parse_json_string(buf, buf_len, &p, &stack, &container_stack,
&next_map_special, &didcomma, &didcolon)
== FAIL) {
// Error message was already given
@@ -806,7 +848,7 @@ json_decode_string_cycle_start:
break;
}
case '[': {
- list_T *list = list_alloc();
+ list_T *list = tv_list_alloc();
list->lv_refcount++;
typval_T tv = {
.v_type = VAR_LIST,
@@ -827,15 +869,9 @@ json_decode_string_cycle_start:
list_T *val_list = NULL;
if (next_map_special) {
next_map_special = false;
- val_list = list_alloc();
- val_list->lv_refcount++;
- create_special_dict(&tv, kMPMap, ((typval_T) {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = val_list },
- }));
+ val_list = decode_create_map_special_dict(&tv);
} else {
- dict_T *dict = dict_alloc();
+ dict_T *dict = tv_dict_alloc();
dict->dv_refcount++;
tv = (typval_T) {
.v_type = VAR_DICT,
@@ -887,7 +923,7 @@ json_decode_string_after_cycle:
json_decode_string_fail:
ret = FAIL;
while (kv_size(stack)) {
- clear_tv(&(kv_pop(stack).val));
+ tv_clear(&(kv_pop(stack).val));
}
json_decode_string_ret:
kv_destroy(stack);
@@ -933,7 +969,7 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
.vval = { .v_number = (varnumber_T) mobj.via.u64 },
};
} else {
- list_T *const list = list_alloc();
+ list_T *const list = tv_list_alloc();
list->lv_refcount++;
create_special_dict(rettv, kMPInteger, ((typval_T) {
.v_type = VAR_LIST,
@@ -941,10 +977,10 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
.vval = { .v_list = list },
}));
uint64_t n = mobj.via.u64;
- list_append_number(list, 1);
- list_append_number(list, (varnumber_T) ((n >> 62) & 0x3));
- list_append_number(list, (varnumber_T) ((n >> 31) & 0x7FFFFFFF));
- list_append_number(list, (varnumber_T) (n & 0x7FFFFFFF));
+ tv_list_append_number(list, 1);
+ tv_list_append_number(list, (varnumber_T)((n >> 62) & 0x3));
+ tv_list_append_number(list, (varnumber_T)((n >> 31) & 0x7FFFFFFF));
+ tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
}
break;
}
@@ -956,22 +992,28 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
.vval = { .v_number = (varnumber_T) mobj.via.i64 },
};
} else {
- list_T *const list = list_alloc();
+ list_T *const list = tv_list_alloc();
list->lv_refcount++;
create_special_dict(rettv, kMPInteger, ((typval_T) {
.v_type = VAR_LIST,
.v_lock = VAR_UNLOCKED,
.vval = { .v_list = list },
}));
- uint64_t n = -((uint64_t) mobj.via.i64);
- list_append_number(list, -1);
- list_append_number(list, (varnumber_T) ((n >> 62) & 0x3));
- list_append_number(list, (varnumber_T) ((n >> 31) & 0x7FFFFFFF));
- list_append_number(list, (varnumber_T) (n & 0x7FFFFFFF));
+ uint64_t n = -((uint64_t)mobj.via.i64);
+ tv_list_append_number(list, -1);
+ tv_list_append_number(list, (varnumber_T)((n >> 62) & 0x3));
+ tv_list_append_number(list, (varnumber_T)((n >> 31) & 0x7FFFFFFF));
+ tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
}
break;
}
- case MSGPACK_OBJECT_FLOAT: {
+#ifdef NVIM_MSGPACK_HAS_FLOAT32
+ case MSGPACK_OBJECT_FLOAT32:
+ case MSGPACK_OBJECT_FLOAT64:
+#else
+ case MSGPACK_OBJECT_FLOAT:
+#endif
+ {
*rettv = (typval_T) {
.v_type = VAR_FLOAT,
.v_lock = VAR_UNLOCKED,
@@ -980,43 +1022,23 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
break;
}
case MSGPACK_OBJECT_STR: {
- list_T *const list = list_alloc();
- list->lv_refcount++;
- create_special_dict(rettv, kMPString, ((typval_T) {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- }));
- if (encode_list_write((void *) list, mobj.via.str.ptr, mobj.via.str.size)
- == -1) {
+ *rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kTrue, false,
+ false);
+ if (rettv->v_type == VAR_UNKNOWN) {
return FAIL;
}
break;
}
case MSGPACK_OBJECT_BIN: {
- if (memchr(mobj.via.bin.ptr, NUL, mobj.via.bin.size) == NULL) {
- *rettv = (typval_T) {
- .v_type = VAR_STRING,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_string = xmemdupz(mobj.via.bin.ptr, mobj.via.bin.size) },
- };
- break;
- }
- list_T *const list = list_alloc();
- list->lv_refcount++;
- create_special_dict(rettv, kMPBinary, ((typval_T) {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- }));
- if (encode_list_write((void *) list, mobj.via.bin.ptr, mobj.via.bin.size)
- == -1) {
+ *rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kNone, true,
+ false);
+ if (rettv->v_type == VAR_UNKNOWN) {
return FAIL;
}
break;
}
case MSGPACK_OBJECT_ARRAY: {
- list_T *const list = list_alloc();
+ list_T *const list = tv_list_alloc();
list->lv_refcount++;
*rettv = (typval_T) {
.v_type = VAR_LIST,
@@ -1024,9 +1046,9 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
.vval = { .v_list = list },
};
for (size_t i = 0; i < mobj.via.array.size; i++) {
- listitem_T *const li = listitem_alloc();
+ listitem_T *const li = tv_list_item_alloc();
li->li_tv.v_type = VAR_UNKNOWN;
- list_append(list, li);
+ tv_list_append(list, li);
if (msgpack_to_vim(mobj.via.array.ptr[i], &li->li_tv) == FAIL) {
return FAIL;
}
@@ -1042,7 +1064,7 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
goto msgpack_to_vim_generic_map;
}
}
- dict_T *const dict = dict_alloc();
+ dict_T *const dict = tv_dict_alloc();
dict->dv_refcount++;
*rettv = (typval_T) {
.v_type = VAR_DICT,
@@ -1055,9 +1077,9 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
memcpy(&di->di_key[0], mobj.via.map.ptr[i].key.via.str.ptr,
mobj.via.map.ptr[i].key.via.str.size);
di->di_tv.v_type = VAR_UNKNOWN;
- if (dict_add(dict, di) == FAIL) {
+ if (tv_dict_add(dict, di) == FAIL) {
// Duplicate key: fallback to generic map
- clear_tv(rettv);
+ tv_clear(rettv);
xfree(di);
goto msgpack_to_vim_generic_map;
}
@@ -1067,22 +1089,16 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
}
break;
msgpack_to_vim_generic_map: {}
- list_T *const list = list_alloc();
- list->lv_refcount++;
- create_special_dict(rettv, kMPMap, ((typval_T) {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- }));
+ list_T *const list = decode_create_map_special_dict(rettv);
for (size_t i = 0; i < mobj.via.map.size; i++) {
- list_T *const kv_pair = list_alloc();
- list_append_list(list, kv_pair);
- listitem_T *const key_li = listitem_alloc();
+ list_T *const kv_pair = tv_list_alloc();
+ tv_list_append_list(list, kv_pair);
+ listitem_T *const key_li = tv_list_item_alloc();
key_li->li_tv.v_type = VAR_UNKNOWN;
- list_append(kv_pair, key_li);
- listitem_T *const val_li = listitem_alloc();
+ tv_list_append(kv_pair, key_li);
+ listitem_T *const val_li = tv_list_item_alloc();
val_li->li_tv.v_type = VAR_UNKNOWN;
- list_append(kv_pair, val_li);
+ tv_list_append(kv_pair, val_li);
if (msgpack_to_vim(mobj.via.map.ptr[i].key, &key_li->li_tv) == FAIL) {
return FAIL;
}
@@ -1093,11 +1109,11 @@ msgpack_to_vim_generic_map: {}
break;
}
case MSGPACK_OBJECT_EXT: {
- list_T *const list = list_alloc();
+ list_T *const list = tv_list_alloc();
list->lv_refcount++;
- list_append_number(list, mobj.via.ext.type);
- list_T *const ext_val_list = list_alloc();
- list_append_list(list, ext_val_list);
+ tv_list_append_number(list, mobj.via.ext.type);
+ list_T *const ext_val_list = tv_list_alloc();
+ tv_list_append_list(list, ext_val_list);
create_special_dict(rettv, kMPExt, ((typval_T) {
.v_type = VAR_LIST,
.v_lock = VAR_UNLOCKED,
diff --git a/src/nvim/eval/decode.h b/src/nvim/eval/decode.h
index 5c25a64f7a..77fc4c78c2 100644
--- a/src/nvim/eval/decode.h
+++ b/src/nvim/eval/decode.h
@@ -5,7 +5,8 @@
#include <msgpack.h>
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
+#include "nvim/globals.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/decode.h.generated.h"
diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c
index ee66b7cf09..ef647b3ee4 100644
--- a/src/nvim/eval/encode.c
+++ b/src/nvim/eval/encode.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// @file encode.c
///
/// File containing functions for encoding and decoding VimL values.
@@ -11,9 +14,9 @@
#include <math.h>
#include "nvim/eval/encode.h"
-#include "nvim/buffer_defs.h" // vimconv_T
+#include "nvim/buffer_defs.h"
#include "nvim/eval.h"
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
#include "nvim/garray.h"
#include "nvim/mbyte.h"
#include "nvim/message.h"
@@ -29,10 +32,6 @@
#define utf_ptr2char(b) utf_ptr2char((char_u *)b)
#define utf_ptr2len(b) ((size_t)utf_ptr2len((char_u *)b))
#define utf_char2len(b) ((size_t)utf_char2len(b))
-#define string_convert(a, b, c) \
- ((char *)string_convert((vimconv_T *)a, (char_u *)b, c))
-#define convert_setup(vcp, from, to) \
- (convert_setup(vcp, (char_u *)from, (char_u *)to))
const char *const encode_special_var_names[] = {
[kSpecialVarNull] = "null",
@@ -45,7 +44,8 @@ const char *const encode_special_var_names[] = {
#endif
/// Msgpack callback for writing to readfile()-style list
-int encode_list_write(void *data, const char *buf, size_t len)
+int encode_list_write(void *const data, const char *const buf, const size_t len)
+ FUNC_ATTR_NONNULL_ARG(1)
{
if (len == 0) {
return 0;
@@ -80,11 +80,11 @@ int encode_list_write(void *data, const char *buf, size_t len)
str = xmemdupz(line_start, line_length);
memchrsub(str, NUL, NL, line_length);
}
- list_append_allocated_string(list, str);
+ tv_list_append_allocated_string(list, str);
line_end++;
}
if (line_end == end) {
- list_append_allocated_string(list, NULL);
+ tv_list_append_allocated_string(list, NULL);
}
return 0;
}
@@ -182,9 +182,9 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
}
}
}
- EMSG3(msg, objname, (kv_size(*mpstack) == 0
- ? _("itself")
- : (char *) msg_ga.ga_data));
+ emsgf(msg, _(objname), (kv_size(*mpstack) == 0
+ ? _("itself")
+ : (char *)msg_ga.ga_data));
ga_clear(&msg_ga);
return FAIL;
}
@@ -253,9 +253,11 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
char *const buf_end = buf + nbuf;
char *p = buf;
while (p < buf_end) {
+ assert(state->li_length == 0 || state->li->li_tv.vval.v_string != NULL);
for (size_t i = state->offset; i < state->li_length && p < buf_end; i++) {
- const char ch = (char) state->li->li_tv.vval.v_string[state->offset++];
- *p++ = (char) ((char) ch == (char) NL ? (char) NUL : (char) ch);
+ assert(state->li->li_tv.vval.v_string != NULL);
+ const char ch = (char)state->li->li_tv.vval.v_string[state->offset++];
+ *p++ = (char)((char)ch == (char)NL ? (char)NUL : (char)ch);
}
if (p < buf_end) {
state->li = state->li->li_next;
@@ -536,17 +538,6 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
} \
} while (0)
-/// Last used p_enc value
-///
-/// Generic pointer: it is not used as a string, only pointer comparisons are
-/// performed. Must not be freed.
-static const void *last_p_enc = NULL;
-
-/// Conversion setup for converting from last_p_enc to UTF-8
-static vimconv_T p_enc_conv = {
- .vc_type = CONV_NONE,
-};
-
/// Escape sequences used in JSON
static const char escapes[][3] = {
[BS] = "\\b",
@@ -578,33 +569,15 @@ static inline int convert_to_json_string(garray_T *const gap,
} else {
size_t utf_len = len;
char *tofree = NULL;
- if (last_p_enc != (const void *) p_enc) {
- p_enc_conv.vc_type = CONV_NONE;
- convert_setup(&p_enc_conv, p_enc, "utf-8");
- p_enc_conv.vc_fail = true;
- last_p_enc = p_enc;
- }
- if (p_enc_conv.vc_type != CONV_NONE) {
- tofree = string_convert(&p_enc_conv, buf, &utf_len);
- if (tofree == NULL) {
- emsgf(_("E474: Failed to convert string \"%.*s\" to UTF-8"),
- utf_len, utf_buf);
- return FAIL;
- }
- utf_buf = tofree;
- }
size_t str_len = 0;
- // Encode character as \u0000 if
- // 1. It is an ASCII control character (0x0 .. 0x1F, 0x7F).
- // 2. &encoding is not UTF-8 and code point is above 0x7F.
- // 3. &encoding is UTF-8 and code point is not printable according to
- // utf_printable().
- // This is done to make it possible to :echo values when &encoding is not
- // UTF-8.
-#define ENCODE_RAW(p_enc_conv, ch) \
- (ch >= 0x20 && (p_enc_conv.vc_type == CONV_NONE \
- ? utf_printable(ch) \
- : ch < 0x7F))
+ // Encode character as \uNNNN if
+ // 1. It is an ASCII control character (0x0 .. 0x1F; 0x7F not
+ // utf_printable and thus not checked specially).
+ // 2. Code point is not printable according to utf_printable().
+ // This is done to make resulting values displayable on screen also not from
+ // Neovim.
+#define ENCODE_RAW(ch) \
+ (ch >= 0x20 && utf_printable(ch))
for (size_t i = 0; i < utf_len;) {
const int ch = utf_ptr2char(utf_buf + i);
const size_t shift = (ch == 0? 1: utf_ptr2len(utf_buf + i));
@@ -635,7 +608,7 @@ static inline int convert_to_json_string(garray_T *const gap,
utf_len - (i - shift), utf_buf + i - shift);
xfree(tofree);
return FAIL;
- } else if (ENCODE_RAW(p_enc_conv, ch)) {
+ } else if (ENCODE_RAW(ch)) {
str_len += shift;
} else {
str_len += ((sizeof("\\u1234") - 1)
@@ -665,7 +638,7 @@ static inline int convert_to_json_string(garray_T *const gap,
break;
}
default: {
- if (ENCODE_RAW(p_enc_conv, ch)) {
+ if (ENCODE_RAW(ch)) {
ga_concat_len(gap, utf_buf + i, shift);
} else if (ch < SURROGATE_FIRST_CHAR) {
ga_concat_len(gap, ((const char[]) {
@@ -743,11 +716,11 @@ bool encode_check_json_key(const typval_T *const tv)
}
const dictitem_T *type_di;
const dictitem_T *val_di;
- if ((type_di = dict_find((dict_T *) spdict, (char_u *) "_TYPE", -1)) == NULL
+ if ((type_di = tv_dict_find(spdict, S_LEN("_TYPE"))) == NULL
|| type_di->di_tv.v_type != VAR_LIST
|| (type_di->di_tv.vval.v_list != eval_msgpack_type_lists[kMPString]
&& type_di->di_tv.vval.v_list != eval_msgpack_type_lists[kMPBinary])
- || (val_di = dict_find((dict_T *) spdict, (char_u *) "_VAL", -1)) == NULL
+ || (val_di = tv_dict_find(spdict, S_LEN("_VAL"))) == NULL
|| val_di->di_tv.v_type != VAR_LIST) {
return false;
}
@@ -822,7 +795,7 @@ char *encode_tv2string(typval_T *tv, size_t *len)
garray_T ga;
ga_init(&ga, (int)sizeof(char), 80);
const int evs_ret = encode_vim_to_string(&ga, tv,
- "encode_tv2string() argument");
+ N_("encode_tv2string() argument"));
(void)evs_ret;
assert(evs_ret == OK);
did_echo_string_emsg = false;
@@ -850,7 +823,7 @@ char *encode_tv2echo(typval_T *tv, size_t *len)
ga_concat(&ga, tv->vval.v_string);
}
} else {
- const int eve_ret = encode_vim_to_echo(&ga, tv, ":echo argument");
+ const int eve_ret = encode_vim_to_echo(&ga, tv, N_(":echo argument"));
(void)eve_ret;
assert(eve_ret == OK);
}
@@ -873,7 +846,8 @@ char *encode_tv2json(typval_T *tv, size_t *len)
{
garray_T ga;
ga_init(&ga, (int)sizeof(char), 80);
- const int evj_ret = encode_vim_to_json(&ga, tv, "encode_tv2json() argument");
+ const int evj_ret = encode_vim_to_json(&ga, tv,
+ N_("encode_tv2json() argument"));
if (!evj_ret) {
ga_clear(&ga);
}
diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c
new file mode 100644
index 0000000000..99298cbbcf
--- /dev/null
+++ b/src/nvim/eval/executor.c
@@ -0,0 +1,118 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include "nvim/eval/typval.h"
+#include "nvim/eval/executor.h"
+#include "nvim/eval.h"
+#include "nvim/message.h"
+#include "nvim/vim.h"
+#include "nvim/globals.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "eval/executor.c.generated.h"
+#endif
+
+static char *e_letwrong = N_("E734: Wrong variable type for %s=");
+
+char *e_listidx = N_("E684: list index out of range: %" PRId64);
+
+/// Hanle tv1 += tv2, -=, .=
+///
+/// @param[in,out] tv1 First operand, modified typval.
+/// @param[in] tv2 Second operand.
+/// @param[in] op Used operator.
+///
+/// @return OK or FAIL.
+int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
+ const char *const op)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NO_SANITIZE_UNDEFINED
+{
+ // Can't do anything with a Funcref, a Dict or special value on the right.
+ if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) {
+ switch (tv1->v_type) {
+ case VAR_DICT:
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ case VAR_SPECIAL: {
+ break;
+ }
+ case VAR_LIST: {
+ if (*op != '+' || tv2->v_type != VAR_LIST) {
+ break;
+ }
+ // List += List
+ if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) {
+ tv_list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
+ }
+ return OK;
+ }
+ case VAR_NUMBER:
+ case VAR_STRING: {
+ if (tv2->v_type == VAR_LIST) {
+ break;
+ }
+ if (*op == '+' || *op == '-') {
+ // nr += nr or nr -= nr
+ varnumber_T n = tv_get_number(tv1);
+ if (tv2->v_type == VAR_FLOAT) {
+ float_T f = (float_T)n;
+
+ if (*op == '+') {
+ f += tv2->vval.v_float;
+ } else {
+ f -= tv2->vval.v_float;
+ }
+ tv_clear(tv1);
+ tv1->v_type = VAR_FLOAT;
+ tv1->vval.v_float = f;
+ } else {
+ if (*op == '+') {
+ n += tv_get_number(tv2);
+ } else {
+ n -= tv_get_number(tv2);
+ }
+ tv_clear(tv1);
+ tv1->v_type = VAR_NUMBER;
+ tv1->vval.v_number = n;
+ }
+ } else {
+ // str .= str
+ if (tv2->v_type == VAR_FLOAT) {
+ break;
+ }
+ const char *tvs = tv_get_string(tv1);
+ char numbuf[NUMBUFLEN];
+ char *const s = (char *)concat_str(
+ (const char_u *)tvs, (const char_u *)tv_get_string_buf(tv2,
+ numbuf));
+ tv_clear(tv1);
+ tv1->v_type = VAR_STRING;
+ tv1->vval.v_string = (char_u *)s;
+ }
+ return OK;
+ }
+ case VAR_FLOAT: {
+ if (*op == '.' || (tv2->v_type != VAR_FLOAT
+ && tv2->v_type != VAR_NUMBER
+ && tv2->v_type != VAR_STRING)) {
+ break;
+ }
+ const float_T f = (tv2->v_type == VAR_FLOAT
+ ? tv2->vval.v_float
+ : (float_T)tv_get_number(tv2));
+ if (*op == '+') {
+ tv1->vval.v_float += f;
+ } else {
+ tv1->vval.v_float -= f;
+ }
+ return OK;
+ }
+ case VAR_UNKNOWN: {
+ assert(false);
+ }
+ }
+ }
+
+ EMSG2(_(e_letwrong), op);
+ return FAIL;
+}
diff --git a/src/nvim/eval/executor.h b/src/nvim/eval/executor.h
new file mode 100644
index 0000000000..3d789f76a5
--- /dev/null
+++ b/src/nvim/eval/executor.h
@@ -0,0 +1,11 @@
+#ifndef NVIM_EVAL_EXECUTOR_H
+#define NVIM_EVAL_EXECUTOR_H
+
+#include "nvim/eval/typval.h"
+
+extern char *e_listidx;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "eval/executor.h.generated.h"
+#endif
+#endif // NVIM_EVAL_EXECUTOR_H
diff --git a/src/nvim/eval/gc.c b/src/nvim/eval/gc.c
new file mode 100644
index 0000000000..2bbf78d827
--- /dev/null
+++ b/src/nvim/eval/gc.c
@@ -0,0 +1,14 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include "nvim/eval/typval.h"
+#include "nvim/eval/gc.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "eval/gc.c.generated.h"
+#endif
+
+/// Head of list of all dictionaries
+dict_T *gc_first_dict = NULL;
+/// Head of list of all lists
+list_T *gc_first_list = NULL;
diff --git a/src/nvim/eval/gc.h b/src/nvim/eval/gc.h
new file mode 100644
index 0000000000..c2e862e469
--- /dev/null
+++ b/src/nvim/eval/gc.h
@@ -0,0 +1,12 @@
+#ifndef NVIM_EVAL_GC_H
+#define NVIM_EVAL_GC_H
+
+#include "nvim/eval/typval.h"
+
+extern dict_T *gc_first_dict;
+extern list_T *gc_first_list;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "eval/gc.h.generated.h"
+#endif
+#endif // NVIM_EVAL_GC_H
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
new file mode 100644
index 0000000000..c339a5cdd2
--- /dev/null
+++ b/src/nvim/eval/typval.c
@@ -0,0 +1,2627 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include <assert.h>
+#include <stdbool.h>
+
+#include "nvim/lib/queue.h"
+#include "nvim/eval/typval.h"
+#include "nvim/eval/gc.h"
+#include "nvim/eval/executor.h"
+#include "nvim/eval/encode.h"
+#include "nvim/eval/typval_encode.h"
+#include "nvim/eval.h"
+#include "nvim/types.h"
+#include "nvim/assert.h"
+#include "nvim/memory.h"
+#include "nvim/globals.h"
+#include "nvim/hashtab.h"
+#include "nvim/vim.h"
+#include "nvim/ascii.h"
+#include "nvim/pos.h"
+#include "nvim/charset.h"
+#include "nvim/garray.h"
+#include "nvim/gettext.h"
+#include "nvim/macros.h"
+#include "nvim/mbyte.h"
+#include "nvim/message.h"
+// TODO(ZyX-I): Move line_breakcheck out of misc1
+#include "nvim/misc1.h" // For line_breakcheck
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "eval/typval.c.generated.h"
+#endif
+
+bool tv_in_free_unref_items = false;
+
+// TODO(ZyX-I): Remove DICT_MAXNEST, make users be non-recursive instead
+
+#define DICT_MAXNEST 100
+
+const char *const tv_empty_string = "";
+
+//{{{1 Lists
+//{{{2 List item
+
+/// Allocate a list item
+///
+/// @warning Allocated item is not initialized, do not forget to initialize it
+/// and specifically set lv_lock.
+///
+/// @return [allocated] new list item.
+listitem_T *tv_list_item_alloc(void)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC
+{
+ return xmalloc(sizeof(listitem_T));
+}
+
+/// Free a list item
+///
+/// Also clears the value. Does not touch watchers.
+///
+/// @param[out] item Item to free.
+void tv_list_item_free(listitem_T *const item)
+ FUNC_ATTR_NONNULL_ALL
+{
+ tv_clear(&item->li_tv);
+ xfree(item);
+}
+
+/// Remove a list item from a List and free it
+///
+/// Also clears the value.
+///
+/// @param[out] l List to remove item from.
+/// @param[in,out] item Item to remove.
+void tv_list_item_remove(list_T *const l, listitem_T *const item)
+ FUNC_ATTR_NONNULL_ALL
+{
+ tv_list_remove_items(l, item, item);
+ tv_list_item_free(item);
+}
+
+//{{{2 List watchers
+
+/// Add a watcher to a list
+///
+/// @param[out] l List to add watcher to.
+/// @param[in] lw Watcher to add.
+void tv_list_watch_add(list_T *const l, listwatch_T *const lw)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lw->lw_next = l->lv_watch;
+ l->lv_watch = lw;
+}
+
+/// Remove a watcher from a list
+///
+/// Does not give a warning if watcher was not found.
+///
+/// @param[out] l List to remove watcher from.
+/// @param[in] lwrem Watcher to remove.
+void tv_list_watch_remove(list_T *const l, listwatch_T *const lwrem)
+ FUNC_ATTR_NONNULL_ALL
+{
+ listwatch_T **lwp = &l->lv_watch;
+ for (listwatch_T *lw = l->lv_watch; lw != NULL; lw = lw->lw_next) {
+ if (lw == lwrem) {
+ *lwp = lw->lw_next;
+ break;
+ }
+ lwp = &lw->lw_next;
+ }
+}
+
+/// Advance watchers to the next item
+///
+/// Used just before removing an item from a list.
+///
+/// @param[out] l List from which item is removed.
+/// @param[in] item List item being removed.
+void tv_list_watch_fix(list_T *const l, const listitem_T *const item)
+ FUNC_ATTR_NONNULL_ALL
+{
+ for (listwatch_T *lw = l->lv_watch; lw != NULL; lw = lw->lw_next) {
+ if (lw->lw_item == item) {
+ lw->lw_item = item->li_next;
+ }
+ }
+}
+
+//{{{2 Alloc/free
+
+/// Allocate an empty list
+///
+/// Caller should take care of the reference count.
+///
+/// @return [allocated] new list.
+list_T *tv_list_alloc(void)
+ FUNC_ATTR_NONNULL_RET
+{
+ list_T *const list = xcalloc(1, sizeof(list_T));
+
+ // Prepend the list to the list of lists for garbage collection.
+ if (gc_first_list != NULL) {
+ gc_first_list->lv_used_prev = list;
+ }
+ list->lv_used_prev = NULL;
+ list->lv_used_next = gc_first_list;
+ gc_first_list = list;
+ return list;
+}
+
+/// Free items contained in a list
+///
+/// @param[in,out] l List to clear.
+void tv_list_free_contents(list_T *const l)
+ FUNC_ATTR_NONNULL_ALL
+{
+ for (listitem_T *item = l->lv_first; item != NULL; item = l->lv_first) {
+ // Remove the item before deleting it.
+ l->lv_first = item->li_next;
+ tv_clear(&item->li_tv);
+ xfree(item);
+ }
+ l->lv_len = 0;
+ l->lv_idx_item = NULL;
+ l->lv_last = NULL;
+ assert(l->lv_watch == NULL);
+}
+
+/// Free a list itself, ignoring items it contains
+///
+/// Ignores the reference count.
+///
+/// @param[in,out] l List to free.
+void tv_list_free_list(list_T *const l)
+ FUNC_ATTR_NONNULL_ALL
+{
+ // Remove the list from the list of lists for garbage collection.
+ if (l->lv_used_prev == NULL) {
+ gc_first_list = l->lv_used_next;
+ } else {
+ l->lv_used_prev->lv_used_next = l->lv_used_next;
+ }
+ if (l->lv_used_next != NULL) {
+ l->lv_used_next->lv_used_prev = l->lv_used_prev;
+ }
+
+ xfree(l);
+}
+
+/// Free a list, including all items it points to
+///
+/// Ignores the reference count. Does not do anything if
+/// tv_in_free_unref_items is true.
+///
+/// @param[in,out] l List to free.
+void tv_list_free(list_T *const l)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (!tv_in_free_unref_items) {
+ tv_list_free_contents(l);
+ tv_list_free_list(l);
+ }
+}
+
+/// Unreference a list
+///
+/// Decrements the reference count and frees when it becomes zero or less.
+///
+/// @param[in,out] l List to unreference.
+void tv_list_unref(list_T *const l)
+{
+ if (l != NULL && --l->lv_refcount <= 0) {
+ tv_list_free(l);
+ }
+}
+
+//{{{2 Add/remove
+
+/// Remove items "item" to "item2" from list "l".
+///
+/// @warning Does not free the listitem or the value!
+///
+/// @param[out] l List to remove from.
+/// @param[in] item First item to remove.
+/// @param[in] item2 Last item to remove.
+void tv_list_remove_items(list_T *const l, listitem_T *const item,
+ listitem_T *const item2)
+ FUNC_ATTR_NONNULL_ALL
+{
+ // Notify watchers.
+ for (listitem_T *ip = item; ip != item2->li_next; ip = ip->li_next) {
+ l->lv_len--;
+ tv_list_watch_fix(l, ip);
+ }
+
+ if (item2->li_next == NULL) {
+ l->lv_last = item->li_prev;
+ } else {
+ item2->li_next->li_prev = item->li_prev;
+ }
+ if (item->li_prev == NULL) {
+ l->lv_first = item2->li_next;
+ } else {
+ item->li_prev->li_next = item2->li_next;
+ }
+ l->lv_idx_item = NULL;
+}
+
+/// Insert list item
+///
+/// @param[out] l List to insert to.
+/// @param[in,out] ni Item to insert.
+/// @param[in] item Item to insert before. If NULL, inserts at the end of the
+/// list.
+void tv_list_insert(list_T *const l, listitem_T *const ni,
+ listitem_T *const item)
+ FUNC_ATTR_NONNULL_ARG(1, 2)
+{
+ if (item == NULL) {
+ // Append new item at end of list.
+ tv_list_append(l, ni);
+ } else {
+ // Insert new item before existing item.
+ ni->li_prev = item->li_prev;
+ ni->li_next = item;
+ if (item->li_prev == NULL) {
+ l->lv_first = ni;
+ l->lv_idx++;
+ } else {
+ item->li_prev->li_next = ni;
+ l->lv_idx_item = NULL;
+ }
+ item->li_prev = ni;
+ l->lv_len++;
+ }
+}
+
+/// Insert VimL value into a list
+///
+/// @param[out] l List to insert to.
+/// @param[in,out] tv Value to insert. Is copied (@see tv_copy()) to an
+/// allocated listitem_T and inserted.
+/// @param[in] item Item to insert before. If NULL, inserts at the end of the
+/// list.
+void tv_list_insert_tv(list_T *const l, typval_T *const tv,
+ listitem_T *const item)
+{
+ listitem_T *const ni = tv_list_item_alloc();
+
+ tv_copy(tv, &ni->li_tv);
+ tv_list_insert(l, ni, item);
+}
+
+/// Append item to the end of list
+///
+/// @param[out] l List to append to.
+/// @param[in,out] item Item to append.
+void tv_list_append(list_T *const l, listitem_T *const item)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (l->lv_last == NULL) {
+ // empty list
+ l->lv_first = item;
+ l->lv_last = item;
+ item->li_prev = NULL;
+ } else {
+ l->lv_last->li_next = item;
+ item->li_prev = l->lv_last;
+ l->lv_last = item;
+ }
+ l->lv_len++;
+ item->li_next = NULL;
+}
+
+/// Append VimL value to the end of list
+///
+/// @param[out] l List to append to.
+/// @param[in,out] tv Value to append. Is copied (@see tv_copy()) to an
+/// allocated listitem_T.
+void tv_list_append_tv(list_T *const l, typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ listitem_T *const li = tv_list_item_alloc();
+ tv_copy(tv, &li->li_tv);
+ tv_list_append(l, li);
+}
+
+/// Append a list to a list as one item
+///
+/// @param[out] l List to append to.
+/// @param[in,out] itemlist List to append. Reference count is increased.
+void tv_list_append_list(list_T *const list, list_T *const itemlist)
+ FUNC_ATTR_NONNULL_ARG(1)
+{
+ listitem_T *const li = tv_list_item_alloc();
+
+ li->li_tv.v_type = VAR_LIST;
+ li->li_tv.v_lock = VAR_UNLOCKED;
+ li->li_tv.vval.v_list = itemlist;
+ tv_list_append(list, li);
+ if (itemlist != NULL) {
+ itemlist->lv_refcount++;
+ }
+}
+
+/// Append a dictionary to a list
+///
+/// @param[out] l List to append to.
+/// @param[in,out] dict Dictionary to append. Reference count is increased.
+void tv_list_append_dict(list_T *const list, dict_T *const dict)
+ FUNC_ATTR_NONNULL_ARG(1)
+{
+ listitem_T *const li = tv_list_item_alloc();
+
+ li->li_tv.v_type = VAR_DICT;
+ li->li_tv.v_lock = VAR_UNLOCKED;
+ li->li_tv.vval.v_dict = dict;
+ tv_list_append(list, li);
+ if (dict != NULL) {
+ dict->dv_refcount++;
+ }
+}
+
+/// Make a copy of "str" and append it as an item to list "l"
+///
+/// @param[out] l List to append to.
+/// @param[in] str String to append.
+/// @param[in] len Length of the appended string. May be -1, in this
+/// case string is considered to be usual zero-terminated
+/// string or NULL “empty†string.
+void tv_list_append_string(list_T *const l, const char *const str,
+ const ptrdiff_t len)
+ FUNC_ATTR_NONNULL_ARG(1)
+{
+ if (str == NULL) {
+ assert(len == 0 || len == -1);
+ tv_list_append_allocated_string(l, NULL);
+ } else {
+ tv_list_append_allocated_string(l, (len >= 0
+ ? xmemdupz(str, (size_t)len)
+ : xstrdup(str)));
+ }
+}
+
+/// Append given string to the list
+///
+/// Unlike list_append_string this function does not copy the string.
+///
+/// @param[out] l List to append to.
+/// @param[in] str String to append.
+void tv_list_append_allocated_string(list_T *const l, char *const str)
+ FUNC_ATTR_NONNULL_ARG(1)
+{
+ listitem_T *const li = tv_list_item_alloc();
+
+ tv_list_append(l, li);
+ li->li_tv.v_type = VAR_STRING;
+ li->li_tv.v_lock = VAR_UNLOCKED;
+ li->li_tv.vval.v_string = (char_u *)str;
+}
+
+/// Append number to the list
+///
+/// @param[out] l List to append to.
+/// @param[in] n Number to append. Will be recorded in the allocated
+/// listitem_T.
+void tv_list_append_number(list_T *const l, const varnumber_T n)
+{
+ listitem_T *const li = tv_list_item_alloc();
+ li->li_tv.v_type = VAR_NUMBER;
+ li->li_tv.v_lock = VAR_UNLOCKED;
+ li->li_tv.vval.v_number = n;
+ tv_list_append(l, li);
+}
+
+//{{{2 Operations on the whole list
+
+/// Make a copy of list
+///
+/// @param[in] conv If non-NULL, then all internal strings will be converted.
+/// Only used when `deep` is true.
+/// @param[in] orig Original list to copy.
+/// @param[in] deep If false, then shallow copy will be done.
+/// @param[in] copyID See var_item_copy().
+///
+/// @return Copied list. May be NULL in case original list is NULL or some
+/// failure happens. The refcount of the new list is set to 1.
+list_T *tv_list_copy(const vimconv_T *const conv, list_T *const orig,
+ const bool deep, const int copyID)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (orig == NULL) {
+ return NULL;
+ }
+
+ list_T *copy = tv_list_alloc();
+ 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;
+ }
+ listitem_T *item;
+ for (item = orig->lv_first; item != NULL && !got_int;
+ item = item->li_next) {
+ listitem_T *const ni = tv_list_item_alloc();
+ if (deep) {
+ if (var_item_copy(conv, &item->li_tv, &ni->li_tv, deep, copyID) == FAIL) {
+ xfree(ni);
+ break;
+ }
+ } else {
+ tv_copy(&item->li_tv, &ni->li_tv);
+ }
+ tv_list_append(copy, ni);
+ }
+ copy->lv_refcount++;
+ if (item != NULL) {
+ tv_list_unref(copy);
+ copy = NULL;
+ }
+
+ return copy;
+}
+
+/// Extend first list with the second
+///
+/// @param[out] l1 List to extend.
+/// @param[in] l2 List to extend with.
+/// @param[in] bef If not NULL, extends before this item.
+void tv_list_extend(list_T *const l1, list_T *const l2,
+ listitem_T *const bef)
+ FUNC_ATTR_NONNULL_ARG(1, 2)
+{
+ int todo = l2->lv_len;
+ listitem_T *const befbef = (bef == NULL ? NULL : bef->li_prev);
+ listitem_T *const saved_next = (befbef == NULL ? NULL : befbef->li_next);
+ // We also quit the loop when we have inserted the original item count of
+ // the list, avoid a hang when we extend a list with itself.
+ for (listitem_T *item = l2->lv_first
+ ; item != NULL && --todo >= 0
+ ; item = (item == befbef ? saved_next : item->li_next)) {
+ tv_list_insert_tv(l1, &item->li_tv, bef);
+ }
+}
+
+/// Concatenate lists into a new list
+///
+/// @param[in] l1 First list.
+/// @param[in] l2 Second list.
+/// @param[out] ret_tv Location where new list is saved.
+///
+/// @return OK or FAIL.
+int tv_list_concat(list_T *const l1, list_T *const l2, typval_T *const tv)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ list_T *l;
+
+ tv->v_type = VAR_LIST;
+
+ if (l1 == NULL && l2 == NULL) {
+ l = NULL;
+ } else if (l1 == NULL) {
+ l = tv_list_copy(NULL, l2, false, 0);
+ } else {
+ l = tv_list_copy(NULL, l1, false, 0);
+ if (l != NULL && l2 != NULL) {
+ tv_list_extend(l, l2, NULL);
+ }
+ }
+ if (l == NULL && !(l1 == NULL && l2 == NULL)) {
+ return FAIL;
+ }
+
+ tv->vval.v_list = l;
+ return OK;
+}
+
+typedef struct {
+ char_u *s;
+ char_u *tofree;
+} Join;
+
+/// Join list into a string, helper function
+///
+/// @param[out] gap Garray where result will be saved.
+/// @param[in] l List to join.
+/// @param[in] sep Used separator.
+/// @param[in] join_gap Garray to keep each list item string.
+///
+/// @return OK in case of success, FAIL otherwise.
+static int list_join_inner(garray_T *const gap, list_T *const l,
+ const char *const sep, garray_T *const join_gap)
+ FUNC_ATTR_NONNULL_ALL
+{
+ size_t sumlen = 0;
+ bool first = true;
+ listitem_T *item;
+
+ // Stringify each item in the list.
+ for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) {
+ char *s;
+ size_t len;
+ s = encode_tv2echo(&item->li_tv, &len);
+ if (s == NULL) {
+ return FAIL;
+ }
+
+ sumlen += len;
+
+ Join *const p = GA_APPEND_VIA_PTR(Join, join_gap);
+ p->tofree = p->s = (char_u *)s;
+
+ line_breakcheck();
+ }
+
+ // Allocate result buffer with its total size, avoid re-allocation and
+ // multiple copy operations. Add 2 for a tailing ']' and NUL.
+ if (join_gap->ga_len >= 2) {
+ sumlen += strlen(sep) * (size_t)(join_gap->ga_len - 1);
+ }
+ ga_grow(gap, (int)sumlen + 2);
+
+ for (int i = 0; i < join_gap->ga_len && !got_int; i++) {
+ if (first) {
+ first = false;
+ } else {
+ ga_concat(gap, (const char_u *)sep);
+ }
+ const Join *const p = ((const Join *)join_gap->ga_data) + i;
+
+ if (p->s != NULL) {
+ ga_concat(gap, p->s);
+ }
+ line_breakcheck();
+ }
+
+ return OK;
+}
+
+/// Join list into a string using given separator
+///
+/// @param[out] gap Garray where result will be saved.
+/// @param[in] l Joined list.
+/// @param[in] sep Separator.
+///
+/// @return OK in case of success, FAIL otherwise.
+int tv_list_join(garray_T *const gap, list_T *const l, const char *const sep)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (l->lv_len < 1) {
+ return OK;
+ }
+
+ garray_T join_ga;
+ int retval;
+
+ ga_init(&join_ga, (int)sizeof(Join), l->lv_len);
+ retval = list_join_inner(gap, l, sep, &join_ga);
+
+#define FREE_JOIN_TOFREE(join) xfree((join)->tofree)
+ GA_DEEP_CLEAR(&join_ga, Join, FREE_JOIN_TOFREE);
+#undef FREE_JOIN_TOFREE
+
+ return retval;
+}
+
+/// Chech whether two lists are equal
+///
+/// @param[in] l1 First list to compare.
+/// @param[in] l2 Second list to compare.
+/// @param[in] ic True if case is to be ignored.
+/// @param[in] recursive True when used recursively.
+///
+/// @return True if lists are equal, false otherwise.
+bool tv_list_equal(list_T *const l1, list_T *const l2, const bool ic,
+ const bool recursive)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (l1 == l2) {
+ return true;
+ }
+ if (l1 == NULL || l2 == NULL) {
+ return false;
+ }
+ if (tv_list_len(l1) != tv_list_len(l2)) {
+ return false;
+ }
+
+ listitem_T *item1 = l1->lv_first;
+ listitem_T *item2 = l2->lv_first;
+ for (; 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;
+ }
+ }
+ assert(item1 == NULL && item2 == NULL);
+ return true;
+}
+
+//{{{2 Indexing/searching
+
+/// Locate item with a given index in a list and return it
+///
+/// @param[in] l List to index.
+/// @param[in] n Index. Negative index is counted from the end, -1 is the last
+/// item.
+///
+/// @return Item at the given index or NULL if `n` is out of range.
+listitem_T *tv_list_find(list_T *const l, int n)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ STATIC_ASSERT(sizeof(n) == sizeof(l->lv_idx),
+ "n and lv_idx sizes do not match");
+ if (l == NULL) {
+ return NULL;
+ }
+
+ // 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;
+ }
+
+ int idx;
+ listitem_T *item;
+
+ // When there is a cached index may start search from there.
+ if (l->lv_idx_item != NULL) {
+ if (n < l->lv_idx / 2) {
+ // Closest to the start of the list.
+ item = l->lv_first;
+ idx = 0;
+ } else if (n > (l->lv_idx + l->lv_len) / 2) {
+ // Closest to the end of the list.
+ item = l->lv_last;
+ idx = l->lv_len - 1;
+ } else {
+ // Closest to the cached index.
+ item = l->lv_idx_item;
+ idx = l->lv_idx;
+ }
+ } else {
+ if (n < l->lv_len / 2) {
+ // Closest to the start of the list.
+ item = l->lv_first;
+ idx = 0;
+ } else {
+ // Closest to the end of the list.
+ item = l->lv_last;
+ idx = l->lv_len - 1;
+ }
+ }
+
+ while (n > idx) {
+ // Search forward.
+ item = item->li_next;
+ idx++;
+ }
+ while (n < idx) {
+ // Search backward.
+ item = item->li_prev;
+ idx--;
+ }
+
+ assert(idx == n);
+ // Cache the used index.
+ l->lv_idx = idx;
+ l->lv_idx_item = item;
+
+ return item;
+}
+
+/// Get list item l[n] as a number
+///
+/// @param[in] l List to index.
+/// @param[in] n Index in a list.
+/// @param[out] ret_error Location where 1 will be saved if index was not
+/// found. May be NULL. If everything is OK,
+/// `*ret_error` is not touched.
+///
+/// @return Integer value at the given index or -1.
+varnumber_T tv_list_find_nr(list_T *const l, const int n, bool *const ret_error)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const listitem_T *const li = tv_list_find(l, n);
+ if (li == NULL) {
+ if (ret_error != NULL) {
+ *ret_error = true;
+ }
+ return -1;
+ }
+ return tv_get_number_chk(&li->li_tv, ret_error);
+}
+
+/// Get list item l[n] as a string
+///
+/// @param[in] l List to index.
+/// @param[in] n Index in a list.
+///
+/// @return List item string value or NULL in case of error.
+const char *tv_list_find_str(list_T *const l, const int n)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const listitem_T *const li = tv_list_find(l, n);
+ if (li == NULL) {
+ emsgf(_(e_listidx), (int64_t)n);
+ return NULL;
+ }
+ return tv_get_string(&li->li_tv);
+}
+
+/// Locate item in a list and return its index
+///
+/// @param[in] l List to search.
+/// @param[in] item Item to search for.
+///
+/// @return Index of an item or -1 if item is not in the list.
+long tv_list_idx_of_item(const list_T *const l, const listitem_T *const item)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
+{
+ if (l == NULL) {
+ return -1;
+ }
+ long idx = 0;
+ const listitem_T *li;
+ for (li = l->lv_first; li != NULL && li != item; li = li->li_next) {
+ idx++;
+ }
+ if (li == NULL) {
+ return -1;
+ }
+ return idx;
+}
+
+//{{{1 Dictionaries
+//{{{2 Dictionary watchers
+
+/// Perform all necessary cleanup for a `DictWatcher` instance
+///
+/// @param watcher Watcher to free.
+static void tv_dict_watcher_free(DictWatcher *watcher)
+ FUNC_ATTR_NONNULL_ALL
+{
+ callback_free(&watcher->callback);
+ xfree(watcher->key_pattern);
+ xfree(watcher);
+}
+
+/// Add watcher to a dictionary
+///
+/// @param[in] dict Dictionary to add watcher to.
+/// @param[in] key_pattern Pattern to watch for.
+/// @param[in] key_pattern_len Key pattern length.
+/// @param callback Function to be called on events.
+void tv_dict_watcher_add(dict_T *const dict, const char *const key_pattern,
+ const size_t key_pattern_len, Callback callback)
+ FUNC_ATTR_NONNULL_ARG(2)
+{
+ if (dict == NULL) {
+ return;
+ }
+ DictWatcher *const watcher = xmalloc(sizeof(DictWatcher));
+ watcher->key_pattern = xmemdupz(key_pattern, key_pattern_len);
+ watcher->key_pattern_len = key_pattern_len;
+ watcher->callback = callback;
+ watcher->busy = false;
+ QUEUE_INSERT_TAIL(&dict->watchers, &watcher->node);
+}
+
+/// Check whether two callbacks are equal
+///
+/// @param[in] cb1 First callback to check.
+/// @param[in] cb2 Second callback to check.
+///
+/// @return True if they are equal, false otherwise.
+bool tv_callback_equal(const Callback *const cb1, const Callback *const cb2)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (cb1->type != cb2->type) {
+ return false;
+ }
+ switch (cb1->type) {
+ case kCallbackFuncref: {
+ return STRCMP(cb1->data.funcref, cb2->data.funcref) == 0;
+ }
+ case kCallbackPartial: {
+ // FIXME: this is inconsistent with tv_equal but is needed for precision
+ // maybe change dictwatcheradd to return a watcher id instead?
+ return cb1->data.partial == cb2->data.partial;
+ }
+ case kCallbackNone: {
+ return true;
+ }
+ }
+ assert(false);
+ return false;
+}
+
+/// Remove watcher from a dictionary
+///
+/// @param dict Dictionary to remove watcher from.
+/// @param[in] key_pattern Pattern to remove watcher for.
+/// @param[in] key_pattern_len Pattern length.
+/// @param callback Callback to remove watcher for.
+///
+/// @return True on success, false if relevant watcher was not found.
+bool tv_dict_watcher_remove(dict_T *const dict, const char *const key_pattern,
+ const size_t key_pattern_len,
+ Callback callback)
+ FUNC_ATTR_NONNULL_ARG(2)
+{
+ if (dict == NULL) {
+ return false;
+ }
+
+ QUEUE *w = NULL;
+ DictWatcher *watcher = NULL;
+ bool matched = false;
+ QUEUE_FOREACH(w, &dict->watchers) {
+ watcher = tv_dict_watcher_node_data(w);
+ if (tv_callback_equal(&watcher->callback, &callback)
+ && watcher->key_pattern_len == key_pattern_len
+ && memcmp(watcher->key_pattern, key_pattern, key_pattern_len) == 0) {
+ matched = true;
+ break;
+ }
+ }
+
+ if (!matched) {
+ return false;
+ }
+
+ QUEUE_REMOVE(w);
+ tv_dict_watcher_free(watcher);
+ return true;
+}
+
+/// Test if `key` matches with with `watcher->key_pattern`
+///
+/// @param[in] watcher Watcher to check key pattern from.
+/// @param[in] key Key to check.
+///
+/// @return true if key matches, false otherwise.
+static bool tv_dict_watcher_matches(DictWatcher *watcher, const char *const key)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
+{
+ // For now only allow very simple globbing in key patterns: a '*' at the end
+ // of the string means it should match everything up to the '*' instead of the
+ // whole string.
+ const size_t len = watcher->key_pattern_len;
+ if (len && watcher->key_pattern[len - 1] == '*') {
+ return strncmp(key, watcher->key_pattern, len - 1) == 0;
+ } else {
+ return strcmp(key, watcher->key_pattern) == 0;
+ }
+}
+
+/// Send a change notification to all dictionary watchers that match given key
+///
+/// @param[in] dict Dictionary which was modified.
+/// @param[in] key Key which was modified.
+/// @param[in] newtv New key value.
+/// @param[in] oldtv Old key value.
+void tv_dict_watcher_notify(dict_T *const dict, const char *const key,
+ typval_T *const newtv, typval_T *const oldtv)
+ FUNC_ATTR_NONNULL_ARG(1, 2)
+{
+ typval_T argv[3];
+
+ argv[0].v_type = VAR_DICT;
+ argv[0].v_lock = VAR_UNLOCKED;
+ argv[0].vval.v_dict = dict;
+ argv[1].v_type = VAR_STRING;
+ argv[1].v_lock = VAR_UNLOCKED;
+ argv[1].vval.v_string = (char_u *)xstrdup(key);
+ argv[2].v_type = VAR_DICT;
+ argv[2].v_lock = VAR_UNLOCKED;
+ argv[2].vval.v_dict = tv_dict_alloc();
+ argv[2].vval.v_dict->dv_refcount++;
+
+ if (newtv) {
+ dictitem_T *const v = tv_dict_item_alloc_len(S_LEN("new"));
+ tv_copy(newtv, &v->di_tv);
+ tv_dict_add(argv[2].vval.v_dict, v);
+ }
+
+ if (oldtv) {
+ dictitem_T *const v = tv_dict_item_alloc_len(S_LEN("old"));
+ tv_copy(oldtv, &v->di_tv);
+ tv_dict_add(argv[2].vval.v_dict, v);
+ }
+
+ typval_T rettv;
+
+ QUEUE *w;
+ QUEUE_FOREACH(w, &dict->watchers) {
+ DictWatcher *watcher = tv_dict_watcher_node_data(w);
+ if (!watcher->busy && tv_dict_watcher_matches(watcher, key)) {
+ rettv = TV_INITIAL_VALUE;
+ watcher->busy = true;
+ callback_call(&watcher->callback, 3, argv, &rettv);
+ watcher->busy = false;
+ tv_clear(&rettv);
+ }
+ }
+
+ for (size_t i = 1; i < ARRAY_SIZE(argv); i++) {
+ tv_clear(argv + i);
+ }
+}
+
+//{{{2 Dictionary item
+
+/// Allocate a dictionary item
+///
+/// @note that the value of the item (->di_tv) still needs to be initialized.
+///
+/// @param[in] key Key, is copied to the new item.
+/// @param[in] key_len Key length.
+///
+/// @return [allocated] new dictionary item.
+dictitem_T *tv_dict_item_alloc_len(const char *const key, const size_t key_len)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+ FUNC_ATTR_MALLOC
+{
+ dictitem_T *const di = xmalloc(offsetof(dictitem_T, di_key) + key_len + 1);
+ memcpy(di->di_key, key, key_len);
+ di->di_key[key_len] = NUL;
+ di->di_flags = DI_FLAGS_ALLOC;
+ return di;
+}
+
+/// Allocate a dictionary item
+///
+/// @note that the value of the item (->di_tv) still needs to be initialized.
+///
+/// @param[in] key Key, is copied to the new item.
+///
+/// @return [allocated] new dictionary item.
+dictitem_T *tv_dict_item_alloc(const char *const key)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+ FUNC_ATTR_MALLOC
+{
+ return tv_dict_item_alloc_len(key, strlen(key));
+}
+
+/// Free a dictionary item, also clearing the value
+///
+/// @param item Item to free.
+void tv_dict_item_free(dictitem_T *const item)
+ FUNC_ATTR_NONNULL_ALL
+{
+ tv_clear(&item->di_tv);
+ if (item->di_flags & DI_FLAGS_ALLOC) {
+ xfree(item);
+ }
+}
+
+/// Make a copy of a dictionary item
+///
+/// @param[in] di Item to copy.
+///
+/// @return [allocated] new dictionary item.
+static dictitem_T *tv_dict_item_copy(dictitem_T *const di)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ dictitem_T *const new_di = tv_dict_item_alloc((const char *)di->di_key);
+ tv_copy(&di->di_tv, &new_di->di_tv);
+ return new_di;
+}
+
+/// Remove item from dictionary and free it
+///
+/// @param dict Dictionary to remove item from.
+/// @param item Item to remove.
+void tv_dict_item_remove(dict_T *const dict, dictitem_T *const item)
+ FUNC_ATTR_NONNULL_ALL
+{
+ hashitem_T *const hi = hash_find(&dict->dv_hashtab, item->di_key);
+ if (HASHITEM_EMPTY(hi)) {
+ emsgf(_(e_intern2), "tv_dict_item_remove()");
+ } else {
+ hash_remove(&dict->dv_hashtab, hi);
+ }
+ tv_dict_item_free(item);
+}
+
+//{{{2 Alloc/free
+
+/// Allocate an empty dictionary
+///
+/// @return [allocated] new dictionary.
+dict_T *tv_dict_alloc(void)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ dict_T *const d = xmalloc(sizeof(dict_T));
+
+ // Add the dict to the list of dicts for garbage collection.
+ if (gc_first_dict != NULL) {
+ gc_first_dict->dv_used_prev = d;
+ }
+ d->dv_used_next = gc_first_dict;
+ d->dv_used_prev = NULL;
+ gc_first_dict = d;
+
+ hash_init(&d->dv_hashtab);
+ d->dv_lock = VAR_UNLOCKED;
+ d->dv_scope = VAR_NO_SCOPE;
+ d->dv_refcount = 0;
+ d->dv_copyID = 0;
+ QUEUE_INIT(&d->watchers);
+
+ return d;
+}
+
+/// Free items contained in a dictionary
+///
+/// @param[in,out] d Dictionary to clear.
+void tv_dict_free_contents(dict_T *const d)
+ FUNC_ATTR_NONNULL_ALL
+{
+ // Lock the hashtab, we don't want it to resize while freeing items.
+ hash_lock(&d->dv_hashtab);
+ assert(d->dv_hashtab.ht_locked > 0);
+ HASHTAB_ITER(&d->dv_hashtab, hi, {
+ // Remove the item before deleting it, just in case there is
+ // something recursive causing trouble.
+ dictitem_T *const di = TV_DICT_HI2DI(hi);
+ hash_remove(&d->dv_hashtab, hi);
+ tv_dict_item_free(di);
+ });
+
+ while (!QUEUE_EMPTY(&d->watchers)) {
+ QUEUE *w = QUEUE_HEAD(&d->watchers);
+ QUEUE_REMOVE(w);
+ DictWatcher *watcher = tv_dict_watcher_node_data(w);
+ tv_dict_watcher_free(watcher);
+ }
+
+ hash_clear(&d->dv_hashtab);
+ d->dv_hashtab.ht_locked--;
+ hash_init(&d->dv_hashtab);
+}
+
+/// Free a dictionary itself, ignoring items it contains
+///
+/// Ignores the reference count.
+///
+/// @param[in,out] d Dictionary to free.
+void tv_dict_free_dict(dict_T *const d)
+ FUNC_ATTR_NONNULL_ALL
+{
+ // Remove the dict from the list of dicts for garbage collection.
+ if (d->dv_used_prev == NULL) {
+ gc_first_dict = d->dv_used_next;
+ } else {
+ d->dv_used_prev->dv_used_next = d->dv_used_next;
+ }
+ if (d->dv_used_next != NULL) {
+ d->dv_used_next->dv_used_prev = d->dv_used_prev;
+ }
+
+ xfree(d);
+}
+
+/// Free a dictionary, including all items it contains
+///
+/// Ignores the reference count.
+///
+/// @param d Dictionary to free.
+void tv_dict_free(dict_T *const d)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (!tv_in_free_unref_items) {
+ tv_dict_free_contents(d);
+ tv_dict_free_dict(d);
+ }
+}
+
+
+/// Unreference a dictionary
+///
+/// Decrements the reference count and frees dictionary when it becomes zero.
+///
+/// @param[in] d Dictionary to operate on.
+void tv_dict_unref(dict_T *const d)
+{
+ if (d != NULL && --d->dv_refcount <= 0) {
+ tv_dict_free(d);
+ }
+}
+
+//{{{2 Indexing/searching
+
+/// Find item in dictionary
+///
+/// @param[in] d Dictionary to check.
+/// @param[in] key Dictionary key.
+/// @param[in] len Key length. If negative, then strlen(key) is used.
+///
+/// @return found item or NULL if nothing was found.
+dictitem_T *tv_dict_find(const dict_T *const d, const char *const key,
+ const ptrdiff_t len)
+ FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (d == NULL) {
+ return NULL;
+ }
+ hashitem_T *const hi = (len < 0
+ ? hash_find(&d->dv_hashtab, (const char_u *)key)
+ : hash_find_len(&d->dv_hashtab, key, (size_t)len));
+ if (HASHITEM_EMPTY(hi)) {
+ return NULL;
+ }
+ return TV_DICT_HI2DI(hi);
+}
+
+/// Get a number item from a dictionary
+///
+/// Returns 0 if the entry does not exist.
+///
+/// @param[in] d Dictionary to get item from.
+/// @param[in] key Key to find in dictionary.
+///
+/// @return Dictionary item.
+varnumber_T tv_dict_get_number(const dict_T *const d, const char *const key)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ dictitem_T *const di = tv_dict_find(d, key, -1);
+ if (di == NULL) {
+ return 0;
+ }
+ return tv_get_number(&di->di_tv);
+}
+
+/// Get a string item from a dictionary
+///
+/// @param[in] d Dictionary to get item from.
+/// @param[in] key Dictionary key.
+/// @param[in] save If true, returned string will be placed in the allocated
+/// memory.
+///
+/// @return NULL if key does not exist, empty string in case of type error,
+/// string item value otherwise. If returned value is not NULL, it may
+/// be allocated depending on `save` argument.
+char *tv_dict_get_string(const dict_T *const d, const char *const key,
+ const bool save)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ static char numbuf[NUMBUFLEN];
+ const char *const s = tv_dict_get_string_buf(d, key, numbuf);
+ if (save && s != NULL) {
+ return xstrdup(s);
+ }
+ return (char *)s;
+}
+
+/// Get a string item from a dictionary
+///
+/// @param[in] d Dictionary to get item from.
+/// @param[in] key Dictionary key.
+/// @param[in] numbuf Buffer for non-string items converted to strings, at
+/// least of #NUMBUFLEN length.
+///
+/// @return NULL if key does not exist, empty string in case of type error,
+/// string item value otherwise.
+const char *tv_dict_get_string_buf(const dict_T *const d, const char *const key,
+ char *const numbuf)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const dictitem_T *const di = tv_dict_find(d, key, -1);
+ if (di == NULL) {
+ return NULL;
+ }
+ return tv_get_string_buf(&di->di_tv, numbuf);
+}
+
+/// Get a string item from a dictionary
+///
+/// @param[in] d Dictionary to get item from.
+/// @param[in] key Dictionary key.
+/// @param[in] key_len Key length.
+/// @param[in] numbuf Buffer for non-string items converted to strings, at
+/// least of #NUMBUFLEN length.
+/// @param[in] def Default return when key does not exist.
+///
+/// @return `def` when key does not exist,
+/// NULL in case of type error,
+/// string item value in case of success.
+const char *tv_dict_get_string_buf_chk(const dict_T *const d,
+ const char *const key,
+ const ptrdiff_t key_len,
+ char *const numbuf,
+ const char *const def)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const dictitem_T *const di = tv_dict_find(d, key, key_len);
+ if (di == NULL) {
+ return def;
+ }
+ return tv_get_string_buf_chk(&di->di_tv, numbuf);
+}
+
+/// Get a function from a dictionary
+///
+/// @param[in] d Dictionary to get callback from.
+/// @param[in] key Dictionary key.
+/// @param[in] key_len Key length, may be -1 to use strlen().
+/// @param[out] result The address where a pointer to the wanted callback
+/// will be left.
+///
+/// @return true/false on success/failure.
+bool tv_dict_get_callback(dict_T *const d,
+ const char *const key, const ptrdiff_t key_len,
+ Callback *const result)
+ FUNC_ATTR_NONNULL_ARG(2, 4) FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ result->type = kCallbackNone;
+
+ dictitem_T *const di = tv_dict_find(d, key, key_len);
+
+ if (di == NULL) {
+ return true;
+ }
+
+ if (!tv_is_func(di->di_tv) && di->di_tv.v_type != VAR_STRING) {
+ emsgf(_("E6000: Argument is not a function or function name"));
+ return false;
+ }
+
+ typval_T tv;
+ tv_copy(&di->di_tv, &tv);
+ set_selfdict(&tv, d);
+ const bool res = callback_from_typval(result, &tv);
+ tv_clear(&tv);
+ return res;
+}
+
+//{{{2 dict_add*
+
+/// Add item to dictionary
+///
+/// @param[out] d Dictionary to add to.
+/// @param[in] item Item to add.
+///
+/// @return FAIL if key already exists.
+int tv_dict_add(dict_T *const d, dictitem_T *const item)
+ FUNC_ATTR_NONNULL_ALL
+{
+ return hash_add(&d->dv_hashtab, item->di_key);
+}
+
+/// Add a list entry to dictionary
+///
+/// @param[out] d Dictionary to add entry to.
+/// @param[in] key Key to add.
+/// @param[in] key_len Key length.
+/// @param list List to add. Will have reference count incremented.
+///
+/// @return OK in case of success, FAIL when key already exists.
+int tv_dict_add_list(dict_T *const d, const char *const key,
+ const size_t key_len, list_T *const list)
+ FUNC_ATTR_NONNULL_ALL
+{
+ dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
+
+ item->di_tv.v_lock = VAR_UNLOCKED;
+ item->di_tv.v_type = VAR_LIST;
+ item->di_tv.vval.v_list = list;
+ list->lv_refcount++;
+ if (tv_dict_add(d, item) == FAIL) {
+ tv_dict_item_free(item);
+ return FAIL;
+ }
+ return OK;
+}
+
+/// Add a dictionary entry to dictionary
+///
+/// @param[out] d Dictionary to add entry to.
+/// @param[in] key Key to add.
+/// @param[in] key_len Key length.
+/// @param dict Dictionary to add. Will have reference count incremented.
+///
+/// @return OK in case of success, FAIL when key already exists.
+int tv_dict_add_dict(dict_T *const d, const char *const key,
+ const size_t key_len, dict_T *const dict)
+ FUNC_ATTR_NONNULL_ALL
+{
+ dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
+
+ item->di_tv.v_lock = VAR_UNLOCKED;
+ item->di_tv.v_type = VAR_DICT;
+ item->di_tv.vval.v_dict = dict;
+ dict->dv_refcount++;
+ if (tv_dict_add(d, item) == FAIL) {
+ tv_dict_item_free(item);
+ return FAIL;
+ }
+ return OK;
+}
+
+/// Add a number entry to dictionary
+///
+/// @param[out] d Dictionary to add entry to.
+/// @param[in] key Key to add.
+/// @param[in] key_len Key length.
+/// @param[in] nr Number to add.
+///
+/// @return OK in case of success, FAIL when key already exists.
+int tv_dict_add_nr(dict_T *const d, const char *const key,
+ const size_t key_len, const varnumber_T nr)
+{
+ dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
+
+ item->di_tv.v_lock = VAR_UNLOCKED;
+ item->di_tv.v_type = VAR_NUMBER;
+ item->di_tv.vval.v_number = nr;
+ if (tv_dict_add(d, item) == FAIL) {
+ tv_dict_item_free(item);
+ return FAIL;
+ }
+ return OK;
+}
+
+/// Add a string entry to dictionary
+///
+/// @param[out] d Dictionary to add entry to.
+/// @param[in] key Key to add.
+/// @param[in] key_len Key length.
+/// @param[in] val String to add.
+///
+/// @return OK in case of success, FAIL when key already exists.
+int tv_dict_add_str(dict_T *const d,
+ const char *const key, const size_t key_len,
+ const char *const val)
+ FUNC_ATTR_NONNULL_ALL
+{
+ return tv_dict_add_allocated_str(d, key, key_len, xstrdup(val));
+}
+
+/// Add a string entry to dictionary
+///
+/// Unlike tv_dict_add_str() saves val to the new dictionary item in place of
+/// creating a new copy.
+///
+/// @warning String will be freed even in case addition fails.
+///
+/// @param[out] d Dictionary to add entry to.
+/// @param[in] key Key to add.
+/// @param[in] key_len Key length.
+/// @param[in] val String to add.
+///
+/// @return OK in case of success, FAIL when key already exists.
+int tv_dict_add_allocated_str(dict_T *const d,
+ const char *const key, const size_t key_len,
+ char *const val)
+ FUNC_ATTR_NONNULL_ALL
+{
+ dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
+
+ item->di_tv.v_lock = VAR_UNLOCKED;
+ item->di_tv.v_type = VAR_STRING;
+ item->di_tv.vval.v_string = (char_u *)val;
+ if (tv_dict_add(d, item) == FAIL) {
+ tv_dict_item_free(item);
+ return FAIL;
+ }
+ return OK;
+}
+
+//{{{2 Operations on the whole dict
+
+/// Clear all the keys of a Dictionary. "d" remains a valid empty Dictionary.
+///
+/// @param d The Dictionary to clear
+void tv_dict_clear(dict_T *const d)
+ FUNC_ATTR_NONNULL_ALL
+{
+ hash_lock(&d->dv_hashtab);
+ assert(d->dv_hashtab.ht_locked > 0);
+
+ HASHTAB_ITER(&d->dv_hashtab, hi, {
+ tv_dict_item_free(TV_DICT_HI2DI(hi));
+ hash_remove(&d->dv_hashtab, hi);
+ });
+
+ hash_unlock(&d->dv_hashtab);
+}
+
+/// Extend dictionary with items from another dictionary
+///
+/// @param d1 Dictionary to extend.
+/// @param[in] d2 Dictionary to extend with.
+/// @param[in] action "error", "force", "keep":
+///
+/// e*, including "error": duplicate key gives an error.
+/// f*, including "force": duplicate d2 keys override d1.
+/// other, including "keep": duplicate d2 keys ignored.
+void tv_dict_extend(dict_T *const d1, dict_T *const d2,
+ const char *const action)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const bool watched = tv_dict_is_watched(d1);
+ const char *const arg_errmsg = _("extend() argument");
+ const size_t arg_errmsg_len = strlen(arg_errmsg);
+
+ TV_DICT_ITER(d2, di2, {
+ dictitem_T *const di1 = tv_dict_find(d1, (const char *)di2->di_key, -1);
+ if (d1->dv_scope != VAR_NO_SCOPE) {
+ // Disallow replacing a builtin function in l: and g:.
+ // Check the key to be valid when adding to any scope.
+ if (d1->dv_scope == VAR_DEF_SCOPE
+ && tv_is_func(di2->di_tv)
+ && !var_check_func_name((const char *)di2->di_key, di1 == NULL)) {
+ break;
+ }
+ if (!valid_varname((const char *)di2->di_key)) {
+ break;
+ }
+ }
+ if (di1 == NULL) {
+ dictitem_T *const new_di = tv_dict_item_copy(di2);
+ if (tv_dict_add(d1, new_di) == FAIL) {
+ tv_dict_item_free(new_di);
+ } else if (watched) {
+ tv_dict_watcher_notify(d1, (const char *)new_di->di_key, &new_di->di_tv,
+ NULL);
+ }
+ } else if (*action == 'e') {
+ emsgf(_("E737: Key already exists: %s"), di2->di_key);
+ break;
+ } else if (*action == 'f' && di2 != di1) {
+ typval_T oldtv;
+
+ if (tv_check_lock(di1->di_tv.v_lock, arg_errmsg, arg_errmsg_len)
+ || var_check_ro(di1->di_flags, arg_errmsg, arg_errmsg_len)) {
+ break;
+ }
+
+ if (watched) {
+ tv_copy(&di1->di_tv, &oldtv);
+ }
+
+ tv_clear(&di1->di_tv);
+ tv_copy(&di2->di_tv, &di1->di_tv);
+
+ if (watched) {
+ tv_dict_watcher_notify(d1, (const char *)di1->di_key, &di1->di_tv,
+ &oldtv);
+ tv_clear(&oldtv);
+ }
+ }
+ });
+}
+
+/// Compare two dictionaries
+///
+/// @param[in] d1 First dictionary.
+/// @param[in] d2 Second dictionary.
+/// @param[in] ic True if case is to be ignored.
+/// @param[in] recursive True when used recursively.
+bool tv_dict_equal(dict_T *const d1, dict_T *const d2,
+ const bool ic, const bool recursive)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (d1 == d2) {
+ return true;
+ }
+ if (d1 == NULL || d2 == NULL) {
+ return false;
+ }
+ if (tv_dict_len(d1) != tv_dict_len(d2)) {
+ return false;
+ }
+
+ TV_DICT_ITER(d1, di1, {
+ dictitem_T *const di2 = tv_dict_find(d2, (const char *)di1->di_key, -1);
+ if (di2 == NULL) {
+ return false;
+ }
+ if (!tv_equal(&di1->di_tv, &di2->di_tv, ic, recursive)) {
+ return false;
+ }
+ });
+ return true;
+}
+
+/// Make a copy of dictionary
+///
+/// @param[in] conv If non-NULL, then all internal strings will be converted.
+/// @param[in] orig Original dictionary to copy.
+/// @param[in] deep If false, then shallow copy will be done.
+/// @param[in] copyID See var_item_copy().
+///
+/// @return Copied dictionary. May be NULL in case original dictionary is NULL
+/// or some failure happens. The refcount of the new dictionary is set
+/// to 1.
+dict_T *tv_dict_copy(const vimconv_T *const conv,
+ dict_T *const orig,
+ const bool deep,
+ const int copyID)
+{
+ if (orig == NULL) {
+ return NULL;
+ }
+
+ dict_T *copy = tv_dict_alloc();
+ if (copyID != 0) {
+ orig->dv_copyID = copyID;
+ orig->dv_copydict = copy;
+ }
+ TV_DICT_ITER(orig, di, {
+ if (got_int) {
+ break;
+ }
+ dictitem_T *new_di;
+ if (conv == NULL || conv->vc_type == CONV_NONE) {
+ new_di = tv_dict_item_alloc((const char *)di->di_key);
+ } else {
+ size_t len = STRLEN(di->di_key);
+ char *const key = (char *)string_convert(conv, di->di_key, &len);
+ if (key == NULL) {
+ new_di = tv_dict_item_alloc_len((const char *)di->di_key, len);
+ } else {
+ new_di = tv_dict_item_alloc_len(key, len);
+ xfree(key);
+ }
+ }
+ if (deep) {
+ if (var_item_copy(conv, &di->di_tv, &new_di->di_tv, deep,
+ copyID) == FAIL) {
+ xfree(new_di);
+ break;
+ }
+ } else {
+ tv_copy(&di->di_tv, &new_di->di_tv);
+ }
+ if (tv_dict_add(copy, new_di) == FAIL) {
+ tv_dict_item_free(new_di);
+ break;
+ }
+ });
+
+ copy->dv_refcount++;
+ if (got_int) {
+ tv_dict_unref(copy);
+ copy = NULL;
+ }
+
+ return copy;
+}
+
+/// Set all existing keys in "dict" as read-only.
+///
+/// This does not protect against adding new keys to the Dictionary.
+///
+/// @param dict The dict whose keys should be frozen.
+void tv_dict_set_keys_readonly(dict_T *const dict)
+ FUNC_ATTR_NONNULL_ALL
+{
+ TV_DICT_ITER(dict, di, {
+ di->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX;
+ });
+}
+
+//{{{1 Generic typval operations
+//{{{2 Init/alloc/clear
+//{{{3 Alloc
+
+/// Allocate an empty list for a return value
+///
+/// Also sets reference count.
+///
+/// @param[out] ret_tv Structure where list is saved.
+///
+/// @return [allocated] pointer to the created list.
+list_T *tv_list_alloc_ret(typval_T *const ret_tv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ list_T *const l = tv_list_alloc();
+ ret_tv->vval.v_list = l;
+ ret_tv->v_type = VAR_LIST;
+ ret_tv->v_lock = VAR_UNLOCKED;
+ l->lv_refcount++;
+ return l;
+}
+
+/// Allocate an empty dictionary for a return value
+///
+/// Also sets reference count.
+///
+/// @param[out] ret_tv Structure where dictionary is saved.
+void tv_dict_alloc_ret(typval_T *const ret_tv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ dict_T *const d = tv_dict_alloc();
+ ret_tv->vval.v_dict = d;
+ ret_tv->v_type = VAR_DICT;
+ ret_tv->v_lock = VAR_UNLOCKED;
+ d->dv_refcount++;
+}
+
+//{{{3 Clear
+#define TYPVAL_ENCODE_ALLOW_SPECIALS false
+
+#define TYPVAL_ENCODE_CONV_NIL(tv) \
+ do { \
+ tv->vval.v_special = kSpecialVarFalse; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
+ TYPVAL_ENCODE_CONV_NIL(tv)
+
+#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
+ do { \
+ (void)num; \
+ tv->vval.v_number = 0; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num)
+
+#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
+ do { \
+ tv->vval.v_float = 0; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
+ do { \
+ xfree(buf); \
+ tv->vval.v_string = NULL; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len)
+
+#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type)
+
+static inline int _nothing_conv_func_start(typval_T *const tv,
+ char_u *const fun)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ARG(1)
+{
+ tv->v_lock = VAR_UNLOCKED;
+ if (tv->v_type == VAR_PARTIAL) {
+ partial_T *const pt_ = tv->vval.v_partial;
+ if (pt_ != NULL && pt_->pt_refcount > 1) {
+ pt_->pt_refcount--;
+ tv->vval.v_partial = NULL;
+ return OK;
+ }
+ } else {
+ func_unref(fun);
+ if ((const char *)fun != tv_empty_string) {
+ xfree(fun);
+ }
+ tv->vval.v_string = NULL;
+ }
+ return NOTDONE;
+}
+#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
+ do { \
+ if (_nothing_conv_func_start(tv, fun) != NOTDONE) { \
+ return OK; \
+ } \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
+#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
+
+static inline void _nothing_conv_func_end(typval_T *const tv, const int copyID)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
+{
+ if (tv->v_type == VAR_PARTIAL) {
+ partial_T *const pt = tv->vval.v_partial;
+ if (pt == NULL) {
+ return;
+ }
+ // Dictionary should already be freed by the time.
+ // If it was not freed then it is a part of the reference cycle.
+ assert(pt->pt_dict == NULL || pt->pt_dict->dv_copyID == copyID);
+ pt->pt_dict = NULL;
+ // As well as all arguments.
+ pt->pt_argc = 0;
+ assert(pt->pt_refcount <= 1);
+ partial_unref(pt);
+ tv->vval.v_partial = NULL;
+ assert(tv->v_lock == VAR_UNLOCKED);
+ }
+}
+#define TYPVAL_ENCODE_CONV_FUNC_END(tv) _nothing_conv_func_end(tv, copyID)
+
+#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
+ do { \
+ tv_list_unref(tv->vval.v_list); \
+ tv->vval.v_list = NULL; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
+ do { \
+ assert((void *)&dict != (void *)&TYPVAL_ENCODE_NODICT_VAR); \
+ tv_dict_unref((dict_T *)dict); \
+ *((dict_T **)&dict) = NULL; \
+ if (tv != NULL) { \
+ ((typval_T *)tv)->v_lock = VAR_UNLOCKED; \
+ } \
+ } while (0)
+
+static inline int _nothing_conv_real_list_after_start(
+ typval_T *const tv, MPConvStackVal *const mpsv)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ assert(tv != NULL);
+ tv->v_lock = VAR_UNLOCKED;
+ if (tv->vval.v_list->lv_refcount > 1) {
+ tv->vval.v_list->lv_refcount--;
+ tv->vval.v_list = NULL;
+ mpsv->data.l.li = NULL;
+ return OK;
+ }
+ return NOTDONE;
+}
+#define TYPVAL_ENCODE_CONV_LIST_START(tv, len)
+
+#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv) \
+ do { \
+ if (_nothing_conv_real_list_after_start(tv, &mpsv) != NOTDONE) { \
+ goto typval_encode_stop_converting_one_item; \
+ } \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv)
+
+static inline void _nothing_conv_list_end(typval_T *const tv)
+ FUNC_ATTR_ALWAYS_INLINE
+{
+ if (tv == NULL) {
+ return;
+ }
+ assert(tv->v_type == VAR_LIST);
+ list_T *const list = tv->vval.v_list;
+ tv_list_unref(list);
+ tv->vval.v_list = NULL;
+}
+#define TYPVAL_ENCODE_CONV_LIST_END(tv) _nothing_conv_list_end(tv)
+
+static inline int _nothing_conv_real_dict_after_start(
+ typval_T *const tv, dict_T **const dictp, const void *const nodictvar,
+ MPConvStackVal *const mpsv)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (tv != NULL) {
+ tv->v_lock = VAR_UNLOCKED;
+ }
+ if ((const void *)dictp != nodictvar && (*dictp)->dv_refcount > 1) {
+ (*dictp)->dv_refcount--;
+ *dictp = NULL;
+ mpsv->data.d.todo = 0;
+ return OK;
+ }
+ return NOTDONE;
+}
+#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len)
+
+#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv) \
+ do { \
+ if (_nothing_conv_real_dict_after_start( \
+ tv, (dict_T **)&dict, (void *)&TYPVAL_ENCODE_NODICT_VAR, \
+ &mpsv) != NOTDONE) { \
+ goto typval_encode_stop_converting_one_item; \
+ } \
+ } while (0)
+
+#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(tv, dict)
+#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict)
+#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict)
+
+static inline void _nothing_conv_dict_end(typval_T *const tv,
+ dict_T **const dictp,
+ const void *const nodictvar)
+ FUNC_ATTR_ALWAYS_INLINE
+{
+ if ((const void *)dictp != nodictvar) {
+ tv_dict_unref(*dictp);
+ *dictp = NULL;
+ }
+}
+#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
+ _nothing_conv_dict_end(tv, (dict_T **)&dict, \
+ (void *)&TYPVAL_ENCODE_NODICT_VAR)
+
+#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type)
+
+#define TYPVAL_ENCODE_SCOPE static
+#define TYPVAL_ENCODE_NAME nothing
+#define TYPVAL_ENCODE_FIRST_ARG_TYPE const void *const
+#define TYPVAL_ENCODE_FIRST_ARG_NAME ignored
+#define TYPVAL_ENCODE_TRANSLATE_OBJECT_NAME
+#include "nvim/eval/typval_encode.c.h"
+#undef TYPVAL_ENCODE_SCOPE
+#undef TYPVAL_ENCODE_NAME
+#undef TYPVAL_ENCODE_FIRST_ARG_TYPE
+#undef TYPVAL_ENCODE_FIRST_ARG_NAME
+#undef TYPVAL_ENCODE_TRANSLATE_OBJECT_NAME
+
+#undef TYPVAL_ENCODE_ALLOW_SPECIALS
+#undef TYPVAL_ENCODE_CONV_NIL
+#undef TYPVAL_ENCODE_CONV_BOOL
+#undef TYPVAL_ENCODE_CONV_NUMBER
+#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
+#undef TYPVAL_ENCODE_CONV_FLOAT
+#undef TYPVAL_ENCODE_CONV_STRING
+#undef TYPVAL_ENCODE_CONV_STR_STRING
+#undef TYPVAL_ENCODE_CONV_EXT_STRING
+#undef TYPVAL_ENCODE_CONV_FUNC_START
+#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS
+#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF
+#undef TYPVAL_ENCODE_CONV_FUNC_END
+#undef TYPVAL_ENCODE_CONV_EMPTY_LIST
+#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
+#undef TYPVAL_ENCODE_CONV_LIST_START
+#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
+#undef TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
+#undef TYPVAL_ENCODE_CONV_LIST_END
+#undef TYPVAL_ENCODE_CONV_DICT_START
+#undef TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START
+#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
+#undef TYPVAL_ENCODE_CONV_DICT_AFTER_KEY
+#undef TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS
+#undef TYPVAL_ENCODE_CONV_DICT_END
+#undef TYPVAL_ENCODE_CONV_RECURSE
+
+/// Free memory for a variable value and set the value to NULL or 0
+///
+/// @param[in,out] tv Value to free.
+void tv_clear(typval_T *const tv)
+{
+ if (tv != NULL && tv->v_type != VAR_UNKNOWN) {
+ // WARNING: do not translate the string here, gettext is slow and function
+ // is used *very* often. At the current state encode_vim_to_nothing() does
+ // not error out and does not use the argument anywhere.
+ //
+ // If situation changes and this argument will be used, translate it in the
+ // place where it is used.
+ const int evn_ret = encode_vim_to_nothing(NULL, tv, "tv_clear() argument");
+ (void)evn_ret;
+ assert(evn_ret == OK);
+ }
+}
+
+//{{{3 Free
+
+/// Free allocated VimL object and value stored inside
+///
+/// @param tv Object to free.
+void tv_free(typval_T *tv)
+{
+ if (tv != NULL) {
+ switch (tv->v_type) {
+ case VAR_PARTIAL: {
+ partial_unref(tv->vval.v_partial);
+ break;
+ }
+ case VAR_FUNC: {
+ func_unref(tv->vval.v_string);
+ FALLTHROUGH;
+ }
+ case VAR_STRING: {
+ xfree(tv->vval.v_string);
+ break;
+ }
+ case VAR_LIST: {
+ tv_list_unref(tv->vval.v_list);
+ break;
+ }
+ case VAR_DICT: {
+ tv_dict_unref(tv->vval.v_dict);
+ break;
+ }
+ case VAR_SPECIAL:
+ case VAR_NUMBER:
+ case VAR_FLOAT:
+ case VAR_UNKNOWN: {
+ break;
+ }
+ }
+ xfree(tv);
+ }
+}
+
+//{{{3 Copy
+
+/// Copy typval from one location to another
+///
+/// When needed allocates string or increases reference count. Does not make
+/// a copy of a container, but copies its reference!
+///
+/// It is OK for `from` and `to` to point to the same location; this is used to
+/// make a copy later.
+///
+/// @param[in] from Location to copy from.
+/// @param[out] to Location to copy to.
+void tv_copy(typval_T *const from, typval_T *const to)
+{
+ to->v_type = from->v_type;
+ to->v_lock = VAR_UNLOCKED;
+ memmove(&to->vval, &from->vval, sizeof(to->vval));
+ switch (from->v_type) {
+ case VAR_NUMBER:
+ case VAR_FLOAT:
+ case VAR_SPECIAL: {
+ break;
+ }
+ case VAR_STRING:
+ case VAR_FUNC: {
+ if (from->vval.v_string != NULL) {
+ to->vval.v_string = vim_strsave(from->vval.v_string);
+ if (from->v_type == VAR_FUNC) {
+ func_ref(to->vval.v_string);
+ }
+ }
+ break;
+ }
+ case VAR_PARTIAL: {
+ if (to->vval.v_partial != NULL) {
+ to->vval.v_partial->pt_refcount++;
+ }
+ break;
+ }
+ case VAR_LIST: {
+ if (from->vval.v_list != NULL) {
+ to->vval.v_list->lv_refcount++;
+ }
+ break;
+ }
+ case VAR_DICT: {
+ if (from->vval.v_dict != NULL) {
+ to->vval.v_dict->dv_refcount++;
+ }
+ break;
+ }
+ case VAR_UNKNOWN: {
+ emsgf(_(e_intern2), "tv_copy(UNKNOWN)");
+ break;
+ }
+ }
+}
+
+//{{{2 Locks
+
+/// Lock or unlock an item
+///
+/// @param[out] tv Item to (un)lock.
+/// @param[in] deep Levels to (un)lock, -1 to (un)lock everything.
+/// @param[in] lock True if it is needed to lock an item, false to unlock.
+void tv_item_lock(typval_T *const tv, const int deep, const bool lock)
+ FUNC_ATTR_NONNULL_ALL
+{
+ // TODO(ZyX-I): Make this not recursive
+ static int recurse = 0;
+
+ if (recurse >= DICT_MAXNEST) {
+ emsgf(_("E743: variable nested too deep for (un)lock"));
+ return;
+ }
+ if (deep == 0) {
+ return;
+ }
+ recurse++;
+
+ // lock/unlock the item itself
+#define CHANGE_LOCK(lock, var) \
+ do { \
+ var = ((VarLockStatus[]) { \
+ [VAR_UNLOCKED] = (lock ? VAR_LOCKED : VAR_UNLOCKED), \
+ [VAR_LOCKED] = (lock ? VAR_LOCKED : VAR_UNLOCKED), \
+ [VAR_FIXED] = VAR_FIXED, \
+ })[var]; \
+ } while (0)
+ CHANGE_LOCK(lock, tv->v_lock);
+
+ switch (tv->v_type) {
+ case VAR_LIST: {
+ list_T *const l = tv->vval.v_list;
+ if (l != NULL) {
+ CHANGE_LOCK(lock, l->lv_lock);
+ if (deep < 0 || deep > 1) {
+ // Recursive: lock/unlock the items the List contains.
+ for (listitem_T *li = l->lv_first; li != NULL; li = li->li_next) {
+ tv_item_lock(&li->li_tv, deep - 1, lock);
+ }
+ }
+ }
+ break;
+ }
+ case VAR_DICT: {
+ dict_T *const d = tv->vval.v_dict;
+ if (d != NULL) {
+ CHANGE_LOCK(lock, d->dv_lock);
+ if (deep < 0 || deep > 1) {
+ // recursive: lock/unlock the items the List contains
+ TV_DICT_ITER(d, di, {
+ tv_item_lock(&di->di_tv, deep - 1, lock);
+ });
+ }
+ }
+ break;
+ }
+ case VAR_NUMBER:
+ case VAR_FLOAT:
+ case VAR_STRING:
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ case VAR_SPECIAL: {
+ break;
+ }
+ case VAR_UNKNOWN: {
+ assert(false);
+ }
+ }
+#undef CHANGE_LOCK
+ recurse--;
+}
+
+/// Check whether VimL value is locked itself or refers to a locked container
+///
+/// @param[in] tv Value to check.
+///
+/// @return True if value is locked, false otherwise.
+bool tv_islocked(const typval_T *const tv)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+{
+ return ((tv->v_lock == VAR_LOCKED)
+ || (tv->v_type == VAR_LIST
+ && tv->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)));
+}
+
+/// Return true if typval is locked
+///
+/// Also gives an error message when typval is locked.
+///
+/// @param[in] lock Lock status.
+/// @param[in] name Variable name, used in the error message.
+/// @param[in] name_len Variable name length. Use #TV_TRANSLATE to translate
+/// variable name and compute the length. Use #TV_CSTRING
+/// to compute the length with strlen() without
+/// translating.
+///
+/// Both #TV_… values are used for optimization purposes:
+/// variable name with its length is needed only in case
+/// of error, when no error occurs computing them is
+/// a waste of CPU resources. This especially applies to
+/// gettext.
+///
+/// @return true if variable is locked, false otherwise.
+bool tv_check_lock(const VarLockStatus lock, const char *name,
+ size_t name_len)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const char *error_message = NULL;
+ switch (lock) {
+ case VAR_UNLOCKED: {
+ return false;
+ }
+ case VAR_LOCKED: {
+ error_message = N_("E741: Value is locked: %.*s");
+ break;
+ }
+ case VAR_FIXED: {
+ error_message = N_("E742: Cannot change value of %.*s");
+ break;
+ }
+ }
+ assert(error_message != NULL);
+
+ if (name == NULL) {
+ name = _("Unknown");
+ name_len = strlen(name);
+ } else if (name_len == TV_TRANSLATE) {
+ name = _(name);
+ name_len = strlen(name);
+ } else if (name_len == TV_CSTRING) {
+ name_len = strlen(name);
+ }
+
+ emsgf(_(error_message), (int)name_len, name);
+
+ return true;
+}
+
+//{{{2 Comparison
+
+static int tv_equal_recurse_limit;
+
+/// Compare two VimL values
+///
+/// Like "==", but strings and numbers are different, as well as floats and
+/// numbers.
+///
+/// @warning Too nested structures may be considered equal even if they are not.
+///
+/// @param[in] tv1 First value to compare.
+/// @param[in] tv2 Second value to compare.
+/// @param[in] ic True if case is to be ignored.
+/// @param[in] recursive True when used recursively.
+///
+/// @return true if values are equal.
+bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic,
+ const bool recursive)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+{
+ // TODO(ZyX-I): Make this not recursive
+ static int recursive_cnt = 0; // Catch recursive loops.
+
+ if (!(tv_is_func(*tv1) && tv_is_func(*tv2)) && tv1->v_type != tv2->v_type) {
+ return false;
+ }
+
+ // Catch lists and dicts that have an endless loop by limiting
+ // recursiveness to a limit. We guess they are equal then.
+ // A fixed limit has the problem of still taking an awful long time.
+ // Reduce the limit every time running into it. That should work fine for
+ // deeply linked structures that are not recursively linked and catch
+ // recursiveness quickly.
+ if (!recursive) {
+ tv_equal_recurse_limit = 1000;
+ }
+ if (recursive_cnt >= tv_equal_recurse_limit) {
+ tv_equal_recurse_limit--;
+ return true;
+ }
+
+ switch (tv1->v_type) {
+ case VAR_LIST: {
+ recursive_cnt++;
+ const bool r = tv_list_equal(tv1->vval.v_list, tv2->vval.v_list, ic,
+ true);
+ recursive_cnt--;
+ return r;
+ }
+ case VAR_DICT: {
+ recursive_cnt++;
+ const bool r = tv_dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic,
+ true);
+ recursive_cnt--;
+ return r;
+ }
+ case VAR_PARTIAL:
+ case VAR_FUNC: {
+ if ((tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial == NULL)
+ || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial == NULL)) {
+ return false;
+ }
+ recursive_cnt++;
+ const bool r = func_equal(tv1, tv2, ic);
+ recursive_cnt--;
+ return r;
+ }
+ case VAR_NUMBER: {
+ return tv1->vval.v_number == tv2->vval.v_number;
+ }
+ case VAR_FLOAT: {
+ return tv1->vval.v_float == tv2->vval.v_float;
+ }
+ case VAR_STRING: {
+ char buf1[NUMBUFLEN];
+ char buf2[NUMBUFLEN];
+ const char *s1 = tv_get_string_buf(tv1, buf1);
+ const char *s2 = tv_get_string_buf(tv2, buf2);
+ return mb_strcmp_ic((bool)ic, s1, s2) == 0;
+ }
+ case VAR_SPECIAL: {
+ return tv1->vval.v_special == tv2->vval.v_special;
+ }
+ case VAR_UNKNOWN: {
+ // VAR_UNKNOWN can be the result of an invalid expression, let’s say it
+ // does not equal anything, not even self.
+ return false;
+ }
+ }
+
+ assert(false);
+ return false;
+}
+
+//{{{2 Type checks
+
+/// Check that given value is a number or string
+///
+/// Error messages are compatible with tv_get_number() previously used for the
+/// same purpose in buf*() functions. Special values are not accepted (previous
+/// behaviour: silently fail to find buffer).
+///
+/// @param[in] tv Value to check.
+///
+/// @return true if everything is OK, false otherwise.
+bool tv_check_str_or_nr(const typval_T *const tv)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+{
+ switch (tv->v_type) {
+ case VAR_NUMBER:
+ case VAR_STRING: {
+ return true;
+ }
+ case VAR_FLOAT: {
+ emsgf(_("E805: Expected a Number or a String, Float found"));
+ return false;
+ }
+ case VAR_PARTIAL:
+ case VAR_FUNC: {
+ emsgf(_("E703: Expected a Number or a String, Funcref found"));
+ return false;
+ }
+ case VAR_LIST: {
+ emsgf(_("E745: Expected a Number or a String, List found"));
+ return false;
+ }
+ case VAR_DICT: {
+ emsgf(_("E728: Expected a Number or a String, Dictionary found"));
+ return false;
+ }
+ case VAR_SPECIAL: {
+ emsgf(_("E5300: Expected a Number or a String"));
+ return false;
+ }
+ case VAR_UNKNOWN: {
+ emsgf(_(e_intern2), "tv_check_str_or_nr(UNKNOWN)");
+ return false;
+ }
+ }
+ assert(false);
+ return false;
+}
+
+#define FUNC_ERROR "E703: Using a Funcref as a Number"
+
+static const char *const num_errors[] = {
+ [VAR_PARTIAL]=N_(FUNC_ERROR),
+ [VAR_FUNC]=N_(FUNC_ERROR),
+ [VAR_LIST]=N_("E745: Using a List as a Number"),
+ [VAR_DICT]=N_("E728: Using a Dictionary as a Number"),
+ [VAR_FLOAT]=N_("E805: Using a Float as a Number"),
+ [VAR_UNKNOWN]=N_("E685: using an invalid value as a Number"),
+};
+
+#undef FUNC_ERROR
+
+/// Check that given value is a number or can be converted to it
+///
+/// Error messages are compatible with tv_get_number_chk() previously used for
+/// the same purpose.
+///
+/// @param[in] tv Value to check.
+///
+/// @return true if everything is OK, false otherwise.
+bool tv_check_num(const typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ switch (tv->v_type) {
+ case VAR_NUMBER:
+ case VAR_SPECIAL:
+ case VAR_STRING: {
+ return true;
+ }
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_FLOAT:
+ case VAR_UNKNOWN: {
+ emsgf(_(num_errors[tv->v_type]));
+ return false;
+ }
+ }
+ assert(false);
+ return false;
+}
+
+#define FUNC_ERROR "E729: using Funcref as a String"
+
+static const char *const str_errors[] = {
+ [VAR_PARTIAL]=N_(FUNC_ERROR),
+ [VAR_FUNC]=N_(FUNC_ERROR),
+ [VAR_LIST]=N_("E730: using List as a String"),
+ [VAR_DICT]=N_("E731: using Dictionary as a String"),
+ [VAR_FLOAT]=((const char *)e_float_as_string),
+ [VAR_UNKNOWN]=N_("E908: using an invalid value as a String"),
+};
+
+#undef FUNC_ERROR
+
+/// Check that given value is a string or can be converted to it
+///
+/// Error messages are compatible with tv_get_string_chk() previously used for
+/// the same purpose.
+///
+/// @param[in] tv Value to check.
+///
+/// @return true if everything is OK, false otherwise.
+bool tv_check_str(const typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ switch (tv->v_type) {
+ case VAR_NUMBER:
+ case VAR_SPECIAL:
+ case VAR_STRING: {
+ return true;
+ }
+ case VAR_PARTIAL:
+ case VAR_FUNC:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_FLOAT:
+ case VAR_UNKNOWN: {
+ emsgf(_(str_errors[tv->v_type]));
+ return false;
+ }
+ }
+ assert(false);
+ return false;
+}
+
+//{{{2 Get
+
+/// Get the number value of a VimL object
+///
+/// @note Use tv_get_number_chk() if you need to determine whether there was an
+/// error.
+///
+/// @param[in] tv Object to get value from.
+///
+/// @return Number value: vim_str2nr() output for VAR_STRING objects, value
+/// for VAR_NUMBER objects, -1 for other types.
+varnumber_T tv_get_number(const typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ bool error = false;
+ return tv_get_number_chk(tv, &error);
+}
+
+/// Get the number value of a VimL object
+///
+/// @param[in] tv Object to get value from.
+/// @param[out] ret_error If type error occurred then `true` will be written
+/// to this location. Otherwise it is not touched.
+///
+/// @note Needs to be initialized to `false` to be
+/// useful.
+///
+/// @return Number value: vim_str2nr() output for VAR_STRING objects, value
+/// for VAR_NUMBER objects, -1 (ret_error == NULL) or 0 (otherwise) for
+/// other types.
+varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1)
+{
+ switch (tv->v_type) {
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_FLOAT: {
+ emsgf(_(num_errors[tv->v_type]));
+ break;
+ }
+ case VAR_NUMBER: {
+ return tv->vval.v_number;
+ }
+ case VAR_STRING: {
+ varnumber_T n = 0;
+ if (tv->vval.v_string != NULL) {
+ vim_str2nr(tv->vval.v_string, NULL, NULL, STR2NR_ALL, &n, NULL, 0);
+ }
+ return n;
+ }
+ case VAR_SPECIAL: {
+ switch (tv->vval.v_special) {
+ case kSpecialVarTrue: {
+ return 1;
+ }
+ case kSpecialVarFalse:
+ case kSpecialVarNull: {
+ return 0;
+ }
+ }
+ break;
+ }
+ case VAR_UNKNOWN: {
+ emsgf(_(e_intern2), "tv_get_number(UNKNOWN)");
+ break;
+ }
+ }
+ if (ret_error != NULL) {
+ *ret_error = true;
+ }
+ return (ret_error == NULL ? -1 : 0);
+}
+
+/// Get the line number from VimL object
+///
+/// @param[in] tv Object to get value from. Is expected to be a number or
+/// a special string like ".", "$", … (works with current buffer
+/// only).
+///
+/// @return Line number or -1 or 0.
+linenr_T tv_get_lnum(const typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ linenr_T lnum = (linenr_T)tv_get_number_chk(tv, NULL);
+ if (lnum == 0) { // No valid number, try using same function as line() does.
+ int fnum;
+ pos_T *const fp = var2fpos(tv, true, &fnum);
+ if (fp != NULL) {
+ lnum = fp->lnum;
+ }
+ }
+ return lnum;
+}
+
+/// Get the floating-point value of a VimL object
+///
+/// Raises an error if object is not number or floating-point.
+///
+/// @param[in] tv Object to get value of.
+///
+/// @return Floating-point value of the variable or zero.
+float_T tv_get_float(const typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ switch (tv->v_type) {
+ case VAR_NUMBER: {
+ return (float_T)(tv->vval.v_number);
+ }
+ case VAR_FLOAT: {
+ return tv->vval.v_float;
+ }
+ case VAR_PARTIAL:
+ case VAR_FUNC: {
+ emsgf(_("E891: Using a Funcref as a Float"));
+ break;
+ }
+ case VAR_STRING: {
+ emsgf(_("E892: Using a String as a Float"));
+ break;
+ }
+ case VAR_LIST: {
+ emsgf(_("E893: Using a List as a Float"));
+ break;
+ }
+ case VAR_DICT: {
+ emsgf(_("E894: Using a Dictionary as a Float"));
+ break;
+ }
+ case VAR_SPECIAL: {
+ emsgf(_("E907: Using a special value as a Float"));
+ break;
+ }
+ case VAR_UNKNOWN: {
+ emsgf(_(e_intern2), "tv_get_float(UNKNOWN)");
+ break;
+ }
+ }
+ return 0;
+}
+
+/// Get the string value of a VimL object
+///
+/// @param[in] tv Object to get value of.
+/// @param buf Buffer used to hold numbers and special variables converted to
+/// string. When function encounters one of these stringified value
+/// will be written to buf and buf will be returned.
+///
+/// Buffer must have NUMBUFLEN size.
+///
+/// @return Object value if it is VAR_STRING object, number converted to
+/// a string for VAR_NUMBER, v: variable name for VAR_SPECIAL or NULL.
+const char *tv_get_string_buf_chk(const typval_T *const tv, char *const buf)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ switch (tv->v_type) {
+ case VAR_NUMBER: {
+ snprintf(buf, NUMBUFLEN, "%" PRIdVARNUMBER, tv->vval.v_number);
+ return buf;
+ }
+ case VAR_STRING: {
+ if (tv->vval.v_string != NULL) {
+ return (const char *)tv->vval.v_string;
+ }
+ return "";
+ }
+ case VAR_SPECIAL: {
+ STRCPY(buf, encode_special_var_names[tv->vval.v_special]);
+ return buf;
+ }
+ case VAR_PARTIAL:
+ case VAR_FUNC:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_FLOAT:
+ case VAR_UNKNOWN: {
+ emsgf(_(str_errors[tv->v_type]));
+ return false;
+ }
+ }
+ return NULL;
+}
+
+/// Get the string value of a VimL object
+///
+/// @warning For number and special values it uses a single, static buffer. It
+/// may be used only once, next call to get_tv_string may reuse it. Use
+/// tv_get_string_buf() if you need to use tv_get_string() output after
+/// calling it again.
+///
+/// @param[in] tv Object to get value of.
+///
+/// @return Object value if it is VAR_STRING object, number converted to
+/// a string for VAR_NUMBER, v: variable name for VAR_SPECIAL or NULL.
+const char *tv_get_string_chk(const typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ static char mybuf[NUMBUFLEN];
+
+ return tv_get_string_buf_chk(tv, mybuf);
+}
+
+/// Get the string value of a VimL object
+///
+/// @warning For number and special values it uses a single, static buffer. It
+/// may be used only once, next call to get_tv_string may reuse it. Use
+/// tv_get_string_buf() if you need to use tv_get_string() output after
+/// calling it again.
+///
+/// @note tv_get_string_chk() and tv_get_string_buf_chk() are similar, but
+/// return NULL on error.
+///
+/// @param[in] tv Object to get value of.
+///
+/// @return Object value if it is VAR_STRING object, number converted to
+/// a string for VAR_NUMBER, v: variable name for VAR_SPECIAL or empty
+/// string.
+const char *tv_get_string(const typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ static char mybuf[NUMBUFLEN];
+ return tv_get_string_buf((typval_T *)tv, mybuf);
+}
+
+/// Get the string value of a VimL object
+///
+/// @note tv_get_string_chk() and tv_get_string_buf_chk() are similar, but
+/// return NULL on error.
+///
+/// @param[in] tv Object to get value of.
+/// @param buf Buffer used to hold numbers and special variables converted to
+/// string. When function encounters one of these stringified value
+/// will be written to buf and buf will be returned.
+///
+/// Buffer must have NUMBUFLEN size.
+///
+/// @return Object value if it is VAR_STRING object, number converted to
+/// a string for VAR_NUMBER, v: variable name for VAR_SPECIAL or empty
+/// string.
+const char *tv_get_string_buf(const typval_T *const tv, char *const buf)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const char *const res = (const char *)tv_get_string_buf_chk(tv, buf);
+
+ return res != NULL ? res : "";
+}
diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h
new file mode 100644
index 0000000000..c44b85644d
--- /dev/null
+++ b/src/nvim/eval/typval.h
@@ -0,0 +1,448 @@
+#ifndef NVIM_EVAL_TYPVAL_H
+#define NVIM_EVAL_TYPVAL_H
+
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "nvim/types.h"
+#include "nvim/hashtab.h"
+#include "nvim/garray.h"
+#include "nvim/mbyte.h"
+#include "nvim/func_attr.h"
+#include "nvim/lib/queue.h"
+#include "nvim/profile.h" // for proftime_T
+#include "nvim/pos.h" // for linenr_T
+#include "nvim/gettext.h"
+#include "nvim/message.h"
+#include "nvim/macros.h"
+
+/// Type used for VimL VAR_NUMBER values
+typedef int64_t varnumber_T;
+typedef uint64_t uvarnumber_T;
+
+/// Type used for VimL VAR_FLOAT values
+typedef double float_T;
+
+/// Maximal possible value of varnumber_T variable
+#define VARNUMBER_MAX INT64_MAX
+#define UVARNUMBER_MAX UINT64_MAX
+
+/// Mimimal possible value of varnumber_T variable
+#define VARNUMBER_MIN INT64_MIN
+
+/// %d printf format specifier for varnumber_T
+#define PRIdVARNUMBER PRId64
+
+typedef struct listvar_S list_T;
+typedef struct dictvar_S dict_T;
+typedef struct partial_S partial_T;
+
+typedef struct ufunc ufunc_T;
+
+typedef enum {
+ kCallbackNone = 0,
+ kCallbackFuncref,
+ kCallbackPartial,
+} CallbackType;
+
+typedef struct {
+ union {
+ char_u *funcref;
+ partial_T *partial;
+ } data;
+ CallbackType type;
+} Callback;
+#define CALLBACK_NONE ((Callback){ .type = kCallbackNone })
+
+/// Structure holding dictionary watcher
+typedef struct dict_watcher {
+ Callback callback;
+ char *key_pattern;
+ size_t key_pattern_len;
+ QUEUE node;
+ bool busy; // prevent recursion if the dict is changed in the callback
+} DictWatcher;
+
+/// Special variable values
+typedef enum {
+ kSpecialVarFalse, ///< v:false
+ kSpecialVarTrue, ///< v:true
+ kSpecialVarNull, ///< v:null
+} SpecialVarValue;
+
+/// Variable lock status for typval_T.v_lock
+typedef enum {
+ VAR_UNLOCKED = 0, ///< Not locked.
+ VAR_LOCKED = 1, ///< User lock, can be unlocked.
+ VAR_FIXED = 2, ///< Locked forever.
+} VarLockStatus;
+
+/// VimL variable types, for use in typval_T.v_type
+typedef enum {
+ VAR_UNKNOWN = 0, ///< Unknown (unspecified) value.
+ VAR_NUMBER, ///< Number, .v_number is used.
+ VAR_STRING, ///< String, .v_string is used.
+ VAR_FUNC, ///< Function reference, .v_string is used as function name.
+ VAR_LIST, ///< List, .v_list is used.
+ VAR_DICT, ///< Dictionary, .v_dict is used.
+ VAR_FLOAT, ///< Floating-point value, .v_float is used.
+ VAR_SPECIAL, ///< Special value (true, false, null), .v_special
+ ///< is used.
+ VAR_PARTIAL, ///< Partial, .v_partial is used.
+} VarType;
+
+/// Structure that holds an internal variable value
+typedef struct {
+ VarType v_type; ///< Variable type.
+ VarLockStatus v_lock; ///< Variable lock status.
+ union typval_vval_union {
+ varnumber_T v_number; ///< Number, for VAR_NUMBER.
+ SpecialVarValue v_special; ///< Special value, for VAR_SPECIAL.
+ float_T v_float; ///< Floating-point number, for VAR_FLOAT.
+ char_u *v_string; ///< String, for VAR_STRING and VAR_FUNC, can be NULL.
+ list_T *v_list; ///< List for VAR_LIST, can be NULL.
+ dict_T *v_dict; ///< Dictionary for VAR_DICT, can be NULL.
+ partial_T *v_partial; ///< Closure: function with args.
+ } vval; ///< Actual value.
+} typval_T;
+
+/// Values for (struct dictvar_S).dv_scope
+typedef enum {
+ VAR_NO_SCOPE = 0, ///< Not a scope dictionary.
+ VAR_SCOPE = 1, ///< Scope dictionary which requires prefix (a:, v:, …).
+ VAR_DEF_SCOPE = 2, ///< Scope dictionary which may be accessed without prefix
+ ///< (l:, g:).
+} ScopeType;
+
+/// Structure to hold an item of a list
+typedef struct listitem_S listitem_T;
+
+struct listitem_S {
+ listitem_T *li_next; ///< Next item in list.
+ listitem_T *li_prev; ///< Previous item in list.
+ typval_T li_tv; ///< Item value.
+};
+
+/// Structure used by those that are using an item in a list
+typedef struct listwatch_S listwatch_T;
+
+struct listwatch_S {
+ listitem_T *lw_item; ///< Item being watched.
+ listwatch_T *lw_next; ///< Next watcher.
+};
+
+/// Structure to hold info about a list
+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; ///< Index of a cached item, used for optimising repeated l[idx].
+ 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().
+ VarLockStatus 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.
+};
+
+// Static list with 10 items. Use init_static_list() to initialize.
+typedef struct {
+ list_T sl_list; // must be first
+ listitem_T sl_items[10];
+} staticList10_T;
+
+// 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!)
+};
+
+#define TV_DICTITEM_STRUCT(KEY_LEN) \
+ struct { \
+ typval_T di_tv; /* Structure that holds scope dictionary itself. */ \
+ uint8_t di_flags; /* Flags. */ \
+ char_u di_key[KEY_LEN]; /* Key value. */ \
+ }
+
+/// Structure to hold a scope dictionary
+///
+/// @warning Must be compatible with dictitem_T.
+///
+/// For use in find_var_in_ht to pretend that it found dictionary item when it
+/// finds scope dictionary.
+typedef TV_DICTITEM_STRUCT(1) ScopeDictDictItem;
+
+/// Structure to hold an item of a Dictionary
+///
+/// @warning Must be compatible with ScopeDictDictItem.
+///
+/// Also used for a variable.
+typedef TV_DICTITEM_STRUCT() dictitem_T;
+
+/// Flags for dictitem_T.di_flags
+typedef enum {
+ DI_FLAGS_RO = 1, ///< Read-only value
+ DI_FLAGS_RO_SBX = 2, ///< Value, read-only in the sandbox
+ DI_FLAGS_FIX = 4, ///< Fixed value: cannot be :unlet or remove()d.
+ DI_FLAGS_LOCK = 8, ///< Locked value.
+ DI_FLAGS_ALLOC = 16, ///< Separately allocated.
+} DictItemFlags;
+
+/// Structure representing a Dictionary
+struct dictvar_S {
+ VarLockStatus dv_lock; ///< Whole dictionary lock status.
+ ScopeType dv_scope; ///< Non-zero (#VAR_SCOPE, #VAR_DEF_SCOPE) if
+ ///< dictionary represents a scope (i.e. g:, l: …).
+ int dv_refcount; ///< Reference count.
+ int dv_copyID; ///< ID used when recursivery traversing a value.
+ hashtab_T dv_hashtab; ///< Hashtab containing all items.
+ dict_T *dv_copydict; ///< Copied dict used by deepcopy().
+ dict_T *dv_used_next; ///< Next dictionary in used dictionaries list.
+ dict_T *dv_used_prev; ///< Previous dictionary in used dictionaries list.
+ QUEUE watchers; ///< Dictionary key watchers set by user code.
+};
+
+/// Type used for script ID
+typedef int scid_T;
+/// Format argument for scid_T
+#define PRIdSCID "d"
+
+// Structure to hold info for a function that is currently being executed.
+typedef struct funccall_S funccall_T;
+
+/// Structure to hold info for a user function.
+struct ufunc {
+ int uf_varargs; ///< variable nr of arguments
+ int uf_flags;
+ int uf_calls; ///< nr of active calls
+ bool uf_cleared; ///< func_clear() was already called
+ garray_T uf_args; ///< arguments
+ garray_T uf_lines; ///< function lines
+ int uf_profiling; ///< true when func is being profiled
+ // Profiling the function as a whole.
+ int uf_tm_count; ///< nr of calls
+ proftime_T uf_tm_total; ///< time spent in function + children
+ proftime_T uf_tm_self; ///< time spent in function itself
+ proftime_T uf_tm_children; ///< time spent in children this call
+ // Profiling the function per line.
+ int *uf_tml_count; ///< nr of times line was executed
+ proftime_T *uf_tml_total; ///< time spent in a line + children
+ proftime_T *uf_tml_self; ///< time spent in a line itself
+ proftime_T uf_tml_start; ///< start time for current line
+ proftime_T uf_tml_children; ///< time spent in children for this line
+ proftime_T uf_tml_wait; ///< start wait time for current line
+ int uf_tml_idx; ///< index of line being timed; -1 if none
+ int uf_tml_execed; ///< line being timed was executed
+ scid_T uf_script_ID; ///< ID of script where function was defined,
+ ///< used for s: variables
+ int uf_refcount; ///< reference count, see func_name_refcount()
+ funccall_T *uf_scoped; ///< l: local variables for closure
+ char_u uf_name[1]; ///< name of function (actually longer); can
+ ///< start with <SNR>123_ (<SNR> is K_SPECIAL
+ ///< KS_EXTRA KE_SNR)
+};
+
+/// Maximum number of function arguments
+#define MAX_FUNC_ARGS 20
+
+struct partial_S {
+ int pt_refcount; ///< Reference count.
+ char_u *pt_name; ///< Function name; when NULL use pt_func->name.
+ ufunc_T *pt_func; ///< Function pointer; when NULL lookup function with
+ ///< pt_name.
+ bool pt_auto; ///< When true the partial was created by using dict.member
+ ///< in handle_subscript().
+ int pt_argc; ///< Number of arguments.
+ typval_T *pt_argv; ///< Arguments in allocated array.
+ dict_T *pt_dict; ///< Dict for "self".
+};
+
+/// Structure used for explicit stack while garbage collecting hash tables
+typedef struct ht_stack_S {
+ hashtab_T *ht;
+ struct ht_stack_S *prev;
+} ht_stack_T;
+
+/// Structure used for explicit stack while garbage collecting lists
+typedef struct list_stack_S {
+ list_T *list;
+ struct list_stack_S *prev;
+} list_stack_T;
+
+// In a hashtab item "hi_key" points to "di_key" in a dictitem.
+// This avoids adding a pointer to the hashtab item.
+
+/// Convert a hashitem pointer to a dictitem pointer
+#define TV_DICT_HI2DI(hi) \
+ ((dictitem_T *)((hi)->hi_key - offsetof(dictitem_T, di_key)))
+
+static inline long tv_list_len(const list_T *const l)
+ REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Get the number of items in a list
+///
+/// @param[in] l List to check.
+static inline long tv_list_len(const list_T *const l)
+{
+ if (l == NULL) {
+ return 0;
+ }
+ return l->lv_len;
+}
+
+static inline long tv_dict_len(const dict_T *const d)
+ REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Get the number of items in a Dictionary
+///
+/// @param[in] d Dictionary to check.
+static inline long tv_dict_len(const dict_T *const d)
+{
+ if (d == NULL) {
+ return 0L;
+ }
+ return (long)d->dv_hashtab.ht_used;
+}
+
+static inline bool tv_dict_is_watched(const dict_T *const d)
+ REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Check if dictionary is watched
+///
+/// @param[in] d Dictionary to check.
+///
+/// @return true if there is at least one watcher.
+static inline bool tv_dict_is_watched(const dict_T *const d)
+{
+ return d && !QUEUE_EMPTY(&d->watchers);
+}
+
+/// Initialize VimL object
+///
+/// Initializes to unlocked VAR_UNKNOWN object.
+///
+/// @param[out] tv Object to initialize.
+static inline void tv_init(typval_T *const tv)
+{
+ if (tv != NULL) {
+ memset(tv, 0, sizeof(*tv));
+ }
+}
+
+#define TV_INITIAL_VALUE \
+ ((typval_T) { \
+ .v_type = VAR_UNKNOWN, \
+ .v_lock = VAR_UNLOCKED, \
+ })
+
+/// Empty string
+///
+/// Needed for hack which allows not allocating empty string and still not
+/// crashing when freeing it.
+extern const char *const tv_empty_string;
+
+/// Specifies that free_unref_items() function has (not) been entered
+extern bool tv_in_free_unref_items;
+
+/// Iterate over a dictionary
+///
+/// @param[in] d Dictionary to iterate over.
+/// @param di Name of the variable with current dictitem_T entry.
+/// @param code Cycle body.
+#define TV_DICT_ITER(d, di, code) \
+ HASHTAB_ITER(&(d)->dv_hashtab, di##hi_, { \
+ { \
+ dictitem_T *const di = TV_DICT_HI2DI(di##hi_); \
+ { \
+ code \
+ } \
+ } \
+ })
+
+static inline bool tv_get_float_chk(const typval_T *const tv,
+ float_T *const ret_f)
+ REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT;
+
+// FIXME circular dependency, cannot import message.h.
+bool emsgf(const char *const fmt, ...);
+
+/// Get the float value
+///
+/// Raises an error if object is not number or floating-point.
+///
+/// @param[in] tv VimL object to get value from.
+/// @param[out] ret_f Location where resulting float is stored.
+///
+/// @return true in case of success, false if tv is not a number or float.
+static inline bool tv_get_float_chk(const typval_T *const tv,
+ float_T *const ret_f)
+{
+ if (tv->v_type == VAR_FLOAT) {
+ *ret_f = tv->vval.v_float;
+ return true;
+ }
+ if (tv->v_type == VAR_NUMBER) {
+ *ret_f = (float_T)tv->vval.v_number;
+ return true;
+ }
+ emsgf(_("E808: Number or Float required"));
+ return false;
+}
+
+static inline DictWatcher *tv_dict_watcher_node_data(QUEUE *q)
+ REAL_FATTR_NONNULL_ALL REAL_FATTR_NONNULL_RET REAL_FATTR_PURE
+ REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_ALWAYS_INLINE;
+
+/// Compute the `DictWatcher` address from a QUEUE node.
+///
+/// This only exists for .asan-blacklist (ASAN doesn't handle QUEUE_DATA pointer
+/// arithmetic).
+static inline DictWatcher *tv_dict_watcher_node_data(QUEUE *q)
+{
+ return QUEUE_DATA(q, DictWatcher, node);
+}
+
+static inline bool tv_is_func(const typval_T tv)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_CONST;
+
+/// Check whether given typval_T contains a function
+///
+/// That is, whether it contains VAR_FUNC or VAR_PARTIAL.
+///
+/// @param[in] tv Typval to check.
+///
+/// @return True if it is a function or a partial, false otherwise.
+static inline bool tv_is_func(const typval_T tv)
+{
+ return tv.v_type == VAR_FUNC || tv.v_type == VAR_PARTIAL;
+}
+
+/// Specify that argument needs to be translated
+///
+/// Used for size_t length arguments to avoid calling gettext() and strlen()
+/// unless needed.
+#define TV_TRANSLATE (SIZE_MAX)
+
+/// Specify that argument is a NUL-terminated C string
+///
+/// Used for size_t length arguments to avoid calling strlen() unless needed.
+#define TV_CSTRING (SIZE_MAX - 1)
+
+#ifdef UNIT_TESTING
+// Do not use enum constants, see commit message.
+EXTERN const size_t kTVCstring INIT(= TV_CSTRING);
+EXTERN const size_t kTVTranslate INIT(= TV_TRANSLATE);
+#endif
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "eval/typval.h.generated.h"
+#endif
+#endif // NVIM_EVAL_TYPVAL_H
diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h
index 365eb2dd77..a93ad2dbba 100644
--- a/src/nvim/eval/typval_encode.c.h
+++ b/src/nvim/eval/typval_encode.c.h
@@ -233,16 +233,12 @@
///
/// This name will only be used by one of the above macros which are defined by
/// the caller. Functions defined here do not use first argument directly.
-#ifndef NVIM_EVAL_TYPVAL_ENCODE_C_H
-#define NVIM_EVAL_TYPVAL_ENCODE_C_H
-#undef NVIM_EVAL_TYPVAL_ENCODE_C_H
-
#include <stddef.h>
#include <inttypes.h>
#include <assert.h>
#include "nvim/lib/kvec.h"
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
#include "nvim/eval/encode.h"
#include "nvim/func_attr.h"
#include "nvim/eval/typval_encode.h"
@@ -344,10 +340,11 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
case VAR_PARTIAL: {
partial_T *const pt = tv->vval.v_partial;
(void)pt;
- TYPVAL_ENCODE_CONV_FUNC_START(tv, (pt == NULL ? NULL : pt->pt_name));
+ TYPVAL_ENCODE_CONV_FUNC_START(tv, (pt == NULL ? NULL : partial_name(pt)));
_mp_push(*mpstack, ((MPConvStackVal) {
.type = kMPConvPartial,
.tv = tv,
+ .saved_copyID = copyID - 1,
.data = {
.p = {
.stage = kMPConvPartialArgs,
@@ -362,12 +359,15 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
TYPVAL_ENCODE_CONV_EMPTY_LIST(tv);
break;
}
+ const int saved_copyID = tv->vval.v_list->lv_copyID;
_TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_list, lv_copyID, copyID,
kMPConvList);
TYPVAL_ENCODE_CONV_LIST_START(tv, tv->vval.v_list->lv_len);
+ assert(saved_copyID != copyID && saved_copyID != copyID - 1);
_mp_push(*mpstack, ((MPConvStackVal) {
.type = kMPConvList,
.tv = tv,
+ .saved_copyID = saved_copyID,
.data = {
.l = {
.list = tv->vval.v_list,
@@ -402,11 +402,11 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
const dictitem_T *val_di;
if (TYPVAL_ENCODE_ALLOW_SPECIALS
&& tv->vval.v_dict->dv_hashtab.ht_used == 2
- && (type_di = dict_find((dict_T *)tv->vval.v_dict,
- (char_u *)"_TYPE", -1)) != NULL
+ && (type_di = tv_dict_find((dict_T *)tv->vval.v_dict,
+ S_LEN("_TYPE"))) != NULL
&& type_di->di_tv.v_type == VAR_LIST
- && (val_di = dict_find((dict_T *)tv->vval.v_dict,
- (char_u *)"_VAL", -1)) != NULL) {
+ && (val_di = tv_dict_find((dict_T *)tv->vval.v_dict,
+ S_LEN("_VAL"))) != NULL) {
size_t i;
for (i = 0; i < ARRAY_SIZE(eval_msgpack_type_lists); i++) {
if (type_di->di_tv.vval.v_list == eval_msgpack_type_lists[i]) {
@@ -485,7 +485,7 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
}
if (is_string) {
TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len);
- } else {
+ } else { // -V523
TYPVAL_ENCODE_CONV_STRING(tv, buf, len);
}
xfree(buf);
@@ -495,14 +495,17 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
if (val_di->di_tv.v_type != VAR_LIST) {
goto _convert_one_value_regular_dict;
}
+ const int saved_copyID = val_di->di_tv.vval.v_list->lv_copyID;
_TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_di->di_tv.vval.v_list,
lv_copyID, copyID,
kMPConvList);
TYPVAL_ENCODE_CONV_LIST_START(tv,
val_di->di_tv.vval.v_list->lv_len);
+ assert(saved_copyID != copyID && saved_copyID != copyID - 1);
_mp_push(*mpstack, ((MPConvStackVal) {
.tv = tv,
.type = kMPConvList,
+ .saved_copyID = saved_copyID,
.data = {
.l = {
.list = val_di->di_tv.vval.v_list,
@@ -528,13 +531,16 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
goto _convert_one_value_regular_dict;
}
}
+ const int saved_copyID = val_di->di_tv.vval.v_list->lv_copyID;
_TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_list, lv_copyID, copyID,
kMPConvPairs);
TYPVAL_ENCODE_CONV_DICT_START(tv, TYPVAL_ENCODE_NODICT_VAR,
val_list->lv_len);
+ assert(saved_copyID != copyID && saved_copyID != copyID - 1);
_mp_push(*mpstack, ((MPConvStackVal) {
.tv = tv,
.type = kMPConvPairs,
+ .saved_copyID = saved_copyID,
.data = {
.l = {
.list = val_list,
@@ -569,14 +575,17 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
}
break;
}
-_convert_one_value_regular_dict:
+_convert_one_value_regular_dict: {}
+ const int saved_copyID = tv->vval.v_dict->dv_copyID;
_TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_dict, dv_copyID, copyID,
kMPConvDict);
TYPVAL_ENCODE_CONV_DICT_START(tv, tv->vval.v_dict,
tv->vval.v_dict->dv_hashtab.ht_used);
+ assert(saved_copyID != copyID && saved_copyID != copyID - 1);
_mp_push(*mpstack, ((MPConvStackVal) {
.tv = tv,
.type = kMPConvDict,
+ .saved_copyID = saved_copyID,
.data = {
.d = {
.dict = tv->vval.v_dict,
@@ -598,7 +607,7 @@ _convert_one_value_regular_dict:
typval_encode_stop_converting_one_item:
return OK;
// Prevent “unused label†warnings.
- goto typval_encode_stop_converting_one_item;
+ goto typval_encode_stop_converting_one_item; // -V779
}
TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE(
@@ -638,7 +647,7 @@ typval_encode_stop_converting_one_item:
case kMPConvDict: {
if (!cur_mpsv->data.d.todo) {
(void)_mp_pop(mpstack);
- cur_mpsv->data.d.dict->dv_copyID = copyID - 1;
+ cur_mpsv->data.d.dict->dv_copyID = cur_mpsv->saved_copyID;
TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, *cur_mpsv->data.d.dictp);
continue;
} else if (cur_mpsv->data.d.todo
@@ -649,7 +658,7 @@ typval_encode_stop_converting_one_item:
while (HASHITEM_EMPTY(cur_mpsv->data.d.hi)) {
cur_mpsv->data.d.hi++;
}
- dictitem_T *const di = HI2DI(cur_mpsv->data.d.hi);
+ dictitem_T *const di = TV_DICT_HI2DI(cur_mpsv->data.d.hi);
cur_mpsv->data.d.todo--;
cur_mpsv->data.d.hi++;
TYPVAL_ENCODE_CONV_STR_STRING(NULL, &di->di_key[0],
@@ -662,7 +671,7 @@ typval_encode_stop_converting_one_item:
case kMPConvList: {
if (cur_mpsv->data.l.li == NULL) {
(void)_mp_pop(mpstack);
- cur_mpsv->data.l.list->lv_copyID = copyID - 1;
+ cur_mpsv->data.l.list->lv_copyID = cur_mpsv->saved_copyID;
TYPVAL_ENCODE_CONV_LIST_END(cur_mpsv->tv);
continue;
} else if (cur_mpsv->data.l.li != cur_mpsv->data.l.list->lv_first) {
@@ -675,7 +684,7 @@ typval_encode_stop_converting_one_item:
case kMPConvPairs: {
if (cur_mpsv->data.l.li == NULL) {
(void)_mp_pop(mpstack);
- cur_mpsv->data.l.list->lv_copyID = copyID - 1;
+ cur_mpsv->data.l.list->lv_copyID = cur_mpsv->saved_copyID;
TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR);
continue;
} else if (cur_mpsv->data.l.li != cur_mpsv->data.l.list->lv_first) {
@@ -711,6 +720,7 @@ typval_encode_stop_converting_one_item:
_mp_push(mpstack, ((MPConvStackVal) {
.type = kMPConvPartialList,
.tv = NULL,
+ .saved_copyID = copyID - 1,
.data = {
.a = {
.arg = pt->pt_argv,
@@ -731,6 +741,7 @@ typval_encode_stop_converting_one_item:
TYPVAL_ENCODE_CONV_EMPTY_DICT(NULL, pt->pt_dict);
continue;
}
+ const int saved_copyID = dict->dv_copyID;
const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(
TYPVAL_ENCODE_FIRST_ARG_NAME,
dict, &dict->dv_copyID, &mpstack, copyID, kMPConvDict,
@@ -744,9 +755,11 @@ typval_encode_stop_converting_one_item:
}
TYPVAL_ENCODE_CONV_DICT_START(NULL, pt->pt_dict,
dict->dv_hashtab.ht_used);
+ assert(saved_copyID != copyID && saved_copyID != copyID - 1);
_mp_push(mpstack, ((MPConvStackVal) {
.type = kMPConvDict,
.tv = NULL,
+ .saved_copyID = saved_copyID,
.data = {
.d = {
.dict = dict,
@@ -797,6 +810,5 @@ encode_vim_to__error_ret:
_mp_destroy(mpstack);
return FAIL;
// Prevent “unused label†warnings.
- goto typval_encode_stop_converting_one_item;
+ goto typval_encode_stop_converting_one_item; // -V779
}
-#endif // NVIM_EVAL_TYPVAL_ENCODE_C_H
diff --git a/src/nvim/eval/typval_encode.h b/src/nvim/eval/typval_encode.h
index ba325b8f55..3475f6d8b3 100644
--- a/src/nvim/eval/typval_encode.h
+++ b/src/nvim/eval/typval_encode.h
@@ -11,7 +11,7 @@
#include <assert.h>
#include "nvim/lib/kvec.h"
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
#include "nvim/func_attr.h"
/// Type of the stack entry
@@ -34,6 +34,7 @@ typedef enum {
typedef struct {
MPConvStackValType type; ///< Type of the stack entry.
typval_T *tv; ///< Currently converted typval_T.
+ int saved_copyID; ///< copyID item used to have.
union {
struct {
dict_T *dict; ///< Currently converted dictionary.
diff --git a/src/nvim/eval_defs.h b/src/nvim/eval_defs.h
deleted file mode 100644
index f478d19ca1..0000000000
--- a/src/nvim/eval_defs.h
+++ /dev/null
@@ -1,198 +0,0 @@
-#ifndef NVIM_EVAL_DEFS_H
-#define NVIM_EVAL_DEFS_H
-
-#include <limits.h>
-#include <stddef.h>
-
-#include "nvim/hashtab.h"
-#include "nvim/lib/queue.h"
-
-typedef int varnumber_T;
-typedef double float_T;
-
-#define VARNUMBER_MAX INT_MAX
-#define VARNUMBER_MIN INT_MIN
-
-typedef struct listvar_S list_T;
-typedef struct dictvar_S dict_T;
-typedef struct partial_S partial_T;
-
-/// Special variable values
-typedef enum {
- kSpecialVarFalse, ///< v:false
- kSpecialVarTrue, ///< v:true
- kSpecialVarNull, ///< v:null
-} SpecialVarValue;
-
-/// Variable lock status for typval_T.v_lock
-typedef enum {
- VAR_UNLOCKED = 0, ///< Not locked.
- VAR_LOCKED, ///< User lock, can be unlocked.
- VAR_FIXED, ///< Locked forever.
-} VarLockStatus;
-
-/// VimL variable types, for use in typval_T.v_type
-typedef enum {
- VAR_UNKNOWN = 0, ///< Unknown (unspecified) value.
- VAR_NUMBER, ///< Number, .v_number is used.
- VAR_STRING, ///< String, .v_string is used.
- VAR_FUNC, ///< Function reference, .v_string is used as function name.
- VAR_LIST, ///< List, .v_list is used.
- VAR_DICT, ///< Dictionary, .v_dict is used.
- VAR_FLOAT, ///< Floating-point value, .v_float is used.
- VAR_SPECIAL, ///< Special value (true, false, null), .v_special
- ///< is used.
- VAR_PARTIAL, ///< Partial, .v_partial is used.
-} VarType;
-
-/// Structure that holds an internal variable value
-typedef struct {
- VarType v_type; ///< Variable type.
- VarLockStatus v_lock; ///< Variable lock status.
- union {
- varnumber_T v_number; ///< Number, for VAR_NUMBER.
- SpecialVarValue v_special; ///< Special value, for VAR_SPECIAL.
- float_T v_float; ///< Floating-point number, for VAR_FLOAT.
- char_u *v_string; ///< String, for VAR_STRING and VAR_FUNC, can be NULL.
- list_T *v_list; ///< List for VAR_LIST, can be NULL.
- dict_T *v_dict; ///< Dictionary for VAR_DICT, can be NULL.
- partial_T *v_partial; ///< Closure: function with args.
- } vval; ///< Actual value.
-} typval_T;
-
-/* Values for "dv_scope". */
-#define VAR_SCOPE 1 /* a:, v:, s:, etc. scope dictionaries */
-#define VAR_DEF_SCOPE 2 /* l:, g: scope dictionaries: here funcrefs are not
- allowed to mask existing functions */
-
-/*
- * Structure to hold an item of a list: an internal variable without a name.
- */
-typedef struct listitem_S listitem_T;
-
-struct listitem_S {
- listitem_T *li_next; /* next item in list */
- listitem_T *li_prev; /* previous item in list */
- typval_T li_tv; /* type and value of the variable */
-};
-
-/*
- * Struct used by those that are using an item in a list.
- */
-typedef struct listwatch_S listwatch_T;
-
-struct listwatch_S {
- listitem_T *lw_item; /* item being watched */
- listwatch_T *lw_next; /* next watcher */
-};
-
-/*
- * Structure to hold info about a list.
- */
-struct listvar_S {
- listitem_T *lv_first; /* first item, NULL if none */
- listitem_T *lv_last; /* last item, NULL if none */
- int lv_refcount; /* reference count */
- int lv_len; /* number of items */
- listwatch_T *lv_watch; /* first watcher, NULL if none */
- int lv_idx; /* cached index of an item */
- listitem_T *lv_idx_item; /* when not NULL item at index "lv_idx" */
- int lv_copyID; /* ID used by deepcopy() */
- list_T *lv_copylist; /* copied list used by deepcopy() */
- char lv_lock; /* zero, VAR_LOCKED, VAR_FIXED */
- list_T *lv_used_next; /* next list in used lists list */
- list_T *lv_used_prev; /* previous list in used lists list */
-};
-
-/*
- * Structure to hold an item of a Dictionary.
- * Also used for a variable.
- * The key is copied into "di_key" to avoid an extra alloc/free for it.
- */
-struct dictitem_S {
- typval_T di_tv; /* type and value of the variable */
- char_u di_flags; /* flags (only used for variable) */
- char_u di_key[1]; /* key (actually longer!) */
-};
-
-typedef struct dictitem_S dictitem_T;
-
-/// A dictitem with a 16 character key (plus NUL)
-struct dictitem16_S {
- typval_T di_tv; ///< type and value of the variable
- char_u di_flags; ///< flags (only used for variable)
- char_u di_key[17]; ///< key
-};
-
-typedef struct dictitem16_S dictitem16_T;
-
-
-#define DI_FLAGS_RO 1 // "di_flags" value: read-only variable
-#define DI_FLAGS_RO_SBX 2 // "di_flags" value: read-only in the sandbox
-#define DI_FLAGS_FIX 4 // "di_flags" value: fixed: no :unlet or remove()
-#define DI_FLAGS_LOCK 8 // "di_flags" value: locked variable
-#define DI_FLAGS_ALLOC 16 // "di_flags" value: separately allocated
-
-/// Structure representing a Dictionary
-struct dictvar_S {
- VarLockStatus dv_lock; ///< Whole dictionary lock status.
- char dv_scope; ///< Non-zero (#VAR_SCOPE, #VAR_DEF_SCOPE) if
- ///< dictionary represents a scope (i.e. g:, l: …).
- int dv_refcount; ///< Reference count.
- int dv_copyID; ///< ID used when recursivery traversing a value.
- hashtab_T dv_hashtab; ///< Hashtab containing all items.
- dict_T *dv_copydict; ///< Copied dict used by deepcopy().
- dict_T *dv_used_next; ///< Next dictionary in used dictionaries list.
- dict_T *dv_used_prev; ///< Previous dictionary in used dictionaries list.
- QUEUE watchers; ///< Dictionary key watchers set by user code.
-};
-
-struct partial_S {
- int pt_refcount; ///< Reference count.
- char_u *pt_name; ///< Function name.
- bool pt_auto; ///< when true the partial was created for using
- ///< dict.member in handle_subscript().
- int pt_argc; ///< Number of arguments.
- typval_T *pt_argv; ///< Arguments in allocated array.
- dict_T *pt_dict; ///< Dict for "self".
-};
-
-// structure used for explicit stack while garbage collecting hash tables
-typedef struct ht_stack_S {
- hashtab_T *ht;
- struct ht_stack_S *prev;
-} ht_stack_T;
-
-// structure used for explicit stack while garbage collecting lists
-typedef struct list_stack_S {
- list_T *list;
- struct list_stack_S *prev;
-} list_stack_T;
-
-// In a hashtab item "hi_key" points to "di_key" in a dictitem.
-// This avoids adding a pointer to the hashtab item.
-
-/// Convert a dictitem pointer to a hashitem key pointer
-#define DI2HIKEY(di) ((di)->di_key)
-
-/// Convert a hashitem key pointer to a dictitem pointer
-#define HIKEY2DI(p) ((dictitem_T *)(p - offsetof(dictitem_T, di_key)))
-
-/// Convert a hashitem value pointer to a dictitem pointer
-#define HIVAL2DI(p) \
- ((dictitem_T *)(((char *)p) - offsetof(dictitem_T, di_tv)))
-
-/// Convert a hashitem pointer to a dictitem pointer
-#define HI2DI(hi) HIKEY2DI((hi)->hi_key)
-
-/// Type of assert_* check being performed
-typedef enum
-{
- ASSERT_EQUAL,
- ASSERT_NOTEQUAL,
- ASSERT_MATCH,
- ASSERT_NOTMATCH,
- ASSERT_OTHER,
-} assert_type_T;
-
-#endif // NVIM_EVAL_DEFS_H
diff --git a/src/nvim/event/defs.h b/src/nvim/event/defs.h
index e5335d9f25..cc875d74b9 100644
--- a/src/nvim/event/defs.h
+++ b/src/nvim/event/defs.h
@@ -8,16 +8,14 @@
typedef void (*argv_callback)(void **argv);
typedef struct message {
- int priority;
argv_callback handler;
void *argv[EVENT_HANDLER_MAX_ARGC];
} Event;
typedef void(*event_scheduler)(Event event, void *data);
-#define VA_EVENT_INIT(event, p, h, a) \
+#define VA_EVENT_INIT(event, h, a) \
do { \
assert(a <= EVENT_HANDLER_MAX_ARGC); \
- (event)->priority = p; \
(event)->handler = h; \
if (a) { \
va_list args; \
@@ -29,11 +27,11 @@ typedef void(*event_scheduler)(Event event, void *data);
} \
} while (0)
-static inline Event event_create(int priority, argv_callback cb, int argc, ...)
+static inline Event event_create(argv_callback cb, int argc, ...)
{
assert(argc <= EVENT_HANDLER_MAX_ARGC);
Event event;
- VA_EVENT_INIT(&event, priority, cb, argc);
+ VA_EVENT_INIT(&event, cb, argc);
return event;
}
diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c
index a68badcc8f..f6a567a520 100644
--- a/src/nvim/event/libuv_process.c
+++ b/src/nvim/event/libuv_process.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <uv.h>
@@ -8,22 +11,31 @@
#include "nvim/event/process.h"
#include "nvim/event/libuv_process.h"
#include "nvim/log.h"
+#include "nvim/macros.h"
+#include "nvim/os/os.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/libuv_process.c.generated.h"
#endif
-bool libuv_process_spawn(LibuvProcess *uvproc)
+/// @returns zero on success, or negative error code
+int libuv_process_spawn(LibuvProcess *uvproc)
FUNC_ATTR_NONNULL_ALL
{
Process *proc = (Process *)uvproc;
uvproc->uvopts.file = proc->argv[0];
uvproc->uvopts.args = proc->argv;
- uvproc->uvopts.flags = UV_PROCESS_WINDOWS_HIDE
- | UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS;
+ uvproc->uvopts.flags = UV_PROCESS_WINDOWS_HIDE;
if (proc->detach) {
uvproc->uvopts.flags |= UV_PROCESS_DETACHED;
}
+#ifdef WIN32
+ // libuv collapses the argv to a CommandLineToArgvW()-style string. cmd.exe
+ // expects a different syntax (must be prepared by the caller before now).
+ if (os_shell_is_cmdexe(proc->argv[0])) {
+ uvproc->uvopts.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS;
+ }
+#endif
uvproc->uvopts.exit_cb = exit_cb;
uvproc->uvopts.cwd = proc->cwd;
uvproc->uvopts.env = NULL;
@@ -36,27 +48,30 @@ bool libuv_process_spawn(LibuvProcess *uvproc)
if (proc->in) {
uvproc->uvstdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
- uvproc->uvstdio[0].data.stream = (uv_stream_t *)&proc->in->uv.pipe;
+ uvproc->uvstdio[0].data.stream = STRUCT_CAST(uv_stream_t,
+ &proc->in->uv.pipe);
}
if (proc->out) {
uvproc->uvstdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
- uvproc->uvstdio[1].data.stream = (uv_stream_t *)&proc->out->uv.pipe;
+ uvproc->uvstdio[1].data.stream = STRUCT_CAST(uv_stream_t,
+ &proc->out->uv.pipe);
}
if (proc->err) {
uvproc->uvstdio[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
- uvproc->uvstdio[2].data.stream = (uv_stream_t *)&proc->err->uv.pipe;
+ uvproc->uvstdio[2].data.stream = STRUCT_CAST(uv_stream_t,
+ &proc->err->uv.pipe);
}
int status;
if ((status = uv_spawn(&proc->loop->uv, &uvproc->uv, &uvproc->uvopts))) {
ELOG("uv_spawn failed: %s", uv_strerror(status));
- return false;
+ return status;
}
proc->pid = uvproc->uv.pid;
- return true;
+ return status;
}
void libuv_process_close(LibuvProcess *uvproc)
diff --git a/src/nvim/event/libuv_process.h b/src/nvim/event/libuv_process.h
index aaaa896e10..1132ce79ca 100644
--- a/src/nvim/event/libuv_process.h
+++ b/src/nvim/event/libuv_process.h
@@ -14,8 +14,9 @@ typedef struct libuv_process {
static inline LibuvProcess libuv_process_init(Loop *loop, void *data)
{
- LibuvProcess rv;
- rv.process = process_init(loop, kProcessTypeUv, data);
+ LibuvProcess rv = {
+ .process = process_init(loop, kProcessTypeUv, data)
+ };
return rv;
}
diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c
index 0e1775d01b..25701a1621 100644
--- a/src/nvim/event/loop.c
+++ b/src/nvim/event/loop.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <stdarg.h>
#include <stdint.h>
@@ -5,6 +8,7 @@
#include "nvim/event/loop.h"
#include "nvim/event/process.h"
+#include "nvim/log.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/loop.c.generated.h"
@@ -41,8 +45,7 @@ void loop_poll_events(Loop *loop, int ms)
// we do not block indefinitely for I/O.
uv_timer_start(&loop->poll_timer, timer_cb, (uint64_t)ms, (uint64_t)ms);
} else if (ms == 0) {
- // For ms == 0, we need to do a non-blocking event poll by
- // setting the run mode to UV_RUN_NOWAIT.
+ // For ms == 0, do a non-blocking event poll.
mode = UV_RUN_NOWAIT;
}
@@ -76,20 +79,34 @@ void loop_on_put(MultiQueue *queue, void *data)
uv_stop(&loop->uv);
}
-void loop_close(Loop *loop, bool wait)
+/// @returns false if the loop could not be closed gracefully
+bool loop_close(Loop *loop, bool wait)
{
+ bool rv = true;
uv_mutex_destroy(&loop->mutex);
uv_close((uv_handle_t *)&loop->children_watcher, NULL);
uv_close((uv_handle_t *)&loop->children_kill_timer, NULL);
uv_close((uv_handle_t *)&loop->poll_timer, NULL);
uv_close((uv_handle_t *)&loop->async, NULL);
- do {
+ uint64_t start = wait ? os_hrtime() : 0;
+ while (true) {
uv_run(&loop->uv, wait ? UV_RUN_DEFAULT : UV_RUN_NOWAIT);
- } while (uv_loop_close(&loop->uv) && wait);
+ if (!uv_loop_close(&loop->uv) || !wait) {
+ break;
+ }
+ if (os_hrtime() - start >= 2 * 1000000000) {
+ // Some libuv resource was not correctly deref'd. Log and bail.
+ rv = false;
+ ELOG("uv_loop_close() hang?");
+ log_uv_handles(&loop->uv);
+ break;
+ }
+ }
multiqueue_free(loop->fast_events);
multiqueue_free(loop->thread_events);
multiqueue_free(loop->events);
kl_destroy(WatcherPtr, loop->children);
+ return rv;
}
void loop_purge(Loop *loop)
diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c
index 79b4dd9458..ef9f3f1870 100644
--- a/src/nvim/event/multiqueue.c
+++ b/src/nvim/event/multiqueue.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
// Multi-level queue for selective async event processing.
// Not threadsafe; access must be synchronized externally.
//
@@ -123,6 +126,7 @@ void multiqueue_free(MultiQueue *this)
xfree(this);
}
+/// Removes the next item and returns its Event.
Event multiqueue_get(MultiQueue *this)
{
return multiqueue_empty(this) ? NILEVENT : multiqueue_remove(this);
@@ -141,7 +145,7 @@ void multiqueue_process_events(MultiQueue *this)
{
assert(this);
while (!multiqueue_empty(this)) {
- Event event = multiqueue_get(this);
+ Event event = multiqueue_remove(this);
if (event.handler) {
event.handler(event.argv);
}
@@ -175,36 +179,48 @@ size_t multiqueue_size(MultiQueue *this)
return this->size;
}
-static Event multiqueue_remove(MultiQueue *this)
+/// Gets an Event from an item.
+///
+/// @param remove Remove the node from its queue, and free it.
+static Event multiqueueitem_get_event(MultiQueueItem *item, bool remove)
{
- assert(!multiqueue_empty(this));
- QUEUE *h = QUEUE_HEAD(&this->headtail);
- QUEUE_REMOVE(h);
- MultiQueueItem *item = multiqueue_node_data(h);
- Event rv;
-
+ assert(item != NULL);
+ Event ev;
if (item->link) {
- assert(!this->parent);
- // remove the next node in the linked queue
+ // get the next node in the linked queue
MultiQueue *linked = item->data.queue;
assert(!multiqueue_empty(linked));
MultiQueueItem *child =
multiqueue_node_data(QUEUE_HEAD(&linked->headtail));
- QUEUE_REMOVE(&child->node);
- rv = child->data.item.event;
- xfree(child);
+ ev = child->data.item.event;
+ // remove the child node
+ if (remove) {
+ QUEUE_REMOVE(&child->node);
+ xfree(child);
+ }
} else {
- if (this->parent) {
- // remove the corresponding link node in the parent queue
+ // remove the corresponding link node in the parent queue
+ if (remove && item->data.item.parent_item) {
QUEUE_REMOVE(&item->data.item.parent_item->node);
xfree(item->data.item.parent_item);
+ item->data.item.parent_item = NULL;
}
- rv = item->data.item.event;
+ ev = item->data.item.event;
}
+ return ev;
+}
+static Event multiqueue_remove(MultiQueue *this)
+{
+ assert(!multiqueue_empty(this));
+ QUEUE *h = QUEUE_HEAD(&this->headtail);
+ QUEUE_REMOVE(h);
+ MultiQueueItem *item = multiqueue_node_data(h);
+ assert(!item->link || !this->parent); // Only a parent queue has link-nodes
+ Event ev = multiqueueitem_get_event(item, true);
this->size--;
xfree(item);
- return rv;
+ return ev;
}
static void multiqueue_push(MultiQueue *this, Event event)
@@ -212,6 +228,7 @@ static void multiqueue_push(MultiQueue *this, Event event)
MultiQueueItem *item = xmalloc(sizeof(MultiQueueItem));
item->link = false;
item->data.item.event = event;
+ item->data.item.parent_item = NULL;
QUEUE_INSERT_TAIL(&this->headtail, &item->node);
if (this->parent) {
// push link node to the parent queue
diff --git a/src/nvim/event/multiqueue.h b/src/nvim/event/multiqueue.h
index def6b95a10..a688107665 100644
--- a/src/nvim/event/multiqueue.h
+++ b/src/nvim/event/multiqueue.h
@@ -10,7 +10,7 @@ typedef struct multiqueue MultiQueue;
typedef void (*put_callback)(MultiQueue *multiq, void *data);
#define multiqueue_put(q, h, ...) \
- multiqueue_put_event(q, event_create(1, h, __VA_ARGS__));
+ multiqueue_put_event(q, event_create(h, __VA_ARGS__));
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c
index dc7886469b..8371d3cd48 100644
--- a/src/nvim/event/process.c
+++ b/src/nvim/event/process.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <stdlib.h>
@@ -11,15 +14,16 @@
#include "nvim/event/libuv_process.h"
#include "nvim/os/pty_process.h"
#include "nvim/globals.h"
+#include "nvim/macros.h"
#include "nvim/log.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/process.c.generated.h"
#endif
-// Time (ns) for a process to exit cleanly before we send TERM/KILL.
-#define TERM_TIMEOUT 1000000000
-#define KILL_TIMEOUT (TERM_TIMEOUT * 2)
+// Time for a process to exit cleanly before we send KILL.
+// For pty processes SIGTERM is sent first (in case SIGHUP was not enough).
+#define KILL_TIMEOUT_MS 2000
#define CLOSE_PROC_STREAM(proc, stream) \
do { \
@@ -30,7 +34,8 @@
static bool process_is_tearing_down = false;
-bool process_spawn(Process *proc) FUNC_ATTR_NONNULL_ALL
+/// @returns zero on success, or negative error code
+int process_spawn(Process *proc) FUNC_ATTR_NONNULL_ALL
{
if (proc->in) {
uv_pipe_init(&proc->loop->uv, &proc->in->uv.pipe, 0);
@@ -44,19 +49,19 @@ bool process_spawn(Process *proc) FUNC_ATTR_NONNULL_ALL
uv_pipe_init(&proc->loop->uv, &proc->err->uv.pipe, 0);
}
- bool success;
+ int status;
switch (proc->type) {
case kProcessTypeUv:
- success = libuv_process_spawn((LibuvProcess *)proc);
+ status = libuv_process_spawn((LibuvProcess *)proc);
break;
case kProcessTypePty:
- success = pty_process_spawn((PtyProcess *)proc);
+ status = pty_process_spawn((PtyProcess *)proc);
break;
default:
abort();
}
- if (!success) {
+ if (status) {
if (proc->in) {
uv_close((uv_handle_t *)&proc->in->uv.pipe, NULL);
}
@@ -74,11 +79,12 @@ bool process_spawn(Process *proc) FUNC_ATTR_NONNULL_ALL
}
shell_free_argv(proc->argv);
proc->status = -1;
- return false;
+ return status;
}
if (proc->in) {
- stream_init(NULL, proc->in, -1, (uv_stream_t *)&proc->in->uv.pipe);
+ stream_init(NULL, proc->in, -1,
+ STRUCT_CAST(uv_stream_t, &proc->in->uv.pipe));
proc->in->events = proc->events;
proc->in->internal_data = proc;
proc->in->internal_close_cb = on_process_stream_close;
@@ -86,7 +92,8 @@ bool process_spawn(Process *proc) FUNC_ATTR_NONNULL_ALL
}
if (proc->out) {
- stream_init(NULL, proc->out, -1, (uv_stream_t *)&proc->out->uv.pipe);
+ stream_init(NULL, proc->out, -1,
+ STRUCT_CAST(uv_stream_t, &proc->out->uv.pipe));
proc->out->events = proc->events;
proc->out->internal_data = proc;
proc->out->internal_close_cb = on_process_stream_close;
@@ -94,7 +101,8 @@ bool process_spawn(Process *proc) FUNC_ATTR_NONNULL_ALL
}
if (proc->err) {
- stream_init(NULL, proc->err, -1, (uv_stream_t *)&proc->err->uv.pipe);
+ stream_init(NULL, proc->err, -1,
+ STRUCT_CAST(uv_stream_t, &proc->err->uv.pipe));
proc->err->events = proc->events;
proc->err->internal_data = proc;
proc->err->internal_close_cb = on_process_stream_close;
@@ -105,7 +113,7 @@ bool process_spawn(Process *proc) FUNC_ATTR_NONNULL_ALL
proc->internal_close_cb = decref;
proc->refcount++;
kl_push(WatcherPtr, proc->loop->children, proc);
- return true;
+ return 0;
}
void process_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL
@@ -117,8 +125,6 @@ void process_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL
// Close handles to process without killing it.
CREATE_EVENT(loop->events, process_close_handles, 1, proc);
} else {
- uv_kill(proc->pid, SIGTERM);
- proc->term_sent = true;
process_stop(proc);
}
}
@@ -155,19 +161,16 @@ void process_close_err(Process *proc) FUNC_ATTR_NONNULL_ALL
/// Synchronously wait for a process to finish
///
-/// @param process The Process instance
-/// @param ms Number of milliseconds to wait, 0 for not waiting, -1 for
-/// waiting until the process quits.
-/// @return returns the status code of the exited process. -1 if the process is
-/// still running and the `timeout` has expired. Note that this is
-/// indistinguishable from the process returning -1 by itself. Which
-/// is possible on some OS. Returns -2 if an user has interruped the
-/// wait.
+/// @param process Process instance
+/// @param ms Time in milliseconds to wait for the process.
+/// 0 for no wait. -1 to wait until the process quits.
+/// @return Exit code of the process.
+/// -1 if the timeout expired while the process is still running.
+/// -2 if the user interruped the wait.
int process_wait(Process *proc, int ms, MultiQueue *events)
FUNC_ATTR_NONNULL_ARG(1)
{
- // The default status is -1, which represents a timeout
- int status = -1;
+ int status = -1; // default
bool interrupted = false;
if (!proc->refcount) {
status = proc->status;
@@ -179,8 +182,8 @@ int process_wait(Process *proc, int ms, MultiQueue *events)
events = proc->events;
}
- // Increase refcount to stop the exit callback from being called(and possibly
- // being freed) before we have a chance to get the status.
+ // Increase refcount to stop the exit callback from being called (and possibly
+ // freed) before we have a chance to get the status.
proc->refcount++;
LOOP_PROCESS_EVENTS_UNTIL(proc->loop, events, ms,
// Until...
@@ -230,9 +233,10 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL
switch (proc->type) {
case kProcessTypeUv:
// Close the process's stdin. If the process doesn't close its own
- // stdout/stderr, they will be closed when it exits(possibly due to being
- // terminated after a timeout)
+ // stdout/stderr, they will be closed when it exits (voluntarily or not).
process_close_in(proc);
+ ILOG("Sending SIGTERM to pid %d", proc->pid);
+ uv_kill(proc->pid, SIGTERM);
break;
case kProcessTypePty:
// close all streams for pty processes to send SIGHUP to the process
@@ -246,9 +250,10 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL
Loop *loop = proc->loop;
if (!loop->children_stop_requests++) {
// When there's at least one stop request pending, start a timer that
- // will periodically check if a signal should be send to a to the job
- DLOG("Starting job kill timer");
- uv_timer_start(&loop->children_kill_timer, children_kill_cb, 100, 100);
+ // will periodically check if a signal should be send to the job.
+ ILOG("Starting job kill timer");
+ uv_timer_start(&loop->children_kill_timer, children_kill_cb,
+ KILL_TIMEOUT_MS, KILL_TIMEOUT_MS);
}
}
@@ -264,15 +269,15 @@ static void children_kill_cb(uv_timer_t *handle)
if (!proc->stopped_time) {
continue;
}
- uint64_t elapsed = now - proc->stopped_time;
-
- if (!proc->term_sent && elapsed >= TERM_TIMEOUT) {
- ILOG("Sending SIGTERM to pid %d", proc->pid);
- uv_kill(proc->pid, SIGTERM);
- proc->term_sent = true;
- } else if (elapsed >= KILL_TIMEOUT) {
- ILOG("Sending SIGKILL to pid %d", proc->pid);
- uv_kill(proc->pid, SIGKILL);
+ uint64_t elapsed = (now - proc->stopped_time) / 1000000 + 1;
+
+ if (elapsed >= KILL_TIMEOUT_MS) {
+ int sig = proc->type == kProcessTypePty && elapsed < KILL_TIMEOUT_MS * 2
+ ? SIGTERM
+ : SIGKILL;
+ ILOG("Sending %s to pid %d", sig == SIGTERM ? "SIGTERM" : "SIGKILL",
+ proc->pid);
+ uv_kill(proc->pid, sig);
}
}
}
diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h
index 5cbf7f9ce7..5c00e8e7ec 100644
--- a/src/nvim/event/process.h
+++ b/src/nvim/event/process.h
@@ -21,12 +21,12 @@ struct process {
int pid, status, refcount;
// set to the hrtime of when process_stop was called for the process.
uint64_t stopped_time;
- char *cwd;
+ const char *cwd;
char **argv;
Stream *in, *out, *err;
process_exit_cb cb;
internal_process_cb internal_exit_cb, internal_close_cb;
- bool closed, term_sent, detach;
+ bool closed, detach;
MultiQueue *events;
};
@@ -48,7 +48,6 @@ static inline Process process_init(Loop *loop, ProcessType type, void *data)
.err = NULL,
.cb = NULL,
.closed = false,
- .term_sent = false,
.internal_close_cb = NULL,
.internal_exit_cb = NULL,
.detach = false
diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c
index 92efc9fa2e..2c4db08b30 100644
--- a/src/nvim/event/rstream.c
+++ b/src/nvim/event/rstream.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <stdint.h>
#include <stdbool.h>
@@ -89,7 +92,10 @@ static void on_rbuffer_nonfull(RBuffer *buf, void *data)
static void alloc_cb(uv_handle_t *handle, size_t suggested, uv_buf_t *buf)
{
Stream *stream = handle->data;
- buf->base = rbuffer_write_ptr(stream->buffer, &buf->len);
+ // `uv_buf_t.len` happens to have different size on Windows.
+ size_t write_count;
+ buf->base = rbuffer_write_ptr(stream->buffer, &write_count);
+ buf->len = write_count;
}
// Callback invoked by libuv after it copies the data into the buffer provided
@@ -112,7 +118,7 @@ static void read_cb(uv_stream_t *uvstream, ssize_t cnt, const uv_buf_t *buf)
// to `alloc_cb` will return the same unused pointer(`rbuffer_produced`
// won't be called)
&& cnt != 0) {
- DLOG("Closing Stream (%p): %s (%s)", stream,
+ DLOG("closing Stream: %p: %s (%s)", stream,
uv_err_name((int)cnt), os_strerror((int)cnt));
// Read error or EOF, either way stop the stream and invoke the callback
// with eof == true
@@ -136,7 +142,10 @@ static void fread_idle_cb(uv_idle_t *handle)
uv_fs_t req;
Stream *stream = handle->data;
- stream->uvbuf.base = rbuffer_write_ptr(stream->buffer, &stream->uvbuf.len);
+ // `uv_buf_t.len` happens to have different size on Windows.
+ size_t write_count;
+ stream->uvbuf.base = rbuffer_write_ptr(stream->buffer, &write_count);
+ stream->uvbuf.len = write_count;
// the offset argument to uv_fs_read is int64_t, could someone really try
// to read more than 9 quintillion (9e18) bytes?
diff --git a/src/nvim/event/signal.c b/src/nvim/event/signal.c
index 11ce15a882..fec46da4ff 100644
--- a/src/nvim/event/signal.c
+++ b/src/nvim/event/signal.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <uv.h>
#include "nvim/event/loop.h"
diff --git a/src/nvim/event/socket.c b/src/nvim/event/socket.c
index 8f9327f3d4..6f45b09fce 100644
--- a/src/nvim/event/socket.c
+++ b/src/nvim/event/socket.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <stdint.h>
@@ -12,99 +15,123 @@
#include "nvim/vim.h"
#include "nvim/strings.h"
#include "nvim/path.h"
+#include "nvim/main.h"
#include "nvim/memory.h"
+#include "nvim/macros.h"
+#include "nvim/charset.h"
+#include "nvim/log.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/socket.c.generated.h"
#endif
-#define NVIM_DEFAULT_TCP_PORT 7450
-
-void socket_watcher_init(Loop *loop, SocketWatcher *watcher,
- const char *endpoint, void *data)
- FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_NONNULL_ARG(3)
+int socket_watcher_init(Loop *loop, SocketWatcher *watcher,
+ const char *endpoint)
+ FUNC_ATTR_NONNULL_ALL
{
- // Trim to `ADDRESS_MAX_SIZE`
- if (xstrlcpy(watcher->addr, endpoint, sizeof(watcher->addr))
- >= sizeof(watcher->addr)) {
- // TODO(aktau): since this is not what the user wanted, perhaps we
- // should return an error here
- WLOG("Address was too long, truncated to %s", watcher->addr);
- }
-
- bool tcp = true;
- char ip[16], *ip_end = xstrchrnul(watcher->addr, ':');
+ xstrlcpy(watcher->addr, endpoint, sizeof(watcher->addr));
+ char *addr = watcher->addr;
+ char *host_end = strrchr(addr, ':');
- // (ip_end - addr) is always > 0, so convert to size_t
- size_t addr_len = (size_t)(ip_end - watcher->addr);
+ if (host_end && addr != host_end) {
+ // Split user specified address into two strings, addr(hostname) and port.
+ // The port part in watcher->addr will be updated later.
+ *host_end = '\0';
+ char *port = host_end + 1;
+ intmax_t iport;
- if (addr_len > sizeof(ip) - 1) {
- // Maximum length of an IPv4 address buffer is 15 (eg: 255.255.255.255)
- addr_len = sizeof(ip) - 1;
- }
+ int ret = getdigits_safe(&(char_u *){ (char_u *)port }, &iport);
+ if (ret == FAIL || iport < 0 || iport > UINT16_MAX) {
+ ELOG("Invalid port: %s", port);
+ return UV_EINVAL;
+ }
- // Extract the address part
- xstrlcpy(ip, watcher->addr, addr_len + 1);
- int port = NVIM_DEFAULT_TCP_PORT;
-
- if (*ip_end == ':') {
- // Extract the port
- long lport = strtol(ip_end + 1, NULL, 10); // NOLINT
- if (lport <= 0 || lport > 0xffff) {
- // Invalid port, treat as named pipe or unix socket
- tcp = false;
- } else {
- port = (int) lport;
+ if (*port == NUL) {
+ // When no port is given, (uv_)getaddrinfo expects NULL otherwise the
+ // implementation may attempt to lookup the service by name (and fail)
+ port = NULL;
}
- }
- if (tcp) {
- // Try to parse ip address
- if (uv_ip4_addr(ip, port, &watcher->uv.tcp.addr)) {
- // Invalid address, treat as named pipe or unix socket
- tcp = false;
+ uv_getaddrinfo_t request;
+
+ int retval = uv_getaddrinfo(&loop->uv, &request, NULL, addr, port,
+ &(struct addrinfo){
+ .ai_family = AF_UNSPEC,
+ .ai_socktype = SOCK_STREAM,
+ });
+ if (retval != 0) {
+ ELOG("Host lookup failed: %s", endpoint);
+ return retval;
}
- }
+ watcher->uv.tcp.addrinfo = request.addrinfo;
- if (tcp) {
uv_tcp_init(&loop->uv, &watcher->uv.tcp.handle);
- watcher->stream = (uv_stream_t *)&watcher->uv.tcp.handle;
+ uv_tcp_nodelay(&watcher->uv.tcp.handle, true);
+ watcher->stream = STRUCT_CAST(uv_stream_t, &watcher->uv.tcp.handle);
} else {
uv_pipe_init(&loop->uv, &watcher->uv.pipe.handle, 0);
- watcher->stream = (uv_stream_t *)&watcher->uv.pipe.handle;
+ watcher->stream = STRUCT_CAST(uv_stream_t, &watcher->uv.pipe.handle);
}
watcher->stream->data = watcher;
watcher->cb = NULL;
watcher->close_cb = NULL;
watcher->events = NULL;
+ watcher->data = NULL;
+
+ return 0;
}
int socket_watcher_start(SocketWatcher *watcher, int backlog, socket_cb cb)
FUNC_ATTR_NONNULL_ALL
{
watcher->cb = cb;
- int result;
+ int result = UV_EINVAL;
if (watcher->stream->type == UV_TCP) {
- result = uv_tcp_bind(&watcher->uv.tcp.handle,
- (const struct sockaddr *)&watcher->uv.tcp.addr, 0);
+ struct addrinfo *ai = watcher->uv.tcp.addrinfo;
+
+ for (; ai; ai = ai->ai_next) {
+ result = uv_tcp_bind(&watcher->uv.tcp.handle, ai->ai_addr, 0);
+ if (result != 0) {
+ continue;
+ }
+ result = uv_listen(watcher->stream, backlog, connection_cb);
+ if (result == 0) {
+ struct sockaddr_storage sas;
+
+ // When the endpoint in socket_watcher_init() didn't specify a port
+ // number, a free random port number will be assigned. sin_port will
+ // contain 0 in this case, unless uv_tcp_getsockname() is used first.
+ uv_tcp_getsockname(&watcher->uv.tcp.handle, (struct sockaddr *)&sas,
+ &(int){ sizeof(sas) });
+ uint16_t port = (uint16_t)(
+ (sas.ss_family == AF_INET)
+ ? (STRUCT_CAST(struct sockaddr_in, &sas))->sin_port
+ : (STRUCT_CAST(struct sockaddr_in6, &sas))->sin6_port);
+ // v:servername uses the string from watcher->addr
+ size_t len = strlen(watcher->addr);
+ snprintf(watcher->addr+len, sizeof(watcher->addr)-len, ":%" PRIu16,
+ ntohs(port));
+ break;
+ }
+ }
+ uv_freeaddrinfo(watcher->uv.tcp.addrinfo);
} else {
result = uv_pipe_bind(&watcher->uv.pipe.handle, watcher->addr);
- }
-
- if (result == 0) {
- result = uv_listen(watcher->stream, backlog, connection_cb);
+ if (result == 0) {
+ result = uv_listen(watcher->stream, backlog, connection_cb);
+ }
}
assert(result <= 0); // libuv should return negative error code or zero.
if (result < 0) {
- if (result == -EACCES) {
+ if (result == UV_EACCES) {
// Libuv converts ENOENT to EACCES for Windows compatibility, but if
// the parent directory does not exist, ENOENT would be more accurate.
*path_tail((char_u *)watcher->addr) = NUL;
if (!os_path_exists((char_u *)watcher->addr)) {
- result = -ENOENT;
+ result = UV_ENOENT;
}
}
return result;
@@ -119,10 +146,11 @@ int socket_watcher_accept(SocketWatcher *watcher, Stream *stream)
uv_stream_t *client;
if (watcher->stream->type == UV_TCP) {
- client = (uv_stream_t *)&stream->uv.tcp;
+ client = STRUCT_CAST(uv_stream_t, &stream->uv.tcp);
uv_tcp_init(watcher->uv.tcp.handle.loop, (uv_tcp_t *)client);
+ uv_tcp_nodelay((uv_tcp_t *)client, true);
} else {
- client = (uv_stream_t *)&stream->uv.pipe;
+ client = STRUCT_CAST(uv_stream_t, &stream->uv.pipe);
uv_pipe_init(watcher->uv.pipe.handle.loop, (uv_pipe_t *)client, 0);
}
@@ -165,3 +193,77 @@ static void close_cb(uv_handle_t *handle)
watcher->close_cb(watcher, watcher->data);
}
}
+
+static void connect_cb(uv_connect_t *req, int status)
+{
+ int *ret_status = req->data;
+ *ret_status = status;
+ if (status != 0) {
+ uv_close((uv_handle_t *)req->handle, NULL);
+ }
+}
+
+bool socket_connect(Loop *loop, Stream *stream,
+ bool is_tcp, const char *address,
+ int timeout, const char **error)
+{
+ bool success = false;
+ int status;
+ uv_connect_t req;
+ req.data = &status;
+ uv_stream_t *uv_stream;
+
+ uv_tcp_t *tcp = &stream->uv.tcp;
+ uv_getaddrinfo_t addr_req;
+ addr_req.addrinfo = NULL;
+ const struct addrinfo *addrinfo = NULL;
+ char *addr = NULL;
+ if (is_tcp) {
+ addr = xstrdup(address);
+ char *host_end = strrchr(addr, ':');
+ if (!host_end) {
+ *error = _("tcp address must be host:port");
+ goto cleanup;
+ }
+ *host_end = NUL;
+
+ const struct addrinfo hints = { .ai_family = AF_UNSPEC,
+ .ai_socktype = SOCK_STREAM,
+ .ai_flags = AI_NUMERICSERV };
+ int retval = uv_getaddrinfo(&loop->uv, &addr_req, NULL,
+ addr, host_end+1, &hints);
+ if (retval != 0) {
+ *error = _("failed to lookup host or port");
+ goto cleanup;
+ }
+ addrinfo = addr_req.addrinfo;
+
+tcp_retry:
+ uv_tcp_init(&loop->uv, tcp);
+ uv_tcp_nodelay(tcp, true);
+ uv_tcp_connect(&req, tcp, addrinfo->ai_addr, connect_cb);
+ uv_stream = (uv_stream_t *)tcp;
+
+ } else {
+ uv_pipe_t *pipe = &stream->uv.pipe;
+ uv_pipe_init(&loop->uv, pipe, 0);
+ uv_pipe_connect(&req, pipe, address, connect_cb);
+ uv_stream = STRUCT_CAST(uv_stream_t, pipe);
+ }
+ status = 1;
+ LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, timeout, status != 1);
+ if (status == 0) {
+ stream_init(NULL, stream, -1, uv_stream);
+ success = true;
+ } else if (is_tcp && addrinfo->ai_next) {
+ addrinfo = addrinfo->ai_next;
+ goto tcp_retry;
+ } else {
+ *error = _("connection refused");
+ }
+
+cleanup:
+ xfree(addr);
+ uv_freeaddrinfo(addr_req.addrinfo);
+ return success;
+}
diff --git a/src/nvim/event/socket.h b/src/nvim/event/socket.h
index eb0823c76d..d30ae45502 100644
--- a/src/nvim/event/socket.h
+++ b/src/nvim/event/socket.h
@@ -20,7 +20,7 @@ struct socket_watcher {
union {
struct {
uv_tcp_t handle;
- struct sockaddr_in addr;
+ struct addrinfo *addrinfo;
} tcp;
struct {
uv_pipe_t handle;
diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c
index 26083c20f4..7c865bfe1e 100644
--- a/src/nvim/event/stream.c
+++ b/src/nvim/event/stream.c
@@ -1,10 +1,15 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <stdio.h>
#include <stdbool.h>
#include <uv.h>
+#include "nvim/log.h"
#include "nvim/rbuffer.h"
+#include "nvim/macros.h"
#include "nvim/event/stream.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -23,8 +28,9 @@ int stream_set_blocking(int fd, bool blocking)
uv_loop_init(&loop);
uv_pipe_init(&loop, &stream, 0);
uv_pipe_open(&stream, fd);
- int retval = uv_stream_set_blocking((uv_stream_t *)&stream, blocking);
- uv_close((uv_handle_t *)&stream, NULL);
+ int retval = uv_stream_set_blocking(STRUCT_CAST(uv_stream_t, &stream),
+ blocking);
+ uv_close(STRUCT_CAST(uv_handle_t, &stream), NULL);
uv_run(&loop, UV_RUN_NOWAIT); // not necessary, but couldn't hurt.
uv_loop_close(&loop);
return retval;
@@ -49,7 +55,7 @@ void stream_init(Loop *loop, Stream *stream, int fd, uv_stream_t *uvstream)
assert(type == UV_NAMED_PIPE || type == UV_TTY);
uv_pipe_init(&loop->uv, &stream->uv.pipe, 0);
uv_pipe_open(&stream->uv.pipe, fd);
- stream->uvstream = (uv_stream_t *)&stream->uv.pipe;
+ stream->uvstream = STRUCT_CAST(uv_stream_t, &stream->uv.pipe);
}
}
@@ -76,6 +82,7 @@ void stream_close(Stream *stream, stream_close_cb on_stream_close, void *data)
FUNC_ATTR_NONNULL_ARG(1)
{
assert(!stream->closed);
+ DLOG("closing Stream: %p", stream);
stream->closed = true;
stream->close_cb = on_stream_close;
stream->close_cb_data = data;
diff --git a/src/nvim/event/time.c b/src/nvim/event/time.c
index 77260546db..80289c27d1 100644
--- a/src/nvim/event/time.c
+++ b/src/nvim/event/time.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <stdint.h>
#include <uv.h>
diff --git a/src/nvim/event/wstream.c b/src/nvim/event/wstream.c
index fc7aad8eb9..320006890d 100644
--- a/src/nvim/event/wstream.c
+++ b/src/nvim/event/wstream.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <stdint.h>
#include <stdbool.h>
@@ -5,6 +8,7 @@
#include <uv.h>
+#include "nvim/log.h"
#include "nvim/event/loop.h"
#include "nvim/event/wstream.h"
#include "nvim/vim.h"
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index b1a17e8c44..32dbf4cc69 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* ex_cmds.c: some functions for command line commands
*/
@@ -315,14 +318,12 @@ static int sort_abort; ///< flag to indicate if sorting has been interrupted
/// Struct to store info to be sorted.
typedef struct {
linenr_T lnum; ///< line number
- long start_col_nr; ///< starting column number or number
- long end_col_nr; ///< ending column number
union {
struct {
- long start_col_nr; ///< starting column number
- long end_col_nr; ///< ending column number
+ varnumber_T start_col_nr; ///< starting column number
+ varnumber_T end_col_nr; ///< ending column number
} line;
- long value; ///< value if sorting by integer
+ varnumber_T value; ///< value if sorting by integer
float_T value_flt; ///< value if sorting by float
} st_u;
} sorti_T;
@@ -357,12 +358,12 @@ static int sort_compare(const void *s1, const void *s2)
// We need to copy one line into "sortbuf1", because there is no
// guarantee that the first pointer becomes invalid when obtaining the
// second one.
- STRNCPY(sortbuf1, ml_get(l1.lnum) + l1.st_u.line.start_col_nr,
- l1.st_u.line.end_col_nr - l1.st_u.line.start_col_nr + 1);
- sortbuf1[l1.st_u.line.end_col_nr - l1.st_u.line.start_col_nr] = 0;
- STRNCPY(sortbuf2, ml_get(l2.lnum) + l2.st_u.line.start_col_nr,
- l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr + 1);
- sortbuf2[l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr] = 0;
+ memcpy(sortbuf1, ml_get(l1.lnum) + l1.st_u.line.start_col_nr,
+ l1.st_u.line.end_col_nr - l1.st_u.line.start_col_nr + 1);
+ sortbuf1[l1.st_u.line.end_col_nr - l1.st_u.line.start_col_nr] = NUL;
+ memcpy(sortbuf2, ml_get(l2.lnum) + l2.st_u.line.start_col_nr,
+ l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr + 1);
+ sortbuf2[l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr] = NUL;
result = sort_ic ? STRICMP(sortbuf1, sortbuf2)
: STRCMP(sortbuf1, sortbuf2);
@@ -596,9 +597,10 @@ void ex_sort(exarg_T *eap)
// Adjust marks for deleted (or added) lines and prepare for displaying.
deleted = (long)(count - (lnum - eap->line2));
if (deleted > 0) {
- mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted);
+ mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted,
+ false);
} else if (deleted < 0) {
- mark_adjust(eap->line2, MAXLNUM, -deleted, 0L);
+ mark_adjust(eap->line2, MAXLNUM, -deleted, 0L, false);
}
changed_lines(eap->line1, 0, eap->line2 + 1, -deleted);
@@ -756,14 +758,6 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
linenr_T num_lines; // Num lines moved
linenr_T last_line; // Last line in file after adding new text
- // Moving lines seems to corrupt the folds, delete folding info now
- // and recreate it when finished. Don't do this for manual folding, it
- // would delete all folds.
- bool isFolded = hasAnyFolding(curwin) && !foldmethodIsManual(curwin);
- if (isFolded) {
- deleteFoldRecurse(&curwin->w_folds);
- }
-
if (dest >= line1 && dest < line2) {
EMSG(_("E134: Move lines into themselves"));
return FAIL;
@@ -801,21 +795,29 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
* their final destination at the new text position -- webb
*/
last_line = curbuf->b_ml.ml_line_count;
- mark_adjust(line1, line2, last_line - line2, 0L);
- changed_lines(last_line - num_lines + 1, 0, last_line + 1, num_lines);
+ mark_adjust_nofold(line1, line2, last_line - line2, 0L, true);
if (dest >= line2) {
- mark_adjust(line2 + 1, dest, -num_lines, 0L);
+ mark_adjust_nofold(line2 + 1, dest, -num_lines, 0L, false);
+ FOR_ALL_TAB_WINDOWS(tab, win) {
+ if (win->w_buffer == curbuf) {
+ foldMoveRange(&win->w_folds, line1, line2, dest);
+ }
+ }
curbuf->b_op_start.lnum = dest - num_lines + 1;
curbuf->b_op_end.lnum = dest;
} else {
- mark_adjust(dest + 1, line1 - 1, num_lines, 0L);
+ mark_adjust_nofold(dest + 1, line1 - 1, num_lines, 0L, false);
+ FOR_ALL_TAB_WINDOWS(tab, win) {
+ if (win->w_buffer == curbuf) {
+ foldMoveRange(&win->w_folds, dest + 1, line1 - 1, line2);
+ }
+ }
curbuf->b_op_start.lnum = dest + 1;
curbuf->b_op_end.lnum = dest + num_lines;
}
curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
- mark_adjust(last_line - num_lines + 1, last_line,
- -(last_line - dest - extra), 0L);
- changed_lines(last_line - num_lines + 1, 0, last_line + 1, -extra);
+ mark_adjust_nofold(last_line - num_lines + 1, last_line,
+ -(last_line - dest - extra), 0L, true);
/*
* Now we delete the original text -- webb
@@ -851,11 +853,6 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
changed_lines(dest + 1, 0, line1 + num_lines, 0L);
}
- // recreate folds
- if (isFolded) {
- foldUpdateAll(curwin);
- }
-
return OK;
}
@@ -1013,8 +1010,8 @@ void do_bang(int addr_count, exarg_T *eap, int forceit, int do_in, int do_out)
AppendToRedobuffLit(cmd, -1);
xfree(cmd);
- AppendToRedobuff((char_u *)"\n");
- bangredo = FALSE;
+ AppendToRedobuff("\n");
+ bangredo = false;
}
/*
* Add quotes around the command, for shells that need them.
@@ -1131,11 +1128,12 @@ static void do_filter(
*/
++no_wait_return; /* don't call wait_return() while busy */
if (itmp != NULL && buf_write(curbuf, itmp, NULL, line1, line2, eap,
- FALSE, FALSE, FALSE, TRUE) == FAIL) {
- msg_putchar('\n'); /* keep message from buf_write() */
- --no_wait_return;
- if (!aborting())
- (void)EMSG2(_(e_notcreate), itmp); /* will call wait_return */
+ false, false, false, true) == FAIL) {
+ msg_putchar('\n'); // Keep message from buf_write().
+ no_wait_return--;
+ if (!aborting()) {
+ EMSG2(_("E482: Can't create file %s"), itmp); // Will call wait_return.
+ }
goto filterend;
}
if (curbuf != old_curbuf)
@@ -1193,8 +1191,8 @@ static void do_filter(
if (do_out) {
if (otmp != NULL) {
- if (readfile(otmp, NULL, line2, (linenr_T)0, (linenr_T)MAXLNUM,
- eap, READ_FILTER) == FAIL) {
+ if (readfile(otmp, NULL, line2, (linenr_T)0, (linenr_T)MAXLNUM, eap,
+ READ_FILTER) != OK) {
if (!aborting()) {
msg_putchar('\n');
EMSG2(_(e_notread), otmp);
@@ -1215,15 +1213,14 @@ static void do_filter(
if (do_in) {
if (cmdmod.keepmarks || vim_strchr(p_cpo, CPO_REMMARK) == NULL) {
- if (read_linecount >= linecount)
- /* move all marks from old lines to new lines */
- mark_adjust(line1, line2, linecount, 0L);
- else {
- /* move marks from old lines to new lines, delete marks
- * that are in deleted lines */
- mark_adjust(line1, line1 + read_linecount - 1,
- linecount, 0L);
- mark_adjust(line1 + read_linecount, line2, MAXLNUM, 0L);
+ if (read_linecount >= linecount) {
+ // move all marks from old lines to new lines
+ mark_adjust(line1, line2, linecount, 0L, false);
+ } else {
+ // move marks from old lines to new lines, delete marks
+ // that are in deleted lines
+ mark_adjust(line1, line1 + read_linecount - 1, linecount, 0L, false);
+ mark_adjust(line1 + read_linecount, line2, MAXLNUM, 0L, false);
}
}
@@ -1404,36 +1401,34 @@ char_u *make_filter_cmd(char_u *cmd, char_u *itmp, char_u *otmp)
: "(%s)";
vim_snprintf(buf, len, fmt, (char *)cmd);
} else {
- strncpy(buf, (char *) cmd, len);
+ xstrlcpy(buf, (char *)cmd, len);
}
if (itmp != NULL) {
- strncat(buf, " < ", len);
- strncat(buf, (char *) itmp, len);
+ xstrlcat(buf, " < ", len - 1);
+ xstrlcat(buf, (const char *)itmp, len - 1);
}
#else
// For shells that don't understand braces around commands, at least allow
// the use of commands in a pipe.
- strncpy(buf, cmd, len);
+ xstrlcpy(buf, cmd, len);
if (itmp != NULL) {
- char_u *p;
-
// If there is a pipe, we have to put the '<' in front of it.
// Don't do this when 'shellquote' is not empty, otherwise the
// redirection would be inside the quotes.
if (*p_shq == NUL) {
- p = strchr(buf, '|');
+ char *const p = strchr(buf, '|');
if (p != NULL) {
*p = NUL;
}
}
- strncat(buf, " < ", len);
- strncat(buf, (char *) itmp, len);
+ xstrlcat(buf, " < ", len);
+ xstrlcat(buf, (const char *)itmp, len);
if (*p_shq == NUL) {
- p = strchr(cmd, '|');
+ const char *const p = strchr((const char *)cmd, '|');
if (p != NULL) {
- strncat(buf, " ", len); // Insert a space before the '|' for DOS
- strncat(buf, p, len);
+ xstrlcat(buf, " ", len - 1); // Insert a space before the '|' for DOS
+ xstrlcat(buf, p, len - 1);
}
}
}
@@ -1476,12 +1471,12 @@ void append_redir(char *const buf, const size_t buflen,
void print_line_no_prefix(linenr_T lnum, int use_number, int list)
{
- char_u numbuf[30];
+ char numbuf[30];
if (curwin->w_p_nu || use_number) {
- vim_snprintf((char *)numbuf, sizeof(numbuf),
- "%*ld ", number_width(curwin), (long)lnum);
- msg_puts_attr(numbuf, hl_attr(HLF_N)); /* Highlight line nrs */
+ vim_snprintf(numbuf, sizeof(numbuf), "%*" PRIdLINENR " ",
+ number_width(curwin), lnum);
+ msg_puts_attr(numbuf, hl_attr(HLF_N)); // Highlight line nrs.
}
msg_prt_line(ml_get(lnum), list);
}
@@ -1493,6 +1488,11 @@ void print_line(linenr_T lnum, int use_number, int list)
{
int save_silent = silent_mode;
+ // apply :filter /pat/
+ if (message_filtered(ml_get(lnum))) {
+ return;
+ }
+
msg_start();
silent_mode = FALSE;
info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
@@ -1906,11 +1906,15 @@ void do_wqall(exarg_T *eap)
FALSE) == FAIL) {
++error;
} else {
- if (buf_write_all(buf, eap->forceit) == FAIL)
- ++error;
- /* an autocommand may have deleted the buffer */
- if (!buf_valid(buf))
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ if (buf_write_all(buf, eap->forceit) == FAIL) {
+ error++;
+ }
+ // An autocommand may have deleted the buffer.
+ if (!bufref_valid(&bufref)) {
buf = firstbuf;
+ }
}
eap->forceit = save_forceit; /* check_overwrite() may set it */
}
@@ -2083,7 +2087,8 @@ int do_ecmd(
char_u *new_name = NULL;
int did_set_swapcommand = FALSE;
buf_T *buf;
- buf_T *old_curbuf = curbuf;
+ bufref_T bufref;
+ bufref_T old_curbuf;
char_u *free_fname = NULL;
int retval = FAIL;
long n;
@@ -2100,6 +2105,8 @@ int do_ecmd(
if (eap != NULL)
command = eap->do_ecmd_cmd;
+ set_bufref(&old_curbuf, curbuf);
+
if (fnum != 0) {
if (fnum == curbuf->b_fnum) /* file is already being edited */
return OK; /* nothing to do */
@@ -2211,23 +2218,27 @@ int do_ecmd(
if (oldwin != NULL) {
oldwin = curwin;
}
- old_curbuf = curbuf;
+ set_bufref(&old_curbuf, curbuf);
}
if (buf == NULL)
goto theend;
- if (buf->b_ml.ml_mfp == NULL) { /* no memfile yet */
- oldbuf = FALSE;
- } else { /* existing memfile */
- oldbuf = TRUE;
- (void)buf_check_timestamp(buf, FALSE);
- /* Check if autocommands made buffer invalid or changed the current
- * buffer. */
- if (!buf_valid(buf)
- || curbuf != old_curbuf
- )
+ if (buf->b_ml.ml_mfp == NULL) {
+ // No memfile yet.
+ oldbuf = false;
+ } else {
+ // Existing memfile.
+ oldbuf = true;
+ set_bufref(&bufref, buf);
+ (void)buf_check_timestamp(buf, false);
+ // Check if autocommands made buffer invalid or changed the current
+ // buffer.
+ if (!bufref_valid(&bufref) || curbuf != old_curbuf.br_buf) {
goto theend;
- if (aborting()) /* autocmds may abort script processing */
+ }
+ if (aborting()) {
+ // Autocmds may abort script processing.
goto theend;
+ }
}
/* May jump to last used line number for a loaded buffer or when asked
@@ -2255,12 +2266,14 @@ int do_ecmd(
* - If we ended up in the new buffer already, need to skip a few
* things, set auto_buf.
*/
- if (buf->b_fname != NULL)
+ if (buf->b_fname != NULL) {
new_name = vim_strsave(buf->b_fname);
- au_new_curbuf = buf;
- apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
- if (!buf_valid(buf)) { /* new buffer has been deleted */
- delbuf_msg(new_name); /* frees new_name */
+ }
+ set_bufref(&au_new_curbuf, buf);
+ apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf);
+ if (!bufref_valid(&au_new_curbuf)) {
+ // New buffer has been deleted.
+ delbuf_msg(new_name); // Frees new_name.
goto theend;
}
if (aborting()) { /* autocmds may abort script processing */
@@ -2272,29 +2285,34 @@ int do_ecmd(
} else {
win_T *the_curwin = curwin;
- // Set the w_closing flag to avoid that autocommands close the window.
+ // Set w_closing to avoid that autocommands close the window.
+ // Set b_locked for the same reason.
the_curwin->w_closing = true;
- if (curbuf == old_curbuf) {
+ buf->b_locked++;
+
+ if (curbuf == old_curbuf.br_buf) {
buf_copy_options(buf, BCO_ENTER);
}
// Close the link to the current buffer. This will set
- // curwin->w_buffer to NULL.
+ // oldwin->w_buffer to NULL.
u_sync(false);
close_buffer(oldwin, curbuf,
(flags & ECMD_HIDE) || curbuf->terminal ? 0 : DOBUF_UNLOAD,
false);
the_curwin->w_closing = false;
+ buf->b_locked--;
// autocmds may abort script processing
if (aborting() && curwin->w_buffer != NULL) {
xfree(new_name);
goto theend;
}
- /* Be careful again, like above. */
- if (!buf_valid(buf)) { /* new buffer has been deleted */
- delbuf_msg(new_name); /* frees new_name */
+ // Be careful again, like above.
+ if (!bufref_valid(&au_new_curbuf)) {
+ // New buffer has been deleted.
+ delbuf_msg(new_name); // Frees new_name.
goto theend;
}
if (buf == curbuf) { // already in new buffer
@@ -2327,7 +2345,8 @@ int do_ecmd(
}
xfree(new_name);
- au_new_curbuf = NULL;
+ au_new_curbuf.br_buf = NULL;
+ au_new_curbuf.br_buf_free_count = 0;
}
curwin->w_pcmark.lnum = 1;
@@ -2380,10 +2399,12 @@ int do_ecmd(
solcol = curwin->w_cursor.col;
}
buf = curbuf;
- if (buf->b_fname != NULL)
+ if (buf->b_fname != NULL) {
new_name = vim_strsave(buf->b_fname);
- else
+ } else {
new_name = NULL;
+ }
+ set_bufref(&bufref, buf);
if (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur) {
/* Save all the text, so that the reload can be undone.
* Sync first so that this is a separate undo-able action. */
@@ -2396,14 +2417,15 @@ int do_ecmd(
u_unchanged(curbuf);
buf_freeall(curbuf, BFA_KEEP_UNDO);
- /* tell readfile() not to clear or reload undo info */
+ // Tell readfile() not to clear or reload undo info.
readfile_flags = READ_KEEP_UNDO;
- } else
- buf_freeall(curbuf, 0); /* free all things for buffer */
- /* If autocommands deleted the buffer we were going to re-edit, give
- * up and jump to the end. */
- if (!buf_valid(buf)) {
- delbuf_msg(new_name); /* frees new_name */
+ } else {
+ buf_freeall(curbuf, 0); // Free all things for buffer.
+ }
+ // If autocommands deleted the buffer we were going to re-edit, give
+ // up and jump to the end.
+ if (!bufref_valid(&bufref)) {
+ delbuf_msg(new_name); // Frees new_name.
goto theend;
}
xfree(new_name);
@@ -2428,11 +2450,6 @@ int do_ecmd(
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);
@@ -2474,7 +2491,7 @@ int do_ecmd(
if (swap_exists_action == SEA_QUIT)
retval = FAIL;
- handle_swap_exists(old_curbuf);
+ handle_swap_exists(&old_curbuf);
} else {
/* Read the modelines, but only to set window-local options. Any
* buffer-local options have already been set and may have been
@@ -2609,7 +2626,8 @@ static void delbuf_msg(char_u *name)
EMSG2(_("E143: Autocommands unexpectedly deleted new buffer %s"),
name == NULL ? (char_u *)"" : name);
xfree(name);
- au_new_curbuf = NULL;
+ au_new_curbuf.br_buf = NULL;
+ au_new_curbuf.br_buf_free_count = 0;
}
static int append_indent = 0; /* autoindent for first line */
@@ -2784,16 +2802,18 @@ void ex_z(exarg_T *eap)
int j;
linenr_T lnum = eap->line2;
- /* Vi compatible: ":z!" uses display height, without a count uses
- * 'scroll' */
- if (eap->forceit)
+ // Vi compatible: ":z!" uses display height, without a count uses
+ // 'scroll'
+ if (eap->forceit) {
bigness = curwin->w_height;
- else if (firstwin == lastwin)
+ } else if (ONE_WINDOW) {
bigness = curwin->w_p_scr * 2;
- else
+ } else {
bigness = curwin->w_height - 3;
- if (bigness < 1)
+ }
+ if (bigness < 1) {
bigness = 1;
+ }
x = eap->arg;
kind = x;
@@ -2862,8 +2882,11 @@ void ex_z(exarg_T *eap)
if (end > curbuf->b_ml.ml_line_count)
end = curbuf->b_ml.ml_line_count;
- if (curs > curbuf->b_ml.ml_line_count)
+ if (curs > curbuf->b_ml.ml_line_count) {
curs = curbuf->b_ml.ml_line_count;
+ } else if (curs < 1) {
+ curs = 1;
+ }
for (i = start; i <= end; i++) {
if (minus && i == lnum) {
@@ -2883,8 +2906,11 @@ void ex_z(exarg_T *eap)
}
}
- curwin->w_cursor.lnum = curs;
- ex_no_reprint = TRUE;
+ if (curwin->w_cursor.lnum != curs) {
+ curwin->w_cursor.lnum = curs;
+ curwin->w_cursor.col = 0;
+ }
+ ex_no_reprint = true;
}
/*
@@ -2946,7 +2972,7 @@ void sub_set_replacement(SubReplacementString sub)
{
xfree(old_sub.sub);
if (sub.additional_elements != old_sub.additional_elements) {
- list_unref(old_sub.additional_elements);
+ tv_list_unref(old_sub.additional_elements);
}
old_sub = sub;
}
@@ -3308,7 +3334,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout)
// Check for a match on each line.
linenr_T line2 = eap->line2;
for (linenr_T lnum = eap->line1;
- lnum <= line2 && !(got_quit || aborting());
+ lnum <= line2 && !(got_quit || aborting())
+ && (!preview || matched_lines.size <= (size_t)p_cwh);
lnum++) {
long nmatch = vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
(colnr_T)0, NULL);
@@ -3473,6 +3500,10 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout)
setmouse(); /* disable mouse in xterm */
curwin->w_cursor.col = regmatch.startpos[0].col;
+ if (curwin->w_p_crb) {
+ do_check_cursorbind();
+ }
+
/* When 'cpoptions' contains "u" don't sync undo when
* asking for confirmation. */
if (vim_strchr(p_cpo, CPO_UNDO) != NULL)
@@ -3565,11 +3596,9 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout)
ui_cursor_goto(msg_row, msg_col);
RedrawingDisabled = temp;
- ++no_mapping; /* don't map this key */
- ++allow_keys; /* allow special keys */
+ no_mapping++; // don't map this key
typed = plain_vgetc();
- --allow_keys;
- --no_mapping;
+ no_mapping--;
/* clear the question */
msg_didout = FALSE; /* don't scroll up */
@@ -3736,7 +3765,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout)
*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);
+ mark_adjust(lnum + 1, (linenr_T)MAXLNUM, 1L, 0L, false);
if (subflags.do_ask) {
appended_lines(lnum - 1, 1L);
} else {
@@ -3825,7 +3854,7 @@ skip:
for (i = 0; i < nmatch_tl; ++i)
ml_delete(lnum, (int)FALSE);
mark_adjust(lnum, lnum + nmatch_tl - 1,
- (long)MAXLNUM, -nmatch_tl);
+ (long)MAXLNUM, -nmatch_tl, false);
if (subflags.do_ask) {
deleted_lines(lnum, nmatch_tl);
}
@@ -4345,19 +4374,22 @@ void ex_help(exarg_T *eap)
if (!curwin->w_buffer->b_help
|| cmdmod.tab != 0
) {
- if (cmdmod.tab != 0)
+ if (cmdmod.tab != 0) {
wp = NULL;
- else
- for (wp = firstwin; wp != NULL; wp = wp->w_next)
- if (wp->w_buffer != NULL && wp->w_buffer->b_help)
+ } else {
+ wp = NULL;
+ FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) {
+ if (wp2->w_buffer != NULL && wp2->w_buffer->b_help) {
+ wp = wp2;
break;
- if (wp != NULL && wp->w_buffer->b_nwindows > 0)
+ }
+ }
+ }
+ if (wp != NULL && wp->w_buffer->b_nwindows > 0) {
win_enter(wp, true);
- else {
- /*
- * There is no help window yet.
- * Try to open the file specified by the "helpfile" option.
- */
+ } else {
+ // There is no help window yet.
+ // Try to open the file specified by the "helpfile" option.
if ((helpfd = mch_fopen((char *)p_hf, READBIN)) == NULL) {
smsg(_("Sorry, help file \"%s\" not found"), p_hf);
goto erret;
@@ -4751,8 +4783,8 @@ void fix_help_buffer(void)
char_u *p;
char_u *rt;
- /* set filetype to "help". */
- set_option_value((char_u *)"ft", 0L, (char_u *)"help", OPT_LOCAL);
+ // Set filetype to "help".
+ set_option_value("ft", 0L, "help", OPT_LOCAL);
if (!syntax_present(curwin)) {
for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) {
@@ -4814,9 +4846,13 @@ void fix_help_buffer(void)
vimconv_T vc;
char_u *cp;
- /* Find all "doc/ *.txt" files in this directory. */
- add_pathsep((char *)NameBuff);
- STRCAT(NameBuff, "doc/*.??[tx]");
+ // Find all "doc/ *.txt" files in this directory.
+ if (!add_pathsep((char *)NameBuff)
+ || STRLCAT(NameBuff, "doc/*.??[tx]",
+ sizeof(NameBuff)) >= MAXPATHL) {
+ EMSG(_(e_fnametoolong));
+ continue;
+ }
// Note: We cannot just do `&NameBuff` because it is a statically sized array
// so `NameBuff == &NameBuff` according to C semantics.
@@ -4847,8 +4883,9 @@ void fix_help_buffer(void)
continue;
e1 = vim_strrchr(t1, '.');
e2 = vim_strrchr(path_tail(f2), '.');
- if (e1 == NUL || e2 == NUL)
+ if (e1 == NULL || e2 == NULL) {
continue;
+ }
if (fnamecmp(e1, ".txt") != 0
&& fnamecmp(e1, fname + 4) != 0) {
/* Not .txt and not .abx, remove it. */
@@ -4979,8 +5016,12 @@ static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname,
// Find all *.txt files.
size_t dirlen = STRLCPY(NameBuff, dir, sizeof(NameBuff));
- STRCAT(NameBuff, "/**/*"); // NOLINT
- STRCAT(NameBuff, ext);
+ if (dirlen >= MAXPATHL
+ || STRLCAT(NameBuff, "/**/*", sizeof(NameBuff)) >= MAXPATHL // NOLINT
+ || STRLCAT(NameBuff, ext, sizeof(NameBuff)) >= MAXPATHL) {
+ EMSG(_(e_fnametoolong));
+ return;
+ }
// Note: We cannot just do `&NameBuff` because it is a statically sized array
// so `NameBuff == &NameBuff` according to C semantics.
@@ -4988,18 +5029,22 @@ static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname,
if (gen_expand_wildcards(1, buff_list, &filecount, &files,
EW_FILE|EW_SILENT) == FAIL
|| filecount == 0) {
- if (!got_int)
- EMSG2("E151: No match: %s", NameBuff);
+ if (!got_int) {
+ EMSG2(_("E151: No match: %s"), NameBuff);
+ }
return;
}
- /*
- * Open the tags file for writing.
- * Do this before scanning through all the files.
- */
- STRLCPY(NameBuff, dir, sizeof(NameBuff));
- add_pathsep((char *)NameBuff);
- STRNCAT(NameBuff, tagfname, sizeof(NameBuff) - dirlen - 2);
+ //
+ // Open the tags file for writing.
+ // Do this before scanning through all the files.
+ //
+ memcpy(NameBuff, dir, dirlen + 1);
+ if (!add_pathsep((char *)NameBuff)
+ || STRLCAT(NameBuff, tagfname, sizeof(NameBuff)) >= MAXPATHL) {
+ EMSG(_(e_fnametoolong));
+ return;
+ }
fd_tags = mch_fopen((char *)NameBuff, "w");
if (fd_tags == NULL) {
EMSG2(_("E152: Cannot open %s for writing"), NameBuff);
@@ -5063,14 +5108,13 @@ static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname,
}
p1 = vim_strchr(IObuff, '*'); /* find first '*' */
while (p1 != NULL) {
- /* Use vim_strbyte() instead of vim_strchr() so that when
- * 'encoding' is dbcs it still works, don't find '*' in the
- * second byte. */
- p2 = vim_strbyte(p1 + 1, '*'); /* find second '*' */
- if (p2 != NULL && p2 > p1 + 1) { /* skip "*" and "**" */
- for (s = p1 + 1; s < p2; ++s)
- if (*s == ' ' || *s == '\t' || *s == '|')
+ p2 = (char_u *)strchr((const char *)p1 + 1, '*'); // Find second '*'.
+ if (p2 != NULL && p2 > p1 + 1) { // Skip "*" and "**".
+ for (s = p1 + 1; s < p2; s++) {
+ if (*s == ' ' || *s == '\t' || *s == '|') {
break;
+ }
+ }
/*
* Only accept a *tag* when it consists of valid
@@ -5173,8 +5217,12 @@ static void do_helptags(char_u *dirname, bool add_help_tags)
// Get a list of all files in the help directory and in subdirectories.
STRLCPY(NameBuff, dirname, sizeof(NameBuff));
- add_pathsep((char *)NameBuff);
- STRCAT(NameBuff, "**");
+ if (!add_pathsep((char *)NameBuff)
+ || STRLCAT(NameBuff, "**", sizeof(NameBuff)) >= MAXPATHL) {
+ EMSG(_(e_fnametoolong));
+ xfree(dirname);
+ return;
+ }
// Note: We cannot just do `&NameBuff` because it is a statically sized array
// so `NameBuff == &NameBuff` according to C semantics.
@@ -5182,7 +5230,7 @@ static void do_helptags(char_u *dirname, bool add_help_tags)
if (gen_expand_wildcards(1, buff_list, &filecount, &files,
EW_FILE|EW_SILENT) == FAIL
|| filecount == 0) {
- EMSG2("E151: No match: %s", NameBuff);
+ EMSG2(_("E151: No match: %s"), NameBuff);
xfree(dirname);
return;
}
@@ -5688,33 +5736,33 @@ void ex_sign(exarg_T *eap)
*/
static void sign_list_defined(sign_T *sp)
{
- char_u *p;
-
smsg("sign %s", sp->sn_name);
if (sp->sn_icon != NULL) {
- MSG_PUTS(" icon=");
+ msg_puts(" icon=");
msg_outtrans(sp->sn_icon);
- MSG_PUTS(_(" (not supported)"));
+ msg_puts(_(" (not supported)"));
}
if (sp->sn_text != NULL) {
- MSG_PUTS(" text=");
+ msg_puts(" text=");
msg_outtrans(sp->sn_text);
}
if (sp->sn_line_hl > 0) {
- MSG_PUTS(" linehl=");
- p = get_highlight_name(NULL, sp->sn_line_hl - 1);
- if (p == NULL)
- MSG_PUTS("NONE");
- else
+ msg_puts(" linehl=");
+ const char *const p = get_highlight_name(NULL, sp->sn_line_hl - 1);
+ if (p == NULL) {
+ msg_puts("NONE");
+ } else {
msg_puts(p);
+ }
}
if (sp->sn_text_hl > 0) {
- MSG_PUTS(" texthl=");
- p = get_highlight_name(NULL, sp->sn_text_hl - 1);
- if (p == NULL)
- MSG_PUTS("NONE");
- else
+ msg_puts(" texthl=");
+ const char *const p = get_highlight_name(NULL, sp->sn_text_hl - 1);
+ if (p == NULL) {
+ msg_puts("NONE");
+ } else {
msg_puts(p);
+ }
}
}
@@ -5908,9 +5956,8 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
// :sign define {name} {args}... {last}=
// | |
// last p
- if (p == NUL)
- {
- /* Expand last argument name (before equal sign). */
+ if (p == NULL) {
+ // Expand last argument name (before equal sign).
xp->xp_pattern = last;
switch (cmd_idx)
{
@@ -6093,7 +6140,6 @@ void ex_substitute(exarg_T *eap)
int save_w_p_cul = curwin->w_p_cul;
int save_w_p_cuc = curwin->w_p_cuc;
- emsg_off++; // No error messages during command preview.
curbuf->b_p_ul = LONG_MAX; // make sure we can undo all changes
curwin->w_p_cul = false; // Disable 'cursorline'
curwin->w_p_cuc = false; // Disable 'cursorcolumn'
@@ -6107,7 +6153,7 @@ void ex_substitute(exarg_T *eap)
// restore it so that undotree() is identical before/after the preview.
curbuf->b_u_newhead = save_b_u_newhead;
curbuf->b_u_time_cur = save_b_u_time_cur;
- curbuf->b_changedtick = save_changedtick;
+ buf_set_changedtick(curbuf, save_changedtick);
}
if (buf_valid(preview_buf)) {
// XXX: Must do this *after* u_undo_and_forget(), why?
@@ -6120,6 +6166,105 @@ void ex_substitute(exarg_T *eap)
restore_search_patterns();
win_size_restore(&save_view);
ga_clear(&save_view);
- emsg_off--;
unblock_autocmds();
}
+
+/// Skip over the pattern argument of ":vimgrep /pat/[g][j]".
+/// Put the start of the pattern in "*s", unless "s" is NULL.
+/// If "flags" is not NULL put the flags in it: VGR_GLOBAL, VGR_NOJUMP.
+/// If "s" is not NULL terminate the pattern with a NUL.
+/// Return a pointer to the char just past the pattern plus flags.
+char_u *skip_vimgrep_pat(char_u *p, char_u **s, int *flags)
+{
+ int c;
+
+ if (vim_isIDc(*p)) {
+ // ":vimgrep pattern fname"
+ if (s != NULL) {
+ *s = p;
+ }
+ p = skiptowhite(p);
+ if (s != NULL && *p != NUL) {
+ *p++ = NUL;
+ }
+ } else {
+ // ":vimgrep /pattern/[g][j] fname"
+ if (s != NULL) {
+ *s = p + 1;
+ }
+ c = *p;
+ p = skip_regexp(p + 1, c, true, NULL);
+ if (*p != c) {
+ return NULL;
+ }
+
+ // Truncate the pattern.
+ if (s != NULL) {
+ *p = NUL;
+ }
+ p++;
+
+ // Find the flags
+ while (*p == 'g' || *p == 'j') {
+ if (flags != NULL) {
+ if (*p == 'g') {
+ *flags |= VGR_GLOBAL;
+ } else {
+ *flags |= VGR_NOJUMP;
+ }
+ }
+ p++;
+ }
+ }
+ return p;
+}
+
+/// List v:oldfiles in a nice way.
+void ex_oldfiles(exarg_T *eap)
+{
+ list_T *l = get_vim_var_list(VV_OLDFILES);
+ listitem_T *li;
+ long nr = 0;
+
+ if (l == NULL) {
+ msg((char_u *)_("No old files"));
+ } else {
+ msg_start();
+ msg_scroll = true;
+ for (li = l->lv_first; li != NULL && !got_int; li = li->li_next) {
+ nr++;
+ const char *fname = tv_get_string(&li->li_tv);
+ if (!message_filtered((char_u *)fname)) {
+ msg_outnum(nr);
+ MSG_PUTS(": ");
+ msg_outtrans((char_u *)tv_get_string(&li->li_tv));
+ msg_clr_eos();
+ msg_putchar('\n');
+ ui_flush(); // output one line at a time
+ os_breakcheck();
+ }
+ }
+
+ // Assume "got_int" was set to truncate the listing.
+ got_int = false;
+
+ // File selection prompt on ":browse oldfiles"
+ if (cmdmod.browse) {
+ quit_more = false;
+ nr = prompt_for_number(false);
+ msg_starthere();
+ if (nr > 0 && nr <= l->lv_len) {
+ const char *const p = tv_list_find_str(l, nr - 1);
+ if (p == NULL) {
+ return;
+ }
+ char *const s = (char *)expand_env_save((char_u *)p);
+ eap->arg = (char_u *)s;
+ eap->cmdidx = CMD_edit;
+ cmdmod.browse = false;
+ do_exedit(eap, NULL);
+ xfree(s);
+ }
+ }
+ }
+}
diff --git a/src/nvim/ex_cmds.h b/src/nvim/ex_cmds.h
index 243b11255e..b564cde56c 100644
--- a/src/nvim/ex_cmds.h
+++ b/src/nvim/ex_cmds.h
@@ -4,8 +4,10 @@
#include <stdbool.h>
#include "nvim/os/time.h"
-#include "nvim/eval_defs.h"
#include "nvim/pos.h"
+#include "nvim/eval/typval.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/ex_cmds_defs.h"
// flags for do_ecmd()
#define ECMD_HIDE 0x01 // don't free the current buffer
diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua
index 88095602ba..5a578cd088 100644
--- a/src/nvim/ex_cmds.lua
+++ b/src/nvim/ex_cmds.lua
@@ -1,4 +1,4 @@
-bit = require 'bit'
+local bit = require 'bit'
-- Description of the values below is contained in ex_cmds_defs.h file.
local RANGE = 0x001
@@ -34,7 +34,8 @@ local ADDR_ARGUMENTS = 2
local ADDR_LOADED_BUFFERS = 3
local ADDR_BUFFERS = 4
local ADDR_TABS = 5
-local ADDR_QUICKFIX = 6
+local ADDR_TABS_RELATIVE = 6
+local ADDR_QUICKFIX = 7
local ADDR_OTHER = 99
-- The following table is described in ex_cmds_defs.h file.
@@ -462,6 +463,12 @@ return {
func='ex_checktime',
},
{
+ command='chistory',
+ flags=bit.bor(TRLBAR),
+ addr_type=ADDR_LINES,
+ func='qf_history',
+ },
+ {
command='clist',
flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN),
addr_type=ADDR_LINES,
@@ -621,13 +628,13 @@ return {
command='cscope',
flags=bit.bor(EXTRA, NOTRLCOM, XFILE),
addr_type=ADDR_LINES,
- func='do_cscope',
+ func='ex_cscope',
},
{
command='cstag',
flags=bit.bor(BANG, TRLBAR, WORD1),
addr_type=ADDR_LINES,
- func='do_cstag',
+ func='ex_cstag',
},
{
command='cunmap',
@@ -924,6 +931,12 @@ return {
func='ex_filetype',
},
{
+ command='filter',
+ flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM),
+ addr_type=ADDR_LINES,
+ func='ex_wrongmodifier',
+ },
+ {
command='find',
flags=bit.bor(RANGE, NOTADR, BANG, FILE1, EDITCMD, ARGOPT, TRLBAR),
addr_type=ADDR_LINES,
@@ -1063,7 +1076,7 @@ return {
},
{
command='hide',
- flags=bit.bor(BANG, RANGE, NOTADR, COUNT, EXTRA, NOTRLCOM),
+ flags=bit.bor(BANG, RANGE, NOTADR, COUNT, EXTRA, TRLBAR),
addr_type=ADDR_WINDOWS,
func='ex_hide',
},
@@ -1311,7 +1324,7 @@ return {
command='lcscope',
flags=bit.bor(EXTRA, NOTRLCOM, XFILE),
addr_type=ADDR_LINES,
- func='do_cscope',
+ func='ex_cscope',
},
{
command='ldo',
@@ -1400,6 +1413,12 @@ return {
func='ex_helpgrep',
},
{
+ command='lhistory',
+ flags=bit.bor(TRLBAR),
+ addr_type=ADDR_LINES,
+ func='qf_history',
+ },
+ {
command='ll',
flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG),
addr_type=ADDR_LINES,
@@ -1529,19 +1548,19 @@ return {
command='lua',
flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN),
addr_type=ADDR_LINES,
- func='ex_script_ni',
+ func='ex_lua',
},
{
command='luado',
flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN),
addr_type=ADDR_LINES,
- func='ex_ni',
+ func='ex_luado',
},
{
command='luafile',
flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN),
addr_type=ADDR_LINES,
- func='ex_ni',
+ func='ex_luafile',
},
{
command='lvimgrep',
@@ -2315,7 +2334,7 @@ return {
command='scscope',
flags=bit.bor(EXTRA, NOTRLCOM),
addr_type=ADDR_LINES,
- func='do_scscope',
+ func='ex_scscope',
},
{
command='set',
@@ -2638,12 +2657,12 @@ return {
{
command='tab',
flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM),
- addr_type=ADDR_LINES,
+ addr_type=ADDR_TABS,
func='ex_wrongmodifier',
},
{
command='tabclose',
- flags=bit.bor(RANGE, NOTADR, COUNT, BANG, TRLBAR, CMDWIN),
+ flags=bit.bor(BANG, RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR, CMDWIN),
addr_type=ADDR_TABS,
func='ex_tabclose',
},
@@ -2668,7 +2687,7 @@ return {
{
command='tabfirst',
flags=bit.bor(TRLBAR),
- addr_type=ADDR_LINES,
+ addr_type=ADDR_TABS,
func='ex_tabnext',
},
{
@@ -2680,13 +2699,13 @@ return {
{
command='tablast',
flags=bit.bor(TRLBAR),
- addr_type=ADDR_LINES,
+ addr_type=ADDR_TABS,
func='ex_tabnext',
},
{
command='tabnext',
- flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR),
- addr_type=ADDR_LINES,
+ flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR),
+ addr_type=ADDR_TABS,
func='ex_tabnext',
},
{
@@ -2697,32 +2716,32 @@ return {
},
{
command='tabonly',
- flags=bit.bor(BANG, RANGE, NOTADR, TRLBAR, CMDWIN),
+ flags=bit.bor(BANG, RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR, CMDWIN),
addr_type=ADDR_TABS,
func='ex_tabonly',
},
{
command='tabprevious',
- flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR),
- addr_type=ADDR_LINES,
+ flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR),
+ addr_type=ADDR_TABS_RELATIVE,
func='ex_tabnext',
},
{
command='tabNext',
- flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR),
- addr_type=ADDR_LINES,
+ flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR),
+ addr_type=ADDR_TABS_RELATIVE,
func='ex_tabnext',
},
{
command='tabrewind',
flags=bit.bor(TRLBAR),
- addr_type=ADDR_LINES,
+ addr_type=ADDR_TABS,
func='ex_tabnext',
},
{
command='tabs',
flags=bit.bor(TRLBAR, CMDWIN),
- addr_type=ADDR_LINES,
+ addr_type=ADDR_TABS,
func='ex_tabs',
},
{
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 3b92b3734a..371f7b3bce 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// @file ex_cmds2.c
///
/// Some more functions for command line commands
@@ -186,7 +189,8 @@ void do_debug(char_u *cmd)
}
xfree(cmdline);
- cmdline = getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL);
+ cmdline = (char_u *)getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL,
+ CALLBACK_NONE);
if (typeahead_saved) {
restore_typeahead(&typeaheadbuf);
@@ -957,23 +961,21 @@ char_u *get_profile_name(expand_T *xp, int idx)
}
/// Handle command line completion for :profile command.
-void set_context_in_profile_cmd(expand_T *xp, char_u *arg)
+void set_context_in_profile_cmd(expand_T *xp, const char *arg)
{
- char_u *end_subcmd;
-
// Default: expand subcommands.
xp->xp_context = EXPAND_PROFILE;
pexpand_what = PEXP_SUBCMD;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
- end_subcmd = skiptowhite(arg);
+ char_u *const end_subcmd = skiptowhite((const char_u *)arg);
if (*end_subcmd == NUL) {
return;
}
- if (end_subcmd - arg == 5 && STRNCMP(arg, "start", 5) == 0) {
+ if ((const char *)end_subcmd - arg == 5 && strncmp(arg, "start", 5) == 0) {
xp->xp_context = EXPAND_FILES;
- xp->xp_pattern = skipwhite(end_subcmd);
+ xp->xp_pattern = skipwhite((const char_u *)end_subcmd);
return;
}
@@ -1181,6 +1183,7 @@ bool prof_def_func(void)
int autowrite(buf_T *buf, int forceit)
{
int r;
+ bufref_T bufref;
if (!(p_aw || p_awa) || !p_write
// never autowrite a "nofile" or "nowrite" buffer
@@ -1188,11 +1191,12 @@ int autowrite(buf_T *buf, int forceit)
|| (!forceit && buf->b_p_ro) || buf->b_ffname == NULL) {
return FAIL;
}
+ set_bufref(&bufref, buf);
r = buf_write_all(buf, forceit);
// Writing may succeed but the buffer still changed, e.g., when there is a
// conversion error. We do want to return FAIL then.
- if (buf_valid(buf) && bufIsChanged(buf)) {
+ if (bufref_valid(&bufref) && bufIsChanged(buf)) {
r = FAIL;
}
return r;
@@ -1207,9 +1211,11 @@ void autowrite_all(void)
FOR_ALL_BUFFERS(buf) {
if (bufIsChanged(buf) && !buf->b_p_ro) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
(void)buf_write_all(buf, false);
// an autocommand may have deleted the buffer
- if (!buf_valid(buf)) {
+ if (!bufref_valid(&bufref)) {
buf = firstbuf;
}
}
@@ -1221,6 +1227,8 @@ void autowrite_all(void)
bool check_changed(buf_T *buf, int flags)
{
int forceit = (flags & CCGD_FORCEIT);
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
if (!forceit
&& bufIsChanged(buf)
@@ -1236,12 +1244,12 @@ bool check_changed(buf_T *buf, int flags)
}
}
}
- if (!buf_valid(buf)) {
+ if (!bufref_valid(&bufref)) {
// Autocommand deleted buffer, oops! It's not changed now.
return false;
}
dialog_changed(buf, count > 1);
- if (!buf_valid(buf)) {
+ if (!bufref_valid(&bufref)) {
// Autocommand deleted buffer, oops! It's not changed now.
return false;
}
@@ -1300,9 +1308,10 @@ void dialog_changed(buf_T *buf, int checkall)
// Skip readonly buffers, these need to be confirmed
// individually.
FOR_ALL_BUFFERS(buf2) {
- if (bufIsChanged(buf2)
- && (buf2->b_ffname != NULL)
- && !buf2->b_p_ro) {
+ if (bufIsChanged(buf2) && (buf2->b_ffname != NULL) && !buf2->b_p_ro) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf2);
+
if (buf2->b_fname != NULL
&& check_overwrite(&ea, buf2, buf2->b_fname,
buf2->b_ffname, false) == OK) {
@@ -1310,7 +1319,7 @@ void dialog_changed(buf_T *buf, int checkall)
(void)buf_write_all(buf2, false);
}
// an autocommand may have deleted the buffer
- if (!buf_valid(buf2)) {
+ if (!bufref_valid(&bufref)) {
buf2 = firstbuf;
}
}
@@ -1407,11 +1416,14 @@ bool check_changed_any(bool hidden, bool unload)
continue;
}
if ((!hidden || buf->b_nwindows == 0) && bufIsChanged(buf)) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+
// Try auto-writing the buffer. If this fails but the buffer no
// longer exists it's not changed, that's OK.
if (check_changed(buf, (p_awa ? CCGD_AW : 0)
| CCGD_MULTWIN
- | CCGD_ALLBUF) && buf_valid(buf)) {
+ | CCGD_ALLBUF) && bufref_valid(&bufref)) {
break; // didn't save - still changes
}
}
@@ -1447,9 +1459,11 @@ bool check_changed_any(bool hidden, bool unload)
if (buf != curbuf) {
FOR_ALL_TAB_WINDOWS(tp, wp) {
if (wp->w_buffer == buf) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
goto_tabpage_win(tp, wp);
// Paranoia: did autocmds wipe out the buffer with changes?
- if (!buf_valid(buf)) {
+ if (!bufref_valid(&bufref)) {
goto theend;
}
goto buf_found;
@@ -2061,9 +2075,9 @@ void ex_listdo(exarg_T *eap)
// Clear 'shm' to avoid that the file message overwrites
// any output from the command.
p_shm_save = vim_strsave(p_shm);
- set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
+ set_option_value("shm", 0L, "", 0);
do_argfile(eap, i);
- set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
+ set_option_value("shm", 0L, (char *)p_shm_save, 0);
xfree(p_shm_save);
}
if (curwin->w_arg_idx != i) {
@@ -2126,9 +2140,9 @@ void ex_listdo(exarg_T *eap)
// Go to the next buffer. Clear 'shm' to avoid that the file
// message overwrites any output from the command.
p_shm_save = vim_strsave(p_shm);
- set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
+ set_option_value("shm", 0L, "", 0);
goto_buffer(eap, DOBUF_FIRST, FORWARD, next_fnum);
- set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
+ set_option_value("shm", 0L, (char *)p_shm_save, 0);
xfree(p_shm_save);
// If autocommands took us elsewhere, quit here.
@@ -2238,14 +2252,14 @@ void ex_compiler(exarg_T *eap)
// plugin will then skip the settings. Afterwards set
// "b:current_compiler" and restore "current_compiler".
// Explicitly prepend "g:" to make it work in a function.
- old_cur_comp = get_var_value((char_u *)"g:current_compiler");
+ old_cur_comp = get_var_value("g:current_compiler");
if (old_cur_comp != NULL) {
old_cur_comp = vim_strsave(old_cur_comp);
}
do_cmdline_cmd("command -nargs=* CompilerSet setlocal <args>");
}
- do_unlet((char_u *)"g:current_compiler", true);
- do_unlet((char_u *)"b:current_compiler", true);
+ do_unlet(S_LEN("g:current_compiler"), true);
+ do_unlet(S_LEN("b:current_compiler"), true);
snprintf((char *)buf, bufsize, "compiler/%s.vim", eap->arg);
if (source_runtime(buf, DIP_ALL) == FAIL) {
@@ -2256,7 +2270,7 @@ void ex_compiler(exarg_T *eap)
do_cmdline_cmd(":delcommand CompilerSet");
// Set "b:current_compiler" from "current_compiler".
- p = get_var_value((char_u *)"g:current_compiler");
+ p = get_var_value("g:current_compiler");
if (p != NULL) {
set_internal_string_var((char_u *)"b:current_compiler", p);
}
@@ -2268,7 +2282,7 @@ void ex_compiler(exarg_T *eap)
old_cur_comp);
xfree(old_cur_comp);
} else {
- do_unlet((char_u *)"g:current_compiler", true);
+ do_unlet(S_LEN("g:current_compiler"), true);
}
}
}
@@ -2305,16 +2319,6 @@ static void source_callback(char_u *fname, void *cookie)
(void)do_source(fname, false, DOSO_NONE);
}
-/// Source the file "name" from all directories in 'runtimepath'.
-/// "name" can contain wildcards.
-/// When "flags" has DIP_ALL: source all files, otherwise only the first one.
-///
-/// return FAIL when no file could be sourced, OK otherwise.
-int source_runtime(char_u *name, int flags)
-{
- return do_in_runtimepath(name, flags, source_callback, NULL);
-}
-
/// Find the file "name" in all directories in "path" and invoke
/// "callback(fname, cookie)".
/// "name" can contain wildcards.
@@ -2349,12 +2353,25 @@ int do_in_path(char_u *path, char_u *name, int flags,
while (*rtp != NUL && ((flags & DIP_ALL) || !did_one)) {
// Copy the path from 'runtimepath' to buf[].
copy_option_part(&rtp, buf, MAXPATHL, ",");
+ size_t buflen = STRLEN(buf);
+
+ // Skip after or non-after directories.
+ if (flags & (DIP_NOAFTER | DIP_AFTER)) {
+ bool is_after = buflen >= 5
+ && STRCMP(buf + buflen - 5, "after") == 0;
+
+ if ((is_after && (flags & DIP_NOAFTER))
+ || (!is_after && (flags & DIP_AFTER))) {
+ continue;
+ }
+ }
+
if (name == NULL) {
(*callback)(buf, (void *)&cookie);
if (!did_one) {
did_one = (cookie == NULL);
}
- } else if (STRLEN(buf) + STRLEN(name) + 2 < MAXPATHL) {
+ } else if (buflen + STRLEN(name) + 2 < MAXPATHL) {
add_pathsep((char *)buf);
tail = buf + STRLEN(buf);
@@ -2407,21 +2424,21 @@ int do_in_path(char_u *path, char_u *name, int flags,
return did_one ? OK : FAIL;
}
-/// Find "name" in 'runtimepath'. When found, invoke the callback function for
+/// Find "name" in "path". When found, invoke the callback function for
/// it: callback(fname, "cookie")
/// When "flags" has DIP_ALL repeat for all matches, otherwise only the first
/// one is used.
/// Returns OK when at least one match found, FAIL otherwise.
-/// If "name" is NULL calls callback for each entry in runtimepath. Cookie is
+/// If "name" is NULL calls callback for each entry in "path". Cookie is
/// passed by reference in this case, setting it to NULL indicates that callback
/// has done its job.
-int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback,
- void *cookie)
+int do_in_path_and_pp(char_u *path, char_u *name, int flags,
+ DoInRuntimepathCB callback, void *cookie)
{
int done = FAIL;
if ((flags & DIP_NORTP) == 0) {
- done = do_in_path(p_rtp, name, flags, callback, cookie);
+ done = do_in_path(path, name, flags, callback, cookie);
}
if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_START)) {
@@ -2449,6 +2466,29 @@ int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback,
return done;
}
+/// Just like do_in_path_and_pp(), using 'runtimepath' for "path".
+int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback,
+ void *cookie)
+{
+ return do_in_path_and_pp(p_rtp, name, flags, callback, cookie);
+}
+
+/// Source the file "name" from all directories in 'runtimepath'.
+/// "name" can contain wildcards.
+/// When "flags" has DIP_ALL: source all files, otherwise only the first one.
+///
+/// return FAIL when no file could be sourced, OK otherwise.
+int source_runtime(char_u *name, int flags)
+{
+ return source_in_path(p_rtp, name, flags);
+}
+
+/// Just like source_runtime(), but use "path" instead of 'runtimepath'.
+int source_in_path(char_u *path, char_u *name, int flags)
+{
+ return do_in_path_and_pp(path, name, flags, source_callback, NULL);
+}
+
// Expand wildcards in "pat" and invoke do_source() for each match.
static void source_all_matches(char_u *pat)
{
@@ -2471,16 +2511,17 @@ static int APP_BOTH;
static void add_pack_plugin(char_u *fname, void *cookie)
{
char_u *p4, *p3, *p2, *p1, *p;
- char_u *new_rtp;
- char_u *ffname = (char_u *)fix_fname((char *)fname);
+ char_u *buf = NULL;
+
+ char *const ffname = fix_fname((char *)fname);
if (ffname == NULL) {
return;
}
- if (cookie != &APP_LOAD && strstr((char *)p_rtp, (char *)ffname) == NULL) {
+ if (cookie != &APP_LOAD && strstr((char *)p_rtp, ffname) == NULL) {
// directory is not yet in 'runtimepath', add it
- p4 = p3 = p2 = p1 = get_past_head(ffname);
+ p4 = p3 = p2 = p1 = get_past_head((char_u *)ffname);
for (p = p1; *p; mb_ptr_adv(p)) {
if (vim_ispathsep_nocolon(*p)) {
p4 = p3; p3 = p2; p2 = p1; p1 = p;
@@ -2496,57 +2537,70 @@ static void add_pack_plugin(char_u *fname, void *cookie)
*p4 = NUL;
// Find "ffname" in "p_rtp", ignoring '/' vs '\' differences
- size_t fname_len = STRLEN(ffname);
- char_u *insp = p_rtp;
- for (;;) {
- if (vim_fnamencmp(insp, ffname, fname_len) == 0) {
- break;
+ size_t fname_len = strlen(ffname);
+ const char *insp = (const char *)p_rtp;
+ buf = try_malloc(MAXPATHL);
+ if (buf == NULL) {
+ goto theend;
+ }
+ while (*insp != NUL) {
+ copy_option_part((char_u **)&insp, buf, MAXPATHL, ",");
+ add_pathsep((char *)buf);
+ char *const rtp_ffname = fix_fname((char *)buf);
+ if (rtp_ffname == NULL) {
+ goto theend;
}
- insp = vim_strchr(insp, ',');
- if (insp == NULL) {
+ bool match = path_fnamencmp(rtp_ffname, ffname, fname_len) == 0;
+ xfree(rtp_ffname);
+ if (match) {
break;
}
- insp++;
}
- if (insp == NULL) {
+ if (*insp == NUL) {
// not found, append at the end
- insp = p_rtp + STRLEN(p_rtp);
+ insp = (const char *)p_rtp + STRLEN(p_rtp);
} else {
// append after the matching directory.
- insp += STRLEN(ffname);
- while (*insp != NUL && *insp != ',') {
- insp++;
- }
+ insp--;
}
*p4 = c;
// check if rtp/pack/name/start/name/after exists
- char *afterdir = concat_fnames((char *)ffname, "after", true);
+ char *afterdir = concat_fnames(ffname, "after", true);
size_t afterlen = 0;
if (os_isdir((char_u *)afterdir)) {
- afterlen = STRLEN(afterdir) + 1; // add one for comma
+ afterlen = strlen(afterdir) + 1; // add one for comma
}
- size_t oldlen = STRLEN(p_rtp);
- size_t addlen = STRLEN(ffname) + 1; // add one for comma
- new_rtp = try_malloc(oldlen + addlen + afterlen + 1); // add one for NUL
+ const size_t oldlen = STRLEN(p_rtp);
+ const size_t addlen = strlen(ffname) + 1; // add one for comma
+ const size_t new_rtp_len = oldlen + addlen + afterlen + 1;
+ // add one for NUL -------------------------------------^
+ char *const new_rtp = try_malloc(new_rtp_len);
if (new_rtp == NULL) {
goto theend;
}
- uintptr_t keep = (uintptr_t)(insp - p_rtp);
+ const size_t keep = (size_t)(insp - (const char *)p_rtp);
+ size_t new_rtp_fill = 0;
memmove(new_rtp, p_rtp, keep);
- new_rtp[keep] = ',';
- memmove(new_rtp + keep + 1, ffname, addlen);
+ new_rtp_fill += keep;
+ new_rtp[new_rtp_fill++] = ',';
+ memmove(new_rtp + new_rtp_fill, ffname, addlen);
+ new_rtp_fill += addlen - 1;
+ assert(new_rtp[new_rtp_fill] == NUL || new_rtp[new_rtp_fill] == ',');
if (p_rtp[keep] != NUL) {
- memmove(new_rtp + keep + addlen, p_rtp + keep,
- oldlen - keep + 1);
+ memmove(new_rtp + new_rtp_fill, p_rtp + keep, oldlen - keep + 1);
+ new_rtp_fill += oldlen - keep;
}
if (afterlen > 0) {
- STRCAT(new_rtp, ",");
- STRCAT(new_rtp, afterdir);
+ assert(new_rtp[new_rtp_fill] == NUL);
+ new_rtp[new_rtp_fill++] = ',';
+ memmove(new_rtp + new_rtp_fill, afterdir, afterlen - 1);
+ new_rtp_fill += afterlen - 1;
}
- set_option_value((char_u *)"rtp", 0L, new_rtp, 0);
+ new_rtp[new_rtp_fill] = NUL;
+ set_option_value("rtp", 0L, new_rtp, 0);
xfree(new_rtp);
xfree(afterdir);
}
@@ -2555,7 +2609,7 @@ static void add_pack_plugin(char_u *fname, void *cookie)
static const char *plugpat = "%s/plugin/**/*.vim"; // NOLINT
static const char *ftpat = "%s/ftdetect/*.vim"; // NOLINT
- size_t len = STRLEN(ffname) + STRLEN(ftpat);
+ size_t len = strlen(ffname) + STRLEN(ftpat);
char_u *pat = try_malloc(len + 1);
if (pat == NULL) {
goto theend;
@@ -2578,25 +2632,35 @@ static void add_pack_plugin(char_u *fname, void *cookie)
}
theend:
+ xfree(buf);
xfree(ffname);
}
-static bool did_source_packages = false;
+/// Add all packages in the "start" directory to 'runtimepath'.
+void add_pack_start_dirs(void)
+{
+ do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT
+ add_pack_plugin, &APP_ADD_DIR);
+}
+
+/// Load plugins from all packages in the "start" directory.
+void load_start_packages(void)
+{
+ did_source_packages = true;
+ do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT
+ add_pack_plugin, &APP_LOAD);
+}
// ":packloadall"
// Find plugins in the package directories and source them.
void ex_packloadall(exarg_T *eap)
{
- if (!did_source_packages || (eap != NULL && eap->forceit)) {
- did_source_packages = true;
-
+ if (!did_source_packages || eap->forceit) {
// First do a round to add all directories to 'runtimepath', then load
// the plugins. This allows for plugins to use an autoload directory
// of another plugin.
- do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT
- add_pack_plugin, &APP_ADD_DIR);
- do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT
- add_pack_plugin, &APP_LOAD);
+ add_pack_start_dirs();
+ load_start_packages();
}
}
@@ -2680,14 +2744,7 @@ static FILE *fopen_noinh_readbin(char *filename)
return NULL;
}
-#ifdef HAVE_FD_CLOEXEC
- {
- int fdflags = fcntl(fd_tmp, F_GETFD);
- if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0) {
- (void)fcntl(fd_tmp, F_SETFD, fdflags | FD_CLOEXEC);
- }
- }
-#endif
+ (void)os_set_cloexec(fd_tmp);
return fdopen(fd_tmp, READBIN);
}
@@ -3581,18 +3638,11 @@ void ex_language(exarg_T *eap)
static char_u **locales = NULL; // Array of all available locales
-static bool did_init_locales = false;
-/// Lazy initialization of all available locales.
-static void init_locales(void)
-{
- if (!did_init_locales) {
- did_init_locales = true;
- locales = find_locales();
- }
-}
+#ifndef WIN32
+static bool did_init_locales = false;
-// Return an array of strings for all available locales + NULL for the
+/// Return an array of strings for all available locales + NULL for the
/// last element. Return NULL in case of error.
static char_u **find_locales(void)
{
@@ -3624,6 +3674,18 @@ static char_u **find_locales(void)
((char_u **)locales_ga.ga_data)[locales_ga.ga_len] = NULL;
return (char_u **)locales_ga.ga_data;
}
+#endif
+
+/// Lazy initialization of all available locales.
+static void init_locales(void)
+{
+#ifndef WIN32
+ if (!did_init_locales) {
+ did_init_locales = true;
+ locales = find_locales();
+ }
+#endif
+}
# if defined(EXITFREE)
void free_locales(void)
@@ -3676,19 +3738,18 @@ char_u *get_locales(expand_T *xp, int idx)
static void script_host_execute(char *name, exarg_T *eap)
{
- uint8_t *script = script_get(eap, eap->arg);
+ size_t len;
+ char *const script = script_get(eap, &len);
- if (!eap->skip) {
- list_T *args = list_alloc();
+ if (script != NULL) {
+ list_T *const args = tv_list_alloc();
// script
- list_append_string(args, script ? script : eap->arg, -1);
+ tv_list_append_allocated_string(args, script);
// current range
- list_append_number(args, (int)eap->line1);
- list_append_number(args, (int)eap->line2);
+ tv_list_append_number(args, (int)eap->line1);
+ tv_list_append_number(args, (int)eap->line2);
(void)eval_call_provider(name, "execute", args);
}
-
- xfree(script);
}
static void script_host_execute_file(char *name, exarg_T *eap)
@@ -3696,21 +3757,21 @@ static void script_host_execute_file(char *name, exarg_T *eap)
uint8_t buffer[MAXPATHL];
vim_FullName((char *)eap->arg, (char *)buffer, sizeof(buffer), false);
- list_T *args = list_alloc();
+ list_T *args = tv_list_alloc();
// filename
- list_append_string(args, buffer, -1);
+ tv_list_append_string(args, (const char *)buffer, -1);
// current range
- list_append_number(args, (int)eap->line1);
- list_append_number(args, (int)eap->line2);
+ tv_list_append_number(args, (int)eap->line1);
+ tv_list_append_number(args, (int)eap->line2);
(void)eval_call_provider(name, "execute_file", args);
}
static void script_host_do_range(char *name, exarg_T *eap)
{
- list_T *args = list_alloc();
- list_append_number(args, (int)eap->line1);
- list_append_number(args, (int)eap->line2);
- list_append_string(args, eap->arg, -1);
+ list_T *args = tv_list_alloc();
+ tv_list_append_number(args, (int)eap->line1);
+ tv_list_append_number(args, (int)eap->line2);
+ tv_list_append_string(args, (const char *)eap->arg, -1);
(void)eval_call_provider(name, "do_range", args);
}
diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h
index c6389a0c8b..d72b83404e 100644
--- a/src/nvim/ex_cmds_defs.h
+++ b/src/nvim/ex_cmds_defs.h
@@ -6,6 +6,7 @@
#include "nvim/pos.h" // for linenr_T
#include "nvim/normal.h"
+#include "nvim/regexp_defs.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_cmds_enum.generated.h"
@@ -72,7 +73,8 @@
#define ADDR_LOADED_BUFFERS 3
#define ADDR_BUFFERS 4
#define ADDR_TABS 5
-#define ADDR_QUICKFIX 6
+#define ADDR_TABS_RELATIVE 6 // Tab page that only relative
+#define ADDR_QUICKFIX 7
#define ADDR_OTHER 99
typedef struct exarg exarg_T;
@@ -162,18 +164,20 @@ struct expand {
/// flag. This needs to be saved for recursive commands, put them in a
/// structure for easy manipulation.
typedef struct {
- int split; ///< flags for win_split()
- int tab; ///< > 0 when ":tab" was used
- bool browse; ///< true to invoke file dialog
- bool confirm; ///< true to invoke yes/no dialog
- bool hide; ///< true when ":hide" was used
- bool keepalt; ///< true when ":keepalt" was used
- bool keepjumps; ///< true when ":keepjumps" was used
- bool keepmarks; ///< true when ":keepmarks" was used
- bool keeppatterns; ///< true when ":keeppatterns" was used
- bool lockmarks; ///< true when ":lockmarks" was used
- bool noswapfile; ///< true when ":noswapfile" was used
- char_u *save_ei; ///< saved value of 'eventignore'
+ int split; ///< flags for win_split()
+ int tab; ///< > 0 when ":tab" was used
+ bool browse; ///< true to invoke file dialog
+ bool confirm; ///< true to invoke yes/no dialog
+ bool hide; ///< true when ":hide" was used
+ bool keepalt; ///< true when ":keepalt" was used
+ bool keepjumps; ///< true when ":keepjumps" was used
+ bool keepmarks; ///< true when ":keepmarks" was used
+ bool keeppatterns; ///< true when ":keeppatterns" was used
+ bool lockmarks; ///< true when ":lockmarks" was used
+ bool noswapfile; ///< true when ":noswapfile" was used
+ char_u *save_ei; ///< saved value of 'eventignore'
+ regmatch_T filter_regmatch; ///< set by :filter /pat/
+ bool filter_force; ///< set for :filter!
} cmdmod_T;
#endif // NVIM_EX_CMDS_DEFS_H
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index eccece7ac7..d1405978b3 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* ex_docmd.c: functions for executing an Ex command line.
*/
@@ -50,6 +53,7 @@
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/spell.h"
+#include "nvim/spellfile.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/tag.h"
@@ -66,6 +70,8 @@
#include "nvim/event/rstream.h"
#include "nvim/event/wstream.h"
#include "nvim/shada.h"
+#include "nvim/lua/executor.h"
+#include "nvim/globals.h"
static int quitmore = 0;
static int ex_pressedreturn = FALSE;
@@ -268,7 +274,7 @@ do_exmode (
/*
* Execute a simple command line. Used for translated commands like "*".
*/
-int do_cmdline_cmd(char *cmd)
+int do_cmdline_cmd(const char *cmd)
{
return do_cmdline((char_u *)cmd, NULL, NULL,
DOCMD_NOWAIT|DOCMD_KEYTYPED);
@@ -334,12 +340,13 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
msg_list = &private_msg_list;
private_msg_list = NULL;
- /* It's possible to create an endless loop with ":execute", catch that
- * here. The value of 200 allows nested function calls, ":source", etc. */
- if (call_depth == 200) {
+ // It's possible to create an endless loop with ":execute", catch that
+ // here. The value of 200 allows nested function calls, ":source", etc.
+ // Allow 200 or 'maxfuncdepth', whatever is larger.
+ if (call_depth >= 200 && call_depth >= p_mfd) {
EMSG(_("E169: Command too recursive"));
- /* When converting to an exception, we do not include the command name
- * since this is not an error of the specific command. */
+ // When converting to an exception, we do not include the command name
+ // since this is not an error of the specific command.
do_errthrow((struct condstack *)NULL, (char_u *)NULL);
msg_list = saved_msg_list;
return FAIL;
@@ -583,10 +590,10 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
++no_wait_return;
verbose_enter_scroll();
- smsg(_("line %" PRId64 ": %s"),
- (int64_t)sourcing_lnum, cmdline_copy);
- if (msg_silent == 0)
- msg_puts((char_u *)"\n"); /* don't overwrite this */
+ smsg(_("line %" PRIdLINENR ": %s"), sourcing_lnum, cmdline_copy);
+ if (msg_silent == 0) {
+ msg_puts("\n"); // don't overwrite this either
+ }
verbose_leave_scroll();
--no_wait_return;
@@ -838,8 +845,6 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
break;
case ET_INTERRUPT:
break;
- default:
- p = vim_strsave((char_u *)_(e_internal));
}
saved_sourcing_name = sourcing_name;
@@ -1244,6 +1249,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
cmdmod_T save_cmdmod;
int ni; /* set when Not Implemented */
char_u *cmd;
+ int address_count = 1;
memset(&ea, 0, sizeof(ea));
ea.line1 = 1;
@@ -1301,7 +1307,6 @@ static char_u * do_one_cmd(char_u **cmdlinep,
/*
* 2. Handle command modifiers.
*/
- p = ea.cmd;
p = skip_range(ea.cmd, NULL);
switch (*p) {
/* When adding an entry, also modify cmd_exists(). */
@@ -1345,6 +1350,31 @@ static char_u * do_one_cmd(char_u **cmdlinep,
cmdmod.keepjumps = true;
continue;
+ case 'f': { // only accept ":filter {pat} cmd"
+ char_u *reg_pat;
+
+ if (!checkforcmd(&p, "filter", 4) || *p == NUL || ends_excmd(*p)) {
+ break;
+ }
+ if (*p == '!') {
+ cmdmod.filter_force = true;
+ p = skipwhite(p + 1);
+ if (*p == NUL || ends_excmd(*p)) {
+ break;
+ }
+ }
+ p = skip_vimgrep_pat(p, &reg_pat, NULL);
+ if (p == NULL || *p == NUL) {
+ break;
+ }
+ cmdmod.filter_regmatch.regprog = vim_regcomp(reg_pat, RE_MAGIC);
+ if (cmdmod.filter_regmatch.regprog == NULL) {
+ break;
+ }
+ ea.cmd = p;
+ continue;
+ }
+
/* ":hide" and ":hide | cmd" are not modifiers */
case 'h': if (p != ea.cmd || !checkforcmd(&p, "hide", 3)
|| *p == NUL || ends_excmd(*p))
@@ -1405,7 +1435,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
continue;
case 't': if (checkforcmd(&p, "tab", 3)) {
- long tabnr = get_address(&ea, &ea.cmd, ADDR_TABS, ea.skip, false);
+ long tabnr = get_address(&ea, &ea.cmd, ADDR_TABS, ea.skip, false, 1);
if (tabnr == MAXLNUM) {
cmdmod.tab = tabpage_index(curtab) + 1;
} else {
@@ -1447,6 +1477,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
}
break;
}
+ char_u *after_modifier = ea.cmd;
ea.skip = did_emsg || got_int || did_throw || (cstack->cs_idx >= 0
&& !(cstack->cs_flags[cstack->
@@ -1520,8 +1551,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.line2 = curwin->w_cursor.lnum;
break;
case ADDR_WINDOWS:
- lnum = CURRENT_WIN_NR;
- ea.line2 = lnum;
+ ea.line2 = CURRENT_WIN_NR;
break;
case ADDR_ARGUMENTS:
ea.line2 = curwin->w_arg_idx + 1;
@@ -1534,8 +1564,10 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.line2 = curbuf->b_fnum;
break;
case ADDR_TABS:
- lnum = CURRENT_TAB_NR;
- ea.line2 = lnum;
+ ea.line2 = CURRENT_TAB_NR;
+ break;
+ case ADDR_TABS_RELATIVE:
+ ea.line2 = 1;
break;
case ADDR_QUICKFIX:
ea.line2 = qf_get_cur_valid_idx(&ea);
@@ -1543,7 +1575,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
}
ea.cmd = skipwhite(ea.cmd);
lnum = get_address(&ea, &ea.cmd, ea.addr_type, ea.skip,
- ea.addr_count == 0);
+ ea.addr_count == 0, address_count++);
if (ea.cmd == NULL) { // error detected
goto doend;
}
@@ -1585,6 +1617,10 @@ static char_u * do_one_cmd(char_u **cmdlinep,
goto doend;
}
break;
+ case ADDR_TABS_RELATIVE:
+ errormsg = (char_u *)_(e_invrange);
+ goto doend;
+ break;
case ADDR_ARGUMENTS:
if (ARGCOUNT == 0) {
ea.line1 = ea.line2 = 0;
@@ -1630,11 +1666,15 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.addr_count++;
if (*ea.cmd == ';') {
- if (!ea.skip)
+ if (!ea.skip) {
curwin->w_cursor.lnum = ea.line2;
- } else if (*ea.cmd != ',')
+ // Don't leave the cursor on an illegal line (caused by ';')
+ check_cursor_lnum();
+ }
+ } else if (*ea.cmd != ',') {
break;
- ++ea.cmd;
+ }
+ ea.cmd++;
}
/* One address given: set start and end lines */
@@ -1645,9 +1685,6 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.addr_count = 0;
}
- /* Don't leave the cursor on an illegal line (caused by ';') */
- check_cursor_lnum();
-
/*
* 5. Parse the command.
*/
@@ -1719,16 +1756,18 @@ static char_u * do_one_cmd(char_u **cmdlinep,
errormsg = (char_u *)_("E464: Ambiguous use of user-defined command");
goto doend;
}
- /* Check for wrong commands. */
- if (*p == '!' && ea.cmd[1] == 0151 && ea.cmd[0] == 78) {
- errormsg = uc_fun_cmd();
- goto doend;
- }
+ // Check for wrong commands.
if (ea.cmdidx == CMD_SIZE) {
if (!ea.skip) {
STRCPY(IObuff, _("E492: Not an editor command"));
if (!(flags & DOCMD_VERBOSE)) {
- append_command(*cmdlinep);
+ // If the modifier was parsed OK the error must be in the following
+ // command
+ if (after_modifier != NULL) {
+ append_command(after_modifier);
+ } else {
+ append_command(*cmdlinep);
+ }
}
errormsg = IObuff;
did_emsg_syntax = TRUE;
@@ -1815,9 +1854,9 @@ static char_u * do_one_cmd(char_u **cmdlinep,
errormsg = (char_u *)_("E493: Backwards range given");
goto doend;
}
- if (ask_yesno((char_u *)
- _("Backwards range given, OK to swap"), FALSE) != 'y')
+ if (ask_yesno(_("Backwards range given, OK to swap"), false) != 'y') {
goto doend;
+ }
}
lnum = ea.line1;
ea.line1 = ea.line2;
@@ -1971,6 +2010,9 @@ static char_u * do_one_cmd(char_u **cmdlinep,
case ADDR_TABS:
ea.line2 = LAST_TAB_NR;
break;
+ case ADDR_TABS_RELATIVE:
+ ea.line2 = 1;
+ break;
case ADDR_ARGUMENTS:
if (ARGCOUNT == 0) {
ea.line1 = ea.line2 = 0;
@@ -2026,11 +2068,11 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.line1 = ea.line2;
ea.line2 += n - 1;
++ea.addr_count;
- /*
- * Be vi compatible: no error message for out of range.
- */
- if (ea.line2 > curbuf->b_ml.ml_line_count)
+ // Be vi compatible: no error message for out of range.
+ if (ea.addr_type == ADDR_LINES
+ && ea.line2 > curbuf->b_ml.ml_line_count) {
ea.line2 = curbuf->b_ml.ml_line_count;
+ }
}
}
@@ -2095,6 +2137,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
case CMD_echomsg:
case CMD_echon:
case CMD_execute:
+ case CMD_filter:
case CMD_help:
case CMD_hide:
case CMD_ijump:
@@ -2246,6 +2289,10 @@ doend:
free_string_option(cmdmod.save_ei);
}
+ if (cmdmod.filter_regmatch.regprog != NULL) {
+ vim_regfree(cmdmod.filter_regmatch.regprog);
+ }
+
cmdmod = save_cmdmod;
if (save_msg_silent != -1) {
@@ -2531,28 +2578,29 @@ static struct cmdmod {
int minlen;
int has_count; /* :123verbose :3tab */
} cmdmods[] = {
- {"aboveleft", 3, FALSE},
- {"belowright", 3, FALSE},
- {"botright", 2, FALSE},
- {"browse", 3, FALSE},
- {"confirm", 4, FALSE},
- {"hide", 3, FALSE},
- {"keepalt", 5, FALSE},
- {"keepjumps", 5, FALSE},
- {"keepmarks", 3, FALSE},
- {"keeppatterns", 5, FALSE},
- {"leftabove", 5, FALSE},
- {"lockmarks", 3, FALSE},
- {"noautocmd", 3, FALSE},
- {"noswapfile", 3, FALSE},
- {"rightbelow", 6, FALSE},
- {"sandbox", 3, FALSE},
- {"silent", 3, FALSE},
- {"tab", 3, TRUE},
- {"topleft", 2, FALSE},
- {"unsilent", 3, FALSE},
- {"verbose", 4, TRUE},
- {"vertical", 4, FALSE},
+ { "aboveleft", 3, false },
+ { "belowright", 3, false },
+ { "botright", 2, false },
+ { "browse", 3, false },
+ { "confirm", 4, false },
+ { "filter", 4, false },
+ { "hide", 3, false },
+ { "keepalt", 5, false },
+ { "keepjumps", 5, false },
+ { "keepmarks", 3, false },
+ { "keeppatterns", 5, false },
+ { "leftabove", 5, false },
+ { "lockmarks", 3, false },
+ { "noautocmd", 3, false },
+ { "noswapfile", 3, false },
+ { "rightbelow", 6, false },
+ { "sandbox", 3, false },
+ { "silent", 3, false },
+ { "tab", 3, true },
+ { "topleft", 2, false },
+ { "unsilent", 3, false },
+ { "verbose", 4, true },
+ { "vertical", 4, false },
};
/*
@@ -2582,27 +2630,29 @@ int modifier_len(char_u *cmd)
* Return 2 if there is an exact match.
* Return 3 if there is an ambiguous match.
*/
-int cmd_exists(char_u *name)
+int cmd_exists(const char *const name)
{
exarg_T ea;
- int full = FALSE;
- int i;
- int j;
char_u *p;
- /* Check command modifiers. */
- for (i = 0; i < (int)ARRAY_SIZE(cmdmods); ++i) {
- for (j = 0; name[j] != NUL; ++j)
- if (name[j] != cmdmods[i].name[j])
+ // Check command modifiers.
+ for (int i = 0; i < (int)ARRAY_SIZE(cmdmods); i++) {
+ int j;
+ for (j = 0; name[j] != NUL; j++) {
+ if (name[j] != (char)cmdmods[i].name[j]) {
break;
- if (name[j] == NUL && j >= cmdmods[i].minlen)
+ }
+ }
+ if (name[j] == NUL && j >= cmdmods[i].minlen) {
return cmdmods[i].name[j] == NUL ? 2 : 1;
+ }
}
/* Check built-in commands and user defined commands.
* For ":2match" and ":3match" we need to skip the number. */
- ea.cmd = (*name == '2' || *name == '3') ? name + 1 : name;
+ ea.cmd = (char_u *)((*name == '2' || *name == '3') ? name + 1 : name);
ea.cmdidx = (cmdidx_T)0;
+ int full = false;
p = find_command(&ea, &full);
if (p == NULL)
return 3;
@@ -2620,32 +2670,27 @@ int cmd_exists(char_u *name)
* perfectly compatible with each other, but then the command line syntax
* probably won't change that much -- webb.
*/
-char_u *
-set_one_cmd_context (
+const char * set_one_cmd_context(
expand_T *xp,
- char_u *buff /* buffer for command string */
+ const char *buff // buffer for command string
)
{
- char_u *p;
- char_u *cmd, *arg;
- int len = 0;
+ size_t len = 0;
exarg_T ea;
- int compl = EXPAND_NOTHING;
- int delim;
- int forceit = FALSE;
- int usefilter = FALSE; /* filter instead of file name */
+ int context = EXPAND_NOTHING;
+ 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 */
+ xp->xp_pattern = (char_u *)buff;
+ xp->xp_context = EXPAND_COMMANDS; // Default until we get past command
ea.argt = 0;
- /*
- * 2. skip comment lines and leading space, colons or bars
- */
- for (cmd = buff; vim_strchr((char_u *)" \t:|", *cmd) != NULL; cmd++)
- ;
- xp->xp_pattern = cmd;
+ // 2. skip comment lines and leading space, colons or bars
+ const char *cmd;
+ for (cmd = buff; vim_strchr((const char_u *)" \t:|", *cmd) != NULL; cmd++) {
+ }
+ xp->xp_pattern = (char_u *)cmd;
if (*cmd == NUL)
return NULL;
@@ -2657,14 +2702,15 @@ set_one_cmd_context (
/*
* 3. parse a range specifier of the form: addr [,addr] [;addr] ..
*/
- cmd = skip_range(cmd, &xp->xp_context);
+ cmd = (const char *)skip_range((const char_u *)cmd, &xp->xp_context);
/*
* 4. parse command
*/
- xp->xp_pattern = cmd;
- if (*cmd == NUL)
+ xp->xp_pattern = (char_u *)cmd;
+ if (*cmd == NUL) {
return NULL;
+ }
if (*cmd == '"') {
xp->xp_context = EXPAND_NOTHING;
return NULL;
@@ -2680,6 +2726,7 @@ set_one_cmd_context (
* do accept "keepmarks", "keepalt" and "keepjumps".
* - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
*/
+ const char *p;
if (*cmd == 'k' && cmd[1] != 'e') {
ea.cmdidx = CMD_k;
p = cmd + 1;
@@ -2702,20 +2749,21 @@ set_one_cmd_context (
}
}
// check for non-alpha command
- if (p == cmd && vim_strchr((char_u *)"@*!=><&~#", *p) != NULL) {
+ if (p == cmd && vim_strchr((const char_u *)"@*!=><&~#", *p) != NULL) {
p++;
}
- len = (int)(p - cmd);
+ len = (size_t)(p - cmd);
if (len == 0) {
xp->xp_context = EXPAND_UNSUCCESSFUL;
return NULL;
}
for (ea.cmdidx = (cmdidx_T)0; (int)ea.cmdidx < (int)CMD_SIZE;
- ea.cmdidx = (cmdidx_T)((int)ea.cmdidx + 1))
- if (STRNCMP(cmdnames[(int)ea.cmdidx].cmd_name, cmd,
- (size_t)len) == 0)
+ ea.cmdidx = (cmdidx_T)((int)ea.cmdidx + 1)) {
+ if (STRNCMP(cmdnames[(int)ea.cmdidx].cmd_name, cmd, len) == 0) {
break;
+ }
+ }
if (cmd[0] >= 'A' && cmd[0] <= 'Z') {
while (ASCII_ISALNUM(*p) || *p == '*') { // Allow * wild card
@@ -2732,16 +2780,15 @@ set_one_cmd_context (
return NULL;
if (ea.cmdidx == CMD_SIZE) {
- if (*cmd == 's' && vim_strchr((char_u *)"cgriI", cmd[1]) != NULL) {
+ if (*cmd == 's' && vim_strchr((const char_u *)"cgriI", cmd[1]) != NULL) {
ea.cmdidx = CMD_substitute;
p = cmd + 1;
} else if (cmd[0] >= 'A' && cmd[0] <= 'Z') {
- ea.cmd = cmd;
- p = find_ucmd(&ea, p, NULL, xp,
- &compl
- );
- if (p == NULL)
- ea.cmdidx = CMD_SIZE; /* ambiguous user command */
+ ea.cmd = (char_u *)cmd;
+ p = (const char *)find_ucmd(&ea, (char_u *)p, NULL, xp, &context);
+ if (p == NULL) {
+ ea.cmdidx = CMD_SIZE; // Ambiguous user command.
+ }
}
}
if (ea.cmdidx == CMD_SIZE) {
@@ -2764,16 +2811,17 @@ set_one_cmd_context (
ea.argt = cmdnames[(int)ea.cmdidx].cmd_argt;
}
- arg = skipwhite(p);
+ const char *arg = (const char *)skipwhite((const char_u *)p);
if (ea.cmdidx == CMD_write || ea.cmdidx == CMD_update) {
- if (*arg == '>') { /* append */
- if (*++arg == '>')
- ++arg;
- arg = skipwhite(arg);
- } else if (*arg == '!' && ea.cmdidx == CMD_write) { /* :w !filter */
- ++arg;
- usefilter = TRUE;
+ if (*arg == '>') { // Append.
+ if (*++arg == '>') {
+ arg++;
+ }
+ arg = (const char *)skipwhite((const char_u *)arg);
+ } else if (*arg == '!' && ea.cmdidx == CMD_write) { // :w !filter
+ arg++;
+ usefilter = true;
}
}
@@ -2786,23 +2834,24 @@ set_one_cmd_context (
}
if (ea.cmdidx == CMD_lshift || ea.cmdidx == CMD_rshift) {
- while (*arg == *cmd) /* allow any number of '>' or '<' */
- ++arg;
- arg = skipwhite(arg);
+ while (*arg == *cmd) { // allow any number of '>' or '<'
+ arg++;
+ }
+ arg = (const char *)skipwhite((const char_u *)arg);
}
/* Does command allow "+command"? */
if ((ea.argt & EDITCMD) && !usefilter && *arg == '+') {
/* Check if we're in the +command */
p = arg + 1;
- arg = skip_cmd_arg(arg, FALSE);
+ arg = (const char *)skip_cmd_arg((char_u *)arg, false);
/* Still touching the command after '+'? */
if (*arg == NUL)
return p;
- /* Skip space(s) after +command to get to the real argument */
- arg = skipwhite(arg);
+ // Skip space(s) after +command to get to the real argument.
+ arg = (const char *)skipwhite((const char_u *)arg);
}
/*
@@ -2831,19 +2880,18 @@ set_one_cmd_context (
}
// no arguments allowed
- if (!(ea.argt & EXTRA) && *arg != NUL
- && vim_strchr((char_u *)"|\"", *arg) == NULL) {
+ if (!(ea.argt & EXTRA) && *arg != NUL && strchr("|\"", *arg) == NULL) {
return NULL;
}
/* Find start of last argument (argument just before cursor): */
p = buff;
- xp->xp_pattern = p;
- len = (int)STRLEN(buff);
+ xp->xp_pattern = (char_u *)p;
+ len = strlen(buff);
while (*p && p < buff + len) {
if (*p == ' ' || *p == TAB) {
- /* argument starts after a space */
- xp->xp_pattern = ++p;
+ // Argument starts after a space.
+ xp->xp_pattern = (char_u *)++p;
} else {
if (*p == '\\' && *(p + 1) != NUL)
++p; /* skip over escaped character */
@@ -2853,25 +2901,26 @@ set_one_cmd_context (
if (ea.argt & XFILE) {
int c;
- int in_quote = FALSE;
- char_u *bow = NULL; /* Beginning of word */
+ int in_quote = false;
+ const char *bow = NULL; // Beginning of word.
/*
* Allow spaces within back-quotes to count as part of the argument
* being expanded.
*/
- xp->xp_pattern = skipwhite(arg);
- p = xp->xp_pattern;
+ xp->xp_pattern = skipwhite((const char_u *)arg);
+ p = (const char *)xp->xp_pattern;
while (*p != NUL) {
- if (has_mbyte)
- c = mb_ptr2char(p);
- else
- c = *p;
- if (c == '\\' && p[1] != NUL)
- ++p;
- else if (c == '`') {
+ if (has_mbyte) {
+ c = mb_ptr2char((const char_u *)p);
+ } else {
+ c = (uint8_t)(*p);
+ }
+ if (c == '\\' && p[1] != NUL) {
+ p++;
+ } else if (c == '`') {
if (!in_quote) {
- xp->xp_pattern = p;
+ xp->xp_pattern = (char_u *)p;
bow = p + 1;
}
in_quote = !in_quote;
@@ -2884,22 +2933,26 @@ set_one_cmd_context (
|| ascii_iswhite(c)) {
len = 0; /* avoid getting stuck when space is in 'isfname' */
while (*p != NUL) {
- if (has_mbyte)
- c = mb_ptr2char(p);
- else
+ if (has_mbyte) {
+ c = mb_ptr2char((const char_u *)p);
+ } else {
c = *p;
- if (c == '`' || vim_isfilec_or_wc(c))
+ }
+ if (c == '`' || vim_isfilec_or_wc(c)) {
break;
- if (has_mbyte)
- len = (*mb_ptr2len)(p);
- else
+ }
+ if (has_mbyte) {
+ len = (size_t)(*mb_ptr2len)((const char_u *)p);
+ } else {
len = 1;
+ }
mb_ptr_adv(p);
}
- if (in_quote)
+ if (in_quote) {
bow = p;
- else
- xp->xp_pattern = p;
+ } else {
+ xp->xp_pattern = (char_u *)p;
+ }
p -= len;
}
mb_ptr_adv(p);
@@ -2909,8 +2962,9 @@ set_one_cmd_context (
* If we are still inside the quotes, and we passed a space, just
* expand from there.
*/
- if (bow != NULL && in_quote)
- xp->xp_pattern = bow;
+ if (bow != NULL && in_quote) {
+ xp->xp_pattern = (char_u *)bow;
+ }
xp->xp_context = EXPAND_FILES;
/* For a shell command more chars need to be escaped. */
@@ -2918,33 +2972,36 @@ set_one_cmd_context (
#ifndef BACKSLASH_IN_FILENAME
xp->xp_shell = TRUE;
#endif
- /* When still after the command name expand executables. */
- if (xp->xp_pattern == skipwhite(arg))
+ // When still after the command name expand executables.
+ if (xp->xp_pattern == skipwhite((const char_u *)arg)) {
xp->xp_context = EXPAND_SHELLCMD;
+ }
}
- /* Check for environment variable */
- if (*xp->xp_pattern == '$'
- ) {
- for (p = xp->xp_pattern + 1; *p != NUL; ++p)
- if (!vim_isIDc(*p))
+ // Check for environment variable.
+ if (*xp->xp_pattern == '$') {
+ for (p = (const char *)xp->xp_pattern + 1; *p != NUL; p++) {
+ if (!vim_isIDc((uint8_t)(*p))) {
break;
+ }
+ }
if (*p == NUL) {
xp->xp_context = EXPAND_ENV_VARS;
- ++xp->xp_pattern;
- /* Avoid that the assignment uses EXPAND_FILES again. */
- if (compl != EXPAND_USER_DEFINED && compl != EXPAND_USER_LIST)
- compl = EXPAND_ENV_VARS;
+ xp->xp_pattern++;
+ // Avoid that the assignment uses EXPAND_FILES again.
+ if (context != EXPAND_USER_DEFINED && context != EXPAND_USER_LIST) {
+ context = EXPAND_ENV_VARS;
+ }
}
}
/* Check for user names */
if (*xp->xp_pattern == '~') {
- for (p = xp->xp_pattern + 1; *p != NUL && *p != '/'; ++p)
- ;
- /* Complete ~user only if it partially matches a user name.
- * A full match ~user<Tab> will be replaced by user's home
- * directory i.e. something like ~user<Tab> -> /home/user/ */
- if (*p == NUL && p > xp->xp_pattern + 1
+ for (p = (const char *)xp->xp_pattern + 1; *p != NUL && *p != '/'; p++) {
+ }
+ // Complete ~user only if it partially matches a user name.
+ // A full match ~user<Tab> will be replaced by user's home
+ // directory i.e. something like ~user<Tab> -> /home/user/
+ if (*p == NUL && p > (const char *)xp->xp_pattern + 1
&& match_user(xp->xp_pattern + 1) == 1) {
xp->xp_context = EXPAND_USER;
++xp->xp_pattern;
@@ -2974,7 +3031,7 @@ set_one_cmd_context (
break;
case CMD_help:
xp->xp_context = EXPAND_HELP;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
/* Command modifiers: return the argument.
@@ -3013,17 +3070,28 @@ set_one_cmd_context (
case CMD_windo:
return arg;
+ case CMD_filter:
+ if (*arg != NUL) {
+ arg = (const char *)skip_vimgrep_pat((char_u *)arg, NULL, NULL);
+ }
+ if (arg == NULL || *arg == NUL) {
+ xp->xp_context = EXPAND_NOTHING;
+ return NULL;
+ }
+ return (const char *)skipwhite((const char_u *)arg);
+
case CMD_match:
if (*arg == NUL || !ends_excmd(*arg)) {
/* also complete "None" */
set_context_in_echohl_cmd(xp, arg);
- arg = skipwhite(skiptowhite(arg));
+ arg = (const char *)skipwhite(skiptowhite((const char_u *)arg));
if (*arg != NUL) {
xp->xp_context = EXPAND_NOTHING;
- arg = skip_regexp(arg + 1, *arg, p_magic, NULL);
+ arg = (const char *)skip_regexp((char_u *)arg + 1, (uint8_t)(*arg),
+ p_magic, NULL);
}
}
- return find_nextcmd(arg);
+ return (const char *)find_nextcmd((char_u *)arg);
/*
* All completion for the +cmdline_compl feature goes here.
@@ -3032,15 +3100,15 @@ set_one_cmd_context (
case CMD_command:
/* Check for attributes */
while (*arg == '-') {
- arg++; /* Skip "-" */
- p = skiptowhite(arg);
+ arg++; // Skip "-".
+ p = (const char *)skiptowhite((const char_u *)arg);
if (*p == NUL) {
- /* Cursor is still in the attribute */
- p = vim_strchr(arg, '=');
+ // Cursor is still in the attribute.
+ p = strchr(arg, '=');
if (p == NULL) {
- /* No "=", so complete attribute names */
+ // No "=", so complete attribute names.
xp->xp_context = EXPAND_USER_CMD_FLAGS;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
return NULL;
}
@@ -3048,73 +3116,81 @@ set_one_cmd_context (
// their arguments as well.
if (STRNICMP(arg, "complete", p - arg) == 0) {
xp->xp_context = EXPAND_USER_COMPLETE;
- xp->xp_pattern = p + 1;
+ xp->xp_pattern = (char_u *)p + 1;
return NULL;
} else if (STRNICMP(arg, "nargs", p - arg) == 0) {
xp->xp_context = EXPAND_USER_NARGS;
- xp->xp_pattern = p + 1;
+ xp->xp_pattern = (char_u *)p + 1;
return NULL;
} else if (STRNICMP(arg, "addr", p - arg) == 0) {
xp->xp_context = EXPAND_USER_ADDR_TYPE;
- xp->xp_pattern = p + 1;
+ xp->xp_pattern = (char_u *)p + 1;
return NULL;
}
return NULL;
}
- arg = skipwhite(p);
+ arg = (const char *)skipwhite((char_u *)p);
}
- /* After the attributes comes the new command name */
- p = skiptowhite(arg);
+ // After the attributes comes the new command name.
+ p = (const char *)skiptowhite((const char_u *)arg);
if (*p == NUL) {
xp->xp_context = EXPAND_USER_COMMANDS;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
}
- /* And finally comes a normal command */
- return skipwhite(p);
+ // And finally comes a normal command.
+ return (const char *)skipwhite((const char_u *)p);
case CMD_delcommand:
xp->xp_context = EXPAND_USER_COMMANDS;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_global:
- case CMD_vglobal:
- delim = *arg; /* get the delimiter */
- if (delim)
- ++arg; /* skip delimiter if there is one */
+ case CMD_vglobal: {
+ const int delim = (uint8_t)(*arg); // Get the delimiter.
+ if (delim) {
+ arg++; // Skip delimiter if there is one.
+ }
- while (arg[0] != NUL && arg[0] != delim) {
- if (arg[0] == '\\' && arg[1] != NUL)
- ++arg;
- ++arg;
+ while (arg[0] != NUL && (uint8_t)arg[0] != delim) {
+ if (arg[0] == '\\' && arg[1] != NUL) {
+ arg++;
+ }
+ arg++;
}
if (arg[0] != NUL)
return arg + 1;
break;
+ }
case CMD_and:
- case CMD_substitute:
- delim = *arg;
+ case CMD_substitute: {
+ const int delim = (uint8_t)(*arg);
if (delim) {
- /* skip "from" part */
- ++arg;
- arg = skip_regexp(arg, delim, p_magic, NULL);
+ // Skip "from" part.
+ arg++;
+ arg = (const char *)skip_regexp((char_u *)arg, delim, p_magic, NULL);
}
- /* skip "to" part */
- while (arg[0] != NUL && arg[0] != delim) {
- if (arg[0] == '\\' && arg[1] != NUL)
- ++arg;
- ++arg;
+ // Skip "to" part.
+ while (arg[0] != NUL && (uint8_t)arg[0] != delim) {
+ if (arg[0] == '\\' && arg[1] != NUL) {
+ arg++;
+ }
+ arg++;
}
- if (arg[0] != NUL) /* skip delimiter */
- ++arg;
- while (arg[0] && vim_strchr((char_u *)"|\"#", arg[0]) == NULL)
- ++arg;
- if (arg[0] != NUL)
+ if (arg[0] != NUL) { // Skip delimiter.
+ arg++;
+ }
+ while (arg[0] && strchr("|\"#", arg[0]) == NULL) {
+ arg++;
+ }
+ if (arg[0] != NUL) {
return arg;
+ }
break;
+ }
case CMD_isearch:
case CMD_dsearch:
case CMD_ilist:
@@ -3124,36 +3200,40 @@ set_one_cmd_context (
case CMD_djump:
case CMD_isplit:
case CMD_dsplit:
- arg = skipwhite(skipdigits(arg)); /* skip count */
- if (*arg == '/') { /* Match regexp, not just whole words */
- for (++arg; *arg && *arg != '/'; arg++)
- if (*arg == '\\' && arg[1] != NUL)
+ // Skip count.
+ arg = (const char *)skipwhite(skipdigits((const char_u *)arg));
+ if (*arg == '/') { // Match regexp, not just whole words.
+ for (++arg; *arg && *arg != '/'; arg++) {
+ if (*arg == '\\' && arg[1] != NUL) {
arg++;
+ }
+ }
if (*arg) {
- arg = skipwhite(arg + 1);
+ arg = (const char *)skipwhite((const char_u *)arg + 1);
- /* Check for trailing illegal characters */
- if (*arg && vim_strchr((char_u *)"|\"\n", *arg) == NULL)
+ // Check for trailing illegal characters.
+ if (*arg && strchr("|\"\n", *arg) == NULL) {
xp->xp_context = EXPAND_NOTHING;
- else
+ } else {
return arg;
+ }
}
}
break;
case CMD_autocmd:
- return set_context_in_autocmd(xp, arg, FALSE);
+ return (const char *)set_context_in_autocmd(xp, (char_u *)arg, false);
case CMD_doautocmd:
case CMD_doautoall:
- return set_context_in_autocmd(xp, arg, TRUE);
+ return (const char *)set_context_in_autocmd(xp, (char_u *)arg, true);
case CMD_set:
- set_context_in_set_cmd(xp, arg, 0);
+ set_context_in_set_cmd(xp, (char_u *)arg, 0);
break;
case CMD_setglobal:
- set_context_in_set_cmd(xp, arg, OPT_GLOBAL);
+ set_context_in_set_cmd(xp, (char_u *)arg, OPT_GLOBAL);
break;
case CMD_setlocal:
- set_context_in_set_cmd(xp, arg, OPT_LOCAL);
+ set_context_in_set_cmd(xp, (char_u *)arg, OPT_LOCAL);
break;
case CMD_tag:
case CMD_stag:
@@ -3165,15 +3245,16 @@ set_one_cmd_context (
case CMD_tjump:
case CMD_stjump:
case CMD_ptjump:
- if (*p_wop != NUL)
+ if (*p_wop != NUL) {
xp->xp_context = EXPAND_TAGS_LISTFILES;
- else
+ } else {
xp->xp_context = EXPAND_TAGS;
- xp->xp_pattern = arg;
+ }
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_augroup:
xp->xp_context = EXPAND_AUGROUP;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_syntax:
set_context_in_syntax_cmd(xp, arg);
@@ -3190,20 +3271,21 @@ set_one_cmd_context (
case CMD_echoerr:
case CMD_call:
case CMD_return:
- set_context_for_expression(xp, arg, ea.cmdidx);
+ set_context_for_expression(xp, (char_u *)arg, ea.cmdidx);
break;
case CMD_unlet:
- while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL)
- arg = xp->xp_pattern + 1;
+ while ((xp->xp_pattern = (char_u *)strchr(arg, ' ')) != NULL) {
+ arg = (const char *)xp->xp_pattern + 1;
+ }
xp->xp_context = EXPAND_USER_VARS;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_function:
case CMD_delfunction:
xp->xp_context = EXPAND_USER_FUNC;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_echohl:
@@ -3218,33 +3300,37 @@ set_one_cmd_context (
set_context_in_cscope_cmd(xp, arg, ea.cmdidx);
break;
case CMD_sign:
- set_context_in_sign_cmd(xp, arg);
+ set_context_in_sign_cmd(xp, (char_u *)arg);
break;
case CMD_bdelete:
case CMD_bwipeout:
case CMD_bunload:
- while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL)
- arg = xp->xp_pattern + 1;
- /*FALLTHROUGH*/
+ while ((xp->xp_pattern = (char_u *)strchr(arg, ' ')) != NULL) {
+ arg = (const char *)xp->xp_pattern + 1;
+ }
+ // FALLTHROUGH
case CMD_buffer:
case CMD_sbuffer:
case CMD_checktime:
xp->xp_context = EXPAND_BUFFERS;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_USER:
case CMD_USER_BUF:
- if (compl != EXPAND_NOTHING) {
- /* XFILE: file names are handled above */
+ if (context != EXPAND_NOTHING) {
+ // XFILE: file names are handled above.
if (!(ea.argt & XFILE)) {
- if (compl == EXPAND_MENUS)
- return set_context_in_menu_cmd(xp, cmd, arg, forceit);
- if (compl == EXPAND_COMMANDS)
+ if (context == EXPAND_MENUS) {
+ return (const char *)set_context_in_menu_cmd(xp, (char_u *)cmd,
+ (char_u *)arg, forceit);
+ } else if (context == EXPAND_COMMANDS) {
return arg;
- if (compl == EXPAND_MAPPINGS)
- return set_context_in_map_cmd(xp, (char_u *)"map",
- arg, forceit, FALSE, FALSE, CMD_map);
- /* Find start of last argument. */
+ } else if (context == EXPAND_MAPPINGS) {
+ return (const char *)set_context_in_map_cmd(
+ xp, (char_u *)"map", (char_u *)arg, forceit, false, false,
+ CMD_map);
+ }
+ // Find start of last argument.
p = arg;
while (*p) {
if (*p == ' ')
@@ -3254,9 +3340,9 @@ set_one_cmd_context (
++p; /* skip over escaped character */
mb_ptr_adv(p);
}
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
}
- xp->xp_context = compl;
+ xp->xp_context = context;
}
break;
case CMD_map: case CMD_noremap:
@@ -3268,8 +3354,8 @@ set_one_cmd_context (
case CMD_lmap: case CMD_lnoremap:
case CMD_smap: case CMD_snoremap:
case CMD_xmap: case CMD_xnoremap:
- return set_context_in_map_cmd(xp, cmd, arg, forceit,
- FALSE, FALSE, ea.cmdidx);
+ return (const char *)set_context_in_map_cmd(
+ xp, (char_u *)cmd, (char_u *)arg, forceit, false, false, ea.cmdidx);
case CMD_unmap:
case CMD_nunmap:
case CMD_vunmap:
@@ -3279,18 +3365,18 @@ set_one_cmd_context (
case CMD_lunmap:
case CMD_sunmap:
case CMD_xunmap:
- return set_context_in_map_cmd(xp, cmd, arg, forceit,
- FALSE, TRUE, ea.cmdidx);
+ return (const char *)set_context_in_map_cmd(
+ xp, (char_u *)cmd, (char_u *)arg, forceit, false, true, ea.cmdidx);
case CMD_abbreviate: case CMD_noreabbrev:
case CMD_cabbrev: case CMD_cnoreabbrev:
case CMD_iabbrev: case CMD_inoreabbrev:
- return set_context_in_map_cmd(xp, cmd, arg, forceit,
- TRUE, FALSE, ea.cmdidx);
+ return (const char *)set_context_in_map_cmd(
+ xp, (char_u *)cmd, (char_u *)arg, forceit, true, false, ea.cmdidx);
case CMD_unabbreviate:
case CMD_cunabbrev:
case CMD_iunabbrev:
- return set_context_in_map_cmd(xp, cmd, arg, forceit,
- TRUE, TRUE, ea.cmdidx);
+ return (const char *)set_context_in_map_cmd(
+ xp, (char_u *)cmd, (char_u *)arg, forceit, true, true, ea.cmdidx);
case CMD_menu: case CMD_noremenu: case CMD_unmenu:
case CMD_amenu: case CMD_anoremenu: case CMD_aunmenu:
case CMD_nmenu: case CMD_nnoremenu: case CMD_nunmenu:
@@ -3300,47 +3386,49 @@ set_one_cmd_context (
case CMD_cmenu: case CMD_cnoremenu: case CMD_cunmenu:
case CMD_tmenu: case CMD_tunmenu:
case CMD_popup: case CMD_emenu:
- return set_context_in_menu_cmd(xp, cmd, arg, forceit);
+ return (const char *)set_context_in_menu_cmd(
+ xp, (char_u *)cmd, (char_u *)arg, forceit);
case CMD_colorscheme:
xp->xp_context = EXPAND_COLORS;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_compiler:
xp->xp_context = EXPAND_COMPILER;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_ownsyntax:
xp->xp_context = EXPAND_OWNSYNTAX;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_setfiletype:
xp->xp_context = EXPAND_FILETYPE;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_packadd:
xp->xp_context = EXPAND_PACKADD;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
#ifdef HAVE_WORKING_LIBINTL
case CMD_language:
- p = skiptowhite(arg);
+ p = (const char *)skiptowhite((const char_u *)arg);
if (*p == NUL) {
xp->xp_context = EXPAND_LANGUAGE;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
} else {
- if ( STRNCMP(arg, "messages", p - arg) == 0
- || STRNCMP(arg, "ctype", p - arg) == 0
- || STRNCMP(arg, "time", p - arg) == 0) {
+ if (strncmp(arg, "messages", p - arg) == 0
+ || strncmp(arg, "ctype", p - arg) == 0
+ || strncmp(arg, "time", p - arg) == 0) {
xp->xp_context = EXPAND_LOCALES;
- xp->xp_pattern = skipwhite(p);
- } else
+ xp->xp_pattern = skipwhite((const char_u *)p);
+ } else {
xp->xp_context = EXPAND_NOTHING;
+ }
}
break;
#endif
@@ -3349,16 +3437,21 @@ set_one_cmd_context (
break;
case CMD_behave:
xp->xp_context = EXPAND_BEHAVE;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
+ break;
+
+ case CMD_messages:
+ xp->xp_context = EXPAND_MESSAGES;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_history:
xp->xp_context = EXPAND_HISTORY;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_syntime:
xp->xp_context = EXPAND_SYNTIME;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
@@ -3377,10 +3470,9 @@ set_one_cmd_context (
* Also skip white space and ":" characters.
* Returns the "cmd" pointer advanced to beyond the range.
*/
-char_u *
-skip_range (
- char_u *cmd,
- int *ctx /* pointer to xp_context or NULL */
+char_u *skip_range(
+ const char_u *cmd,
+ int *ctx // pointer to xp_context or NULL
)
{
unsigned delim;
@@ -3405,7 +3497,7 @@ skip_range (
while (*cmd == ':')
cmd = skipwhite(cmd + 1);
- return cmd;
+ return (char_u *)cmd;
}
/*
@@ -3420,8 +3512,8 @@ static linenr_T get_address(exarg_T *eap,
char_u **ptr,
int addr_type, // flag: one of ADDR_LINES, ...
int skip, // only skip the address, don't use it
- int to_other_file // flag: may jump to other file
- )
+ int to_other_file, // flag: may jump to other file
+ int address_count) // 1 for first, >1 after comma
{
int c;
int i;
@@ -3455,6 +3547,11 @@ static linenr_T get_address(exarg_T *eap,
case ADDR_TABS:
lnum = CURRENT_TAB_NR;
break;
+ case ADDR_TABS_RELATIVE:
+ EMSG(_(e_invrange));
+ cmd = NULL;
+ goto error;
+ break;
case ADDR_QUICKFIX:
lnum = qf_get_cur_valid_idx(eap);
break;
@@ -3489,6 +3586,11 @@ static linenr_T get_address(exarg_T *eap,
case ADDR_TABS:
lnum = LAST_TAB_NR;
break;
+ case ADDR_TABS_RELATIVE:
+ EMSG(_(e_invrange));
+ cmd = NULL;
+ goto error;
+ break;
case ADDR_QUICKFIX:
lnum = qf_get_size(eap);
if (lnum == 0) {
@@ -3637,6 +3739,9 @@ static linenr_T get_address(exarg_T *eap,
case ADDR_TABS:
lnum = CURRENT_TAB_NR;
break;
+ case ADDR_TABS_RELATIVE:
+ lnum = 1;
+ break;
case ADDR_QUICKFIX:
lnum = qf_get_cur_valid_idx(eap);
break;
@@ -3651,13 +3756,27 @@ static linenr_T get_address(exarg_T *eap,
n = 1;
else
n = getdigits(&cmd);
- if (addr_type == ADDR_LOADED_BUFFERS || addr_type == ADDR_BUFFERS)
+
+ if (addr_type == ADDR_TABS_RELATIVE) {
+ EMSG(_(e_invrange));
+ cmd = NULL;
+ goto error;
+ } else if (addr_type == ADDR_LOADED_BUFFERS || addr_type == ADDR_BUFFERS) {
lnum = compute_buffer_local_count(
addr_type, lnum, (i == '-') ? -1 * n : n);
- else if (i == '-')
- lnum -= n;
- else
- lnum += n;
+ } else {
+ // Relative line addressing, need to adjust for folded lines
+ // now, but only do it after the first address.
+ if (addr_type == ADDR_LINES && (i == '-' || i == '+')
+ && address_count >= 2) {
+ (void)hasFolding(lnum, NULL, &lnum);
+ }
+ if (i == '-') {
+ lnum -= n;
+ } else {
+ lnum += n;
+ }
+ }
}
} while (*cmd == '/' || *cmd == '?');
@@ -3694,10 +3813,12 @@ void ex_ni(exarg_T *eap)
/// Skips over ":perl <<EOF" constructs.
static void ex_script_ni(exarg_T *eap)
{
- if (!eap->skip)
+ if (!eap->skip) {
ex_ni(eap);
- else
- xfree(script_get(eap, eap->arg));
+ } else {
+ size_t len;
+ xfree(script_get(eap, &len));
+ }
}
/*
@@ -3764,6 +3885,9 @@ static char_u *invalid_range(exarg_T *eap)
return (char_u *)_(e_invrange);
}
break;
+ case ADDR_TABS_RELATIVE:
+ // Do nothing
+ break;
case ADDR_QUICKFIX:
assert(eap->line2 >= 0);
if (eap->line2 != 1 && (size_t)eap->line2 > qf_get_size(eap)) {
@@ -3854,7 +3978,7 @@ static char_u *replace_makeprg(exarg_T *eap, char_u *p, char_u **cmdlinep)
ptr = new_cmdline;
while ((pos = (char_u *)strstr((char *)program, "$*")) != NULL) {
i = (int)(pos - program);
- STRNCPY(ptr, program, i);
+ memcpy(ptr, program, i);
STRCPY(ptr += i, p);
ptr += len;
program = pos + 2;
@@ -3940,8 +4064,6 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
* Don't do this for:
* - replacement that already has been escaped: "##"
* - shell commands (may have to use quotes instead).
- * - non-unix systems when there is a single argument (spaces don't
- * separate arguments then).
*/
if (!eap->usefilter
&& !escaped
@@ -3952,9 +4074,7 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
&& eap->cmdidx != CMD_lgrep
&& eap->cmdidx != CMD_grepadd
&& eap->cmdidx != CMD_lgrepadd
-#ifndef UNIX
&& !(eap->argt & NOSPC)
-#endif
) {
char_u *l;
#ifdef BACKSLASH_IN_FILENAME
@@ -4016,28 +4136,6 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
}
}
- // Replace any other wildcards, remove backslashes.
-#ifdef UNIX
- /*
- * Only for Unix we check for more than one file name.
- * For other systems spaces are considered to be part
- * of the file name.
- * Only check here if there is no wildcard, otherwise
- * ExpandOne() will check for errors. This allows
- * ":e `ls ve*.c`" on Unix.
- */
- if (!has_wildcards)
- for (p = eap->arg; *p; ++p) {
- /* skip escaped characters */
- if (p[1] && (*p == '\\' || *p == Ctrl_V))
- ++p;
- else if (ascii_iswhite(*p)) {
- *errormsgp = (char_u *)_("E172: Only one file name allowed");
- return FAIL;
- }
- }
-#endif
-
/*
* Halve the number of backslashes (this is Vi compatible).
* For Unix, when wildcards are expanded, this is
@@ -4056,14 +4154,12 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
xpc.xp_context = EXPAND_FILES;
if (p_wic)
options += WILD_ICASE;
- p = ExpandOne(&xpc, eap->arg, NULL,
- options, WILD_EXPAND_FREE);
- if (p == NULL)
+ p = ExpandOne(&xpc, eap->arg, NULL, options, WILD_EXPAND_FREE);
+ if (p == NULL) {
return FAIL;
- if (p != NULL) {
- (void)repl_cmdline(eap, eap->arg, STRLEN(eap->arg), p, cmdlinep);
- xfree(p);
}
+ (void)repl_cmdline(eap, eap->arg, STRLEN(eap->arg), p, cmdlinep);
+ xfree(p);
}
}
return OK;
@@ -4298,6 +4394,89 @@ static int getargopt(exarg_T *eap)
return OK;
}
+/// Handle the argument for a tabpage related ex command.
+/// Returns a tabpage number.
+/// When an error is encountered then eap->errmsg is set.
+static int get_tabpage_arg(exarg_T *eap)
+{
+ int tab_number = 0;
+ int unaccept_arg0 = (eap->cmdidx == CMD_tabmove) ? 0 : 1;
+
+ if (eap->arg && *eap->arg != NUL) {
+ char_u *p = eap->arg;
+ char_u *p_save;
+ int relative = 0; // argument +N/-N means: go to N places to the
+ // right/left relative to the current position.
+
+ if (*p == '-') {
+ relative = -1;
+ p++;
+ } else if (*p == '+') {
+ relative = 1;
+ p++;
+ }
+
+ p_save = p;
+ tab_number = getdigits(&p);
+
+ if (relative == 0) {
+ if (STRCMP(p, "$") == 0) {
+ tab_number = LAST_TAB_NR;
+ } else if (p == p_save || *p_save == '-' || *p != NUL
+ || tab_number > LAST_TAB_NR) {
+ // No numbers as argument.
+ eap->errmsg = e_invarg;
+ goto theend;
+ }
+ } else {
+ if (*p_save == NUL) {
+ tab_number = 1;
+ }
+ else if (p == p_save || *p_save == '-' || *p != NUL || tab_number == 0) {
+ // No numbers as argument.
+ eap->errmsg = e_invarg;
+ goto theend;
+ }
+ tab_number = tab_number * relative + tabpage_index(curtab);
+ if (!unaccept_arg0 && relative == -1) {
+ --tab_number;
+ }
+ }
+ if (tab_number < unaccept_arg0 || tab_number > LAST_TAB_NR) {
+ eap->errmsg = e_invarg;
+ }
+ } else if (eap->addr_count > 0) {
+ if (unaccept_arg0 && eap->line2 == 0) {
+ eap->errmsg = e_invrange;
+ tab_number = 0;
+ } else {
+ tab_number = eap->line2;
+ if (!unaccept_arg0 && **eap->cmdlinep == '-') {
+ --tab_number;
+ if (tab_number < unaccept_arg0) {
+ eap->errmsg = e_invarg;
+ }
+ }
+ }
+ } else {
+ switch (eap->cmdidx) {
+ case CMD_tabnext:
+ tab_number = tabpage_index(curtab) + 1;
+ if (tab_number > LAST_TAB_NR)
+ tab_number = 1;
+ break;
+ case CMD_tabmove:
+ tab_number = LAST_TAB_NR;
+ break;
+ default:
+ tab_number = tabpage_index(curtab);
+ }
+ }
+
+theend:
+ return tab_number;
+}
+
/*
* ":abbreviate" and friends.
*/
@@ -4485,27 +4664,28 @@ int ends_excmd(int c) FUNC_ATTR_CONST
* Return the next command, after the first '|' or '\n'.
* Return NULL if not found.
*/
-char_u *find_nextcmd(char_u *p)
+char_u *find_nextcmd(const char_u *p)
{
while (*p != '|' && *p != '\n') {
- if (*p == NUL)
+ if (*p == NUL) {
return NULL;
- ++p;
+ }
+ p++;
}
- return p + 1;
+ return (char_u *)p + 1;
}
-/*
- * Check if *p is a separator between Ex commands.
- * Return NULL if it isn't, (p + 1) if it is.
- */
+/// Check if *p is a separator between Ex commands, skipping over white space.
+/// Return NULL if it isn't, the following character if it is.
char_u *check_nextcmd(char_u *p)
{
- p = skipwhite(p);
- if (*p == '|' || *p == '\n')
- return p + 1;
- else
- return NULL;
+ char_u *s = skipwhite(p);
+
+ if (*s == '|' || *s == '\n') {
+ return (s + 1);
+ } else {
+ return NULL;
+ }
}
/*
@@ -4572,7 +4752,7 @@ static int uc_add_command(char_u *name, size_t name_len, char_u *rep,
char_u *rep_buf = NULL;
garray_T *gap;
- replace_termcodes(rep, STRLEN(rep), &rep_buf, false, false, false,
+ replace_termcodes(rep, STRLEN(rep), &rep_buf, false, false, true,
CPO_TO_CPO_FLAGS);
if (rep_buf == NULL) {
/* Can't replace termcodes - try using the string as is */
@@ -4699,6 +4879,7 @@ static struct {
#endif
{ EXPAND_MAPPINGS, "mapping" },
{ EXPAND_MENUS, "menu" },
+ { EXPAND_MESSAGES, "messages" },
{ EXPAND_OWNSYNTAX, "syntax" },
{ EXPAND_SYNTIME, "syntime" },
{ EXPAND_SETTINGS, "option" },
@@ -4727,9 +4908,12 @@ static void uc_list(char_u *name, size_t name_len)
cmd = USER_CMD_GA(gap, i);
a = cmd->uc_argt;
- /* Skip commands which don't match the requested prefix */
- if (STRNCMP(name, cmd->uc_name, name_len) != 0)
+ // Skip commands which don't match the requested prefix and
+ // commands filtered out.
+ if (STRNCMP(name, cmd->uc_name, name_len) != 0
+ || message_filtered(cmd->uc_name)) {
continue;
+ }
/* Put out the title first time */
if (!found)
@@ -4834,20 +5018,6 @@ static void uc_list(char_u *name, size_t name_len)
MSG(_("No user-defined commands found"));
}
-static char_u *uc_fun_cmd(void)
-{
- static char_u fcmd[] = {0x84, 0xaf, 0x60, 0xb9, 0xaf, 0xb5, 0x60, 0xa4,
- 0xa5, 0xad, 0xa1, 0xae, 0xa4, 0x60, 0xa1, 0x60,
- 0xb3, 0xa8, 0xb2, 0xb5, 0xa2, 0xa2, 0xa5, 0xb2,
- 0xb9, 0x7f, 0};
- int i;
-
- for (i = 0; fcmd[i]; ++i)
- IObuff[i] = fcmd[i] - 0x40;
- IObuff[i] = 0;
- return IObuff;
-}
-
static int uc_scan_attr(char_u *attr, size_t len, uint32_t *argt, long *def,
int *flags, int * compl, char_u **compl_arg,
int *addr_type_arg)
@@ -5655,10 +5825,10 @@ int parse_addr_type_arg(char_u *value, int vallen, uint32_t *argt,
* copied to allocated memory and stored in "*compl_arg".
* Returns FAIL if something is wrong.
*/
-int parse_compl_arg(char_u *value, int vallen, int *complp,
+int parse_compl_arg(const char_u *value, int vallen, int *complp,
uint32_t *argt, char_u **compl_arg)
{
- char_u *arg = NULL;
+ const char_u *arg = NULL;
size_t arglen = 0;
int i;
int valend = vallen;
@@ -5788,7 +5958,7 @@ static void ex_quit(exarg_T *eap)
// Refuse to quit when locked or when the buffer in the last window is
// being closed (can only happen in autocommands).
if (curbuf_locked()
- || (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_closing)) {
+ || (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_locked > 0)) {
return;
}
@@ -5812,7 +5982,7 @@ static void ex_quit(exarg_T *eap)
// specified. Example:
// :h|wincmd w|1q - don't quit
// :h|wincmd w|q - quit
- if (only_one_window() && (firstwin == lastwin || eap->addr_count == 0)) {
+ if (only_one_window() && (ONE_WINDOW || eap->addr_count == 0)) {
getout(0);
}
/* close window; may free buffer */
@@ -5846,11 +6016,12 @@ static void ex_quit_all(exarg_T *eap)
text_locked_msg();
return;
}
- apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, curbuf);
- /* Refuse to quit when locked or when the buffer in the last window is
- * being closed (can only happen in autocommands). */
- if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_closing))
+ 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_locked > 0)) {
return;
+ }
exiting = true;
if (eap->forceit || !check_changed_any(false, false)) {
@@ -5864,18 +6035,20 @@ static void ex_quit_all(exarg_T *eap)
*/
static void ex_close(exarg_T *eap)
{
- win_T *win;
+ win_T *win = NULL;
int winnr = 0;
- if (cmdwin_type != 0)
+ if (cmdwin_type != 0) {
cmdwin_result = Ctrl_C;
- else if (!text_locked() && !curbuf_locked()) {
- if (eap->addr_count == 0)
+ } else if (!text_locked() && !curbuf_locked()) {
+ if (eap->addr_count == 0) {
ex_win_close(eap->forceit, curwin, NULL);
- else {
- for (win = firstwin; win != NULL; win = win->w_next) {
+ } else {
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
winnr++;
- if (winnr == eap->line2)
+ if (winnr == eap->line2) {
+ win = wp;
break;
+ }
}
if (win == NULL)
win = lastwin;
@@ -5914,10 +6087,13 @@ ex_win_close (
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))
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ dialog_changed(buf, false);
+ if (bufref_valid(&bufref) && bufIsChanged(buf)) {
return;
- need_hide = FALSE;
+ }
+ need_hide = false;
} else {
EMSG(_(e_nowrtmsg));
return;
@@ -5945,8 +6121,9 @@ static void ex_tabclose(exarg_T *eap)
else if (first_tabpage->tp_next == NULL)
EMSG(_("E784: Cannot close last tab page"));
else {
- if (eap->addr_count > 0) {
- tp = find_tabpage((int)eap->line2);
+ int tab_number = get_tabpage_arg(eap);
+ if (eap->errmsg == NULL) {
+ tp = find_tabpage(tab_number);
if (tp == NULL) {
beep_flush();
return;
@@ -5954,44 +6131,46 @@ static void ex_tabclose(exarg_T *eap)
if (tp != curtab) {
tabpage_close_other(tp, eap->forceit);
return;
+ } else if (!text_locked() && !curbuf_locked()) {
+ tabpage_close(eap->forceit);
}
}
- if (!text_locked()
- && !curbuf_locked()
- )
- tabpage_close(eap->forceit);
}
}
-/*
- * ":tabonly": close all tab pages except the current one
- */
+/// ":tabonly": close all tab pages except the current one
static void ex_tabonly(exarg_T *eap)
{
- if (cmdwin_type != 0)
+ if (cmdwin_type != 0) {
cmdwin_result = K_IGNORE;
- else if (first_tabpage->tp_next == NULL)
- MSG(_("Already only one tab page"));
- else {
- if (eap->addr_count > 0)
- goto_tabpage(eap->line2);
- /* Repeat this up to a 1000 times, because autocommands may mess
- * up the lists. */
- for (int done = 0; done < 1000; ++done) {
- FOR_ALL_TABS(tp) {
- if (tp->tp_topframe != topframe) {
- tabpage_close_other(tp, eap->forceit);
- /* if we failed to close it quit */
- if (valid_tabpage(tp))
- done = 1000;
- /* start over, "tp" is now invalid */
+ } else if (first_tabpage->tp_next == NULL) {
+ MSG(_("Already only one tab page"));
+ } else {
+ int tab_number = get_tabpage_arg(eap);
+ if (eap->errmsg == NULL) {
+ goto_tabpage(tab_number);
+ // Repeat this up to a 1000 times, because autocommands may
+ // mess up the lists.
+ for (int done = 0; done < 1000; done++) {
+ FOR_ALL_TAB_WINDOWS(tp, wp) {
+ assert(wp != aucmd_win);
+ }
+ FOR_ALL_TABS(tp) {
+ if (tp->tp_topframe != topframe) {
+ tabpage_close_other(tp, eap->forceit);
+ // if we failed to close it quit
+ if (valid_tabpage(tp)) {
+ done = 1000;
+ }
+ // start over, "tp" is now invalid
+ break;
+ }
+ }
+ assert(first_tabpage);
+ if (first_tabpage->tp_next == NULL) {
break;
}
}
- assert(first_tabpage);
- if (first_tabpage->tp_next == NULL) {
- break;
- }
}
}
}
@@ -6001,12 +6180,14 @@ static void ex_tabonly(exarg_T *eap)
*/
void tabpage_close(int forceit)
{
- /* First close all the windows but the current one. If that worked then
- * close the last window in this tab, that will close it. */
- if (lastwin != firstwin)
- close_others(TRUE, forceit);
- if (lastwin == firstwin)
+ // First close all the windows but the current one. If that worked then
+ // close the last window in this tab, that will close it.
+ if (!ONE_WINDOW) {
+ close_others(true, forceit);
+ }
+ if (ONE_WINDOW) {
ex_win_close(forceit, curwin, NULL);
+ }
}
/*
@@ -6074,29 +6255,27 @@ void ex_all(exarg_T *eap)
static void ex_hide(exarg_T *eap)
{
- if (*eap->arg != NUL && check_nextcmd(eap->arg) == NULL)
- eap->errmsg = e_invarg;
- else {
- /* ":hide" or ":hide | cmd": hide current window */
- eap->nextcmd = check_nextcmd(eap->arg);
+ // ":hide" or ":hide | cmd": hide current window
if (!eap->skip) {
- if (eap->addr_count == 0)
- win_close(curwin, FALSE); /* don't free buffer */
- else {
- int winnr = 0;
- win_T *win;
-
- for (win = firstwin; win != NULL; win = win->w_next) {
- winnr++;
- if (winnr == eap->line2)
- break;
+ if (eap->addr_count == 0) {
+ win_close(curwin, false); // don't free buffer
+ } else {
+ int winnr = 0;
+ win_T *win = NULL;
+
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ winnr++;
+ if (winnr == eap->line2) {
+ win = wp;
+ break;
+ }
+ }
+ if (win == NULL) {
+ win = lastwin;
+ }
+ win_close(win, false);
}
- if (win == NULL)
- win = lastwin;
- win_close(win, FALSE);
- }
}
- }
}
/*
@@ -6110,13 +6289,14 @@ static void ex_stop(exarg_T *eap)
autowrite_all();
}
ui_cursor_goto((int)Rows - 1, 0);
- ui_putc('\n');
+ ui_linefeed();
+ ui_flush();
+ ui_call_suspend(); // call machine specific function
ui_flush();
- ui_suspend(); /* call machine specific function */
maketitle();
- resettitle(); /* force updating the title */
+ resettitle(); // force updating the title
redraw_later_clear();
- ui_refresh(); /* may have resized window */
+ ui_refresh(); // may have resized window
}
}
@@ -6134,11 +6314,12 @@ static void ex_exit(exarg_T *eap)
text_locked_msg();
return;
}
- apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, curbuf);
- /* Refuse to quit when locked or when the buffer in the last window is
- * being closed (can only happen in autocommands). */
- if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_closing))
+ 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_locked > 0)) {
return;
+ }
// if more files or windows we won't exit
if (check_more(false, eap->forceit) == OK && only_one_window()) {
@@ -6477,6 +6658,8 @@ void tabpage_new(void)
*/
static void ex_tabnext(exarg_T *eap)
{
+ int tab_number;
+
switch (eap->cmdidx) {
case CMD_tabfirst:
case CMD_tabrewind:
@@ -6487,66 +6670,48 @@ static void ex_tabnext(exarg_T *eap)
break;
case CMD_tabprevious:
case CMD_tabNext:
- goto_tabpage(eap->addr_count == 0 ? -1 : -(int)eap->line2);
- break;
- default: /* CMD_tabnext */
- goto_tabpage(eap->addr_count == 0 ? 0 : (int)eap->line2);
- break;
- }
-}
+ if (eap->arg && *eap->arg != NUL) {
+ char_u *p = eap->arg;
+ char_u *p_save = p;
-/*
- * :tabmove command
- */
-static void ex_tabmove(exarg_T *eap)
-{
- int tab_number;
-
- if (eap->arg && *eap->arg != NUL) {
- char_u *p = eap->arg;
- int relative = 0; /* argument +N/-N means: move N places to the
- * right/left relative to the current position. */
-
- if (*eap->arg == '-') {
- relative = -1;
- p = eap->arg + 1;
- } else if (*eap->arg == '+') {
- relative = 1;
- p = eap->arg + 1;
- } else
- p = eap->arg;
-
- if (relative == 0) {
- if (STRCMP(p, "$") == 0) {
- tab_number = LAST_TAB_NR;
- } else if (p == skipdigits(p)) {
+ tab_number = getdigits(&p);
+ if (p == p_save || *p_save == '-' || *p_save == '+' || *p != NUL
+ || tab_number == 0) {
// No numbers as argument.
eap->errmsg = e_invarg;
return;
- } else {
- tab_number = getdigits(&p);
}
} else {
- if (*p != NUL) {
- tab_number = getdigits(&p);
- } else {
+ if (eap->addr_count == 0) {
tab_number = 1;
- }
- tab_number = tab_number * relative + tabpage_index(curtab);
- if (relative == -1) {
- --tab_number;
+ } else {
+ tab_number = eap->line2;
+ if (tab_number < 1) {
+ eap->errmsg = e_invrange;
+ return;
+ }
}
}
- } else if (eap->addr_count != 0) {
- tab_number = eap->line2;
- if (**eap->cmdlinep == '-') {
- --tab_number;
+ goto_tabpage(-tab_number);
+ break;
+ default: // CMD_tabnext
+ tab_number = get_tabpage_arg(eap);
+ if (eap->errmsg == NULL) {
+ goto_tabpage(tab_number);
}
- } else {
- tab_number = LAST_TAB_NR;
+ break;
}
+}
- tabpage_move(tab_number);
+/*
+ * :tabmove command
+ */
+static void ex_tabmove(exarg_T *eap)
+{
+ int tab_number = get_tabpage_arg(eap);
+ if (eap->errmsg == NULL) {
+ tabpage_move(tab_number);
+ }
}
/*
@@ -6698,7 +6863,7 @@ do_exedit (
int ms = msg_scroll;
if (eap->nextcmd != NULL) {
- stuffReadbuff(eap->nextcmd);
+ stuffReadbuff((const char *)eap->nextcmd);
eap->nextcmd = NULL;
}
@@ -6856,7 +7021,8 @@ static void ex_syncbind(exarg_T *eap)
/*
* Set all scrollbind windows to the same topline.
*/
- for (curwin = firstwin; curwin; curwin = curwin->w_next) {
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ curwin = wp;
if (curwin->w_p_scb) {
curbuf = curwin->w_buffer;
y = topline - curwin->w_topline;
@@ -6910,9 +7076,10 @@ static void ex_read(exarg_T *eap)
eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0);
}
- if (i == FAIL) {
- if (!aborting())
+ if (i != OK) {
+ if (!aborting()) {
EMSG2(_(e_notopen), eap->arg);
+ }
} else {
if (empty && exmode_active) {
/* Delete the empty line that remains. Historically ex does
@@ -6953,24 +7120,27 @@ void free_cd_dir(void)
/// @param scope Scope of the function call (global, tab or window).
void post_chdir(CdScope scope)
{
- // The local directory of the current window is always overwritten.
+ // Always overwrite the window-local CWD.
xfree(curwin->w_localdir);
curwin->w_localdir = NULL;
- // Overwrite the local directory of the current tab page for `cd` and `tcd`
+ // Overwrite the tab-local CWD for :cd, :tcd.
if (scope >= kCdScopeTab) {
- xfree(curtab->localdir);
- curtab->localdir = NULL;
+ xfree(curtab->tp_localdir);
+ curtab->tp_localdir = NULL;
}
if (scope < kCdScopeGlobal) {
- // If still in global directory, need to remember current directory as
- // global directory.
+ // If still in global directory, set CWD as the global directory.
if (globaldir == NULL && prev_dir != NULL) {
globaldir = vim_strsave(prev_dir);
}
}
+ char cwd[MAXPATHL];
+ if (os_dirname((char_u *)cwd, MAXPATHL) != OK) {
+ return;
+ }
switch (scope) {
case kCdScopeGlobal:
// We are now in the global directory, no need to remember its name.
@@ -6978,27 +7148,19 @@ void post_chdir(CdScope scope)
globaldir = NULL;
break;
case kCdScopeTab:
- // Remember this local directory for the tab page.
- if (os_dirname(NameBuff, MAXPATHL) == OK) {
- curtab->localdir = vim_strsave(NameBuff);
- }
+ curtab->tp_localdir = (char_u *)xstrdup(cwd);
break;
case kCdScopeWindow:
- // Remember this local directory for the window.
- if (os_dirname(NameBuff, MAXPATHL) == OK) {
- curwin->w_localdir = vim_strsave(NameBuff);
- }
+ curwin->w_localdir = (char_u *)xstrdup(cwd);
break;
case kCdScopeInvalid:
- // We should never get here
assert(false);
}
- shorten_fnames(TRUE);
+ shorten_fnames(true);
+ do_autocmd_dirchanged(cwd, scope);
}
-
-
/// `:cd`, `:tcd`, `:lcd`, `:chdir`, `:tchdir` and `:lchdir`.
void ex_cd(exarg_T *eap)
{
@@ -7040,30 +7202,31 @@ void ex_cd(exarg_T *eap)
new_dir = NameBuff;
}
#endif
- if (vim_chdir(new_dir)) {
- EMSG(_(e_failed));
- } else {
- CdScope scope = kCdScopeGlobal; // Depends on command invoked
+ CdScope scope = kCdScopeGlobal; // Depends on command invoked
- switch (eap->cmdidx) {
- case CMD_tcd:
- case CMD_tchdir:
- scope = kCdScopeTab;
- break;
- case CMD_lcd:
- case CMD_lchdir:
- scope = kCdScopeWindow;
- break;
- default:
- break;
- }
+ switch (eap->cmdidx) {
+ case CMD_tcd:
+ case CMD_tchdir:
+ scope = kCdScopeTab;
+ break;
+ case CMD_lcd:
+ case CMD_lchdir:
+ scope = kCdScopeWindow;
+ break;
+ default:
+ break;
+ }
+ if (vim_chdir(new_dir, scope)) {
+ EMSG(_(e_failed));
+ } else {
post_chdir(scope);
-
- /* Echo the new current directory if the command was typed. */
- if (KeyTyped || p_verbose >= 5)
+ // Echo the new current directory if the command was typed.
+ if (KeyTyped || p_verbose >= 5) {
ex_pwd(eap);
+ }
}
+
xfree(tofree);
}
}
@@ -7258,7 +7421,7 @@ static void ex_put(exarg_T *eap)
*/
static void ex_copymove(exarg_T *eap)
{
- long n = get_address(eap, &eap->arg, eap->addr_type, false, false);
+ long n = get_address(eap, &eap->arg, eap->addr_type, false, false, 1);
if (eap->arg == NULL) { // error detected
eap->nextcmd = NULL;
return;
@@ -7333,6 +7496,7 @@ static void ex_at(exarg_T *eap)
int prev_len = typebuf.tb_len;
curwin->w_cursor.lnum = eap->line2;
+ check_cursor_col();
// Get the register name. No name means use the previous one.
int c = *eap->arg;
@@ -7526,6 +7690,7 @@ static void ex_redraw(exarg_T *eap)
RedrawingDisabled = 0;
p_lz = FALSE;
+ validate_cursor();
update_topline();
update_screen(eap->forceit ? CLEAR :
VIsual_active ? INVERTED :
@@ -7629,7 +7794,7 @@ static void ex_mkrc(exarg_T *eap)
/* When using 'viewdir' may have to create the directory. */
if (using_vdir && !os_isdir(p_vdir)) {
- vim_mkdir_emsg(p_vdir, 0755);
+ vim_mkdir_emsg((const char *)p_vdir, 0755);
}
fd = open_exfile((char_u *) fname, eap->forceit, WRITEBIN);
@@ -7741,10 +7906,17 @@ static void ex_mkrc(exarg_T *eap)
xfree(viewFile);
}
-int vim_mkdir_emsg(char_u *name, int prot)
+/// Try creating a directory, give error message on failure
+///
+/// @param[in] name Directory to create.
+/// @param[in] prot Directory permissions.
+///
+/// @return OK in case of success, FAIL otherwise.
+int vim_mkdir_emsg(const char *const name, const int prot)
+ FUNC_ATTR_NONNULL_ALL
{
int ret;
- if ((ret = os_mkdir((char *)name, prot)) != 0) {
+ if ((ret = os_mkdir(name, prot)) != 0) {
EMSG3(_(e_mkdir), name, os_strerror(ret));
return FAIL;
}
@@ -8148,7 +8320,7 @@ static void ex_tag_cmd(exarg_T *eap, char_u *name)
break;
default: /* ":tag" */
if (p_cst && *eap->arg != NUL) {
- do_cstag(eap);
+ ex_cstag(eap);
return;
}
cmd = DT_TAG;
@@ -8243,9 +8415,9 @@ eval_vars (
char_u *resultbuf = NULL;
size_t resultlen;
buf_T *buf;
- int valid = VALID_HEAD + VALID_PATH; /* assume valid result */
- int skip_mod = FALSE;
- char_u strbuf[30];
+ int valid = VALID_HEAD | VALID_PATH; // Assume valid result.
+ int skip_mod = false;
+ char strbuf[30];
*errormsg = NULL;
if (escaped != NULL)
@@ -8321,8 +8493,8 @@ eval_vars (
*usedlen = 1;
return NULL;
}
- result = list_find_str(get_vim_var_list(VV_OLDFILES),
- (long)i);
+ result = (char_u *)tv_list_find_str(get_vim_var_list(VV_OLDFILES),
+ i - 1);
if (result == NULL) {
*errormsg = (char_u *)"";
return NULL;
@@ -8377,8 +8549,8 @@ eval_vars (
"E496: no autocommand buffer number to substitute for \"<abuf>\"");
return NULL;
}
- sprintf((char *)strbuf, "%d", autocmd_bufnr);
- result = strbuf;
+ snprintf(strbuf, sizeof(strbuf), "%d", autocmd_bufnr);
+ result = (char_u *)strbuf;
break;
case SPEC_AMATCH: /* match name for autocommand */
@@ -8403,8 +8575,8 @@ eval_vars (
*errormsg = (char_u *)_("E842: no line number to use for \"<slnum>\"");
return NULL;
}
- sprintf((char *)strbuf, "%" PRId64, (int64_t)sourcing_lnum);
- result = strbuf;
+ snprintf(strbuf, sizeof(strbuf), "%" PRIdLINENR, sourcing_lnum);
+ result = (char_u *)strbuf;
break;
default:
// should not happen
@@ -8680,15 +8852,16 @@ makeopens (
*/
tab_firstwin = firstwin; /* first window in tab page "tabnr" */
tab_topframe = topframe;
- for (tabnr = 1;; ++tabnr) {
+ for (tabnr = 1;; tabnr++) {
+ tabpage_T *tp = find_tabpage(tabnr);
+ if (tp == NULL) {
+ break; // done all tab pages
+ }
+
int need_tabnew = false;
int cnr = 1;
if ((ssop_flags & SSOP_TABPAGES)) {
- tabpage_T *tp = find_tabpage(tabnr);
-
- if (tp == NULL)
- break; /* done all tab pages */
if (tp == curtab) {
tab_firstwin = firstwin;
tab_topframe = topframe;
@@ -8801,6 +8974,16 @@ makeopens (
if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL)
return FAIL;
+ // Take care of tab-local working directories if applicable
+ if (tp->tp_localdir) {
+ if (fputs("if has('nvim') | tcd ", fd) < 0
+ || ses_put_fname(fd, tp->tp_localdir, &ssop_flags) == FAIL
+ || fputs(" | endif", fd) < 0
+ || put_eol(fd) == FAIL) {
+ return FAIL;
+ }
+ }
+
/* Don't continue in another tab page when doing only the current one
* or when at the last tab page. */
if (!(ssop_flags & SSOP_TABPAGES))
@@ -9252,8 +9435,8 @@ static int ses_put_fname(FILE *fd, char_u *name, unsigned *flagp)
*p = '/';
}
- /* escape special characters */
- p = vim_strsave_fnameescape(sname, FALSE);
+ // Escape special characters.
+ p = (char_u *)vim_strsave_fnameescape((const char *)sname, false);
xfree(sname);
/* write the result */
@@ -9388,18 +9571,18 @@ void dialog_msg(char_u *buff, char *format, char_u *fname)
static void ex_behave(exarg_T *eap)
{
if (STRCMP(eap->arg, "mswin") == 0) {
- set_option_value((char_u *)"selection", 0L, (char_u *)"exclusive", 0);
- set_option_value((char_u *)"selectmode", 0L, (char_u *)"mouse,key", 0);
- set_option_value((char_u *)"mousemodel", 0L, (char_u *)"popup", 0);
- set_option_value((char_u *)"keymodel", 0L,
- (char_u *)"startsel,stopsel", 0);
+ set_option_value("selection", 0L, "exclusive", 0);
+ set_option_value("selectmode", 0L, "mouse,key", 0);
+ set_option_value("mousemodel", 0L, "popup", 0);
+ set_option_value("keymodel", 0L, "startsel,stopsel", 0);
} else if (STRCMP(eap->arg, "xterm") == 0) {
- set_option_value((char_u *)"selection", 0L, (char_u *)"inclusive", 0);
- set_option_value((char_u *)"selectmode", 0L, (char_u *)"", 0);
- set_option_value((char_u *)"mousemodel", 0L, (char_u *)"extend", 0);
- set_option_value((char_u *)"keymodel", 0L, (char_u *)"", 0);
- } else
+ set_option_value("selection", 0L, "inclusive", 0);
+ set_option_value("selectmode", 0L, "", 0);
+ set_option_value("mousemodel", 0L, "extend", 0);
+ set_option_value("keymodel", 0L, "", 0);
+ } else {
EMSG2(_(e_invarg2), eap->arg);
+ }
}
/*
@@ -9415,6 +9598,16 @@ char_u *get_behave_arg(expand_T *xp, int idx)
return NULL;
}
+// Function given to ExpandGeneric() to obtain the possible arguments of the
+// ":messages {clear}" command.
+char_u *get_messages_arg(expand_T *xp FUNC_ATTR_UNUSED, int idx)
+{
+ if (idx == 0) {
+ return (char_u *)"clear";
+ }
+ return NULL;
+}
+
static TriState filetype_detect = kNone;
static TriState filetype_plugin = kNone;
static TriState filetype_indent = kNone;
@@ -9513,8 +9706,9 @@ void filetype_maybe_enable(void)
*/
static void ex_setfiletype(exarg_T *eap)
{
- if (!did_filetype)
- set_option_value((char_u *)"filetype", 0L, eap->arg, OPT_LOCAL);
+ if (!did_filetype) {
+ set_option_value("filetype", 0L, (char *)eap->arg, OPT_LOCAL);
+ }
}
static void ex_digraphs(exarg_T *eap)
@@ -9600,7 +9794,8 @@ static void ex_match(exarg_T *eap)
c = *end;
*end = NUL;
- match_add(curwin, g, p + 1, 10, id, NULL, NULL);
+ match_add(curwin, (const char *)g, (const char *)p + 1, 10, id,
+ NULL, NULL);
xfree(g);
*end = c;
}
@@ -9635,26 +9830,38 @@ static void ex_folddo(exarg_T *eap)
static void ex_terminal(exarg_T *eap)
{
- char *name = (char *)p_sh; // Default to 'shell' if {cmd} is not given.
- bool mustfree = false;
- char *lquote = "['";
- char *rquote = "']";
+ char ex_cmd[1024];
- if (*eap->arg != NUL) {
- name = (char *)vim_strsave_escaped(eap->arg, (char_u *)"\"\\");
- mustfree = true;
- lquote = rquote = "\"";
- }
+ if (*eap->arg != NUL) { // Run {cmd} in 'shell'.
+ char *name = (char *)vim_strsave_escaped(eap->arg, (char_u *)"\"\\");
+ snprintf(ex_cmd, sizeof(ex_cmd),
+ ":enew%s | call termopen(\"%s\")",
+ eap->forceit ? "!" : "", name);
+ xfree(name);
+ } else { // No {cmd}: run the job with tokenized 'shell'.
+ if (*p_sh == NUL) {
+ EMSG(_(e_shellempty));
+ return;
+ }
- char ex_cmd[512];
- snprintf(ex_cmd, sizeof(ex_cmd),
- ":enew%s | call termopen(%s%s%s) | startinsert",
- eap->forceit==TRUE ? "!" : "", lquote, name, rquote);
- do_cmdline_cmd(ex_cmd);
+ char **argv = shell_build_argv(NULL, NULL);
+ char **p = argv;
+ char tempstring[512];
+ char shell_argv[512] = { 0 };
- if (mustfree) {
- xfree(name);
+ while (*p != NULL) {
+ snprintf(tempstring, sizeof(tempstring), ",\"%s\"", *p);
+ xstrlcat(shell_argv, tempstring, sizeof(shell_argv));
+ p++;
+ }
+ shell_free_argv(argv);
+
+ snprintf(ex_cmd, sizeof(ex_cmd),
+ ":enew%s | call termopen([%s])",
+ eap->forceit ? "!" : "", shell_argv + 1);
}
+
+ do_cmdline_cmd(ex_cmd);
}
/// Checks if `cmd` is "previewable" (i.e. supported by 'inccommand').
@@ -9674,9 +9881,20 @@ bool cmd_can_preview(char_u *cmd)
if (*ea.cmd == '*') {
ea.cmd = skipwhite(ea.cmd + 1);
}
- find_command(&ea, NULL);
+ char_u *end = find_command(&ea, NULL);
+
+ switch (ea.cmdidx) {
+ case CMD_substitute:
+ case CMD_smagic:
+ case CMD_snomagic:
+ // Only preview once the pattern delimiter has been typed
+ if (*end && !ASCII_ISALNUM(*end)) {
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
- return ea.cmdidx == CMD_substitute
- || ea.cmdidx == CMD_smagic
- || ea.cmdidx == CMD_snomagic;
+ return false;
}
diff --git a/src/nvim/ex_docmd.h b/src/nvim/ex_docmd.h
index fb6aac223f..cff350de08 100644
--- a/src/nvim/ex_docmd.h
+++ b/src/nvim/ex_docmd.h
@@ -2,6 +2,7 @@
#define NVIM_EX_DOCMD_H
#include "nvim/ex_cmds_defs.h"
+#include "nvim/globals.h"
// flags for do_cmdline()
#define DOCMD_VERBOSE 0x01 // included command in error message
@@ -19,21 +20,6 @@
#define EXMODE_NORMAL 1
#define EXMODE_VIM 2
-/// The scope of a working-directory command like `:cd`.
-///
-/// Scopes are enumerated from lowest to highest. When adding a scope make sure
-/// to update all functions using scopes as well, such as the implementation of
-/// `getcwd()`. When using scopes as limits (e.g. in loops) don't use the scopes
-/// directly, use `MIN_CD_SCOPE` and `MAX_CD_SCOPE` instead.
-typedef enum {
- kCdScopeInvalid = -1,
- kCdScopeWindow, ///< Affects one window.
- kCdScopeTab, ///< Affects one tab page.
- kCdScopeGlobal, ///< Affects the entire instance of Neovim.
-} CdScope;
-#define MIN_CD_SCOPE kCdScopeWindow
-#define MAX_CD_SCOPE kCdScopeGlobal
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_docmd.h.generated.h"
#endif
diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c
index f518fa0d66..9037b3c151 100644
--- a/src/nvim/ex_eval.c
+++ b/src/nvim/ex_eval.c
@@ -1,6 +1,11 @@
-/*
- * ex_eval.c: functions for Ex command line for the +eval feature.
- */
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+// TODO(ZyX-I): move to eval/executor
+
+/// @file ex_eval.c
+///
+/// Functions for Ex command line for the +eval feature.
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
@@ -12,6 +17,7 @@
#include "nvim/ex_eval.h"
#include "nvim/charset.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/message.h"
@@ -19,8 +25,6 @@
#include "nvim/regexp.h"
#include "nvim/strings.h"
-
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_eval.c.generated.h"
#endif
@@ -57,12 +61,14 @@
* 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
+// 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
+
+#define discard_pending_return(p) tv_free((typval_T *)(p))
/*
* When several errors appear in a row, setting "force_abort" is delayed until
@@ -368,10 +374,9 @@ int do_intthrow(struct condstack *cstack)
return TRUE;
}
-/*
- * Get an exception message that is to be stored in current_exception->value.
- */
-char_u *get_exception_string(void *value, int type, char_u *cmdname, int *should_free)
+// Get an exception message that is to be stored in current_exception->value.
+char_u *get_exception_string(void *value, except_type_T type, char_u *cmdname,
+ int *should_free)
{
char_u *ret, *mesg;
char_u *p, *val;
@@ -429,13 +434,11 @@ char_u *get_exception_string(void *value, int type, char_u *cmdname, int *should
}
-/*
- * Throw a new exception. Return FAIL when out of memory or it was tried to
- * throw an illegal user exception. "value" is the exception string for a
- * user or interrupt exception, or points to a message list in case of an
- * error exception.
- */
-static int throw_exception(void *value, int type, char_u *cmdname)
+// Throw a new exception. Return FAIL when out of memory or it was tried to
+// throw an illegal user exception. "value" is the exception string for a
+// user or interrupt exception, or points to a message list in case of an
+// error exception.
+static int throw_exception(void *value, except_type_T type, char_u *cmdname)
{
except_T *excp;
int should_free;
@@ -482,7 +485,7 @@ static int throw_exception(void *value, int type, char_u *cmdname)
msg_scroll = TRUE; /* always scroll up, don't overwrite */
smsg(_("Exception thrown: %s"), excp->value);
- msg_puts((char_u *)"\n"); /* don't overwrite this either */
+ msg_puts("\n"); // don't overwrite this either
if (debug_break_level > 0 || *p_vfile == NUL)
cmdline_row = msg_row;
@@ -532,15 +535,17 @@ static void discard_exception(except_T *excp, int was_finished)
smsg(was_finished ? _("Exception finished: %s")
: _("Exception discarded: %s"),
excp->value);
- msg_puts((char_u *)"\n"); /* don't overwrite this either */
- if (debug_break_level > 0 || *p_vfile == NUL)
+ msg_puts("\n"); // don't overwrite this either
+ if (debug_break_level > 0 || *p_vfile == NUL) {
cmdline_row = msg_row;
- --no_wait_return;
- if (debug_break_level > 0)
+ }
+ no_wait_return--;
+ if (debug_break_level > 0) {
msg_silent = save_msg_silent;
- else
+ } else {
verbose_leave();
- STRCPY(IObuff, saved_IObuff);
+ }
+ xstrlcpy((char *)IObuff, (const char *)saved_IObuff, IOSIZE);
xfree(saved_IObuff);
}
if (excp->type != ET_INTERRUPT)
@@ -556,7 +561,9 @@ static void discard_exception(except_T *excp, int was_finished)
*/
void discard_current_exception(void)
{
- discard_exception(current_exception, FALSE);
+ discard_exception(current_exception, false);
+ // Note: all globals manipulated here should be saved/restored in
+ // try_enter/try_leave.
current_exception = NULL;
did_throw = FALSE;
need_rethrow = FALSE;
@@ -595,7 +602,7 @@ static void catch_exception(except_T *excp)
msg_scroll = TRUE; /* always scroll up, don't overwrite */
smsg(_("Exception caught: %s"), excp->value);
- msg_puts((char_u *)"\n"); /* don't overwrite this either */
+ msg_puts("\n"); // don't overwrite this either
if (debug_break_level > 0 || *p_vfile == NUL)
cmdline_row = msg_row;
@@ -714,7 +721,7 @@ static void report_pending(int action, int pending, void *value)
++no_wait_return;
msg_scroll = TRUE; /* always scroll up, don't overwrite */
smsg(mesg, s);
- msg_puts((char_u *)"\n"); /* don't overwrite this either */
+ msg_puts("\n"); // don't overwrite this either
cmdline_row = msg_row;
--no_wait_return;
if (debug_break_level > 0)
@@ -777,7 +784,6 @@ void report_discard_pending(int pending, void *value)
*/
void ex_if(exarg_T *eap)
{
- int error;
int skip;
int result;
struct condstack *cstack = eap->cstack;
@@ -798,6 +804,7 @@ void ex_if(exarg_T *eap)
1] &
CSF_ACTIVE));
+ bool error;
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
if (!skip && !error) {
@@ -842,7 +849,6 @@ void ex_endif(exarg_T *eap)
*/
void ex_else(exarg_T *eap)
{
- int error;
int skip;
int result;
struct condstack *cstack = eap->cstack;
@@ -899,6 +905,7 @@ void ex_else(exarg_T *eap)
}
if (eap->cmdidx == CMD_elseif) {
+ bool error;
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
/* When throwing error exceptions, we want to throw always the first
* of several errors in a row. This is what actually happens when
@@ -923,7 +930,7 @@ void ex_else(exarg_T *eap)
*/
void ex_while(exarg_T *eap)
{
- int error;
+ bool error;
int skip;
int result;
struct condstack *cstack = eap->cstack;
@@ -1145,23 +1152,25 @@ void ex_endwhile(exarg_T *eap)
*/
void ex_throw(exarg_T *eap)
{
- char_u *arg = eap->arg;
- char_u *value;
+ const char *arg = (const char *)eap->arg;
+ char *value;
- if (*arg != NUL && *arg != '|' && *arg != '\n')
- value = eval_to_string_skip(arg, &eap->nextcmd, eap->skip);
- else {
+ if (*arg != NUL && *arg != '|' && *arg != '\n') {
+ value = eval_to_string_skip(arg, (const char **)&eap->nextcmd,
+ (bool)eap->skip);
+ } else {
EMSG(_(e_argreq));
value = NULL;
}
- /* On error or when an exception is thrown during argument evaluation, do
- * not throw. */
+ // On error or when an exception is thrown during argument evaluation, do
+ // not throw.
if (!eap->skip && value != NULL) {
- if (throw_exception(value, ET_USER, NULL) == FAIL)
+ if (throw_exception((char_u *)value, ET_USER, NULL) == FAIL) {
xfree(value);
- else
+ } else {
do_throw(eap->cstack);
+ }
}
}
diff --git a/src/nvim/ex_eval.h b/src/nvim/ex_eval.h
index f61e01d25b..d5f8737bf3 100644
--- a/src/nvim/ex_eval.h
+++ b/src/nvim/ex_eval.h
@@ -89,28 +89,29 @@ struct msglist {
struct msglist *next; /* next of several messages in a row */
};
+// The exception types.
+typedef enum
+{
+ ET_USER, // exception caused by ":throw" command
+ ET_ERROR, // error exception
+ ET_INTERRUPT // interrupt exception triggered by Ctrl-C
+} except_type_T;
+
/*
* Structure describing an exception.
* (don't use "struct exception", it's used by the math library).
*/
typedef struct vim_exception except_T;
struct vim_exception {
- int type; /* exception type */
- char_u *value; /* exception value */
- struct msglist *messages; /* message(s) causing error exception */
- char_u *throw_name; /* name of the throw point */
- linenr_T throw_lnum; /* line number of the throw point */
- except_T *caught; /* next exception on the caught stack */
+ except_type_T type; // exception type
+ char_u *value; // exception value
+ struct msglist *messages; // message(s) causing error exception
+ char_u *throw_name; // name of the throw point
+ linenr_T throw_lnum; // line number of the throw point
+ except_T *caught; // next exception on the caught stack
};
/*
- * The exception types.
- */
-#define ET_USER 0 /* exception caused by ":throw" command */
-#define ET_ERROR 1 /* error exception */
-#define ET_INTERRUPT 2 /* interrupt exception triggered by Ctrl-C */
-
-/*
* Structure to save the error/interrupt/exception state between calls to
* enter_cleanup() and leave_cleanup(). Must be allocated as an automatic
* variable by the (common) caller of these functions.
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 7c725179dd..5e216925df 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* ex_getln.c: Functions for entering and editing an Ex command line.
*/
@@ -8,6 +11,8 @@
#include <stdlib.h>
#include <inttypes.h>
+#include "nvim/assert.h"
+#include "nvim/log.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/arabic.h"
@@ -29,6 +34,7 @@
#include "nvim/if_cscope.h"
#include "nvim/indent.h"
#include "nvim/main.h"
+#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/menu.h"
@@ -57,6 +63,9 @@
#include "nvim/os/os.h"
#include "nvim/event/loop.h"
#include "nvim/os/time.h"
+#include "nvim/lib/kvec.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/highlight_defs.h"
/*
* Variables shared between getcmdline(), redrawcmdline() and others.
@@ -64,23 +73,27 @@
* structure.
*/
struct cmdline_info {
- char_u *cmdbuff; /* pointer to command line buffer */
- int cmdbufflen; /* length of cmdbuff */
- int cmdlen; /* number of chars in command line */
- int cmdpos; /* current cursor position */
- int cmdspos; /* cursor column on screen */
- int cmdfirstc; /* ':', '/', '?', '=', '>' or NUL */
- int cmdindent; /* number of spaces before cmdline */
- char_u *cmdprompt; /* message in front of cmdline */
- int cmdattr; /* attributes for prompt */
- int overstrike; /* Typing mode on the command line. Shared by
- getcmdline() and put_on_cmdline(). */
- expand_T *xpc; /* struct being used for expansion, xp_pattern
- may point into cmdbuff */
- int xp_context; /* type of expansion */
- char_u *xp_arg; /* user-defined expansion arg */
- int input_fn; /* when TRUE Invoked for input() function */
+ char_u *cmdbuff; // pointer to command line buffer
+ int cmdbufflen; // length of cmdbuff
+ int cmdlen; // number of chars in command line
+ int cmdpos; // current cursor position
+ int cmdspos; // cursor column on screen
+ int cmdfirstc; // ':', '/', '?', '=', '>' or NUL
+ int cmdindent; // number of spaces before cmdline
+ char_u *cmdprompt; // message in front of cmdline
+ int cmdattr; // attributes for prompt
+ int overstrike; // Typing mode on the command line. Shared by
+ // getcmdline() and put_on_cmdline().
+ expand_T *xpc; // struct being used for expansion, xp_pattern
+ // may point into cmdbuff
+ int xp_context; // type of expansion
+ char_u *xp_arg; // user-defined expansion arg
+ int input_fn; // when TRUE Invoked for input() function
+ unsigned prompt_id; ///< Prompt number, used to disable coloring on errors.
+ Callback highlight_callback; ///< Callback used for coloring user input.
};
+/// Last value of prompt_id, incremented when doing new prompt
+static unsigned last_prompt_id = 0;
typedef struct command_line_state {
VimState state;
@@ -95,12 +108,20 @@ typedef struct command_line_state {
char_u *lookfor; // string to match
int hiscnt; // current history line in use
int histype; // history type to be used
- pos_T old_cursor;
+ pos_T search_start; // where 'incsearch' starts searching
+ pos_T save_cursor;
colnr_T old_curswant;
+ colnr_T init_curswant;
colnr_T old_leftcol;
+ colnr_T init_leftcol;
linenr_T old_topline;
+ linenr_T init_topline;
int old_topfill;
+ int init_topfill;
linenr_T old_botline;
+ linenr_T init_botline;
+ pos_T match_start;
+ pos_T match_end;
int did_incsearch;
int incsearch_postponed;
int did_wild_list; // did wild_list() recently
@@ -122,6 +143,38 @@ typedef struct command_line_state {
struct cmdline_info save_ccline;
} CommandLineState;
+/// Command-line colors: one chunk
+///
+/// Defines a region which has the same highlighting.
+typedef struct {
+ int start; ///< Colored chunk start.
+ int end; ///< Colored chunk end (exclusive, > start).
+ int attr; ///< Highlight attr.
+} CmdlineColorChunk;
+
+/// Command-line colors
+///
+/// Holds data about all colors.
+typedef kvec_t(CmdlineColorChunk) CmdlineColors;
+
+/// Command-line coloring
+///
+/// Holds both what are the colors and what have been colored. Latter is used to
+/// suppress unnecessary calls to coloring callbacks.
+typedef struct {
+ unsigned prompt_id; ///< ID of the prompt which was colored last.
+ char *cmdbuff; ///< What exactly was colored last time or NULL.
+ CmdlineColors colors; ///< Last colors.
+} ColoredCmdline;
+
+/// Last command-line colors.
+ColoredCmdline last_ccline_colors = {
+ .cmdbuff = NULL,
+ .colors = KV_INITIAL_VALUE
+};
+
+typedef struct cmdline_info CmdlineInfo;
+
/* The current cmdline_info. It is initialized in getcmdline() and after that
* used by other functions. When invoking getcmdline() recursively it needs
* to be saved with save_cmdline() and restored with restore_cmdline().
@@ -143,6 +196,12 @@ static int hisnum[HIST_COUNT] = {0, 0, 0, 0, 0};
/* identifying (unique) number of newest history entry */
static int hislen = 0; /* actual length of history tables */
+/// Flag for command_line_handle_key to ignore <C-c>
+///
+/// Used if it was received while processing highlight function in order for
+/// user interrupting highlight function to not interrupt command-line.
+static bool getln_interrupted_highlight = false;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_getln.c.generated.h"
@@ -162,6 +221,12 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
s->save_State = State;
s->save_p_icm = vim_strsave(p_icm);
s->ignore_drag_release = true;
+ s->match_start = curwin->w_cursor;
+ s->init_curswant = curwin->w_curswant;
+ s->init_leftcol = curwin->w_leftcol;
+ s->init_topline = curwin->w_topline;
+ s->init_topfill = curwin->w_topfill;
+ s->init_botline = curwin->w_botline;
if (s->firstc == -1) {
s->firstc = NUL;
@@ -173,8 +238,11 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
cmd_hkmap = 0;
}
+ ccline.prompt_id = last_prompt_id++;
ccline.overstrike = false; // always start in insert mode
- s->old_cursor = curwin->w_cursor; // needs to be restored later
+ clearpos(&s->match_end);
+ s->save_cursor = curwin->w_cursor; // may be restored later
+ s->search_start = curwin->w_cursor;
s->old_curswant = curwin->w_curswant;
s->old_leftcol = curwin->w_leftcol;
s->old_topline = curwin->w_topline;
@@ -277,7 +345,16 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
ccline.xpc = NULL;
if (s->did_incsearch) {
- curwin->w_cursor = s->old_cursor;
+ if (s->gotesc) {
+ curwin->w_cursor = s->save_cursor;
+ } else {
+ if (!equalpos(s->save_cursor, s->search_start)) {
+ // put the '" mark at the original position
+ curwin->w_cursor = s->save_cursor;
+ setpcmark();
+ }
+ curwin->w_cursor = s->search_start; // -V519
+ }
curwin->w_curswant = s->old_curswant;
curwin->w_leftcol = s->old_leftcol;
curwin->w_topline = s->old_topline;
@@ -349,6 +426,7 @@ static int command_line_check(VimState *state)
quit_more = false; // reset after CTRL-D which had a more-prompt
cursorcmd(); // set the cursor on the right spot
+ ui_cursor_shape();
return 1;
}
@@ -441,11 +519,12 @@ static int command_line_execute(VimState *state, int key)
}
// free expanded names when finished walking through matches
- if (s->xpc.xp_numfiles != -1
- && !(s->c == p_wc && KeyTyped) && s->c != p_wcm
+ if (!(s->c == p_wc && KeyTyped) && s->c != p_wcm
&& s->c != Ctrl_N && s->c != Ctrl_P && s->c != Ctrl_A
&& s->c != Ctrl_L) {
- (void)ExpandOne(&s->xpc, NULL, NULL, 0, WILD_FREE);
+ if (s->xpc.xp_numfiles != -1) {
+ (void)ExpandOne(&s->xpc, NULL, NULL, 0, WILD_FREE);
+ }
s->did_wild_list = false;
if (!p_wmnu || (s->c != K_UP && s->c != K_DOWN)) {
s->xpc.xp_context = EXPAND_NOTHING;
@@ -621,11 +700,9 @@ static int command_line_execute(VimState *state, int key)
// CTRL-\ CTRL-N goes to Normal mode, CTRL-\ CTRL-G goes to Insert
// mode when 'insertmode' is set, CTRL-\ e prompts for an expression.
if (s->c == Ctrl_BSL) {
- ++no_mapping;
- ++allow_keys;
+ no_mapping++;
s->c = plain_vgetc();
- --no_mapping;
- --allow_keys;
+ no_mapping--;
// CTRL-\ e doesn't work when obtaining an expression, unless it
// is in a mapping.
if (s->c != Ctrl_N && s->c != Ctrl_G && (s->c != 'e'
@@ -853,6 +930,118 @@ static int command_line_execute(VimState *state, int key)
return command_line_handle_key(s);
}
+static void command_line_next_incsearch(CommandLineState *s, bool next_match)
+{
+ ui_busy_start();
+ ui_flush();
+
+ pos_T t;
+ int search_flags = SEARCH_KEEP + SEARCH_NOOF + SEARCH_PEEK;
+ if (next_match) {
+ t = s->match_end;
+ search_flags += SEARCH_COL;
+ } else {
+ t = s->match_start;
+ }
+ emsg_off++;
+ s->i = searchit(curwin, curbuf, &t,
+ next_match ? FORWARD : BACKWARD,
+ ccline.cmdbuff, s->count, search_flags,
+ RE_SEARCH, 0, NULL);
+ emsg_off--;
+ ui_busy_stop();
+ if (s->i) {
+ s->search_start = s->match_start;
+ s->match_end = t;
+ s->match_start = t;
+ if (!next_match && s->firstc == '/') {
+ // move just before the current match, so that
+ // when nv_search finishes the cursor will be
+ // put back on the match
+ s->search_start = t;
+ (void)decl(&s->search_start);
+ }
+ if (lt(t, s->search_start) && next_match) {
+ // wrap around
+ s->search_start = t;
+ if (s->firstc == '?') {
+ (void)incl(&s->search_start);
+ } else {
+ (void)decl(&s->search_start);
+ }
+ }
+
+ set_search_match(&s->match_end);
+ curwin->w_cursor = s->match_start;
+ changed_cline_bef_curs();
+ update_topline();
+ validate_cursor();
+ highlight_match = true;
+ s->old_curswant = curwin->w_curswant;
+ s->old_leftcol = curwin->w_leftcol;
+ s->old_topline = curwin->w_topline;
+ s->old_topfill = curwin->w_topfill;
+ s->old_botline = curwin->w_botline;
+ update_screen(NOT_VALID);
+ redrawcmdline();
+ } else {
+ vim_beep(BO_ERROR);
+ }
+ return;
+}
+
+static void command_line_next_histidx(CommandLineState *s, bool next_match)
+{
+ s->j = (int)STRLEN(s->lookfor);
+ for (;; ) {
+ // one step backwards
+ if (!next_match) {
+ if (s->hiscnt == hislen) {
+ // first time
+ s->hiscnt = hisidx[s->histype];
+ } else if (s->hiscnt == 0 && hisidx[s->histype] != hislen - 1) {
+ s->hiscnt = hislen - 1;
+ } else if (s->hiscnt != hisidx[s->histype] + 1) {
+ s->hiscnt--;
+ } else {
+ // at top of list
+ s->hiscnt = s->i;
+ break;
+ }
+ } else { // one step forwards
+ // on last entry, clear the line
+ if (s->hiscnt == hisidx[s->histype]) {
+ s->hiscnt = hislen;
+ break;
+ }
+
+ // not on a history line, nothing to do
+ if (s->hiscnt == hislen) {
+ break;
+ }
+
+ if (s->hiscnt == hislen - 1) {
+ // wrap around
+ s->hiscnt = 0;
+ } else {
+ s->hiscnt++;
+ }
+ }
+
+ if (s->hiscnt < 0 || history[s->histype][s->hiscnt].hisstr == NULL) {
+ s->hiscnt = s->i;
+ break;
+ }
+
+ if ((s->c != K_UP && s->c != K_DOWN)
+ || s->hiscnt == s->i
+ || STRNCMP(history[s->histype][s->hiscnt].hisstr,
+ s->lookfor, (size_t)s->j) == 0) {
+ break;
+ }
+ }
+}
+
static int command_line_handle_key(CommandLineState *s)
{
// Big switch for a typed command line character.
@@ -925,6 +1114,16 @@ static int command_line_handle_key(CommandLineState *s)
// Truncate at the end, required for multi-byte chars.
ccline.cmdbuff[ccline.cmdlen] = NUL;
+ if (ccline.cmdlen == 0) {
+ s->search_start = s->save_cursor;
+ // save view settings, so that the screen won't be restored at the
+ // wrong position
+ s->old_curswant = s->init_curswant;
+ s->old_leftcol = s->init_leftcol;
+ s->old_topline = s->init_topline;
+ s->old_topfill = s->init_topfill;
+ s->old_botline = s->init_botline;
+ }
redrawcmd();
} else if (ccline.cmdlen == 0 && s->c != Ctrl_W
&& ccline.cmdprompt == NULL && s->indent == 0) {
@@ -943,6 +1142,7 @@ static int command_line_handle_key(CommandLineState *s)
}
msg_putchar(' '); // delete ':'
}
+ s->search_start = s->save_cursor;
redraw_cmdline = true;
return 0; // back to cmd mode
}
@@ -962,7 +1162,7 @@ static int command_line_handle_key(CommandLineState *s)
return command_line_not_changed(s);
case Ctrl_HAT:
- if (map_to_exists_mode((char_u *)"", LANGMAP, false)) {
+ if (map_to_exists_mode("", LANGMAP, false)) {
// ":lmap" mappings exists, toggle use of mappings.
State ^= LANGMAP;
if (s->b_im_ptr != NULL) {
@@ -997,14 +1197,20 @@ static int command_line_handle_key(CommandLineState *s)
// Truncate at the end, required for multi-byte chars.
ccline.cmdbuff[ccline.cmdlen] = NUL;
+ if (ccline.cmdlen == 0) {
+ s->search_start = s->save_cursor;
+ }
redrawcmd();
return command_line_changed(s);
case ESC: // get here if p_wc != ESC or when ESC typed twice
case Ctrl_C:
// In exmode it doesn't make sense to return. Except when
- // ":normal" runs out of characters.
- if (exmode_active && (ex_normal_busy == 0 || typebuf.tb_len > 0)) {
+ // ":normal" runs out of characters. Also when highlight callback is active
+ // <C-c> should interrupt only it.
+ if ((exmode_active && (ex_normal_busy == 0 || typebuf.tb_len > 0))
+ || (getln_interrupted_highlight && s->c == Ctrl_C)) {
+ getln_interrupted_highlight = false;
return command_line_not_changed(s);
}
@@ -1067,6 +1273,7 @@ static int command_line_handle_key(CommandLineState *s)
break; // Use ^D as normal char instead
}
+ wild_menu_showing = WM_LIST;
redrawcmd();
return 1; // don't do incremental search now
@@ -1226,24 +1433,27 @@ static int command_line_handle_key(CommandLineState *s)
case Ctrl_L:
if (p_is && !cmd_silent && (s->firstc == '/' || s->firstc == '?')) {
// Add a character from under the cursor for 'incsearch'
- if (s->did_incsearch && !equalpos(curwin->w_cursor, s->old_cursor)) {
- s->c = gchar_cursor();
- // If 'ignorecase' and 'smartcase' are set and the
- // command line has no uppercase characters, convert
- // the character to lowercase
- if (p_ic && p_scs && !pat_has_uppercase(ccline.cmdbuff)) {
- s->c = vim_tolower(s->c);
- }
-
- if (s->c != NUL) {
- if (s->c == s->firstc
- || vim_strchr((char_u *)(p_magic ? "\\^$.*[" : "\\^$"), s->c)
- != NULL) {
- // put a backslash before special characters
- stuffcharReadbuff(s->c);
- s->c = '\\';
+ if (s->did_incsearch) {
+ curwin->w_cursor = s->match_end;
+ if (!equalpos(curwin->w_cursor, s->search_start)) {
+ s->c = gchar_cursor();
+ // If 'ignorecase' and 'smartcase' are set and the
+ // command line has no uppercase characters, convert
+ // the character to lowercase
+ if (p_ic && p_scs
+ && !pat_has_uppercase(ccline.cmdbuff)) {
+ s->c = mb_tolower(s->c);
+ }
+ if (s->c != NUL) {
+ if (s->c == s->firstc
+ || vim_strchr((char_u *)(p_magic ? "\\^$.*[" : "\\^$"), s->c)
+ != NULL) {
+ // put a backslash before special characters
+ stuffcharReadbuff(s->c);
+ s->c = '\\';
+ }
+ break;
}
- break;
}
}
return command_line_not_changed(s);
@@ -1262,8 +1472,9 @@ static int command_line_handle_key(CommandLineState *s)
0, s->firstc != '@') == FAIL) {
break;
}
- return command_line_changed(s);
+ return command_line_not_changed(s);
}
+ // fallthrough
case K_UP:
case K_DOWN:
@@ -1286,60 +1497,14 @@ static int command_line_handle_key(CommandLineState *s)
s->lookfor[ccline.cmdpos] = NUL;
}
- s->j = (int)STRLEN(s->lookfor);
- for (;; ) {
- // one step backwards
- if (s->c == K_UP|| s->c == K_S_UP || s->c == Ctrl_P
- || s->c == K_PAGEUP || s->c == K_KPAGEUP) {
- if (s->hiscnt == hislen) {
- // first time
- s->hiscnt = hisidx[s->histype];
- } else if (s->hiscnt == 0 && hisidx[s->histype] != hislen - 1) {
- s->hiscnt = hislen - 1;
- } else if (s->hiscnt != hisidx[s->histype] + 1) {
- --s->hiscnt;
- } else {
- // at top of list
- s->hiscnt = s->i;
- break;
- }
- } else { // one step forwards
- // on last entry, clear the line
- if (s->hiscnt == hisidx[s->histype]) {
- s->hiscnt = hislen;
- break;
- }
-
- // not on a history line, nothing to do
- if (s->hiscnt == hislen) {
- break;
- }
-
- if (s->hiscnt == hislen - 1) {
- // wrap around
- s->hiscnt = 0;
- } else {
- ++s->hiscnt;
- }
- }
-
- if (s->hiscnt < 0 || history[s->histype][s->hiscnt].hisstr == NULL) {
- s->hiscnt = s->i;
- break;
- }
-
- if ((s->c != K_UP && s->c != K_DOWN)
- || s->hiscnt == s->i
- || STRNCMP(history[s->histype][s->hiscnt].hisstr,
- s->lookfor, (size_t)s->j) == 0) {
- break;
- }
- }
+ bool next_match = (s->c == K_DOWN || s->c == K_S_DOWN || s->c == Ctrl_N
+ || s->c == K_PAGEDOWN || s->c == K_KPAGEDOWN);
+ command_line_next_histidx(s, next_match);
if (s->hiscnt != s->i) {
// jumped to other entry
char_u *p;
- int len;
+ int len = 0;
int old_firstc;
xfree(ccline.cmdbuff);
@@ -1402,6 +1567,17 @@ static int command_line_handle_key(CommandLineState *s)
beep_flush();
return command_line_not_changed(s);
+ case Ctrl_G: // next match
+ case Ctrl_T: // previous match
+ if (p_is && !cmd_silent && (s->firstc == '/' || s->firstc == '?')) {
+ if (char_avail()) {
+ return 1;
+ }
+ command_line_next_incsearch(s, s->c == Ctrl_G);
+ return command_line_not_changed(s);
+ }
+ break;
+
case Ctrl_V:
case Ctrl_Q:
s->ignore_drag_release = true;
@@ -1516,7 +1692,7 @@ static int command_line_changed(CommandLineState *s)
return 1;
}
s->incsearch_postponed = false;
- curwin->w_cursor = s->old_cursor; // start at old position
+ curwin->w_cursor = s->search_start; // start at old position
// If there is no command line, don't do anything
if (ccline.cmdlen == 0) {
@@ -1561,16 +1737,11 @@ static int command_line_changed(CommandLineState *s)
if (s->i != 0) {
pos_T save_pos = curwin->w_cursor;
- // First move cursor to end of match, then to the start. This
- // moves the whole match onto the screen when 'nowrap' is set.
- curwin->w_cursor.lnum += search_match_lines;
- curwin->w_cursor.col = search_match_endcol;
- if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
- curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
- coladvance((colnr_T)MAXCOL);
- }
+ s->match_start = curwin->w_cursor;
+ set_search_match(&curwin->w_cursor);
validate_cursor();
end_pos = curwin->w_cursor;
+ s->match_end = end_pos;
curwin->w_cursor = save_pos;
} else {
end_pos = curwin->w_cursor; // shutup gcc 4
@@ -1607,10 +1778,12 @@ static int command_line_changed(CommandLineState *s)
// - Update the screen while the effects are in place.
// - Immediately undo the effects.
State |= CMDPREVIEW;
+ emsg_silent++; // Block error reporting as the command may be incomplete
do_cmdline(ccline.cmdbuff, NULL, NULL, DOCMD_KEEPLINE|DOCMD_NOWAIT);
+ emsg_silent--; // Unblock error reporting
// Restore the window "view".
- curwin->w_cursor = s->old_cursor;
+ curwin->w_cursor = s->save_cursor;
curwin->w_curswant = s->old_curswant;
curwin->w_leftcol = s->old_leftcol;
curwin->w_topline = s->old_topline;
@@ -1666,41 +1839,50 @@ getcmdline (
return command_line_enter(firstc, count, indent);
}
-/*
- * Get a command line with a prompt.
- * This is prepared to be called recursively from getcmdline() (e.g. by
- * f_input() when evaluating an expression from CTRL-R =).
- * Returns the command line in allocated memory, or NULL.
- */
-char_u *
-getcmdline_prompt (
- int firstc,
- char_u *prompt, /* command line prompt */
- int attr, /* attributes for prompt */
- int xp_context, /* type of expansion */
- char_u *xp_arg /* user-defined expansion argument */
-)
+/// Get a command line with a prompt
+///
+/// This is prepared to be called recursively from getcmdline() (e.g. by
+/// f_input() when evaluating an expression from `<C-r>=`).
+///
+/// @param[in] firstc Prompt type: e.g. '@' for input(), '>' for debug.
+/// @param[in] prompt Prompt string: what is displayed before the user text.
+/// @param[in] attr Prompt highlighting.
+/// @param[in] xp_context Type of expansion.
+/// @param[in] xp_arg User-defined expansion argument.
+/// @param[in] highlight_callback Callback used for highlighting user input.
+///
+/// @return [allocated] Command line or NULL.
+char *getcmdline_prompt(const char firstc, const char *const prompt,
+ const int attr, const int xp_context,
+ const char *const xp_arg,
+ const Callback highlight_callback)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
{
- char_u *s;
- struct cmdline_info save_ccline;
- int msg_col_save = msg_col;
+ const int msg_col_save = msg_col;
+ struct cmdline_info save_ccline;
save_cmdline(&save_ccline);
- ccline.cmdprompt = prompt;
+
+ ccline.prompt_id = last_prompt_id++;
+ ccline.cmdprompt = (char_u *)prompt;
ccline.cmdattr = attr;
ccline.xp_context = xp_context;
- ccline.xp_arg = xp_arg;
+ ccline.xp_arg = (char_u *)xp_arg;
ccline.input_fn = (firstc == '@');
- s = getcmdline(firstc, 1L, 0);
+ ccline.highlight_callback = highlight_callback;
+
+ char *const ret = (char *)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)
+ // Restore msg_col, the prompt from input() may have changed it.
+ // But only if called recursively and the commandline is therefore being
+ // restored to an old one; if not, the input() prompt stays on the screen,
+ // so we need its modified msg_col left intact.
+ if (ccline.cmdbuff != NULL) {
msg_col = msg_col_save;
+ }
- return s;
+ return ret;
}
/*
@@ -1877,7 +2059,7 @@ getexmodeline (
vcol = indent;
while (indent >= 8) {
ga_append(&line_ga, TAB);
- msg_puts((char_u *)" ");
+ msg_puts(" ");
indent -= 8;
}
while (indent-- > 0) {
@@ -1885,8 +2067,7 @@ getexmodeline (
msg_putchar(' ');
}
}
- ++no_mapping;
- ++allow_keys;
+ no_mapping++;
/*
* Get the line, one character at a time.
@@ -2076,8 +2257,7 @@ redraw:
}
}
- --no_mapping;
- --allow_keys;
+ no_mapping--;
/* make following messages go to the next line */
msg_didout = FALSE;
@@ -2092,6 +2272,18 @@ redraw:
return (char_u *)line_ga.ga_data;
}
+bool cmdline_overstrike(void)
+{
+ return ccline.overstrike;
+}
+
+
+/// Return true if the cursor is at the end of the cmdline.
+bool cmdline_at_end(void)
+{
+ return (ccline.cmdpos >= ccline.cmdlen);
+}
+
/*
* Allocate a new command line buffer.
* Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
@@ -2151,75 +2343,329 @@ void free_cmdline_buf(void)
# endif
+enum { MAX_CB_ERRORS = 1 };
+
+/// Color command-line
+///
+/// Should use built-in command parser or user-specified one. Currently only the
+/// latter is supported.
+///
+/// @param[in] colored_ccline Command-line to color.
+/// @param[out] ret_ccline_colors What should be colored. Also holds a cache:
+/// if ->prompt_id and ->cmdbuff values happen
+/// to be equal to those from colored_cmdline it
+/// will just do nothing, assuming that ->colors
+/// already contains needed data.
+///
+/// Always colors the whole cmdline.
+///
+/// @return true if draw_cmdline may proceed, false if it does not need anything
+/// to do.
+static bool color_cmdline(const CmdlineInfo *const colored_ccline,
+ ColoredCmdline *const ret_ccline_colors)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ bool printed_errmsg = false;
+#define PRINT_ERRMSG(...) \
+ do { \
+ msg_putchar('\n'); \
+ msg_printf_attr(hl_attr(HLF_E)|MSG_HIST, __VA_ARGS__); \
+ printed_errmsg = true; \
+ } while (0)
+ bool ret = true;
+
+ // Check whether result of the previous call is still valid.
+ if (ret_ccline_colors->prompt_id == colored_ccline->prompt_id
+ && ret_ccline_colors->cmdbuff != NULL
+ && STRCMP(ret_ccline_colors->cmdbuff, colored_ccline->cmdbuff) == 0) {
+ return ret;
+ }
+
+ kv_size(ret_ccline_colors->colors) = 0;
+
+ if (colored_ccline->cmdbuff == NULL || *colored_ccline->cmdbuff == NUL) {
+ // Nothing to do, exiting.
+ xfree(ret_ccline_colors->cmdbuff);
+ ret_ccline_colors->cmdbuff = NULL;
+ return ret;
+ }
+
+ bool arg_allocated = false;
+ typval_T arg = {
+ .v_type = VAR_STRING,
+ .vval.v_string = colored_ccline->cmdbuff,
+ };
+ typval_T tv = { .v_type = VAR_UNKNOWN };
+
+ static unsigned prev_prompt_id = UINT_MAX;
+ static int prev_prompt_errors = 0;
+ Callback color_cb = { .type = kCallbackNone };
+ bool can_free_cb = false;
+ TryState tstate;
+ Error err = ERROR_INIT;
+ const char *err_errmsg = (const char *)e_intern2;
+ bool dgc_ret = true;
+ bool tl_ret = true;
+
+ if (colored_ccline->prompt_id != prev_prompt_id) {
+ prev_prompt_errors = 0;
+ prev_prompt_id = colored_ccline->prompt_id;
+ } else if (prev_prompt_errors >= MAX_CB_ERRORS) {
+ goto color_cmdline_end;
+ }
+ if (colored_ccline->highlight_callback.type != kCallbackNone) {
+ // Currently this should only happen while processing input() prompts.
+ assert(colored_ccline->input_fn);
+ color_cb = colored_ccline->highlight_callback;
+ } else if (colored_ccline->cmdfirstc == ':') {
+ try_enter(&tstate);
+ err_errmsg = N_(
+ "E5408: Unable to get g:Nvim_color_cmdline callback: %s");
+ dgc_ret = tv_dict_get_callback(&globvardict, S_LEN("Nvim_color_cmdline"),
+ &color_cb);
+ tl_ret = try_leave(&tstate, &err);
+ can_free_cb = true;
+ } else if (colored_ccline->cmdfirstc == '=') {
+ try_enter(&tstate);
+ err_errmsg = N_(
+ "E5409: Unable to get g:Nvim_color_expr callback: %s");
+ dgc_ret = tv_dict_get_callback(&globvardict, S_LEN("Nvim_color_expr"),
+ &color_cb);
+ tl_ret = try_leave(&tstate, &err);
+ can_free_cb = true;
+ }
+ if (!tl_ret || !dgc_ret) {
+ goto color_cmdline_error;
+ }
+
+ if (color_cb.type == kCallbackNone) {
+ goto color_cmdline_end;
+ }
+ if (colored_ccline->cmdbuff[colored_ccline->cmdlen] != NUL) {
+ arg_allocated = true;
+ arg.vval.v_string = xmemdupz((const char *)colored_ccline->cmdbuff,
+ (size_t)colored_ccline->cmdlen);
+ }
+ // msg_start() called by e.g. :echo may shift command-line to the first column
+ // even though msg_silent is here. Two ways to workaround this problem without
+ // altering message.c: use full_screen or save and restore msg_col.
+ //
+ // Saving and restoring full_screen does not work well with :redraw!. Saving
+ // and restoring msg_col is neither ideal, but while with full_screen it
+ // appears shifted one character to the right and cursor position is no longer
+ // correct, with msg_col it just misses leading `:`. Since `redraw!` in
+ // callback lags this is least of the user problems.
+ //
+ // Also using try_enter() because error messages may overwrite typed
+ // command-line which is not expected.
+ getln_interrupted_highlight = false;
+ try_enter(&tstate);
+ err_errmsg = N_("E5407: Callback has thrown an exception: %s");
+ const int saved_msg_col = msg_col;
+ msg_silent++;
+ const bool cbcall_ret = callback_call(&color_cb, 1, &arg, &tv);
+ msg_silent--;
+ msg_col = saved_msg_col;
+ if (got_int) {
+ getln_interrupted_highlight = true;
+ }
+ if (!try_leave(&tstate, &err) || !cbcall_ret) {
+ goto color_cmdline_error;
+ }
+ if (tv.v_type != VAR_LIST) {
+ PRINT_ERRMSG(_("E5400: Callback should return list"));
+ goto color_cmdline_error;
+ }
+ if (tv.vval.v_list == NULL) {
+ goto color_cmdline_end;
+ }
+ varnumber_T prev_end = 0;
+ int i = 0;
+ for (const listitem_T *li = tv.vval.v_list->lv_first;
+ li != NULL; li = li->li_next, i++) {
+ if (li->li_tv.v_type != VAR_LIST) {
+ PRINT_ERRMSG(_("E5401: List item %i is not a List"), i);
+ goto color_cmdline_error;
+ }
+ const list_T *const l = li->li_tv.vval.v_list;
+ if (tv_list_len(l) != 3) {
+ PRINT_ERRMSG(_("E5402: List item %i has incorrect length: %li /= 3"),
+ i, tv_list_len(l));
+ goto color_cmdline_error;
+ }
+ bool error = false;
+ const varnumber_T start = tv_get_number_chk(&l->lv_first->li_tv, &error);
+ if (error) {
+ goto color_cmdline_error;
+ } else if (!(prev_end <= start && start < colored_ccline->cmdlen)) {
+ PRINT_ERRMSG(_("E5403: Chunk %i start %" PRIdVARNUMBER " not in range "
+ "[%" PRIdVARNUMBER ", %i)"),
+ i, start, prev_end, colored_ccline->cmdlen);
+ goto color_cmdline_error;
+ } else if (utf8len_tab_zero[(uint8_t)colored_ccline->cmdbuff[start]] == 0) {
+ PRINT_ERRMSG(_("E5405: Chunk %i start %" PRIdVARNUMBER " splits "
+ "multibyte character"), i, start);
+ goto color_cmdline_error;
+ }
+ if (start != prev_end) {
+ kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) {
+ .start = prev_end,
+ .end = start,
+ .attr = 0,
+ }));
+ }
+ const varnumber_T end = tv_get_number_chk(&l->lv_first->li_next->li_tv,
+ &error);
+ if (error) {
+ goto color_cmdline_error;
+ } else if (!(start < end && end <= colored_ccline->cmdlen)) {
+ PRINT_ERRMSG(_("E5404: Chunk %i end %" PRIdVARNUMBER " not in range "
+ "(%" PRIdVARNUMBER ", %i]"),
+ i, end, start, colored_ccline->cmdlen);
+ goto color_cmdline_error;
+ } else if (end < colored_ccline->cmdlen
+ && (utf8len_tab_zero[(uint8_t)colored_ccline->cmdbuff[end]]
+ == 0)) {
+ PRINT_ERRMSG(_("E5406: Chunk %i end %" PRIdVARNUMBER " splits multibyte "
+ "character"), i, end);
+ goto color_cmdline_error;
+ }
+ prev_end = end;
+ const char *const group = tv_get_string_chk(&l->lv_last->li_tv);
+ if (group == NULL) {
+ goto color_cmdline_error;
+ }
+ const int id = syn_name2id((char_u *)group);
+ const int attr = (id == 0 ? 0 : syn_id2attr(id));
+ kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) {
+ .start = start,
+ .end = end,
+ .attr = attr,
+ }));
+ }
+ if (prev_end < colored_ccline->cmdlen) {
+ kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) {
+ .start = prev_end,
+ .end = colored_ccline->cmdlen,
+ .attr = 0,
+ }));
+ }
+ prev_prompt_errors = 0;
+color_cmdline_end:
+ assert(!ERROR_SET(&err));
+ if (can_free_cb) {
+ callback_free(&color_cb);
+ }
+ xfree(ret_ccline_colors->cmdbuff);
+ // Note: errors “output†is cached just as well as regular results.
+ ret_ccline_colors->prompt_id = colored_ccline->prompt_id;
+ if (arg_allocated) {
+ ret_ccline_colors->cmdbuff = (char *)arg.vval.v_string;
+ } else {
+ ret_ccline_colors->cmdbuff = xmemdupz((const char *)colored_ccline->cmdbuff,
+ (size_t)colored_ccline->cmdlen);
+ }
+ tv_clear(&tv);
+ return ret;
+color_cmdline_error:
+ if (ERROR_SET(&err)) {
+ PRINT_ERRMSG(_(err_errmsg), err.msg);
+ api_clear_error(&err);
+ }
+ assert(printed_errmsg);
+ (void)printed_errmsg;
+
+ prev_prompt_errors++;
+ kv_size(ret_ccline_colors->colors) = 0;
+ redrawcmdline();
+ ret = false;
+ goto color_cmdline_end;
+#undef PRINT_ERRMSG
+}
+
/*
* Draw part of the cmdline at the current cursor position. But draw stars
* when cmdline_star is TRUE.
*/
static void draw_cmdline(int start, int len)
{
- int i;
+ if (!color_cmdline(&ccline, &last_ccline_colors)) {
+ return;
+ }
- if (cmdline_star > 0)
- for (i = 0; i < len; ++i) {
+ if (cmdline_star > 0) {
+ for (int i = 0; i < len; i++) {
msg_putchar('*');
- if (has_mbyte)
+ if (has_mbyte) {
i += (*mb_ptr2len)(ccline.cmdbuff + start + i) - 1;
+ }
}
- else if (p_arshape && !p_tbidi && enc_utf8 && len > 0) {
- static int buflen = 0;
- char_u *p;
- int j;
- int newlen = 0;
+ } else if (p_arshape && !p_tbidi && enc_utf8 && len > 0) {
+ bool do_arabicshape = false;
int mb_l;
- int pc, pc1 = 0;
- int prev_c = 0;
- int prev_c1 = 0;
- int u8c;
- int u8cc[MAX_MCO];
- int nc = 0;
+ for (int i = start; i < start + len; i += mb_l) {
+ char_u *p = ccline.cmdbuff + i;
+ int u8cc[MAX_MCO];
+ int u8c = utfc_ptr2char_len(p, u8cc, start + len - i);
+ mb_l = utfc_ptr2len_len(p, start + len - i);
+ if (arabic_char(u8c)) {
+ do_arabicshape = true;
+ break;
+ }
+ }
+ if (!do_arabicshape) {
+ goto draw_cmdline_no_arabicshape;
+ }
- /*
- * Do arabic shaping into a temporary buffer. This is very
- * inefficient!
- */
+ static int buflen = 0;
+
+ // Do arabic shaping into a temporary buffer. This is very
+ // inefficient!
if (len * 2 + 2 > buflen) {
- /* Re-allocate the buffer. We keep it around to avoid a lot of
- * alloc()/free() calls. */
+ // Re-allocate the buffer. We keep it around to avoid a lot of
+ // alloc()/free() calls.
xfree(arshape_buf);
buflen = len * 2 + 2;
arshape_buf = xmalloc(buflen);
}
+ int newlen = 0;
if (utf_iscomposing(utf_ptr2char(ccline.cmdbuff + start))) {
- /* Prepend a space to draw the leading composing char on. */
+ // Prepend a space to draw the leading composing char on.
arshape_buf[0] = ' ';
newlen = 1;
}
- for (j = start; j < start + len; j += mb_l) {
- p = ccline.cmdbuff + j;
- u8c = utfc_ptr2char_len(p, u8cc, start + len - j);
- mb_l = utfc_ptr2len_len(p, start + len - j);
+ int prev_c = 0;
+ int prev_c1 = 0;
+ for (int i = start; i < start + len; i += mb_l) {
+ char_u *p = ccline.cmdbuff + i;
+ int u8cc[MAX_MCO];
+ int u8c = utfc_ptr2char_len(p, u8cc, start + len - i);
+ mb_l = utfc_ptr2len_len(p, start + len - i);
if (arabic_char(u8c)) {
- /* Do Arabic shaping. */
+ int pc;
+ int pc1 = 0;
+ int nc = 0;
+ // Do Arabic shaping.
if (cmdmsg_rl) {
- /* displaying from right to left */
+ // Displaying from right to left.
pc = prev_c;
pc1 = prev_c1;
prev_c1 = u8cc[0];
- if (j + mb_l >= start + len)
+ if (i + mb_l >= start + len) {
nc = NUL;
- else
+ } else {
nc = utf_ptr2char(p + mb_l);
+ }
} else {
- /* displaying from left to right */
- if (j + mb_l >= start + len)
+ // Displaying from left to right.
+ if (i + mb_l >= start + len) {
pc = NUL;
- else {
+ } else {
int pcc[MAX_MCO];
- pc = utfc_ptr2char_len(p + mb_l, pcc,
- start + len - j - mb_l);
+ pc = utfc_ptr2char_len(p + mb_l, pcc, start + len - i - mb_l);
pc1 = pcc[0];
}
nc = prev_c;
@@ -2243,8 +2689,23 @@ static void draw_cmdline(int start, int len)
}
msg_outtrans_len(arshape_buf, newlen);
- } else
- msg_outtrans_len(ccline.cmdbuff + start, len);
+ } else {
+draw_cmdline_no_arabicshape:
+ if (kv_size(last_ccline_colors.colors)) {
+ for (size_t i = 0; i < kv_size(last_ccline_colors.colors); i++) {
+ CmdlineColorChunk chunk = kv_A(last_ccline_colors.colors, i);
+ if (chunk.end <= start) {
+ continue;
+ }
+ const int chunk_start = MAX(chunk.start, start);
+ msg_outtrans_len_attr(ccline.cmdbuff + chunk_start,
+ chunk.end - chunk_start,
+ chunk.attr);
+ }
+ } else {
+ msg_outtrans_len(ccline.cmdbuff + start, len);
+ }
+ }
}
/*
@@ -2262,6 +2723,7 @@ void putcmdline(int c, int shift)
draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
msg_no_more = FALSE;
cursorcmd();
+ ui_cursor_shape();
}
/*
@@ -2281,6 +2743,7 @@ void unputcmdline(void)
draw_cmdline(ccline.cmdpos, 1);
msg_no_more = FALSE;
cursorcmd();
+ ui_cursor_shape();
}
/*
@@ -2555,19 +3018,22 @@ void cmdline_paste_str(char_u *s, int literally)
else
while (*s != NUL) {
cv = *s;
- if (cv == Ctrl_V && s[1])
- ++s;
- if (has_mbyte)
- c = mb_cptr2char_adv(&s);
- else
+ if (cv == Ctrl_V && s[1]) {
+ s++;
+ }
+ if (has_mbyte) {
+ c = mb_cptr2char_adv((const char_u **)&s);
+ } else {
c = *s++;
+ }
if (cv == Ctrl_V || c == ESC || c == Ctrl_C
|| c == CAR || c == NL || c == Ctrl_L
#ifdef UNIX
|| c == intr_char
#endif
- || (c == Ctrl_BSL && *s == Ctrl_N))
+ || (c == Ctrl_BSL && *s == Ctrl_N)) {
stuffcharReadbuff(Ctrl_V);
+ }
stuffcharReadbuff(c);
}
}
@@ -2595,6 +3061,7 @@ void redrawcmdline(void)
compute_cmdrow();
redrawcmd();
cursorcmd();
+ ui_cursor_shape();
}
static void redrawcmdprompt(void)
@@ -2606,7 +3073,7 @@ static void redrawcmdprompt(void)
if (ccline.cmdfirstc != NUL)
msg_putchar(ccline.cmdfirstc);
if (ccline.cmdprompt != NULL) {
- msg_puts_attr(ccline.cmdprompt, ccline.cmdattr);
+ msg_puts_attr((const char *)ccline.cmdprompt, ccline.cmdattr);
ccline.cmdindent = msg_col + (msg_row - cmdline_row) * Columns;
/* do the reverse of set_cmdspos() */
if (ccline.cmdfirstc != NUL)
@@ -3016,7 +3483,7 @@ ExpandOne (
|| xp->xp_context == EXPAND_FILES
|| xp->xp_context == EXPAND_SHELLCMD
|| xp->xp_context == EXPAND_BUFFERS)) {
- if (vim_tolower(c0) != vim_tolower(ci)) {
+ if (mb_tolower(c0) != mb_tolower(ci)) {
break;
}
} else if (c0 != ci) {
@@ -3122,9 +3589,10 @@ void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int o
#endif
}
#ifdef BACKSLASH_IN_FILENAME
- p = vim_strsave_fnameescape(files[i], FALSE);
+ p = (char_u *)vim_strsave_fnameescape((const char *)files[i], false);
#else
- p = vim_strsave_fnameescape(files[i], xp->xp_shell);
+ p = (char_u *)vim_strsave_fnameescape((const char *)files[i],
+ xp->xp_shell);
#endif
xfree(files[i]);
files[i] = p;
@@ -3154,42 +3622,49 @@ void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int o
}
}
-/*
- * Escape special characters in "fname" for when used as a file name argument
- * after a Vim command, or, when "shell" is non-zero, a shell command.
- * Returns the result in allocated memory.
- */
-char_u *vim_strsave_fnameescape(char_u *fname, int shell) FUNC_ATTR_NONNULL_RET
+/// Escape special characters in a file name for use as a command argument
+///
+/// @param[in] fname File name to escape.
+/// @param[in] shell What to escape for: if false, escapes for VimL command,
+/// if true then it escapes for a shell command.
+///
+/// @return [allocated] escaped file name.
+char *vim_strsave_fnameescape(const char *const fname, const bool shell)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
- char_u *p;
#ifdef BACKSLASH_IN_FILENAME
-#define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`%#'\"|!<")
- char_u buf[20];
+#define PATH_ESC_CHARS " \t\n*?[{`%#'\"|!<"
+ char_u buf[sizeof(PATH_ESC_CHARS)];
int j = 0;
- /* Don't escape '[', '{' and '!' if they are in 'isfname'. */
- for (p = PATH_ESC_CHARS; *p != NUL; ++p)
- if ((*p != '[' && *p != '{' && *p != '!') || !vim_isfilec(*p))
- buf[j++] = *p;
+ // Don't escape '[', '{' and '!' if they are in 'isfname'.
+ for (const char *s = PATH_ESC_CHARS; *s != NUL; s++) {
+ if ((*s != '[' && *s != '{' && *s != '!') || !vim_isfilec(*s)) {
+ buf[j++] = *s;
+ }
+ }
buf[j] = NUL;
- p = vim_strsave_escaped(fname, buf);
+ char *p = (char *)vim_strsave_escaped((const char_u *)fname,
+ (const char_u *)buf);
#else
#define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<")
#define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&")
- p = vim_strsave_escaped(fname, shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS);
+ char *p = (char *)vim_strsave_escaped(
+ (const char_u *)fname, (shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS));
if (shell && csh_like_shell()) {
- /* For csh and similar shells need to put two backslashes before '!'.
- * One is taken by Vim, one by the shell. */
- char_u *s = vim_strsave_escaped(p, (char_u *)"!");
+ // For csh and similar shells need to put two backslashes before '!'.
+ // One is taken by Vim, one by the shell.
+ char *s = (char *)vim_strsave_escaped((const char_u *)p,
+ (const char_u *)"!");
xfree(p);
p = s;
}
#endif
- /* '>' and '+' are special at the start of some commands, e.g. ":edit" and
- * ":write". "cd -" has a special meaning. */
+ // '>' and '+' are special at the start of some commands, e.g. ":edit" and
+ // ":write". "cd -" has a special meaning.
if (*p == '>' || *p == '+' || (*p == '-' && p[1] == NUL)) {
- escape_fname(&p);
+ escape_fname((char_u **)&p);
}
return p;
@@ -3315,7 +3790,7 @@ static int showmatches(expand_T *xp, int wildmenu)
msg_outtrans_attr(files_found[k], hl_attr(HLF_D));
p = files_found[k] + STRLEN(files_found[k]) + 1;
msg_advance(maxlen + 1);
- msg_puts(p);
+ msg_puts((const char *)p);
msg_advance(maxlen + 3);
msg_puts_long_attr(p + 2, hl_attr(HLF_D));
break;
@@ -3626,7 +4101,6 @@ set_cmd_context (
)
{
int old_char = NUL;
- char_u *nextcomm;
/*
* Avoid a UMR warning from Purify, only save the character if it has been
@@ -3635,7 +4109,7 @@ set_cmd_context (
if (col < len)
old_char = str[col];
str[col] = NUL;
- nextcomm = str;
+ const char *nextcomm = (const char *)str;
if (use_ccline && ccline.cmdfirstc == '=') {
// pass CMD_SIZE because there is no real command
@@ -3644,9 +4118,11 @@ set_cmd_context (
xp->xp_context = ccline.xp_context;
xp->xp_pattern = ccline.cmdbuff;
xp->xp_arg = ccline.xp_arg;
- } else
- while (nextcomm != NULL)
+ } else {
+ while (nextcomm != NULL) {
nextcomm = set_one_cmd_context(xp, nextcomm);
+ }
+ }
/* Store the string here so that call_user_expand_func() can get to them
* easily. */
@@ -3757,6 +4233,8 @@ static void cleanup_help_tags(int num_file, char_u **file)
}
}
+typedef char_u *(*ExpandFunc)(expand_T *, int);
+
/*
* Do the expansion based on xp->xp_context and "pat".
*/
@@ -3896,39 +4374,39 @@ ExpandFromContext (
else {
static struct expgen {
int context;
- char_u *((*func)(expand_T *, int));
+ ExpandFunc func;
int ic;
int escaped;
- } tab[] =
- {
- {EXPAND_COMMANDS, get_command_name, FALSE, TRUE},
- {EXPAND_BEHAVE, get_behave_arg, TRUE, TRUE},
- {EXPAND_HISTORY, get_history_arg, TRUE, TRUE},
- {EXPAND_USER_COMMANDS, get_user_commands, FALSE, TRUE},
- {EXPAND_USER_ADDR_TYPE, get_user_cmd_addr_type, FALSE, TRUE},
- {EXPAND_USER_CMD_FLAGS, get_user_cmd_flags, FALSE, TRUE},
- {EXPAND_USER_NARGS, get_user_cmd_nargs, FALSE, TRUE},
- {EXPAND_USER_COMPLETE, get_user_cmd_complete, FALSE, TRUE},
- {EXPAND_USER_VARS, get_user_var_name, FALSE, TRUE},
- {EXPAND_FUNCTIONS, get_function_name, FALSE, TRUE},
- {EXPAND_USER_FUNC, get_user_func_name, FALSE, TRUE},
- {EXPAND_EXPRESSION, get_expr_name, FALSE, TRUE},
- {EXPAND_MENUS, get_menu_name, FALSE, TRUE},
- {EXPAND_MENUNAMES, get_menu_names, FALSE, TRUE},
- {EXPAND_SYNTAX, get_syntax_name, TRUE, TRUE},
- {EXPAND_SYNTIME, get_syntime_arg, TRUE, TRUE},
- {EXPAND_HIGHLIGHT, get_highlight_name, TRUE, TRUE},
- {EXPAND_EVENTS, get_event_name, TRUE, TRUE},
- {EXPAND_AUGROUP, get_augroup_name, TRUE, TRUE},
- {EXPAND_CSCOPE, get_cscope_name, TRUE, TRUE},
- {EXPAND_SIGN, get_sign_name, TRUE, TRUE},
- {EXPAND_PROFILE, get_profile_name, TRUE, TRUE},
+ } tab[] = {
+ { EXPAND_COMMANDS, get_command_name, false, true },
+ { EXPAND_BEHAVE, get_behave_arg, true, true },
+ { EXPAND_MESSAGES, get_messages_arg, true, true },
+ { EXPAND_HISTORY, get_history_arg, true, true },
+ { EXPAND_USER_COMMANDS, get_user_commands, false, true },
+ { EXPAND_USER_ADDR_TYPE, get_user_cmd_addr_type, false, true },
+ { EXPAND_USER_CMD_FLAGS, get_user_cmd_flags, false, true },
+ { EXPAND_USER_NARGS, get_user_cmd_nargs, false, true },
+ { EXPAND_USER_COMPLETE, get_user_cmd_complete, false, true },
+ { EXPAND_USER_VARS, get_user_var_name, false, true },
+ { EXPAND_FUNCTIONS, get_function_name, false, true },
+ { EXPAND_USER_FUNC, get_user_func_name, false, true },
+ { EXPAND_EXPRESSION, get_expr_name, false, true },
+ { EXPAND_MENUS, get_menu_name, false, true },
+ { EXPAND_MENUNAMES, get_menu_names, false, true },
+ { EXPAND_SYNTAX, get_syntax_name, true, true },
+ { EXPAND_SYNTIME, get_syntime_arg, true, true },
+ { EXPAND_HIGHLIGHT, (ExpandFunc)get_highlight_name, true, true },
+ { EXPAND_EVENTS, get_event_name, true, true },
+ { EXPAND_AUGROUP, get_augroup_name, true, true },
+ { EXPAND_CSCOPE, get_cscope_name, true, true },
+ { EXPAND_SIGN, get_sign_name, true, true },
+ { EXPAND_PROFILE, get_profile_name, true, true },
#ifdef HAVE_WORKING_LIBINTL
- {EXPAND_LANGUAGE, get_lang_arg, TRUE, FALSE},
- {EXPAND_LOCALES, get_locales, TRUE, FALSE},
+ { EXPAND_LANGUAGE, get_lang_arg, true, false },
+ { EXPAND_LOCALES, get_locales, true, false },
#endif
- {EXPAND_ENV_VARS, get_env_name, TRUE, TRUE},
- {EXPAND_USER, get_users, TRUE, FALSE},
+ { EXPAND_ENV_VARS, get_env_name, true, true },
+ { EXPAND_USER, get_users, true, false },
};
int i;
@@ -4040,7 +4518,7 @@ void ExpandGeneric(
/// @param flagsarg is a combination of EW_* flags.
static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
int flagsarg)
- FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_ALL
{
char_u *pat;
int i;
@@ -4141,10 +4619,8 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
}
}
-/*
- * Call "user_expand_func()" to invoke a user defined VimL function and return
- * the result (either a string or a List).
- */
+/// Call "user_expand_func()" to invoke a user defined Vim script function and
+/// return the result (either a string or a List).
static void * call_user_expand_func(user_expand_func_T user_expand_func,
expand_T *xp, int *num_file, char_u ***file)
{
@@ -4198,9 +4674,11 @@ static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file,
char_u keep;
garray_T ga;
- retstr = call_user_expand_func(call_func_retstr, xp, num_file, file);
- if (retstr == NULL)
+ retstr = call_user_expand_func((user_expand_func_T)call_func_retstr, xp,
+ num_file, file);
+ if (retstr == NULL) {
return FAIL;
+ }
ga_init(&ga, (int)sizeof(char *), 3);
for (s = retstr; *s != NUL; s = e) {
@@ -4238,9 +4716,11 @@ static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file)
listitem_T *li;
garray_T ga;
- retlist = call_user_expand_func(call_func_retlist, xp, num_file, file);
- if (retlist == NULL)
+ retlist = call_user_expand_func((user_expand_func_T)call_func_retlist, xp,
+ num_file, file);
+ if (retlist == NULL) {
return FAIL;
+ }
ga_init(&ga, (int)sizeof(char *), 3);
/* Loop over the items in the list. */
@@ -4250,7 +4730,7 @@ static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file)
GA_APPEND(char_u *, &ga, vim_strsave(li->li_tv.vval.v_string));
}
- list_unref(retlist);
+ tv_list_unref(retlist);
*file = ga.ga_data;
*num_file = ga.ga_len;
@@ -4546,7 +5026,7 @@ static inline void hist_free_entry(histentry_T *hisptr)
FUNC_ATTR_NONNULL_ALL
{
xfree(hisptr->hisstr);
- list_unref(hisptr->additional_elements);
+ tv_list_unref(hisptr->additional_elements);
clear_hist_entry(hisptr);
}
@@ -4602,7 +5082,7 @@ in_history (
history[type][last_i] = history[type][i];
last_i = i;
}
- list_unref(list);
+ tv_list_unref(list);
history[type][i].hisnum = ++hisnum[type];
history[type][i].hisstr = str;
history[type][i].timestamp = os_time();
@@ -4624,7 +5104,7 @@ in_history (
///
/// @return Any value from HistoryType enum, including HIST_INVALID. May not
/// return HIST_DEFAULT unless return_default is true.
-HistoryType get_histtype(const char_u *const name, const size_t len,
+HistoryType get_histtype(const char *const name, const size_t len,
const bool return_default)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -4678,8 +5158,8 @@ add_to_history (
* down, only lines that were added.
*/
if (histype == HIST_SEARCH && in_map) {
- if (maptick == last_maptick) {
- /* Current line is from the same mapping, remove it */
+ if (maptick == last_maptick && hisidx[HIST_SEARCH] >= 0) {
+ // Current line is from the same mapping, remove it
hisptr = &history[HIST_SEARCH][hisidx[HIST_SEARCH]];
hist_free_entry(hisptr);
--hisnum[histype];
@@ -4967,7 +5447,7 @@ int get_list_range(char_u **str, int *num1, int *num2)
{
int len;
int first = false;
- long num;
+ varnumber_T num;
*str = skipwhite(*str);
if (**str == '-' || ascii_isdigit(**str)) { // parse "from" part of range
@@ -5017,7 +5497,7 @@ void ex_history(exarg_T *eap)
while (ASCII_ISALPHA(*end)
|| vim_strchr((char_u *)":=@>/?", *end) != NULL)
end++;
- histype1 = get_histtype(arg, end - arg, false);
+ histype1 = get_histtype((const char *)arg, end - arg, false);
if (histype1 == HIST_INVALID) {
if (STRNICMP(arg, "all", end - arg) == 0) {
histype1 = 0;
@@ -5132,9 +5612,9 @@ int cmd_gchar(int offset)
static int ex_window(void)
{
struct cmdline_info save_ccline;
- buf_T *old_curbuf = curbuf;
+ bufref_T old_curbuf;
+ bufref_T bufref;
win_T *old_curwin = curwin;
- buf_T *bp;
win_T *wp;
int i;
linenr_T lnum;
@@ -5153,6 +5633,8 @@ static int ex_window(void)
return K_IGNORE;
}
+ set_bufref(&old_curbuf, curbuf);
+
/* Save current window sizes. */
win_size_save(&winsizes);
@@ -5172,7 +5654,7 @@ static int ex_window(void)
// Create empty command-line buffer.
buf_open_scratch(0, "[Command Line]");
// Command-line buffer has bufhidden=wipe, unlike a true "scratch" buffer.
- set_option_value((char_u *)"bh", 0L, (char_u *)"wipe", OPT_LOCAL);
+ set_option_value("bh", 0L, "wipe", OPT_LOCAL);
curwin->w_p_rl = cmdmsg_rl;
cmdmsg_rl = false;
curbuf->b_p_ma = true;
@@ -5190,7 +5672,7 @@ static int ex_window(void)
add_map((char_u *)"<buffer> <Tab> <C-X><C-V>", INSERT);
add_map((char_u *)"<buffer> <Tab> a<C-X><C-V>", NORMAL);
}
- set_option_value((char_u *)"ft", 0L, (char_u *)"vim", OPT_LOCAL);
+ set_option_value("ft", 0L, "vim", OPT_LOCAL);
}
/* Reset 'textwidth' after setting 'filetype' (the Vim filetype plugin
@@ -5222,10 +5704,8 @@ static int ex_window(void)
invalidate_botline();
redraw_later(SOME_VALID);
- /* Save the command line info, can be used recursively. */
- save_ccline = ccline;
- ccline.cmdbuff = NULL;
- ccline.cmdprompt = NULL;
+ // Save the command line info, can be used recursively.
+ save_cmdline(&save_ccline);
/* No Ex mode here! */
exmode_active = 0;
@@ -5259,15 +5739,15 @@ static int ex_window(void)
/* Restore KeyTyped in case it is modified by autocommands */
KeyTyped = save_KeyTyped;
- /* Restore the command line info. */
- ccline = save_ccline;
+ // Restore the command line info.
+ restore_cmdline(&save_ccline);
cmdwin_type = 0;
exmode_active = save_exmode;
/* Safety check: The old window or buffer was deleted: It's a bug when
* this happens! */
- if (!win_valid(old_curwin) || !buf_valid(old_curbuf)) {
+ if (!win_valid(old_curwin) || !bufref_valid(&old_curbuf)) {
cmdwin_result = Ctrl_C;
EMSG(_("E199: Active window or buffer deleted"));
} else {
@@ -5276,18 +5756,18 @@ static int ex_window(void)
cmdwin_result = Ctrl_C;
/* Set the new command line from the cmdline buffer. */
xfree(ccline.cmdbuff);
- if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) { /* :qa[!] typed */
- char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!";
+ if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) { // :qa[!] typed
+ const char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!";
if (histtype == HIST_CMD) {
- /* Execute the command directly. */
- ccline.cmdbuff = vim_strsave((char_u *)p);
+ // Execute the command directly.
+ ccline.cmdbuff = (char_u *)xstrdup(p);
cmdwin_result = CAR;
} else {
- /* First need to cancel what we were doing. */
+ // First need to cancel what we were doing.
ccline.cmdbuff = NULL;
stuffcharReadbuff(':');
- stuffReadbuff((char_u *)p);
+ stuffReadbuff(p);
stuffcharReadbuff(CAR);
}
} else if (cmdwin_result == K_XF2) { /* :qa typed */
@@ -5318,14 +5798,15 @@ static int ex_window(void)
// Avoid command-line window first character being concealed
curwin->w_p_cole = 0;
wp = curwin;
- bp = curbuf;
+ set_bufref(&bufref, curbuf);
win_goto(old_curwin);
win_close(wp, TRUE);
- /* win_close() may have already wiped the buffer when 'bh' is
- * set to 'wipe' */
- if (buf_valid(bp))
- close_buffer(NULL, bp, DOBUF_WIPE, FALSE);
+ // win_close() may have already wiped the buffer when 'bh' is
+ // set to 'wipe'.
+ if (bufref_valid(&bufref)) {
+ close_buffer(NULL, bufref.br_buf, DOBUF_WIPE, false);
+ }
/* Restore window sizes. */
win_size_restore(&winsizes);
@@ -5343,47 +5824,61 @@ static int ex_window(void)
return cmdwin_result;
}
-/*
- * Used for commands that either take a simple command string argument, or:
- * cmd << endmarker
- * {script}
- * endmarker
- * Returns a pointer to allocated memory with {script} or NULL.
- */
-char_u *script_get(exarg_T *eap, char_u *cmd)
+/// Get script string
+///
+/// Used for commands which accept either `:command script` or
+///
+/// :command << endmarker
+/// script
+/// endmarker
+///
+/// @param eap Command being run.
+/// @param[out] lenp Location where length of resulting string is saved. Will
+/// be set to zero when skipping.
+///
+/// @return [allocated] NULL or script. Does not show any error messages.
+/// NULL is returned when skipping and on error.
+char *script_get(exarg_T *const eap, size_t *const lenp)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
{
- char_u *theline;
- char *end_pattern = NULL;
- char dot[] = ".";
- garray_T ga;
-
- if (cmd[0] != '<' || cmd[1] != '<' || eap->getline == NULL)
- return NULL;
+ const char *const cmd = (const char *)eap->arg;
- ga_init(&ga, 1, 0x400);
+ if (cmd[0] != '<' || cmd[1] != '<' || eap->getline == NULL) {
+ *lenp = STRLEN(eap->arg);
+ return eap->skip ? NULL : xmemdupz(eap->arg, *lenp);
+ }
- if (cmd[2] != NUL)
- end_pattern = (char *)skipwhite(cmd + 2);
- else
- end_pattern = dot;
+ garray_T ga = { .ga_data = NULL, .ga_len = 0 };
+ if (!eap->skip) {
+ ga_init(&ga, 1, 0x400);
+ }
- for (;; ) {
- theline = eap->getline(
+ const char *const end_pattern = (
+ cmd[2] != NUL
+ ? (const char *)skipwhite((const char_u *)cmd + 2)
+ : ".");
+ for (;;) {
+ char *const theline = (char *)eap->getline(
eap->cstack->cs_looplevel > 0 ? -1 :
NUL, eap->cookie, 0);
- if (theline == NULL || STRCMP(end_pattern, theline) == 0) {
+ if (theline == NULL || strcmp(end_pattern, theline) == 0) {
xfree(theline);
break;
}
- ga_concat(&ga, theline);
- ga_append(&ga, '\n');
+ if (!eap->skip) {
+ ga_concat(&ga, (const char_u *)theline);
+ ga_append(&ga, '\n');
+ }
xfree(theline);
}
- ga_append(&ga, NUL);
+ *lenp = (size_t)ga.ga_len; // Set length without trailing NUL.
+ if (!eap->skip) {
+ ga_append(&ga, NUL);
+ }
- return (char_u *)ga.ga_data;
+ return (char *)ga.ga_data;
}
/// Iterate over history items
@@ -5469,3 +5964,15 @@ histentry_T *hist_get_array(const uint8_t history_type, int **const new_hisidx,
*new_hisnum = &(hisnum[history_type]);
return history[history_type];
}
+
+static void set_search_match(pos_T *t)
+{
+ // First move cursor to end of match, then to the start. This
+ // moves the whole match onto the screen when 'nowrap' is set.
+ t->lnum += search_match_lines;
+ t->col = search_match_endcol;
+ if (t->lnum > curbuf->b_ml.ml_line_count) {
+ t->lnum = curbuf->b_ml.ml_line_count;
+ coladvance((colnr_T)MAXCOL);
+ }
+}
diff --git a/src/nvim/ex_getln.h b/src/nvim/ex_getln.h
index 24eebdc303..051564fbe1 100644
--- a/src/nvim/ex_getln.h
+++ b/src/nvim/ex_getln.h
@@ -1,8 +1,11 @@
#ifndef NVIM_EX_GETLN_H
#define NVIM_EX_GETLN_H
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_cmds.h"
+#include "nvim/ex_cmds_defs.h"
+#include "nvim/os/time.h"
+#include "nvim/regexp_defs.h"
/* Values for nextwild() and ExpandOne(). See ExpandOne() for meaning. */
#define WILD_FREE 1
diff --git a/src/nvim/farsi.c b/src/nvim/farsi.c
index eb22ad1428..1053cb3ac2 100644
--- a/src/nvim/farsi.c
+++ b/src/nvim/farsi.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// @file farsi.c
///
/// Functions for Farsi language
@@ -131,7 +134,7 @@ static char_u toF_Xor_X_(int c)
/// @param c The character to convert.
///
/// @return Character converted to the Farsi capital leter.
-char_u toF_TyA(char_u c)
+static char_u toF_TyA(char_u c)
{
char_u tempc;
@@ -321,7 +324,7 @@ static void put_curr_and_l_to_X(char_u c)
}
if ((curwin->w_cursor.col < (colnr_T)STRLEN(get_cursor_line_ptr()))) {
- if ((p_ri && curwin->w_cursor.col) || !p_ri) {
+ if (!p_ri || curwin->w_cursor.col) {
if (p_ri) {
dec_cursor();
} else {
@@ -1557,7 +1560,7 @@ static char_u toF_ending(char_u c)
}
/// Convert the Farsi 3342 standard into Farsi VIM.
-void conv_to_pvim(void)
+static void conv_to_pvim(void)
{
char_u *ptr;
int lnum, llen, i;
@@ -1588,23 +1591,23 @@ void conv_to_pvim(void)
}
// Following lines contains Farsi encoded character.
- do_cmdline_cmd("%s/\202\231/\232/g");
- do_cmdline_cmd("%s/\201\231/\370\334/g");
+ do_cmdline_cmd("%s/\202\231/\232/ge");
+ do_cmdline_cmd("%s/\201\231/\370\334/ge");
// Assume the screen has been messed up: clear it and redraw.
redraw_later(CLEAR);
- MSG_ATTR(farsi_text_1, hl_attr(HLF_S));
+ MSG_ATTR((const char *)farsi_text_1, hl_attr(HLF_S));
}
/// Convert the Farsi VIM into Farsi 3342 standard.
-void conv_to_pstd(void)
+static void conv_to_pstd(void)
{
char_u *ptr;
int lnum, llen, i;
// Following line contains Farsi encoded character.
- do_cmdline_cmd("%s/\232/\202\231/g");
- for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) {
+ do_cmdline_cmd("%s/\232/\202\231/ge");
+ for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; lnum++) {
ptr = ml_get((linenr_T)lnum);
llen = (int)STRLEN(ptr);
for (i = 0; i < llen; i++) {
@@ -1614,7 +1617,7 @@ void conv_to_pstd(void)
// Assume the screen has been messed up: clear it and redraw.
redraw_later(CLEAR);
- MSG_ATTR(farsi_text_2, hl_attr(HLF_S));
+ msg_attr((const char *)farsi_text_2, hl_attr(HLF_S));
}
/// left-right swap the characters in buf[len].
@@ -2036,34 +2039,31 @@ bool F_ischar(int c)
return c >= TEE_ && c <= YE_;
}
-void farsi_fkey(cmdarg_T *cap)
+void farsi_f8(cmdarg_T *cap FUNC_ATTR_UNUSED)
{
- int c = cap->cmdchar;
-
- if (c == K_F8) {
- if (p_altkeymap) {
- if (curwin->w_farsi & W_R_L) {
- p_fkmap = 0;
- do_cmdline_cmd("set norl");
- MSG("");
- } else {
- p_fkmap = 1;
- do_cmdline_cmd("set rl");
- MSG("");
- }
-
- curwin->w_farsi = curwin->w_farsi ^ W_R_L;
+ if (p_altkeymap) {
+ if (curwin->w_farsi & W_R_L) {
+ p_fkmap = 0;
+ do_cmdline_cmd("set norl");
+ MSG("");
+ } else {
+ p_fkmap = 1;
+ do_cmdline_cmd("set rl");
+ MSG("");
}
+
+ curwin->w_farsi = curwin->w_farsi ^ W_R_L;
}
+}
- if (c == K_F9) {
- if (p_altkeymap && curwin->w_p_rl) {
- curwin->w_farsi = curwin->w_farsi ^ W_CONV;
- if (curwin->w_farsi & W_CONV) {
- conv_to_pvim();
- } else {
- conv_to_pstd();
- }
+void farsi_f9(cmdarg_T *cap FUNC_ATTR_UNUSED)
+{
+ if (p_altkeymap && curwin->w_p_rl) {
+ curwin->w_farsi = curwin->w_farsi ^ W_CONV;
+ if (curwin->w_farsi & W_CONV) {
+ conv_to_pvim();
+ } else {
+ conv_to_pstd();
}
}
}
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c
index 2ac8e27047..8094a1b266 100644
--- a/src/nvim/file_search.c
+++ b/src/nvim/file_search.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
// File searching functions for 'path', 'tags' and 'cdpath' options.
//
// External visible functions:
@@ -48,6 +51,7 @@
#include <limits.h>
#include "nvim/vim.h"
+#include "nvim/eval.h"
#include "nvim/ascii.h"
#include "nvim/file_search.h"
#include "nvim/charset.h"
@@ -192,7 +196,6 @@ typedef struct ff_search_ctx_T {
static char_u e_pathtoolong[] = N_("E854: path too long for completion");
-
/*
* Initialization routine for vim_findfile().
*
@@ -322,8 +325,11 @@ vim_findfile_init (
drive[0] = path[0];
drive[1] = ':';
drive[2] = NUL;
- if (vim_FullName(drive, ff_expand_buffer, MAXPATHL, TRUE) == FAIL)
+ if (vim_FullName((const char *)drive, (char *)ff_expand_buffer, MAXPATHL,
+ true)
+ == FAIL) {
goto error_return;
+ }
path += 2;
} else
#endif
@@ -636,9 +642,8 @@ char_u *vim_findfile(void *search_ctx_arg)
if (p_verbose >= 5) {
verbose_enter_scroll();
smsg("Already Searched: %s (%s)",
- stackp->ffs_fix_path, stackp->ffs_wc_path);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ stackp->ffs_fix_path, stackp->ffs_wc_path);
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
#endif
@@ -650,8 +655,7 @@ char_u *vim_findfile(void *search_ctx_arg)
verbose_enter_scroll();
smsg("Searching: %s (%s)",
stackp->ffs_fix_path, stackp->ffs_wc_path);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
#endif
@@ -809,10 +813,8 @@ char_u *vim_findfile(void *search_ctx_arg)
) == FAIL) {
if (p_verbose >= 5) {
verbose_enter_scroll();
- smsg("Already: %s",
- file_path);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ smsg("Already: %s", file_path);
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
continue;
@@ -837,8 +839,7 @@ char_u *vim_findfile(void *search_ctx_arg)
if (p_verbose >= 5) {
verbose_enter_scroll();
smsg("HIT: %s", file_path);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
#endif
@@ -999,10 +1000,8 @@ static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename, ff_visited_l
#ifdef FF_VERBOSE
if (p_verbose >= 5) {
verbose_enter_scroll();
- smsg("ff_get_visited_list: FOUND list for %s",
- filename);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ smsg("ff_get_visited_list: FOUND list for %s", filename);
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
#endif
@@ -1016,8 +1015,7 @@ static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename, ff_visited_l
if (p_verbose >= 5) {
verbose_enter_scroll();
smsg("ff_get_visited_list: new list for %s", filename);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
#endif
@@ -1062,7 +1060,7 @@ static bool ff_wc_equal(char_u *s1, char_u *s2)
c1 = PTR2CHAR(s1 + i);
c2 = PTR2CHAR(s2 + j);
- if ((p_fic ? vim_tolower(c1) != vim_tolower(c2) : c1 != c2)
+ if ((p_fic ? mb_tolower(c1) != mb_tolower(c2) : c1 != c2)
&& (prev1 != '*' || prev2 != '*')) {
return false;
}
@@ -1370,6 +1368,11 @@ find_file_in_path_option (
char_u *buf = NULL;
int rel_to_curdir;
+ if (rel_fname != NULL && path_with_url((const char *)rel_fname)) {
+ // Do not attempt to search "relative" to a URL. #6009
+ rel_fname = NULL;
+ }
+
if (first == TRUE) {
/* copy file name into NameBuff, expanding environment variables */
save_char = ptr[len];
@@ -1522,26 +1525,85 @@ theend:
return file_name;
}
+void do_autocmd_dirchanged(char *new_dir, CdScope scope)
+{
+ static bool recursive = false;
+
+ if (recursive || !has_event(EVENT_DIRCHANGED)) {
+ // No autocommand was defined or we changed
+ // the directory from this autocommand.
+ return;
+ }
+
+ recursive = true;
+
+ dict_T *dict = get_vim_var_dict(VV_EVENT);
+ char buf[8];
+
+ switch (scope) {
+ case kCdScopeGlobal:
+ snprintf(buf, sizeof(buf), "global");
+ break;
+ case kCdScopeTab:
+ snprintf(buf, sizeof(buf), "tab");
+ break;
+ case kCdScopeWindow:
+ snprintf(buf, sizeof(buf), "window");
+ break;
+ case kCdScopeInvalid:
+ // Should never happen.
+ assert(false);
+ }
+
+ tv_dict_add_str(dict, S_LEN("scope"), buf);
+ tv_dict_add_str(dict, S_LEN("cwd"), new_dir);
+ tv_dict_set_keys_readonly(dict);
+
+ apply_autocmds(EVENT_DIRCHANGED, (char_u *)buf, (char_u *)new_dir, false,
+ NULL);
+
+ tv_dict_clear(dict);
+
+ recursive = false;
+}
+
/// Change to a file's directory.
/// Caller must call shorten_fnames()!
/// @return OK or FAIL
int vim_chdirfile(char_u *fname)
{
- char_u dir[MAXPATHL];
+ char dir[MAXPATHL];
STRLCPY(dir, fname, MAXPATHL);
- *path_tail_with_sep(dir) = NUL;
- return os_chdir((char *)dir) == 0 ? OK : FAIL;
+ *path_tail_with_sep((char_u *)dir) = NUL;
+
+ if (os_dirname(NameBuff, sizeof(NameBuff)) != OK) {
+ NameBuff[0] = NUL;
+ }
+
+ if (os_chdir(dir) != 0) {
+ return FAIL;
+ }
+
+#ifdef BACKSLASH_IN_FILENAME
+ slash_adjust(dir);
+#endif
+ if (!strequal(dir, (char *)NameBuff)) {
+ do_autocmd_dirchanged(dir, kCdScopeWindow);
+ }
+
+ return OK;
}
/// Change directory to "new_dir". Search 'cdpath' for relative directory names.
-int vim_chdir(char_u *new_dir)
+int vim_chdir(char_u *new_dir, CdScope scope)
{
char_u *dir_name = find_directory_in_path(new_dir, STRLEN(new_dir),
FNAME_MESS, curbuf->b_ffname);
if (dir_name == NULL) {
return -1;
}
+
int r = os_chdir((char *)dir_name);
xfree(dir_name);
return r;
diff --git a/src/nvim/file_search.h b/src/nvim/file_search.h
index 833a1a05ff..b128029123 100644
--- a/src/nvim/file_search.h
+++ b/src/nvim/file_search.h
@@ -1,6 +1,11 @@
#ifndef NVIM_FILE_SEARCH_H
#define NVIM_FILE_SEARCH_H
+#include <stdlib.h> // for size_t
+
+#include "nvim/types.h" // for char_u
+#include "nvim/globals.h" // for CdScope
+
/* Flags for find_file_*() functions. */
#define FINDFILE_FILE 0 /* only files */
#define FINDFILE_DIR 1 /* only directories */
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 29114201d2..feb16f44d4 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* fileio.c: read from and write to a file
*/
@@ -200,18 +203,14 @@ void filemess(buf_T *buf, char_u *name, char_u *s, int attr)
{
int msg_scroll_save;
- if (msg_silent != 0)
+ if (msg_silent != 0) {
return;
- msg_add_fname(buf, name); /* put file name in IObuff with quotes */
- /* If it's extremely long, truncate it. */
- if (STRLEN(IObuff) > IOSIZE - 80)
- IObuff[IOSIZE - 80] = NUL;
- STRCAT(IObuff, s);
- /*
- * For the first message may have to start a new line.
- * For further ones overwrite the previous one, reset msg_scroll before
- * calling filemess().
- */
+ }
+ add_quoted_fname((char *)IObuff, IOSIZE - 80, buf, (const char *)name);
+ xstrlcat((char *)IObuff, (const char *)s, IOSIZE);
+ // For the first message may have to start a new line.
+ // For further ones overwrite the previous one, reset msg_scroll before
+ // calling filemess().
msg_scroll_save = msg_scroll;
if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0)
msg_scroll = FALSE;
@@ -248,8 +247,9 @@ void filemess(buf_T *buf, char_u *name, char_u *s, int attr)
* stdin)
* READ_DUMMY read into a dummy buffer (to check if file contents changed)
* READ_KEEP_UNDO don't clear undo info or read it from a file
+ * READ_FIFO read from fifo/socket instead of a file
*
- * return FAIL for failure, OK otherwise
+ * return FAIL for failure, NOTDONE for directory (failure), or OK
*/
int
readfile (
@@ -258,7 +258,7 @@ readfile (
linenr_T from,
linenr_T lines_to_skip,
linenr_T lines_to_read,
- exarg_T *eap, /* can be NULL! */
+ exarg_T *eap, // can be NULL!
int flags
)
{
@@ -268,6 +268,7 @@ readfile (
int filtering = (flags & READ_FILTER);
int read_stdin = (flags & READ_STDIN);
int read_buffer = (flags & READ_BUFFER);
+ int read_fifo = (flags & READ_FIFO);
int set_options = newfile || read_buffer
|| (eap != NULL && eap->read_edit);
linenr_T read_buf_lnum = 1; /* next line to read from curbuf */
@@ -281,9 +282,9 @@ readfile (
int wasempty; /* buffer was empty before reading */
colnr_T len;
long size = 0;
- char_u *p;
- off_t filesize = 0;
- int skip_read = FALSE;
+ char_u *p = NULL;
+ off_T filesize = 0;
+ int skip_read = false;
context_sha256_T sha_ctx;
int read_undo_file = FALSE;
int split = 0; /* number of split lines */
@@ -427,8 +428,8 @@ readfile (
}
}
- if (!read_buffer && !read_stdin) {
- perm = os_getperm(fname);
+ if (!read_buffer && !read_stdin && !read_fifo) {
+ perm = os_getperm((const char *)fname);
#ifdef UNIX
// On Unix it is possible to read a directory, so we have to
// check for it before os_open().
@@ -444,13 +445,14 @@ readfile (
// ... or a character special file named /dev/fd/<n>
# endif
) {
- if (S_ISDIR(perm))
+ if (S_ISDIR(perm)) {
filemess(curbuf, fname, (char_u *)_("is a directory"), 0);
- else
+ } else {
filemess(curbuf, fname, (char_u *)_("is not a file"), 0);
+ }
msg_end();
msg_scroll = msg_save;
- return FAIL;
+ return S_ISDIR(perm) ? NOTDONE : FAIL;
}
#endif
}
@@ -468,8 +470,8 @@ readfile (
if (check_readonly && !readonlymode)
curbuf->b_p_ro = FALSE;
- if (newfile && !read_stdin && !read_buffer) {
- /* Remember time of file. */
+ if (newfile && !read_stdin && !read_buffer && !read_fifo) {
+ // Remember time of file.
FileInfo file_info;
if (os_fileinfo((char *)fname, &file_info)) {
buf_store_file_info(curbuf, &file_info);
@@ -613,10 +615,12 @@ readfile (
return FAIL;
}
#ifdef UNIX
- /* Set swap file protection bits after creating it. */
+ // Set swap file protection bits after creating it.
if (swap_mode > 0 && curbuf->b_ml.ml_mfp != NULL
- && curbuf->b_ml.ml_mfp->mf_fname != NULL)
- (void)os_setperm(curbuf->b_ml.ml_mfp->mf_fname, (long)swap_mode);
+ && curbuf->b_ml.ml_mfp->mf_fname != NULL) {
+ (void)os_setperm((const char *)curbuf->b_ml.ml_mfp->mf_fname,
+ (long)swap_mode);
+ }
#endif
}
@@ -699,16 +703,9 @@ readfile (
wasempty = (curbuf->b_ml.ml_flags & ML_EMPTY);
if (!recoverymode && !filtering && !(flags & READ_DUMMY)) {
- /*
- * Show the user that we are busy reading the input. Sometimes this
- * may take a while. When reading from stdin another program may
- * still be running, don't move the cursor to the last line, unless
- * always using the GUI.
- */
- if (read_stdin) {
- mch_msg(_("Nvim: Reading from stdin...\n"));
- } else if (!read_buffer)
+ if (!read_stdin && !read_buffer) {
filemess(curbuf, sfname, (char_u *)"", 0);
+ }
}
msg_scroll = FALSE; /* overwrite the file message */
@@ -738,43 +735,16 @@ readfile (
fenc = (char_u *)""; /* binary: don't convert */
fenc_alloced = FALSE;
} else if (curbuf->b_help) {
- char_u firstline[80];
- int fc;
-
- /* Help files are either utf-8 or latin1. Try utf-8 first, if this
- * fails it must be latin1.
- * Always do this when 'encoding' is "utf-8". Otherwise only do
- * this when needed to avoid [converted] remarks all the time.
- * It is needed when the first line contains non-ASCII characters.
- * That is only in *.??x files. */
- fenc = (char_u *)"latin1";
- c = enc_utf8;
- if (!c && !read_stdin) {
- fc = fname[STRLEN(fname) - 1];
- if (TOLOWER_ASC(fc) == 'x') {
- /* Read the first line (and a bit more). Immediately rewind to
- * the start of the file. If the read() fails "len" is -1. */
- len = read_eintr(fd, firstline, 80);
- lseek(fd, (off_t)0L, SEEK_SET);
- for (p = firstline; p < firstline + len; ++p)
- if (*p >= 0x80) {
- c = TRUE;
- break;
- }
- }
- }
+ // Help files are either utf-8 or latin1. Try utf-8 first, if this
+ // fails it must be latin1.
+ // It is needed when the first line contains non-ASCII characters.
+ // That is only in *.??x files.
+ fenc_next = (char_u *)"latin1";
+ fenc = (char_u *)"utf-8";
- if (c) {
- fenc_next = fenc;
- fenc = (char_u *)"utf-8";
+ fenc_alloced = false;
- /* 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;
+ c = 1;
} else if (*p_fencs == NUL) {
fenc = curbuf->b_p_fenc; /* use format from buffer */
fenc_alloced = FALSE;
@@ -809,9 +779,9 @@ retry:
if (read_buffer) {
read_buf_lnum = 1;
read_buf_col = 0;
- } else if (read_stdin || lseek(fd, (off_t)0L, SEEK_SET) != 0) {
- /* Can't rewind the file, give up. */
- error = TRUE;
+ } else if (read_stdin || vim_lseek(fd, (off_T)0L, SEEK_SET) != 0) {
+ // Can't rewind the file, give up.
+ error = true;
goto failed;
}
/* Delete the previously read lines. */
@@ -927,6 +897,7 @@ retry:
* and we can't do it internally or with iconv().
*/
if (fio_flags == 0 && !read_stdin && !read_buffer && *p_ccv != NUL
+ && !read_fifo
# ifdef USE_ICONV
&& iconv_fd == (iconv_t)-1
# endif
@@ -967,7 +938,7 @@ retry:
/* Set "can_retry" when it's possible to rewind the file and try with
* another "fenc" value. It's FALSE when no other "fenc" to try, reading
* stdin or fixed at a specific encoding. */
- can_retry = (*fenc != NUL && !read_stdin && !keep_dest_enc);
+ can_retry = (*fenc != NUL && !read_stdin && !keep_dest_enc && !read_fifo);
if (!skip_read) {
linerest = 0;
@@ -979,6 +950,7 @@ retry:
&& curbuf->b_ffname != NULL
&& curbuf->b_p_udf
&& !filtering
+ && !read_fifo
&& !read_stdin
&& !read_buffer);
if (read_undo_file)
@@ -1646,19 +1618,16 @@ rewind_retry:
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)) {
+ len--;
+ } else if (ff_error != EOL_DOS) {
+ // Reading in Dos format, but no CR-LF found!
+ // When 'fileformats' includes "unix", delete all
+ // the lines read so far and start all over again.
+ // Otherwise give an error message later.
+ if (try_unix
+ && !read_stdin
+ && (read_buffer
+ || vim_lseek(fd, (off_T)0L, SEEK_SET) == 0)) {
fileformat = EOL_UNIX;
if (set_options)
set_fileformat(EOL_UNIX, OPT_LOCAL);
@@ -1741,16 +1710,11 @@ failed:
}
# endif
- if (!read_buffer && !read_stdin)
- close(fd); /* errors are ignored */
-#ifdef HAVE_FD_CLOEXEC
- else {
- int fdflags = fcntl(fd, F_GETFD);
- if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0) {
- (void)fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC);
- }
+ if (!read_buffer && !read_stdin) {
+ close(fd); // errors are ignored
+ } else {
+ (void)os_set_cloexec(fd);
}
-#endif
xfree(buffer);
if (read_stdin) {
@@ -1809,8 +1773,8 @@ failed:
}
if (!filtering && !(flags & READ_DUMMY)) {
- msg_add_fname(curbuf, sfname); /* fname in IObuff with quotes */
- c = FALSE;
+ add_quoted_fname((char *)IObuff, IOSIZE, curbuf, (const char *)sfname);
+ c = false;
#ifdef UNIX
# ifdef S_ISFIFO
@@ -1881,17 +1845,22 @@ failed:
xfree(keep_msg);
keep_msg = NULL;
+ p = NULL;
msg_scrolled_ign = TRUE;
- p = msg_trunc_attr(IObuff, FALSE, 0);
+
+ if (!read_stdin && !read_buffer) {
+ p = msg_trunc_attr(IObuff, FALSE, 0);
+ }
+
if (read_stdin || read_buffer || restart_edit != 0
- || (msg_scrolled != 0 && !need_wait_return))
- /* Need to repeat the message after redrawing when:
- * - When reading from stdin (the screen will be cleared next).
- * - When restart_edit is set (otherwise there will be a delay
- * before redrawing).
- * - When the screen was scrolled but there is no wait-return
- * prompt. */
+ || (msg_scrolled != 0 && !need_wait_return)) {
+ // Need to repeat the message after redrawing when:
+ // - When reading from stdin (the screen will be cleared next).
+ // - When restart_edit is set (otherwise there will be a delay before
+ // redrawing).
+ // - When the screen was scrolled but there is no wait-return prompt.
set_keep_msg(p, 0);
+ }
msg_scrolled_ign = FALSE;
}
@@ -1954,7 +1923,7 @@ failed:
u_read_undo(NULL, hash, fname);
}
- if (!read_stdin && !read_buffer) {
+ if (!read_stdin && !read_fifo && (!read_buffer || sfname != NULL)) {
int m = msg_scroll;
int n = msg_scrolled;
@@ -1972,7 +1941,7 @@ failed:
if (filtering) {
apply_autocmds_exarg(EVENT_FILTERREADPOST, NULL, sfname,
false, curbuf, eap);
- } else if (newfile) {
+ } else if (newfile || (read_buffer && sfname != NULL)) {
apply_autocmds_exarg(EVENT_BUFREADPOST, NULL, sfname,
false, curbuf, eap);
if (!au_did_filetype && *curbuf->b_p_ft != NUL) {
@@ -2005,7 +1974,7 @@ failed:
/// Do not accept "/dev/fd/[012]", opening these may hang Vim.
///
/// @param fname file name to check
-static bool is_dev_fd_file(char_u *fname)
+bool is_dev_fd_file(char_u *fname)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
return STRNCMP(fname, "/dev/fd/", 8) == 0
@@ -2262,9 +2231,16 @@ buf_write (
int len;
linenr_T lnum;
long nchars;
- char_u *errmsg = NULL;
- int errmsg_allocated = FALSE;
- char_u *errnum = NULL;
+#define SET_ERRMSG_NUM(num, msg) \
+ errnum = num, errmsg = msg, errmsgarg = 0
+#define SET_ERRMSG_ARG(msg, error) \
+ errnum = NULL, errmsg = msg, errmsgarg = error
+#define SET_ERRMSG(msg) \
+ errnum = NULL, errmsg = msg, errmsgarg = 0
+ const char *errnum = NULL;
+ char *errmsg = NULL;
+ int errmsgarg = 0;
+ bool errmsg_allocated = false;
char_u *buffer;
char_u smallbuf[SMBUFSIZE];
char_u *backup_ext;
@@ -2286,7 +2262,6 @@ buf_write (
/* writing everything */
int whole = (start == 1 && end == buf->b_ml.ml_line_count);
linenr_T old_line_count = buf->b_ml.ml_line_count;
- int attr;
int fileformat;
int write_bin;
struct bw_info write_info; /* info for buf_write_bytes() */
@@ -2396,6 +2371,7 @@ buf_write (
int did_cmd = FALSE;
int nofile_err = FALSE;
int empty_memline = (buf->b_ml.ml_mfp == NULL);
+ bufref_T bufref;
/*
* Apply PRE autocommands.
@@ -2411,8 +2387,9 @@ buf_write (
if (fname == buf->b_sfname)
buf_fname_s = TRUE;
- /* set curwin/curbuf to buf and save a few things */
+ // Set curwin/curbuf to buf and save a few things.
aucmd_prepbuf(&aco, buf);
+ set_bufref(&bufref, buf);
if (append) {
if (!(did_cmd = apply_autocmds_exarg(EVENT_FILEAPPENDCMD,
@@ -2460,14 +2437,13 @@ buf_write (
/* restore curwin/curbuf and a few other things */
aucmd_restbuf(&aco);
- /*
- * In three situations we return here and don't write the file:
- * 1. the autocommands deleted or unloaded the buffer.
- * 2. The autocommands abort script processing.
- * 3. If one of the "Cmd" autocommands was executed.
- */
- if (!buf_valid(buf))
+ // In three situations we return here and don't write the file:
+ // 1. the autocommands deleted or unloaded the buffer.
+ // 2. The autocommands abort script processing.
+ // 3. If one of the "Cmd" autocommands was executed.
+ if (!bufref_valid(&bufref)) {
buf = NULL;
+ }
if (buf == NULL || (buf->b_ml.ml_mfp == NULL && !empty_memline)
|| did_cmd || nofile_err
|| aborting()
@@ -2580,13 +2556,11 @@ buf_write (
perm = file_info_old.stat.st_mode;
if (!S_ISREG(file_info_old.stat.st_mode)) { /* not a file */
if (S_ISDIR(file_info_old.stat.st_mode)) {
- errnum = (char_u *)"E502: ";
- errmsg = (char_u *)_("is a directory");
+ SET_ERRMSG_NUM("E502", _("is a directory"));
goto fail;
}
if (os_nodetype((char *)fname) != NODE_WRITABLE) {
- errnum = (char_u *)"E503: ";
- errmsg = (char_u *)_("is not a file or writable device");
+ SET_ERRMSG_NUM("E503", _("is not a file or writable device"));
goto fail;
}
/* It's a device of some kind (or a fifo) which we can write to
@@ -2596,14 +2570,11 @@ buf_write (
perm = -1;
}
}
-#else /* win32 */
- /*
- * Check for a writable device name.
- */
- c = os_nodetype((char *)fname);
+#else // win32
+ // Check for a writable device name.
+ c = fname == NULL ? NODE_OTHER : os_nodetype((char *)fname);
if (c == NODE_OTHER) {
- errnum = (char_u *)"E503: ";
- errmsg = (char_u *)_("is not a file or writable device");
+ SET_ERRMSG_NUM("E503", _("is not a file or writable device"));
goto fail;
}
if (c == NODE_WRITABLE) {
@@ -2611,20 +2582,18 @@ buf_write (
newfile = TRUE;
perm = -1;
} else {
- perm = os_getperm(fname);
- if (perm < 0)
- newfile = TRUE;
- else if (os_isdir(fname)) {
- errnum = (char_u *)"E502: ";
- errmsg = (char_u *)_("is a directory");
+ perm = os_getperm((const char *)fname);
+ if (perm < 0) {
+ newfile = true;
+ } else if (os_isdir(fname)) {
+ SET_ERRMSG_NUM("E502", _("is a directory"));
goto fail;
}
if (overwriting) {
os_fileinfo((char *)fname, &file_info_old);
}
-
}
-#endif /* !UNIX */
+#endif // !UNIX
if (!device && !newfile) {
/*
@@ -2635,11 +2604,9 @@ buf_write (
if (!forceit && file_readonly) {
if (vim_strchr(p_cpo, CPO_FWRITE) != NULL) {
- errnum = (char_u *)"E504: ";
- errmsg = (char_u *)_(err_readonly);
+ SET_ERRMSG_NUM("E504", _(err_readonly));
} else {
- errnum = (char_u *)"E505: ";
- errmsg = (char_u *)_("is read-only (add ! to override)");
+ SET_ERRMSG_NUM("E505", _("is read-only (add ! to override)"));
}
goto fail;
}
@@ -2875,9 +2842,9 @@ buf_write (
xfree(backup);
backup = NULL;
} else {
- /* set file protection same as original file, but
- * strip s-bit */
- (void)os_setperm(backup, perm & 0777);
+ // set file protection same as original file, but
+ // strip s-bit.
+ (void)os_setperm((const char *)backup, perm & 0777);
#ifdef UNIX
/*
@@ -2888,7 +2855,8 @@ buf_write (
*/
if (file_info_new.stat.st_gid != file_info_old.stat.st_gid
&& os_fchown(bfd, -1, file_info_old.stat.st_gid) != 0) {
- os_setperm(backup, (perm & 0707) | ((perm & 07) << 3));
+ os_setperm((const char *)backup,
+ (perm & 0707) | ((perm & 07) << 3));
}
# ifdef HAVE_SELINUX
mch_copy_sec(fname, backup);
@@ -2906,23 +2874,27 @@ buf_write (
while ((write_info.bw_len = read_eintr(fd, copybuf,
BUFSIZE)) > 0) {
if (buf_write_bytes(&write_info) == FAIL) {
- errmsg = (char_u *)_(
- "E506: Can't write to backup file (add ! to override)");
+ SET_ERRMSG(_(
+ "E506: Can't write to backup file (add ! to override)"));
break;
}
os_breakcheck();
if (got_int) {
- errmsg = (char_u *)_(e_interr);
+ SET_ERRMSG(_(e_interr));
break;
}
}
- if (close(bfd) < 0 && errmsg == NULL)
- errmsg = (char_u *)_(
- "E507: Close error for backup file (add ! to override)");
- if (write_info.bw_len < 0)
- errmsg = (char_u *)_(
- "E508: Can't read file for backup (add ! to override)");
+ int error;
+ if ((error = os_close(bfd)) != 0 && errmsg == NULL) {
+ SET_ERRMSG_ARG(_("E507: Close error for backup file "
+ "(add ! to override): %s"),
+ error);
+ }
+ if (write_info.bw_len < 0) {
+ SET_ERRMSG(_(
+ "E508: Can't read file for backup (add ! to override)"));
+ }
#ifdef UNIX
set_file_time(backup,
file_info_old.stat.st_atim.tv_sec,
@@ -2939,18 +2911,19 @@ buf_write (
}
}
nobackup:
- close(fd); /* ignore errors for closing read file */
+ os_close(fd); // Ignore errors for closing read file.
xfree(copybuf);
- if (backup == NULL && errmsg == NULL)
- errmsg = (char_u *)_(
- "E509: Cannot create backup file (add ! to override)");
- /* ignore errors when forceit is TRUE */
+ if (backup == NULL && errmsg == NULL) {
+ SET_ERRMSG(_(
+ "E509: Cannot create backup file (add ! to override)"));
+ }
+ // Ignore errors when forceit is TRUE.
if ((some_error || errmsg != NULL) && !forceit) {
retval = FAIL;
goto fail;
}
- errmsg = NULL;
+ SET_ERRMSG(NULL);
} else {
char_u *dirp;
char_u *p;
@@ -2965,8 +2938,7 @@ nobackup:
* anyway, thus we need an extra check here.
*/
if (file_readonly && vim_strchr(p_cpo, CPO_FWRITE) != NULL) {
- errnum = (char_u *)"E504: ";
- errmsg = (char_u *)_(err_readonly);
+ SET_ERRMSG_NUM("E504", _(err_readonly));
goto fail;
}
@@ -3030,7 +3002,7 @@ nobackup:
}
}
if (backup == NULL && !forceit) {
- errmsg = (char_u *)_("E510: Can't make backup file (add ! to override)");
+ SET_ERRMSG(_("E510: Can't make backup file (add ! to override)"));
goto fail;
}
}
@@ -3042,8 +3014,8 @@ nobackup:
&& file_info_old.stat.st_uid == getuid()
&& vim_strchr(p_cpo, CPO_FWRITE) == NULL) {
perm |= 0200;
- (void)os_setperm(fname, perm);
- made_writable = TRUE;
+ (void)os_setperm((const char *)fname, perm);
+ made_writable = true;
}
#endif
@@ -3071,7 +3043,7 @@ nobackup:
&& !(exiting && backup != NULL)) {
ml_preserve(buf, FALSE);
if (got_int) {
- errmsg = (char_u *)_(e_interr);
+ SET_ERRMSG(_(e_interr));
goto restore_backup;
}
}
@@ -3142,8 +3114,8 @@ nobackup:
*/
if (*p_ccv != NUL) {
wfname = vim_tempname();
- if (wfname == NULL) { /* Can't write without a tempfile! */
- errmsg = (char_u *)_("E214: Can't find temp file for writing");
+ if (wfname == NULL) { // Can't write without a tempfile!
+ SET_ERRMSG(_("E214: Can't find temp file for writing"));
goto restore_backup;
}
}
@@ -3155,8 +3127,8 @@ nobackup:
&& wfname == fname
) {
if (!forceit) {
- errmsg = (char_u *)_(
- "E213: Cannot convert (add ! to write without conversion)");
+ SET_ERRMSG(_(
+ "E213: Cannot convert (add ! to write without conversion)"));
goto restore_backup;
}
notconverted = TRUE;
@@ -3187,15 +3159,14 @@ nobackup:
#ifdef UNIX
FileInfo file_info;
- /* Don't delete the file when it's a hard or symbolic link. */
- if ((!newfile && os_fileinfo_hardlinks(&file_info) > 1)
+ // Don't delete the file when it's a hard or symbolic link.
+ if ((!newfile && os_fileinfo_hardlinks(&file_info_old) > 1)
|| (os_fileinfo_link((char *)fname, &file_info)
&& !os_fileinfo_id_equal(&file_info, &file_info_old))) {
- errmsg = (char_u *)_("E166: Can't open linked file for writing");
- } else
+ SET_ERRMSG(_("E166: Can't open linked file for writing"));
+ } else {
#endif
- {
- errmsg = (char_u *)_("E212: Can't open file for writing");
+ SET_ERRMSG_ARG(_("E212: Can't open file for writing: %s"), fd);
if (forceit && vim_strchr(p_cpo, CPO_FWRITE) == NULL
&& perm >= 0) {
#ifdef UNIX
@@ -3213,7 +3184,9 @@ nobackup:
os_remove((char *)wfname);
continue;
}
+#ifdef UNIX
}
+#endif
}
restore_backup:
@@ -3255,7 +3228,7 @@ restore_backup:
xfree(wfname);
goto fail;
}
- errmsg = NULL;
+ SET_ERRMSG(NULL);
write_info.bw_fd = fd;
@@ -3375,7 +3348,6 @@ restore_backup:
nchars += len;
}
-#if defined(UNIX)
// On many journalling file systems there is a bug that causes both the
// original and the backup file to be lost when halting the system right
// after writing the file. That's because only the meta-data is
@@ -3384,11 +3356,11 @@ restore_backup:
// For a device do try the fsync() but don't complain if it does not work
// (could be a pipe).
// If the 'fsync' option is FALSE, don't fsync(). Useful for laptops.
- if (p_fs && os_fsync(fd) != 0 && !device) {
- errmsg = (char_u *)_("E667: Fsync failed");
+ int error;
+ if (p_fs && (error = os_fsync(fd)) != 0 && !device) {
+ SET_ERRMSG_ARG(_("E667: Fsync failed: %s"), error);
end = 0;
}
-#endif
#ifdef HAVE_SELINUX
/* Probably need to set the security context. */
@@ -3407,8 +3379,9 @@ restore_backup:
|| file_info.stat.st_uid != file_info_old.stat.st_uid
|| file_info.stat.st_gid != file_info_old.stat.st_gid) {
os_fchown(fd, file_info_old.stat.st_uid, file_info_old.stat.st_gid);
- if (perm >= 0) /* set permission again, may have changed */
- (void)os_setperm(wfname, perm);
+ if (perm >= 0) { // Set permission again, may have changed.
+ (void)os_setperm((const char *)wfname, perm);
+ }
}
buf_set_file_id(buf);
} else if (!buf->file_id_valid) {
@@ -3417,8 +3390,8 @@ restore_backup:
}
#endif
- if (close(fd) != 0) {
- errmsg = (char_u *)_("E512: Close failed");
+ if ((error = os_close(fd)) != 0) {
+ SET_ERRMSG_ARG(_("E512: Close failed: %s"), error);
end = 0;
}
@@ -3426,8 +3399,9 @@ restore_backup:
if (made_writable)
perm &= ~0200; /* reset 'w' bit for security reasons */
#endif
- if (perm >= 0) /* set perm. of new file same as old file */
- (void)os_setperm(wfname, perm);
+ if (perm >= 0) { // Set perm. of new file same as old file.
+ (void)os_setperm((const char *)wfname, perm);
+ }
#ifdef HAVE_ACL
/* Probably need to set the ACL before changing the user (can't set the
* ACL on a file the user doesn't own). */
@@ -3454,21 +3428,24 @@ restore_backup:
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 = xmalloc(300);
- vim_snprintf((char *)errmsg, 300,
- _("E513: write error, conversion failed in line %" PRId64
+ if (write_info.bw_conv_error_lnum == 0) {
+ SET_ERRMSG(_(
+ "E513: write error, conversion failed "
+ "(make 'fenc' empty to override)"));
+ } else {
+ errmsg_allocated = true;
+ SET_ERRMSG(xmalloc(300));
+ vim_snprintf(
+ errmsg, 300,
+ _("E513: write error, conversion failed in line %" PRIdLINENR
" (make 'fenc' empty to override)"),
- (int64_t)write_info.bw_conv_error_lnum);
+ write_info.bw_conv_error_lnum);
}
- } else if (got_int)
- errmsg = (char_u *)_(e_interr);
- else
- errmsg = (char_u *)_("E514: write error (file system full?)");
+ } else if (got_int) {
+ SET_ERRMSG(_(e_interr));
+ } else {
+ SET_ERRMSG(_("E514: write error (file system full?)"));
+ }
}
/*
@@ -3523,8 +3500,8 @@ restore_backup:
fname = sfname; /* use shortname now, for the messages */
#endif
if (!filtering) {
- msg_add_fname(buf, fname); /* put fname in IObuff with quotes */
- c = FALSE;
+ add_quoted_fname((char *)IObuff, IOSIZE, buf, (const char *)fname);
+ c = false;
if (write_info.bw_conv_error) {
STRCAT(IObuff, _(" CONVERSION ERROR"));
c = TRUE;
@@ -3633,7 +3610,7 @@ restore_backup:
close(empty_fd);
}
if (org != NULL) {
- os_setperm((char_u *)org, os_getperm(fname) & 0777);
+ os_setperm(org, os_getperm((const char *)fname) & 0777);
xfree(org);
}
}
@@ -3673,33 +3650,32 @@ nofail:
#endif
if (errmsg != NULL) {
- int numlen = errnum != NULL ? (int)STRLEN(errnum) : 0;
-
- attr = hl_attr(HLF_E); /* set highlight for error messages */
- msg_add_fname(buf,
+ // - 100 to save some space for further error message
#ifndef UNIX
- sfname
+ add_quoted_fname((char *)IObuff, IOSIZE - 100, buf, (const char *)sfname);
#else
- fname
+ add_quoted_fname((char *)IObuff, IOSIZE - 100, buf, (const char *)fname);
#endif
- ); /* put file name in IObuff with quotes */
- if (STRLEN(IObuff) + STRLEN(errmsg) + numlen >= IOSIZE)
- IObuff[IOSIZE - STRLEN(errmsg) - numlen - 1] = NUL;
- /* If the error message has the form "is ...", put the error number in
- * front of the file name. */
if (errnum != NULL) {
- STRMOVE(IObuff + numlen, IObuff);
- memmove(IObuff, errnum, (size_t)numlen);
+ if (errmsgarg != 0) {
+ emsgf("%s: %s%s: %s", errnum, IObuff, errmsg, os_strerror(errmsgarg));
+ } else {
+ emsgf("%s: %s%s", errnum, IObuff, errmsg);
+ }
+ } else if (errmsgarg != 0) {
+ emsgf(errmsg, os_strerror(errmsgarg));
+ } else {
+ emsgf(errmsg);
}
- STRCAT(IObuff, errmsg);
- emsg(IObuff);
- if (errmsg_allocated)
+ if (errmsg_allocated) {
xfree(errmsg);
+ }
retval = FAIL;
if (end == 0) {
+ const int attr = hl_attr(HLF_E); // Set highlight for error messages.
MSG_PUTS_ATTR(_("\nWARNING: Original file may be lost or damaged\n"),
- attr | MSG_HIST);
+ attr | MSG_HIST);
MSG_PUTS_ATTR(_(
"don't quit the editor until the file is successfully written!"),
attr | MSG_HIST);
@@ -3759,6 +3735,9 @@ nofail:
got_int |= prev_got_int;
return retval;
+#undef SET_ERRMSG
+#undef SET_ERRMSG_ARG
+#undef SET_ERRMSG_NUM
}
/*
@@ -3802,16 +3781,25 @@ static int set_rw_fname(char_u *fname, char_u *sfname)
return OK;
}
-/*
- * Put file name into IObuff with quotes.
- */
-void msg_add_fname(buf_T *buf, char_u *fname)
+/// Put file name into the specified buffer with quotes
+///
+/// Replaces home directory at the start with `~`.
+///
+/// @param[out] ret_buf Buffer to save results to.
+/// @param[in] buf_len ret_buf length.
+/// @param[in] buf buf_T file name is coming from.
+/// @param[in] fname File name to write.
+static void add_quoted_fname(char *const ret_buf, const size_t buf_len,
+ const buf_T *const buf, const char *fname)
+ FUNC_ATTR_NONNULL_ARG(1)
{
- if (fname == NULL)
- fname = (char_u *)"-stdin-";
- home_replace(buf, fname, IObuff + 1, IOSIZE - 4, TRUE);
- IObuff[0] = '"';
- STRCAT(IObuff, "\" ");
+ if (fname == NULL) {
+ fname = "-stdin-";
+ }
+ ret_buf[0] = '"';
+ home_replace(buf, (const char_u *)fname, (char_u *)ret_buf + 1,
+ (int)buf_len - 4, true);
+ xstrlcat(ret_buf, "\" ", buf_len);
}
/// Append message for text mode to IObuff.
@@ -3843,7 +3831,7 @@ static bool msg_add_fileformat(int eol_type)
/*
* Append line and character count to IObuff.
*/
-void msg_add_lines(int insert_space, long lnum, off_t nchars)
+void msg_add_lines(int insert_space, long lnum, off_T nchars)
{
char_u *p;
@@ -3888,15 +3876,15 @@ static int check_mtime(buf_T *buf, FileInfo *file_info)
if (buf->b_mtime_read != 0
&& time_differs(file_info->stat.st_mtim.tv_sec,
buf->b_mtime_read)) {
- msg_scroll = TRUE; /* don't overwrite messages here */
- msg_silent = 0; /* must give this prompt */
- /* don't use emsg() here, don't want to flush the buffers */
- MSG_ATTR(_("WARNING: The file has been changed since reading it!!!"),
- hl_attr(HLF_E));
- if (ask_yesno((char_u *)_("Do you really want to write to it"),
- TRUE) == 'n')
+ msg_scroll = true; // Don't overwrite messages here.
+ msg_silent = 0; // Must give this prompt.
+ // Don't use emsg() here, don't want to flush the buffers.
+ msg_attr(_("WARNING: The file has been changed since reading it!!!"),
+ hl_attr(HLF_E));
+ if (ask_yesno(_("Do you really want to write to it"), true) == 'n') {
return FAIL;
- msg_scroll = FALSE; /* always overwrite the file message now */
+ }
+ msg_scroll = false; // Always overwrite the file message now.
}
return OK;
}
@@ -4553,9 +4541,10 @@ int put_time(FILE *fd, time_t time_)
/// os_rename() only works if both files are on the same file system, this
/// function will (attempts to?) copy the file across if rename fails -- webb
-//
+///
/// @return -1 for failure, 0 for success
-int vim_rename(char_u *from, char_u *to)
+int vim_rename(const char_u *from, const char_u *to)
+ FUNC_ATTR_NONNULL_ALL
{
int fd_in;
int fd_out;
@@ -4574,10 +4563,12 @@ int vim_rename(char_u *from, char_u *to)
* the file name differs we need to go through a temp file.
*/
if (fnamecmp(from, to) == 0) {
- if (p_fic && STRCMP(path_tail(from), path_tail(to)) != 0)
+ if (p_fic && (STRCMP(path_tail((char_u *)from), path_tail((char_u *)to))
+ != 0)) {
use_tmp_file = true;
- else
+ } else {
return 0;
+ }
}
// Fail if the "from" file doesn't exist. Avoids that "to" is deleted.
@@ -4643,9 +4634,9 @@ int vim_rename(char_u *from, char_u *to)
/*
* Rename() failed, try copying the file.
*/
- perm = os_getperm(from);
+ perm = os_getperm((const char *)from);
#ifdef HAVE_ACL
- /* For systems that support ACL: get the ACL from the original file. */
+ // For systems that support ACL: get the ACL from the original file.
acl = mch_get_acl(from);
#endif
fd_in = os_open((char *)from, O_RDONLY, 0);
@@ -4667,7 +4658,7 @@ int vim_rename(char_u *from, char_u *to)
return -1;
}
- // Avoid xmalloc() here as vim_rename() is called by buf_write() when neovim
+ // Avoid xmalloc() here as vim_rename() is called by buf_write() when nvim
// is `preserve_exit()`ing.
buffer = try_malloc(BUFSIZE);
if (buffer == NULL) {
@@ -4693,8 +4684,8 @@ int vim_rename(char_u *from, char_u *to)
errmsg = _("E210: Error reading \"%s\"");
to = from;
}
-#ifndef UNIX /* for Unix os_open() already set the permission */
- os_setperm(to, perm);
+#ifndef UNIX // For Unix os_open() already set the permission.
+ os_setperm((const char *)to, perm);
#endif
#ifdef HAVE_ACL
mch_set_acl(to, acl);
@@ -4726,7 +4717,6 @@ check_timestamps (
int focus /* called for GUI focus event */
)
{
- buf_T *buf;
int didit = 0;
int n;
@@ -4745,32 +4735,33 @@ check_timestamps (
if (!stuff_empty() || global_busy || !typebuf_typed()
|| autocmd_busy || curbuf_lock > 0 || allbuf_lock > 0
- )
- need_check_timestamps = TRUE; /* check later */
- else {
- ++no_wait_return;
- did_check_timestamps = TRUE;
- already_warned = FALSE;
- for (buf = firstbuf; buf != NULL; ) {
- /* Only check buffers in a window. */
+ ) {
+ need_check_timestamps = true; // check later
+ } else {
+ no_wait_return++;
+ did_check_timestamps = true;
+ already_warned = false;
+ FOR_ALL_BUFFERS(buf) {
+ // Only check buffers in a window.
if (buf->b_nwindows > 0) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
n = buf_check_timestamp(buf, focus);
- if (didit < n)
+ if (didit < n) {
didit = n;
- if (n > 0 && !buf_valid(buf)) {
- /* Autocommands have removed the buffer, start at the
- * first one again. */
+ }
+ if (n > 0 && !bufref_valid(&bufref)) {
+ // Autocommands have removed the buffer, start at the first one again.
buf = firstbuf;
continue;
}
}
- buf = buf->b_next;
}
--no_wait_return;
need_check_timestamps = FALSE;
if (need_wait_return && didit == 2) {
- /* make sure msg isn't overwritten */
- msg_puts((char_u *)"\n");
+ // make sure msg isn't overwritten
+ msg_puts("\n");
ui_flush();
}
}
@@ -4829,6 +4820,7 @@ buf_check_timestamp (
buf_T *buf,
int focus /* called for GUI focus event */
)
+ FUNC_ATTR_NONNULL_ALL
{
int retval = 0;
char_u *path;
@@ -4844,6 +4836,9 @@ buf_check_timestamp (
char_u *s;
char *reason;
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+
// If its a terminal, there is no file name, the buffer is not loaded,
// 'buftype' is set, we are in the middle of a save or being called
// recursively: ignore this buffer.
@@ -4913,8 +4908,9 @@ buf_check_timestamp (
allbuf_lock--;
busy = false;
if (n) {
- if (!buf_valid(buf))
+ if (!bufref_valid(&bufref)) {
EMSG(_("E246: FileChangedShell autocommand deleted buffer"));
+ }
s = get_vim_var_str(VV_FCS_CHOICE);
if (STRCMP(s, "reload") == 0 && *reason != 'd')
reload = TRUE;
@@ -4976,8 +4972,8 @@ buf_check_timestamp (
set_vim_var_string(VV_WARNINGMSG, tbuf, -1);
if (can_reload) {
if (*mesg2 != NUL) {
- strncat(tbuf, "\n", tbuf_len);
- strncat(tbuf, mesg2, tbuf_len);
+ xstrlcat(tbuf, "\n", tbuf_len - 1);
+ xstrlcat(tbuf, mesg2, tbuf_len - 1);
}
if (do_dialog(VIM_WARNING, (char_u *) _("Warning"), (char_u *) tbuf,
(char_u *) _("&OK\n&Load File"), 1, NULL, true) == 2) {
@@ -4985,18 +4981,17 @@ buf_check_timestamp (
}
} else if (State > NORMAL_BUSY || (State & CMDLINE) || already_warned) {
if (*mesg2 != NUL) {
- strncat(tbuf, "; ", tbuf_len);
- strncat(tbuf, mesg2, tbuf_len);
+ xstrlcat(tbuf, "; ", tbuf_len - 1);
+ xstrlcat(tbuf, mesg2, tbuf_len - 1);
}
EMSG(tbuf);
retval = 2;
} else {
if (!autocmd_busy) {
msg_start();
- msg_puts_attr((char_u *) tbuf, hl_attr(HLF_E) + MSG_HIST);
+ msg_puts_attr(tbuf, hl_attr(HLF_E) + MSG_HIST);
if (*mesg2 != NUL) {
- msg_puts_attr((char_u *)mesg2,
- hl_attr(HLF_W) + MSG_HIST);
+ msg_puts_attr(mesg2, hl_attr(HLF_W) + MSG_HIST);
}
msg_clr_eos();
(void)msg_end();
@@ -5031,11 +5026,11 @@ buf_check_timestamp (
}
}
- /* Trigger FileChangedShell when the file was changed in any way. */
- if (buf_valid(buf) && retval != 0)
- (void)apply_autocmds(EVENT_FILECHANGEDSHELLPOST,
- buf->b_fname, buf->b_fname, FALSE, buf);
-
+ // Trigger FileChangedShell when the file was changed in any way.
+ if (bufref_valid(&bufref) && retval != 0) {
+ (void)apply_autocmds(EVENT_FILECHANGEDSHELLPOST, buf->b_fname, buf->b_fname,
+ false, buf);
+ }
return retval;
}
@@ -5052,6 +5047,7 @@ void buf_reload(buf_T *buf, int orig_mode)
linenr_T old_topline;
int old_ro = buf->b_p_ro;
buf_T *savebuf;
+ bufref_T bufref;
int saved = OK;
aco_save_T aco;
int flags = READ_NEW;
@@ -5087,6 +5083,7 @@ void buf_reload(buf_T *buf, int orig_mode)
} else {
// Allocate a buffer without putting it in the buffer list.
savebuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
+ set_bufref(&bufref, savebuf);
if (savebuf != NULL && buf == curbuf) {
/* Open the memline. */
curbuf = savebuf;
@@ -5104,19 +5101,21 @@ void buf_reload(buf_T *buf, int orig_mode)
}
if (saved == OK) {
- curbuf->b_flags |= BF_CHECK_RO; /* check for RO again */
- keep_filetype = TRUE; /* don't detect 'filetype' */
- if (readfile(buf->b_ffname, buf->b_fname, (linenr_T)0,
- (linenr_T)0,
- (linenr_T)MAXLNUM, &ea, flags) == FAIL) {
- if (!aborting())
+ curbuf->b_flags |= BF_CHECK_RO; // check for RO again
+ keep_filetype = true; // don't detect 'filetype'
+ if (readfile(buf->b_ffname, buf->b_fname, (linenr_T)0, (linenr_T)0,
+ (linenr_T)MAXLNUM, &ea, flags) != OK) {
+ if (!aborting()) {
EMSG2(_("E321: Could not reload \"%s\""), buf->b_fname);
- if (savebuf != NULL && buf_valid(savebuf) && buf == curbuf) {
- /* Put the text back from the save buffer. First
- * delete any lines that readfile() added. */
- while (!bufempty())
- if (ml_delete(buf->b_ml.ml_line_count, FALSE) == FAIL)
+ }
+ if (savebuf != NULL && bufref_valid(&bufref) && buf == curbuf) {
+ // Put the text back from the save buffer. First
+ // delete any lines that readfile() added.
+ while (!bufempty()) {
+ if (ml_delete(buf->b_ml.ml_line_count, false) == FAIL) {
break;
+ }
+ }
(void)move_lines(savebuf, buf);
}
} else if (buf == curbuf) { /* "buf" still valid */
@@ -5133,8 +5132,9 @@ void buf_reload(buf_T *buf, int orig_mode)
}
xfree(ea.cmd);
- if (savebuf != NULL && buf_valid(savebuf))
- wipe_buffer(savebuf, FALSE);
+ if (savebuf != NULL && bufref_valid(&bufref)) {
+ wipe_buffer(savebuf, false);
+ }
/* Invalidate diff info if necessary. */
diff_invalidate(curbuf);
@@ -5197,7 +5197,7 @@ void forward_slash(char_u *fname)
{
char_u *p;
- if (path_with_url(fname)) {
+ if (path_with_url((const char *)fname)) {
return;
}
for (p = fname; *p != NUL; p++) {
@@ -5258,7 +5258,7 @@ static void vim_maketempdir(void)
/// Delete "name" and everything in it, recursively.
/// @param name The path which should be deleted.
/// @return 0 for success, -1 if some file was not deleted.
-int delete_recursive(char_u *name)
+int delete_recursive(const char *name)
{
int result = 0;
@@ -5272,7 +5272,7 @@ int delete_recursive(char_u *name)
EW_DIR | EW_FILE | EW_SILENT | EW_ALLLINKS
| EW_DODOT | EW_EMPTYOK) == OK) {
for (int i = 0; i < file_count; i++) {
- if (delete_recursive(files[i]) != 0) {
+ if (delete_recursive((const char *)files[i]) != 0) {
result = -1;
}
}
@@ -5282,9 +5282,9 @@ int delete_recursive(char_u *name)
}
xfree(exp);
- os_rmdir((char *)name);
+ os_rmdir(name);
} else {
- result = os_remove((char *)name) == 0 ? 0 : -1;
+ result = os_remove(name) == 0 ? 0 : -1;
}
return result;
@@ -5296,7 +5296,7 @@ void vim_deltempdir(void)
if (vim_tempdir != NULL) {
// remove the trailing path separator
path_tail(vim_tempdir)[-1] = NUL;
- delete_recursive(vim_tempdir);
+ delete_recursive((const char *)vim_tempdir);
xfree(vim_tempdir);
vim_tempdir = NULL;
}
@@ -5367,11 +5367,9 @@ char_u *vim_tempname(void)
static AutoPatCmd *active_apc_list = NULL; /* stack of active autocommands */
-/*
- * augroups stores a list of autocmd group names.
- */
-static garray_T augroups = {0, 0, sizeof(char_u *), 10, NULL};
-#define AUGROUP_NAME(i) (((char_u **)augroups.ga_data)[i])
+/// List of autocmd group names
+static garray_T augroups = { 0, 0, sizeof(char_u *), 10, NULL };
+#define AUGROUP_NAME(i) (((char **)augroups.ga_data)[i])
/*
* The ID of the current group. Group 0 is the default one.
@@ -5386,6 +5384,18 @@ static event_T last_event;
static int last_group;
static int autocmd_blocked = 0; /* block all autocmds */
+// use get_deleted_augroup() to get this
+static const char *deleted_augroup = NULL;
+
+static inline const char *get_deleted_augroup(void)
+ FUNC_ATTR_ALWAYS_INLINE
+{
+ if (deleted_augroup == NULL) {
+ deleted_augroup = _("--Deleted--");
+ }
+ return deleted_augroup;
+}
+
/*
* Show the autocommands for one AutoPat.
*/
@@ -5405,11 +5415,12 @@ static void show_autocmd(AutoPat *ap, event_T event)
return;
if (event != last_event || ap->group != last_group) {
if (ap->group != AUGROUP_DEFAULT) {
- if (AUGROUP_NAME(ap->group) == NULL)
- msg_puts_attr((char_u *)_("--Deleted--"), hl_attr(HLF_E));
- else
+ if (AUGROUP_NAME(ap->group) == NULL) {
+ msg_puts_attr(get_deleted_augroup(), hl_attr(HLF_E));
+ } else {
msg_puts_attr(AUGROUP_NAME(ap->group), hl_attr(HLF_T));
- msg_puts((char_u *)" ");
+ }
+ msg_puts(" ");
}
msg_puts_attr(event_nr2name(event), hl_attr(HLF_T));
last_event = event;
@@ -5538,7 +5549,7 @@ void aubuflocal_remove(buf_T *buf)
if (p_verbose >= 6) {
verbose_enter();
smsg(_("auto-removing autocommand: %s <buffer=%d>"),
- event_nr2name(event), buf->b_fnum);
+ event_nr2name(event), buf->b_fnum);
verbose_leave();
}
}
@@ -5561,9 +5572,10 @@ static int au_new_group(char_u *name)
ga_grow(&augroups, 1);
}
- AUGROUP_NAME(i) = vim_strsave(name);
- if (i == augroups.ga_len)
- ++augroups.ga_len;
+ AUGROUP_NAME(i) = xstrdup((char *)name);
+ if (i == augroups.ga_len) {
+ augroups.ga_len++;
+ }
}
return i;
@@ -5574,11 +5586,33 @@ static void au_del_group(char_u *name)
int i;
i = au_find_group(name);
- if (i == AUGROUP_ERROR) /* the group doesn't exist */
+ if (i == AUGROUP_ERROR) { // the group doesn't exist
EMSG2(_("E367: No such group: \"%s\""), name);
- else {
+ } else if (i == current_augroup) {
+ EMSG(_("E936: Cannot delete the current group"));
+ } else {
+ event_T event;
+ AutoPat *ap;
+ int in_use = false;
+
+ for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
+ event = (event_T)((int)event + 1)) {
+ for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) {
+ if (ap->group == i && ap->pat != NULL) {
+ give_warning((char_u *)
+ _("W19: Deleting augroup that is still in use"), true);
+ in_use = true;
+ event = NUM_EVENTS;
+ break;
+ }
+ }
+ }
xfree(AUGROUP_NAME(i));
- AUGROUP_NAME(i) = NULL;
+ if (in_use) {
+ AUGROUP_NAME(i) = (char *)get_deleted_augroup();
+ } else {
+ AUGROUP_NAME(i) = NULL;
+ }
}
}
@@ -5590,8 +5624,9 @@ static void au_del_group(char_u *name)
static int au_find_group(const char_u *name)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- for (int i = 0; i < augroups.ga_len; ++i) {
- if (AUGROUP_NAME(i) != NULL && STRCMP(AUGROUP_NAME(i), name) == 0) {
+ for (int i = 0; i < augroups.ga_len; i++) {
+ if (AUGROUP_NAME(i) != NULL && AUGROUP_NAME(i) != get_deleted_augroup()
+ && STRCMP(AUGROUP_NAME(i), name) == 0) {
return i;
}
}
@@ -5628,7 +5663,7 @@ void do_augroup(char_u *arg, int del_group)
for (int i = 0; i < augroups.ga_len; ++i) {
if (AUGROUP_NAME(i) != NULL) {
msg_puts(AUGROUP_NAME(i));
- msg_puts((char_u *)" ");
+ msg_puts(" ");
}
}
msg_clr_eos();
@@ -5640,11 +5675,18 @@ void do_augroup(char_u *arg, int del_group)
void free_all_autocmds(void)
{
for (current_augroup = -1; current_augroup < augroups.ga_len;
- ++current_augroup)
- do_autocmd((char_u *)"", TRUE);
- ga_clear_strings(&augroups);
-}
+ current_augroup++) {
+ do_autocmd((char_u *)"", true);
+ }
+ for (int i = 0; i < augroups.ga_len; i++) {
+ char *const s = ((char **)(augroups.ga_data))[i];
+ if ((const char *)s != get_deleted_augroup()) {
+ xfree(s);
+ }
+ }
+ ga_clear(&augroups);
+}
#endif
/*
@@ -5652,13 +5694,13 @@ void free_all_autocmds(void)
* Return NUM_EVENTS if the event name was not found.
* Return a pointer to the next event name in "end".
*/
-static event_T event_name2nr(char_u *start, char_u **end)
+static event_T event_name2nr(const char_u *start, char_u **end)
{
- char_u *p;
+ const char_u *p;
int i;
int len;
- // the event name ends with end of line, '|', a blank or a comma */
+ // the event name ends with end of line, '|', a blank or a comma
for (p = start; *p && !ascii_iswhite(*p) && *p != ',' && *p != '|'; p++) {
}
for (i = 0; event_names[i].name != NULL; i++) {
@@ -5667,25 +5709,32 @@ static event_T event_name2nr(char_u *start, char_u **end)
break;
}
}
- if (*p == ',')
- ++p;
- *end = p;
- if (event_names[i].name == NULL)
+ if (*p == ',') {
+ p++;
+ }
+ *end = (char_u *)p;
+ if (event_names[i].name == NULL) {
return NUM_EVENTS;
+ }
return event_names[i].event;
}
-/*
- * Return the name for event "event".
- */
-static char_u *event_nr2name(event_T event)
+/// Return the name for event
+///
+/// @param[in] event Event to return name for.
+///
+/// @return Event name, static string. Returns "Unknown" for unknown events.
+static const char *event_nr2name(event_T event)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_CONST
{
int i;
- for (i = 0; event_names[i].name != NULL; ++i)
- if (event_names[i].event == event)
- return (char_u *)event_names[i].name;
- return (char_u *)"Unknown";
+ for (i = 0; event_names[i].name != NULL; i++) {
+ if (event_names[i].event == event) {
+ return event_names[i].name;
+ }
+ }
+ return "Unknown";
}
/*
@@ -6237,6 +6286,7 @@ void ex_doautoall(exarg_T *eap)
aco_save_T aco;
char_u *arg = eap->arg;
int call_do_modelines = check_nomodeline(&arg);
+ bufref_T bufref;
/*
* This is a bit tricky: For some commands curwin->w_buffer needs to be
@@ -6249,8 +6299,9 @@ void ex_doautoall(exarg_T *eap)
if (buf->b_ml.ml_mfp == NULL) {
continue;
}
- /* find a window for this buffer and save some values */
+ // Find a window for this buffer and save some values.
aucmd_prepbuf(&aco, buf);
+ set_bufref(&bufref, buf);
bool did_aucmd;
// execute the autocommands for this buffer
@@ -6266,9 +6317,10 @@ void ex_doautoall(exarg_T *eap)
/* restore the current window */
aucmd_restbuf(&aco);
- /* stop if there is some error or buffer was deleted */
- if (retval == FAIL || !buf_valid(buf))
+ // Stop if there is some error or buffer was deleted.
+ if (retval == FAIL || !bufref_valid(&bufref)) {
break;
+ }
}
check_cursor(); /* just in case lines got deleted */
@@ -6375,7 +6427,7 @@ aucmd_prepbuf (
}
curbuf = buf;
aco->new_curwin = curwin;
- aco->new_curbuf = curbuf;
+ set_bufref(&aco->new_curbuf, curbuf);
}
/// Cleanup after executing autocommands for a (hidden) buffer.
@@ -6409,6 +6461,12 @@ win_found:
win_remove(curwin, NULL);
aucmd_win_used = false;
last_status(false); // may need to remove last status line
+
+ if (!valid_tabpage_win(curtab)) {
+ // no valid window in current tabpage
+ close_tabpage(curtab);
+ }
+
restore_snapshot(SNAP_AUCMD_IDX, false);
(void)win_comp_pos(); // recompute window positions
unblock_autocmds();
@@ -6438,14 +6496,14 @@ win_found:
// 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) {
+ && curbuf != aco->new_curbuf.br_buf
+ && bufref_valid(&aco->new_curbuf)
+ && aco->new_curbuf.br_buf->b_ml.ml_mfp != NULL) {
if (curwin->w_s == &curbuf->b_s) {
- curwin->w_s = &aco->new_curbuf->b_s;
+ curwin->w_s = &aco->new_curbuf.br_buf->b_s;
}
curbuf->b_nwindows--;
- curbuf = aco->new_curbuf;
+ curbuf = aco->new_curbuf.br_buf;
curwin->w_buffer = curbuf;
curbuf->b_nwindows++;
}
@@ -6715,8 +6773,9 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
fname = vim_strsave(fname); /* make a copy, so we can change it */
} else {
sfname = vim_strsave(fname);
- // don't try expanding the following events
+ // Don't try expanding the following events.
if (event == EVENT_COLORSCHEME
+ || event == EVENT_DIRCHANGED
|| event == EVENT_FILETYPE
|| event == EVENT_FUNCUNDEFINED
|| event == EVENT_OPTIONSET
@@ -6725,10 +6784,11 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
|| event == EVENT_REMOTEREPLY
|| event == EVENT_SPELLFILEMISSING
|| event == EVENT_SYNTAX
- || event == EVENT_TABCLOSED)
+ || event == EVENT_TABCLOSED) {
fname = vim_strsave(fname);
- else
- fname = (char_u *)FullName_save((char *)fname, FALSE);
+ } else {
+ fname = (char_u *)FullName_save((char *)fname, false);
+ }
}
if (fname == NULL) { /* out of memory */
xfree(sfname);
@@ -6810,8 +6870,8 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
patcmd.next = active_apc_list;
active_apc_list = &patcmd;
- /* set v:cmdarg (only when there is a matching pattern) */
- save_cmdbang = get_vim_var_nr(VV_CMDBANG);
+ // set v:cmdarg (only when there is a matching pattern)
+ save_cmdbang = (long)get_vim_var_nr(VV_CMDBANG);
if (eap != NULL) {
save_cmdarg = set_cmdarg(eap, NULL);
set_vim_var_nr(VV_CMDBANG, (long)eap->forceit);
@@ -6945,7 +7005,6 @@ auto_next_pat (
{
AutoPat *ap;
AutoCmd *cp;
- char_u *name;
char *s;
xfree(sourcing_name);
@@ -6964,11 +7023,13 @@ auto_next_pat (
? match_file_pat(NULL, &ap->reg_prog, apc->fname, apc->sfname,
apc->tail, ap->allow_dirs)
: ap->buflocal_nr == apc->arg_bufnr) {
- name = event_nr2name(apc->event);
+ const char *const name = event_nr2name(apc->event);
s = _("%s Auto commands for \"%s\"");
- sourcing_name = xmalloc(STRLEN(s) + STRLEN(name) + ap->patlen + 1);
- sprintf((char *)sourcing_name, s,
- (char *)name, (char *)ap->pat);
+ const size_t sourcing_name_len = (STRLEN(s) + strlen(name) + ap->patlen
+ + 1);
+ sourcing_name = xmalloc(sourcing_name_len);
+ snprintf((char *)sourcing_name, sourcing_name_len, s, name,
+ (char *)ap->pat);
if (p_verbose >= 8) {
verbose_enter();
smsg(_("Executing %s"), sourcing_name);
@@ -7034,7 +7095,7 @@ char_u *getnextac(int c, void *cookie, int indent)
if (p_verbose >= 9) {
verbose_enter_scroll();
smsg(_("autocommand %s"), ac->cmd);
- msg_puts((char_u *)"\n"); /* don't overwrite this either */
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
retval = vim_strsave(ac->cmd);
@@ -7100,13 +7161,17 @@ bool has_autocmd(event_T event, char_u *sfname, buf_T *buf)
*/
char_u *get_augroup_name(expand_T *xp, int idx)
{
- if (idx == augroups.ga_len) /* add "END" add the end */
+ if (idx == augroups.ga_len) { // add "END" add the end
return (char_u *)"END";
- if (idx >= augroups.ga_len) /* end of list */
+ }
+ if (idx >= augroups.ga_len) { // end of list
return NULL;
- if (AUGROUP_NAME(idx) == NULL) /* skip deleted entries */
+ }
+ if (AUGROUP_NAME(idx) == NULL || AUGROUP_NAME(idx) == get_deleted_augroup()) {
+ // skip deleted entries
return (char_u *)"";
- return AUGROUP_NAME(idx); /* return a name */
+ }
+ return (char_u *)AUGROUP_NAME(idx);
}
static int include_groups = FALSE;
@@ -7163,21 +7228,27 @@ set_context_in_autocmd (
*/
char_u *get_event_name(expand_T *xp, int idx)
{
- if (idx < augroups.ga_len) { /* First list group names, if wanted */
- if (!include_groups || AUGROUP_NAME(idx) == NULL)
- return (char_u *)""; /* skip deleted entries */
- return AUGROUP_NAME(idx); /* return a name */
+ if (idx < augroups.ga_len) { // First list group names, if wanted
+ if (!include_groups || AUGROUP_NAME(idx) == NULL
+ || AUGROUP_NAME(idx) == get_deleted_augroup()) {
+ return (char_u *)""; // skip deleted entries
+ }
+ return (char_u *)AUGROUP_NAME(idx);
}
return (char_u *)event_names[idx - augroups.ga_len].name;
}
-/// Return true if autocmd "event" is supported.
-bool autocmd_supported(char_u *event)
+/// Check whether given autocommand is supported
+///
+/// @param[in] event Event to check.
+///
+/// @return True if it is, false otherwise.
+bool autocmd_supported(const char *const event)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
char_u *p;
-
- return event_name2nr(event, &p) != NUM_EVENTS;
+ return event_name2nr((const char_u *)event, &p) != NUM_EVENTS;
}
/// Return true if an autocommand is defined for a group, event and
@@ -7192,26 +7263,24 @@ bool autocmd_supported(char_u *event)
/// exists("#Event#pat")
///
/// @param arg autocommand string
-bool au_exists(const char_u *arg) FUNC_ATTR_WARN_UNUSED_RESULT
+bool au_exists(const char *const arg) FUNC_ATTR_WARN_UNUSED_RESULT
{
- char_u *arg_save;
- char_u *pattern = NULL;
- char_u *event_name;
- char_u *p;
event_T event;
AutoPat *ap;
buf_T *buflocal_buf = NULL;
int group;
bool retval = false;
- /* Make a copy so that we can change the '#' chars to a NUL. */
- arg_save = vim_strsave(arg);
- p = vim_strchr(arg_save, '#');
- if (p != NULL)
+ // Make a copy so that we can change the '#' chars to a NUL.
+ char *const arg_save = xstrdup(arg);
+ char *p = strchr(arg_save, '#');
+ if (p != NULL) {
*p++ = NUL;
+ }
- /* First, look for an autocmd group name */
- group = au_find_group(arg_save);
+ // First, look for an autocmd group name.
+ group = au_find_group((char_u *)arg_save);
+ char *event_name;
if (group == AUGROUP_ERROR) {
/* Didn't match a group name, assume the first argument is an event. */
group = AUGROUP_ALL;
@@ -7223,17 +7292,18 @@ bool au_exists(const char_u *arg) FUNC_ATTR_WARN_UNUSED_RESULT
goto theend;
}
- /* Must be "Group#Event" or "Group#Event#pat". */
+ // Must be "Group#Event" or "Group#Event#pat".
event_name = p;
- p = vim_strchr(event_name, '#');
- if (p != NULL)
- *p++ = NUL; /* "Group#Event#pat" */
+ p = strchr(event_name, '#');
+ if (p != NULL) {
+ *p++ = NUL; // "Group#Event#pat"
+ }
}
- pattern = p; /* "pattern" is NULL when there is no pattern */
+ char *pattern = p; // "pattern" is NULL when there is no pattern.
- /* find the index (enum) for the event name */
- event = event_name2nr(event_name, &p);
+ // Find the index (enum) for the event name.
+ event = event_name2nr((char_u *)event_name, (char_u **)&p);
/* return FALSE if the event name is not recognized */
if (event == NUM_EVENTS)
@@ -7259,7 +7329,7 @@ bool au_exists(const char_u *arg) FUNC_ATTR_WARN_UNUSED_RESULT
&& (group == AUGROUP_ALL || ap->group == group)
&& (pattern == NULL
|| (buflocal_buf == NULL
- ? fnamecmp(ap->pat, pattern) == 0
+ ? fnamecmp(ap->pat, (char_u *)pattern) == 0
: ap->buflocal_nr == buflocal_buf->b_fnum))) {
retval = true;
break;
diff --git a/src/nvim/fileio.h b/src/nvim/fileio.h
index ceb101167d..8db4b89806 100644
--- a/src/nvim/fileio.h
+++ b/src/nvim/fileio.h
@@ -4,13 +4,14 @@
#include "nvim/buffer_defs.h"
#include "nvim/os/os.h"
-/* Values for readfile() flags */
-#define READ_NEW 0x01 /* read a file into a new buffer */
-#define READ_FILTER 0x02 /* read filter output */
-#define READ_STDIN 0x04 /* read from stdin */
-#define READ_BUFFER 0x08 /* read from curbuf (converting stdin) */
-#define READ_DUMMY 0x10 /* reading into a dummy buffer */
-#define READ_KEEP_UNDO 0x20 /* keep undo info*/
+// Values for readfile() flags
+#define READ_NEW 0x01 // read a file into a new buffer
+#define READ_FILTER 0x02 // read filter output
+#define READ_STDIN 0x04 // read from stdin
+#define READ_BUFFER 0x08 // read from curbuf (converting stdin)
+#define READ_DUMMY 0x10 // reading into a dummy buffer
+#define READ_KEEP_UNDO 0x20 // keep undo info
+#define READ_FIFO 0x40 // read from fifo or socket
#define READ_STRING(x, y) (char_u *)read_string((x), (size_t)(y))
@@ -19,12 +20,12 @@
* not the current buffer.
*/
typedef struct {
- buf_T *save_curbuf; /* saved curbuf */
- int use_aucmd_win; /* using aucmd_win */
- win_T *save_curwin; /* saved curwin */
- win_T *new_curwin; /* new curwin */
- buf_T *new_curbuf; /* new curbuf */
- char_u *globaldir; /* saved value of globaldir */
+ buf_T *save_curbuf; ///< saved curbuf
+ int use_aucmd_win; ///< using aucmd_win
+ win_T *save_curwin; ///< saved curwin
+ win_T *new_curwin; ///< new curwin
+ bufref_T new_curbuf; ///< new curbuf
+ char_u *globaldir; ///< saved value of globaldir
} aco_save_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index dcd32acfb7..db88791967 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
// vim: set fdm=marker fdl=1 fdc=3
/*
@@ -29,6 +32,7 @@
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/undo.h"
+#include "nvim/ops.h"
/* local declarations. {{{1 */
/* typedef fold_T {{{2 */
@@ -1438,13 +1442,16 @@ static void foldMarkAdjustRecurse(garray_T *gap, linenr_T line1, linenr_T line2,
} else {
/* 5. fold is below line1 and contains line2; need to
* correct nested folds too */
- foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
- line2 - fp->fd_top, amount,
- amount_after + (fp->fd_top - top));
if (amount == MAXLNUM) {
+ foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
+ line2 - fp->fd_top, amount,
+ amount_after + (fp->fd_top - top));
fp->fd_len -= line2 - fp->fd_top + 1;
fp->fd_top = line1;
} else {
+ foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
+ line2 - fp->fd_top, amount,
+ amount_after - amount);
fp->fd_len += amount_after - amount;
fp->fd_top += amount;
}
@@ -1590,29 +1597,32 @@ static void foldCreateMarkers(linenr_T start, linenr_T end)
/*
* Add "marker[markerlen]" in 'commentstring' to line "lnum".
*/
-static void foldAddMarker(linenr_T lnum, char_u *marker, size_t markerlen)
+static void foldAddMarker(linenr_T lnum, const char_u *marker, size_t markerlen)
{
char_u *cms = curbuf->b_p_cms;
char_u *line;
char_u *newline;
char_u *p = (char_u *)strstr((char *)curbuf->b_p_cms, "%s");
+ bool line_is_comment = false;
- /* Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end */
+ // Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end
line = ml_get(lnum);
size_t line_len = STRLEN(line);
if (u_save(lnum - 1, lnum + 1) == OK) {
+ // Check if the line ends with an unclosed comment
+ skip_comment(line, false, false, &line_is_comment);
newline = xmalloc(line_len + markerlen + STRLEN(cms) + 1);
STRCPY(newline, line);
- if (p == NULL)
+ // Append the marker to the end of the line
+ if (p == NULL || line_is_comment) {
STRLCPY(newline + line_len, marker, markerlen + 1);
- else {
+ } else {
STRCPY(newline + line_len, cms);
- STRNCPY(newline + line_len + (p - cms), marker, markerlen);
+ memcpy(newline + line_len + (p - cms), marker, markerlen);
STRCPY(newline + line_len + (p - cms) + markerlen, p + 2);
}
-
- ml_replace(lnum, newline, FALSE);
+ ml_replace(lnum, newline, false);
}
}
@@ -1673,7 +1683,8 @@ static void foldDelMarker(linenr_T lnum, char_u *marker, size_t markerlen)
if (u_save(lnum - 1, lnum + 1) == OK) {
/* Make new line: text-before-marker + text-after-marker */
newline = xmalloc(STRLEN(line) - len + 1);
- STRNCPY(newline, line, p - line);
+ assert(p >= line);
+ memcpy(newline, line, (size_t)(p - line));
STRCPY(newline + (p - line), p + len);
ml_replace(lnum, newline, FALSE);
}
@@ -1681,12 +1692,10 @@ static void foldDelMarker(linenr_T lnum, char_u *marker, size_t markerlen)
}
}
-/* get_foldtext() {{{2 */
-/*
- * Return the text for a closed fold at line "lnum", with last line "lnume".
- * When 'foldtext' isn't set puts the result in "buf[51]". Otherwise the
- * result is in allocated memory.
- */
+// get_foldtext() {{{2
+/// Return the text for a closed fold at line "lnum", with last line "lnume".
+/// When 'foldtext' isn't set puts the result in "buf[FOLD_TEXT_LEN]".
+/// Otherwise the result is in allocated memory.
char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume,
foldinfo_T *foldinfo, char_u *buf)
FUNC_ATTR_NONNULL_ARG(1)
@@ -1773,8 +1782,12 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume,
}
}
if (text == NULL) {
- sprintf((char *)buf, _("+--%3ld lines folded "),
- (long)(lnume - lnum + 1));
+ unsigned long count = (unsigned long)(lnume - lnum + 1);
+
+ vim_snprintf((char *)buf, FOLD_TEXT_LEN,
+ ngettext("+--%3ld line folded",
+ "+--%3ld lines folded ", count),
+ count);
text = buf;
}
return text;
@@ -2224,32 +2237,51 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
* before where we started looking, extend it. If it
* starts at another line, update nested folds to keep
* their position, compensating for the new fd_top. */
- if (fp->fd_top >= startlnum && fp->fd_top != firstlnum) {
- if (fp->fd_top > firstlnum)
- /* like lines are inserted */
+ if (fp->fd_top == firstlnum) {
+ // We have found a fold beginning exactly where we want one.
+ } else if (fp->fd_top >= startlnum) {
+ if (fp->fd_top > firstlnum) {
+ // We will move the start of this fold up, hence we move all
+ // nested folds (with relative line numbers) down.
foldMarkAdjustRecurse(&fp->fd_nested,
- (linenr_T)0, (linenr_T)MAXLNUM,
- (long)(fp->fd_top - firstlnum), 0L);
- else
- /* like lines are deleted */
+ (linenr_T)0, (linenr_T)MAXLNUM,
+ (long)(fp->fd_top - firstlnum), 0L);
+ } else {
+ // Will move fold down, move nested folds relatively up.
foldMarkAdjustRecurse(&fp->fd_nested,
- (linenr_T)0,
- (long)(firstlnum - fp->fd_top - 1),
- (linenr_T)MAXLNUM,
- (long)(fp->fd_top - firstlnum));
+ (linenr_T)0,
+ (long)(firstlnum - fp->fd_top - 1),
+ (linenr_T)MAXLNUM,
+ (long)(fp->fd_top - firstlnum));
+ }
fp->fd_len += fp->fd_top - firstlnum;
fp->fd_top = firstlnum;
- fold_changed = TRUE;
- } else if (flp->start != 0 && lvl == level
- && fp->fd_top != firstlnum) {
- /* Existing fold that includes startlnum must stop
- * if we find the start of a new fold at the same
- * level. Split it. Delete contained folds at
- * this point to split them too. */
- foldRemove(&fp->fd_nested, flp->lnum - fp->fd_top,
- flp->lnum - fp->fd_top);
+ fold_changed = true;
+ } else if ((flp->start != 0 && lvl == level)
+ || (firstlnum != startlnum)) {
+ // Before there was a fold spanning from above startlnum to below
+ // firstlnum. This fold is valid above startlnum (because we are
+ // not updating that range), but there is now a break in it.
+ // If the break is because we are now forced to start a new fold
+ // at the level "level" at line fline->lnum, then we need to
+ // split the fold at fline->lnum.
+ // If the break is because the range [startlnum, firstlnum) is
+ // now at a lower indent than "level", we need to split the fold
+ // in this range.
+ // Any splits have to be done recursively.
+ linenr_T breakstart;
+ linenr_T breakend;
+ if (firstlnum != startlnum) {
+ breakstart = startlnum;
+ breakend = firstlnum;
+ } else {
+ breakstart = flp->lnum;
+ breakend = flp->lnum;
+ }
+ foldRemove(&fp->fd_nested, breakstart - fp->fd_top,
+ breakend - fp->fd_top);
i = (int)(fp - (fold_T *)gap->ga_data);
- foldSplit(gap, i, flp->lnum, flp->lnum - 1);
+ foldSplit(gap, i, breakstart, breakend - 1);
fp = (fold_T *)gap->ga_data + i + 1;
/* If using the "marker" or "syntax" method, we
* need to continue until the end of the fold is
@@ -2259,6 +2291,16 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
|| getlevel == foldlevelSyntax)
finish = TRUE;
}
+ if (fp->fd_top == startlnum && concat) {
+ i = (int)(fp - (fold_T *)gap->ga_data);
+ if (i != 0) {
+ fp2 = fp - 1;
+ if (fp2->fd_top + fp2->fd_len == fp->fd_top) {
+ foldMerge(fp2, gap, fp);
+ fp = fp2;
+ }
+ }
+ }
break;
}
if (fp->fd_top >= startlnum) {
@@ -2499,6 +2541,8 @@ static void foldSplit(garray_T *gap, int i, linenr_T top, linenr_T bot)
fp = (fold_T *)gap->ga_data + i;
fp[1].fd_top = bot + 1;
+ // check for wrap around (MAXLNUM, and 32bit)
+ assert(fp[1].fd_top > bot);
fp[1].fd_len = fp->fd_len - (fp[1].fd_top - fp->fd_top);
fp[1].fd_flags = fp->fd_flags;
fp[1].fd_small = MAYBE;
@@ -2531,10 +2575,10 @@ static void foldSplit(garray_T *gap, int i, linenr_T top, linenr_T bot)
* 1 2 3
* 1 2 3
* top 2 3 4 5
- * 2 3 4 5
- * bot 2 3 4 5
- * 3 5 6
- * 3 5 6
+ * 2 3 4 5
+ * bot 2 3 4 5
+ * 3 5 6
+ * 3 5 6
*
* 1: not changed
* 2: truncate to stop above "top"
@@ -2547,34 +2591,35 @@ static void foldRemove(garray_T *gap, linenr_T top, linenr_T bot)
{
fold_T *fp = NULL;
- if (bot < top)
- return; /* nothing to do */
+ if (bot < top) {
+ return; // nothing to do
+ }
for (;; ) {
- /* Find fold that includes top or a following one. */
+ // Find fold that includes top or a following one.
if (foldFind(gap, top, &fp) && fp->fd_top < top) {
- /* 2: or 3: need to delete nested folds */
+ // 2: or 3: need to delete nested folds
foldRemove(&fp->fd_nested, top - fp->fd_top, bot - fp->fd_top);
- if (fp->fd_top + fp->fd_len > bot + 1) {
- /* 3: need to split it. */
+ if (fp->fd_top + fp->fd_len - 1 > bot) {
+ // 3: need to split it.
foldSplit(gap, (int)(fp - (fold_T *)gap->ga_data), top, bot);
} else {
- /* 2: truncate fold at "top". */
+ // 2: truncate fold at "top".
fp->fd_len = top - fp->fd_top;
}
- fold_changed = TRUE;
+ fold_changed = true;
continue;
}
if (fp >= (fold_T *)(gap->ga_data) + gap->ga_len
|| fp->fd_top > bot) {
- /* 6: Found a fold below bot, can stop looking. */
+ // 6: Found a fold below bot, can stop looking.
break;
}
if (fp->fd_top >= top) {
- /* Found an entry below top. */
- fold_changed = TRUE;
+ // Found an entry below top.
+ fold_changed = true;
if (fp->fd_top + fp->fd_len - 1 > bot) {
- /* 5: Make fold that includes bot start below bot. */
+ // 5: Make fold that includes bot start below bot.
foldMarkAdjustRecurse(&fp->fd_nested,
(linenr_T)0, (long)(bot - fp->fd_top),
(linenr_T)MAXLNUM, (long)(fp->fd_top - bot - 1));
@@ -2583,11 +2628,162 @@ static void foldRemove(garray_T *gap, linenr_T top, linenr_T bot)
break;
}
- /* 4: Delete completely contained fold. */
- deleteFoldEntry(gap, (int)(fp - (fold_T *)gap->ga_data), TRUE);
+ // 4: Delete completely contained fold.
+ deleteFoldEntry(gap, (int)(fp - (fold_T *)gap->ga_data), true);
+ }
+ }
+}
+
+// foldMoveRange() {{{2
+static void reverse_fold_order(garray_T *gap, size_t start, size_t end)
+{
+ for (; start < end; start++, end--) {
+ fold_T *left = (fold_T *)gap->ga_data + start;
+ fold_T *right = (fold_T *)gap->ga_data + end;
+ fold_T tmp = *left;
+ *left = *right;
+ *right = tmp;
+ }
+}
+
+// Move folds within the inclusive range "line1" to "line2" to after "dest"
+// require "line1" <= "line2" <= "dest"
+//
+// There are the following situations for the first fold at or below line1 - 1.
+// 1 2 3 4
+// 1 2 3 4
+// line1 2 3 4
+// 2 3 4 5 6 7
+// line2 3 4 5 6 7
+// 3 4 6 7 8 9
+// dest 4 7 8 9
+// 4 7 8 10
+// 4 7 8 10
+//
+// In the following descriptions, "moved" means moving in the buffer, *and* in
+// the fold array.
+// Meanwhile, "shifted" just means moving in the buffer.
+// 1. not changed
+// 2. truncated above line1
+// 3. length reduced by line2 - line1, folds starting between the end of 3 and
+// dest are truncated and shifted up
+// 4. internal folds moved (from [line1, line2] to dest)
+// 5. moved to dest.
+// 6. truncated below line2 and moved.
+// 7. length reduced by line2 - dest, folds starting between line2 and dest are
+// removed, top is moved down by move_len.
+// 8. truncated below dest and shifted up.
+// 9. shifted up
+// 10. not changed
+static void truncate_fold(fold_T *fp, linenr_T end)
+{
+ // I want to stop *at here*, foldRemove() stops *above* top
+ end += 1;
+ foldRemove(&fp->fd_nested, end - fp->fd_top, MAXLNUM);
+ fp->fd_len = end - fp->fd_top;
+}
+
+#define FOLD_END(fp) ((fp)->fd_top + (fp)->fd_len - 1)
+#define VALID_FOLD(fp, gap) ((fp) < ((fold_T *)(gap)->ga_data + (gap)->ga_len))
+#define FOLD_INDEX(fp, gap) ((size_t)(fp - ((fold_T *)(gap)->ga_data)))
+void foldMoveRange(garray_T *gap, const linenr_T line1, const linenr_T line2,
+ const linenr_T dest)
+{
+ fold_T *fp;
+ const linenr_T range_len = line2 - line1 + 1;
+ const linenr_T move_len = dest - line2;
+ const bool at_start = foldFind(gap, line1 - 1, &fp);
+
+ if (at_start) {
+ if (FOLD_END(fp) > dest) {
+ // Case 4 -- don't have to change this fold, but have to move nested
+ // folds.
+ foldMoveRange(&fp->fd_nested, line1 - fp->fd_top, line2 -
+ fp->fd_top, dest - fp->fd_top);
+ return;
+ } else if (FOLD_END(fp) > line2) {
+ // Case 3 -- Remove nested folds between line1 and line2 & reduce the
+ // length of fold by "range_len".
+ // Folds after this one must be dealt with.
+ foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
+ line2 - fp->fd_top, MAXLNUM, -range_len);
+ fp->fd_len -= range_len;
+ } else {
+ // Case 2 -- truncate fold *above* line1.
+ // Folds after this one must be dealt with.
+ truncate_fold(fp, line1 - 1);
+ }
+ // Look at the next fold, and treat that one as if it were the first after
+ // "line1" (because now it is).
+ fp = fp + 1;
+ }
+
+ if (!VALID_FOLD(fp, gap) || fp->fd_top > dest) {
+ // No folds after "line1" and before "dest"
+ // Case 10.
+ return;
+ } else if (fp->fd_top > line2) {
+ for (; VALID_FOLD(fp, gap) && FOLD_END(fp) <= dest; fp++) {
+ // Case 9. (for all case 9's) -- shift up.
+ fp->fd_top -= range_len;
+ }
+ if (VALID_FOLD(fp, gap) && fp->fd_top <= dest) {
+ // Case 8. -- ensure truncated at dest, shift up
+ truncate_fold(fp, dest);
+ fp->fd_top -= range_len;
+ }
+ return;
+ } else if (FOLD_END(fp) > dest) {
+ // Case 7 -- remove nested folds and shrink
+ foldMarkAdjustRecurse(&fp->fd_nested, line2 + 1 - fp->fd_top,
+ dest - fp->fd_top, MAXLNUM, -move_len);
+ fp->fd_len -= move_len;
+ fp->fd_top += move_len;
+ return;
+ }
+
+ // Case 5 or 6: changes rely on whether there are folds between the end of
+ // this fold and "dest".
+ size_t move_start = FOLD_INDEX(fp, gap);
+ size_t move_end = 0, dest_index = 0;
+ for (; VALID_FOLD(fp, gap) && fp->fd_top <= dest; fp++) {
+ if (fp->fd_top <= line2) {
+ // 5, or 6
+ if (FOLD_END(fp) > line2) {
+ // 6, truncate before moving
+ truncate_fold(fp, line2);
+ }
+ fp->fd_top += move_len;
+ continue;
+ }
+
+ // Record index of the first fold after the moved range.
+ if (move_end == 0) {
+ move_end = FOLD_INDEX(fp, gap);
+ }
+
+ if (FOLD_END(fp) > dest) {
+ truncate_fold(fp, dest);
}
+
+ fp->fd_top -= range_len;
+ }
+ dest_index = FOLD_INDEX(fp, gap);
+
+ // All folds are now correct, but not necessarily in the correct order.
+ // We must swap folds in the range [move_end, dest_index) with those in the
+ // range [move_start, move_end).
+ if (move_end == 0) {
+ // There are no folds after those moved, so none were moved out of order.
+ return;
}
+ reverse_fold_order(gap, move_start, dest_index - 1);
+ reverse_fold_order(gap, move_start, move_start + dest_index - move_end - 1);
+ reverse_fold_order(gap, move_start + dest_index - move_end, dest_index - 1);
}
+#undef FOLD_END
+#undef VALID_FOLD
+#undef FOLD_INDEX
/* foldMerge() {{{2 */
/*
@@ -2698,7 +2894,7 @@ static void foldlevelExpr(fline_T *flp)
/* KeyTyped may be reset to 0 when calling a function which invokes
* do_cmdline(). To make 'foldopen' work correctly restore KeyTyped. */
save_keytyped = KeyTyped;
- n = eval_foldexpr(flp->wp->w_p_fde, &c);
+ n = (int)eval_foldexpr(flp->wp->w_p_fde, &c);
KeyTyped = save_keytyped;
switch (c) {
diff --git a/src/nvim/fold.h b/src/nvim/fold.h
index 2ff10c0e91..f35b328fb1 100644
--- a/src/nvim/fold.h
+++ b/src/nvim/fold.h
@@ -1,7 +1,12 @@
#ifndef NVIM_FOLD_H
#define NVIM_FOLD_H
+#include <stdio.h>
+
#include "nvim/pos.h"
+#include "nvim/garray.h"
+#include "nvim/types.h"
+#include "nvim/buffer_defs.h"
/*
* Info used to pass info about a fold from the fold-detection code to the
diff --git a/src/nvim/func_attr.h b/src/nvim/func_attr.h
index d98fe5b22b..bd26205d6d 100644
--- a/src/nvim/func_attr.h
+++ b/src/nvim/func_attr.h
@@ -41,9 +41,7 @@
// $ gcc -E -dM - </dev/null
// $ echo | clang -dM -E -
-#ifndef NVIM_FUNC_ATTR_H
-#define NVIM_FUNC_ATTR_H
-#undef NVIM_FUNC_ATTR_H
+#include "nvim/macros.h"
#ifdef FUNC_ATTR_MALLOC
# undef FUNC_ATTR_MALLOC
@@ -93,11 +91,18 @@
# undef FUNC_ATTR_NONNULL_RET
#endif
+#ifdef FUNC_ATTR_NORETURN
+# undef FUNC_ATTR_NORETURN
+#endif
+
+#ifdef FUNC_ATTR_NO_SANITIZE_UNDEFINED
+# undef FUNC_ATTR_NO_SANITIZE_UNDEFINED
+#endif
+
#ifndef DID_REAL_ATTR
# define DID_REAL_ATTR
# ifdef __GNUC__
-// place defines for all gnulikes here, for now that's gcc, clang and
-// intel.
+// For all gnulikes: gcc, clang, intel.
// place these after the argument list of the function declaration
// (not definition), like so:
@@ -111,27 +116,27 @@
# define REAL_FATTR_UNUSED __attribute__((unused))
# define REAL_FATTR_NONNULL_ALL __attribute__((nonnull))
# define REAL_FATTR_NONNULL_ARG(...) __attribute__((nonnull(__VA_ARGS__)))
+# define REAL_FATTR_NORETURN __attribute__((noreturn))
+
+# if NVIM_HAS_ATTRIBUTE(returns_nonnull)
+# define REAL_FATTR_NONNULL_RET __attribute__((returns_nonnull))
+# endif
-# ifdef __clang__
-// clang only
-# elif defined(__INTEL_COMPILER)
-// intel only
-# else
-# define GCC_VERSION \
- (__GNUC__ * 10000 + \
- __GNUC_MINOR__ * 100 + \
- __GNUC_PATCHLEVEL__)
-// gcc only
+# if NVIM_HAS_ATTRIBUTE(alloc_size)
# define REAL_FATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
# define REAL_FATTR_ALLOC_SIZE_PROD(x, y) __attribute__((alloc_size(x, y)))
-# if GCC_VERSION >= 40900
-# define REAL_FATTR_NONNULL_RET __attribute__((returns_nonnull))
-# endif
+# endif
+
+# if NVIM_HAS_ATTRIBUTE(no_sanitize_undefined)
+# define REAL_FATTR_NO_SANITIZE_UNDEFINED \
+ __attribute__((no_sanitize_undefined))
+# elif NVIM_HAS_ATTRIBUTE(no_sanitize)
+# define REAL_FATTR_NO_SANITIZE_UNDEFINED \
+ __attribute__((no_sanitize("undefined")))
# endif
# endif
-// define function attributes that haven't been defined for this specific
-// compiler.
+// Define attributes that are not defined for this compiler.
# ifndef REAL_FATTR_MALLOC
# define REAL_FATTR_MALLOC
@@ -180,12 +185,22 @@
# ifndef REAL_FATTR_NONNULL_RET
# define REAL_FATTR_NONNULL_RET
# endif
+
+# ifndef REAL_FATTR_NORETURN
+# define REAL_FATTR_NORETURN
+# endif
+
+# ifndef REAL_FATTR_NO_SANITIZE_UNDEFINED
+# define REAL_FATTR_NO_SANITIZE_UNDEFINED
+# endif
#endif
#ifdef DEFINE_FUNC_ATTRIBUTES
# define FUNC_API_ASYNC
# define FUNC_API_NOEXPORT
-# define FUNC_API_NOEVAL
+# define FUNC_API_REMOTE_ONLY
+# define FUNC_API_SINCE(X)
+# define FUNC_API_DEPRECATED_SINCE(X)
# define FUNC_ATTR_MALLOC REAL_FATTR_MALLOC
# define FUNC_ATTR_ALLOC_SIZE(x) REAL_FATTR_ALLOC_SIZE(x)
# define FUNC_ATTR_ALLOC_SIZE_PROD(x, y) REAL_FATTR_ALLOC_SIZE_PROD(x, y)
@@ -198,6 +213,8 @@
# define FUNC_ATTR_NONNULL_ALL REAL_FATTR_NONNULL_ALL
# define FUNC_ATTR_NONNULL_ARG(...) REAL_FATTR_NONNULL_ARG(__VA_ARGS__)
# define FUNC_ATTR_NONNULL_RET REAL_FATTR_NONNULL_RET
+# define FUNC_ATTR_NORETURN REAL_FATTR_NORETURN
+# define FUNC_ATTR_NO_SANITIZE_UNDEFINED REAL_FATTR_NO_SANITIZE_UNDEFINED
#elif !defined(DO_NOT_DEFINE_EMPTY_ATTRIBUTES)
# define FUNC_ATTR_MALLOC
# define FUNC_ATTR_ALLOC_SIZE(x)
@@ -211,5 +228,6 @@
# define FUNC_ATTR_NONNULL_ALL
# define FUNC_ATTR_NONNULL_ARG(...)
# define FUNC_ATTR_NONNULL_RET
+# define FUNC_ATTR_NORETURN
+# define FUNC_ATTR_NO_SANITIZE_UNDEFINED
#endif
-#endif // NVIM_FUNC_ATTR_H
diff --git a/src/nvim/garray.c b/src/nvim/garray.c
index 9ed3b901ef..2d2af54c95 100644
--- a/src/nvim/garray.c
+++ b/src/nvim/garray.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// @file garray.c
///
/// Functions for handling growing arrays.
diff --git a/src/nvim/garray.h b/src/nvim/garray.h
index 5d7806bbfa..94e1b61671 100644
--- a/src/nvim/garray.h
+++ b/src/nvim/garray.h
@@ -37,7 +37,7 @@ typedef struct growarray {
static inline void *ga_append_via_ptr(garray_T *gap, size_t item_size)
{
if ((int)item_size != gap->ga_itemsize) {
- ELOG("wrong item size in garray(%d), should be %d", item_size);
+ WLOG("wrong item size (%d), should be %d", item_size, gap->ga_itemsize);
}
ga_grow(gap, 1);
return ((char *)gap->ga_data) + (item_size * (size_t)gap->ga_len++);
diff --git a/src/nvim/generators/c_grammar.lua b/src/nvim/generators/c_grammar.lua
new file mode 100644
index 0000000000..d3047e1a9c
--- /dev/null
+++ b/src/nvim/generators/c_grammar.lua
@@ -0,0 +1,50 @@
+lpeg = require('lpeg')
+
+-- lpeg grammar for building api metadata from a set of header files. It
+-- ignores comments and preprocessor commands and parses a very small subset
+-- of C prototypes with a limited set of types
+local P, R, S = lpeg.P, lpeg.R, lpeg.S
+local C, Ct, Cc, Cg = lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cg
+
+local any = P(1) -- (consume one character)
+local letter = R('az', 'AZ') + S('_$')
+local num = R('09')
+local alpha = letter + num
+local nl = P('\r\n') + P('\n')
+local not_nl = any - nl
+local ws = S(' \t') + nl
+local fill = ws ^ 0
+local c_comment = P('//') * (not_nl ^ 0)
+local c_preproc = P('#') * (not_nl ^ 0)
+local typed_container =
+ (P('ArrayOf(') + P('DictionaryOf(')) * ((any - P(')')) ^ 1) * P(')')
+local c_id = (
+ typed_container +
+ (letter * (alpha ^ 0))
+)
+local c_void = P('void')
+local c_param_type = (
+ ((P('Error') * fill * P('*') * fill) * Cc('error')) +
+ (C(c_id) * (ws ^ 1))
+ )
+local c_type = (C(c_void) * (ws ^ 1)) + c_param_type
+local c_param = Ct(c_param_type * C(c_id))
+local c_param_list = c_param * (fill * (P(',') * fill * c_param) ^ 0)
+local c_params = Ct(c_void + c_param_list)
+local c_proto = Ct(
+ Cg(c_type, 'return_type') * Cg(c_id, 'name') *
+ fill * P('(') * fill * Cg(c_params, 'parameters') * fill * P(')') *
+ Cg(Cc(false), 'async') *
+ (fill * Cg((P('FUNC_API_SINCE(') * C(num ^ 1)) * P(')'), 'since') ^ -1) *
+ (fill * Cg((P('FUNC_API_DEPRECATED_SINCE(') * C(num ^ 1)) * P(')'),
+ 'deprecated_since') ^ -1) *
+ (fill * Cg((P('FUNC_API_ASYNC') * Cc(true)), 'async') ^ -1) *
+ (fill * Cg((P('FUNC_API_NOEXPORT') * Cc(true)), 'noexport') ^ -1) *
+ (fill * Cg((P('FUNC_API_REMOTE_ONLY') * Cc(true)), 'remote_only') ^ -1) *
+ (fill * Cg((P('FUNC_API_REMOTE_IMPL') * Cc(true)), 'remote_impl') ^ -1) *
+ (fill * Cg((P('FUNC_API_BRIDGE_IMPL') * Cc(true)), 'bridge_impl') ^ -1) *
+ fill * P(';')
+ )
+
+local grammar = Ct((c_proto + c_comment + c_preproc + ws) ^ 1)
+return {grammar=grammar, typed_container=typed_container}
diff --git a/src/nvim/generators/dump_bin_array.lua b/src/nvim/generators/dump_bin_array.lua
new file mode 100644
index 0000000000..bee5aba73f
--- /dev/null
+++ b/src/nvim/generators/dump_bin_array.lua
@@ -0,0 +1,17 @@
+local function dump_bin_array(output, name, data)
+ output:write([[
+ static const uint8_t ]]..name..[[[] = {
+]])
+
+ for i = 1, #data do
+ output:write(string.byte(data, i)..', ')
+ if i % 10 == 0 then
+ output:write('\n ')
+ end
+ end
+ output:write([[
+};
+]])
+end
+
+return dump_bin_array
diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua
new file mode 100644
index 0000000000..b01321e713
--- /dev/null
+++ b/src/nvim/generators/gen_api_dispatch.lua
@@ -0,0 +1,458 @@
+mpack = require('mpack')
+
+-- we need at least 4 arguments since the last two are output files
+if arg[1] == '--help' then
+ print('Usage: genmsgpack.lua args')
+ print('Args: 1: source directory')
+ print(' 2: dispatch output file (dispatch_wrappers.generated.h)')
+ print(' 3: functions metadata output file (funcs_metadata.generated.h)')
+ print(' 4: API metadata output file (api_metadata.mpack)')
+ print(' 5: lua C bindings output file (msgpack_lua_c_bindings.generated.c)')
+ print(' rest: C files where API functions are defined')
+end
+assert(#arg >= 4)
+functions = {}
+
+local nvimdir = arg[1]
+package.path = nvimdir .. '/?.lua;' .. package.path
+
+-- names of all headers relative to the source root (for inclusion in the
+-- generated file)
+headers = {}
+
+-- output h file with generated dispatch functions
+dispatch_outputf = arg[2]
+-- output h file with packed metadata
+funcs_metadata_outputf = arg[3]
+-- output metadata mpack file, for use by other build scripts
+mpack_outputf = arg[4]
+lua_c_bindings_outputf = arg[5]
+
+-- set of function names, used to detect duplicates
+function_names = {}
+
+c_grammar = require('generators.c_grammar')
+
+-- read each input file, parse and append to the api metadata
+for i = 6, #arg do
+ local full_path = arg[i]
+ local parts = {}
+ for part in string.gmatch(full_path, '[^/]+') do
+ parts[#parts + 1] = part
+ end
+ headers[#headers + 1] = parts[#parts - 1]..'/'..parts[#parts]
+
+ local input = io.open(full_path, 'rb')
+
+ local tmp = c_grammar.grammar:match(input:read('*all'))
+ for i = 1, #tmp do
+ local fn = tmp[i]
+ if not fn.noexport then
+ functions[#functions + 1] = tmp[i]
+ function_names[fn.name] = true
+ if #fn.parameters ~= 0 and fn.parameters[1][2] == 'channel_id' then
+ -- this function should receive the channel id
+ fn.receives_channel_id = true
+ -- remove the parameter since it won't be passed by the api client
+ table.remove(fn.parameters, 1)
+ end
+ if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'error' then
+ -- function can fail if the last parameter type is 'Error'
+ fn.can_fail = true
+ -- remove the error parameter, msgpack has it's own special field
+ -- for specifying errors
+ fn.parameters[#fn.parameters] = nil
+ end
+ end
+ end
+ input:close()
+end
+
+local function shallowcopy(orig)
+ local copy = {}
+ for orig_key, orig_value in pairs(orig) do
+ copy[orig_key] = orig_value
+ end
+ return copy
+end
+
+local function startswith(String,Start)
+ return string.sub(String,1,string.len(Start))==Start
+end
+
+-- Export functions under older deprecated names.
+-- These will be removed eventually.
+local deprecated_aliases = require("api.dispatch_deprecated")
+for i,f in ipairs(shallowcopy(functions)) do
+ local ismethod = false
+ if startswith(f.name, "nvim_") then
+ if startswith(f.name, "nvim__") then
+ f.since = -1
+ elseif f.since == nil then
+ print("Function "..f.name.." lacks since field.\n")
+ os.exit(1)
+ end
+ f.since = tonumber(f.since)
+ if f.deprecated_since ~= nil then
+ f.deprecated_since = tonumber(f.deprecated_since)
+ end
+
+ if startswith(f.name, "nvim_buf_") then
+ ismethod = true
+ elseif startswith(f.name, "nvim_win_") then
+ ismethod = true
+ elseif startswith(f.name, "nvim_tabpage_") then
+ ismethod = true
+ end
+ else
+ f.remote_only = true
+ f.since = 0
+ f.deprecated_since = 1
+ end
+ f.method = ismethod
+ local newname = deprecated_aliases[f.name]
+ if newname ~= nil then
+ if function_names[newname] then
+ -- duplicate
+ print("Function "..f.name.." has deprecated alias\n"
+ ..newname.." which has a separate implementation.\n"..
+ "Please remove it from src/nvim/api/dispatch_deprecated.lua")
+ os.exit(1)
+ end
+ local newf = shallowcopy(f)
+ newf.name = newname
+ if newname == "ui_try_resize" then
+ -- The return type was incorrectly set to Object in 0.1.5.
+ -- Keep it that way for clients that rely on this.
+ newf.return_type = "Object"
+ end
+ newf.impl_name = f.name
+ newf.remote_only = true
+ newf.since = 0
+ newf.deprecated_since = 1
+ functions[#functions+1] = newf
+ end
+end
+
+-- don't expose internal attributes like "impl_name" in public metadata
+exported_attributes = {'name', 'parameters', 'return_type', 'method',
+ 'since', 'deprecated_since'}
+exported_functions = {}
+for _,f in ipairs(functions) do
+ if not startswith(f.name, "nvim__") then
+ local f_exported = {}
+ for _,attr in ipairs(exported_attributes) do
+ f_exported[attr] = f[attr]
+ end
+ exported_functions[#exported_functions+1] = f_exported
+ end
+end
+
+
+-- serialize the API metadata using msgpack and embed into the resulting
+-- binary for easy querying by clients
+funcs_metadata_output = io.open(funcs_metadata_outputf, 'wb')
+packed = mpack.pack(exported_functions)
+dump_bin_array = require("generators.dump_bin_array")
+dump_bin_array(funcs_metadata_output, 'funcs_metadata', packed)
+funcs_metadata_output:close()
+
+-- start building the dispatch wrapper output
+output = io.open(dispatch_outputf, 'wb')
+
+local function real_type(type)
+ local rv = type
+ if c_grammar.typed_container:match(rv) then
+ if rv:match('Array') then
+ rv = 'Array'
+ else
+ rv = 'Dictionary'
+ end
+ end
+ return rv
+end
+
+local function attr_name(rt)
+ if rt == 'Float' then
+ return 'floating'
+ else
+ return rt:lower()
+ end
+end
+
+-- start the handler functions. Visit each function metadata to build the
+-- handler function with code generated for validating arguments and calling to
+-- the real API.
+for i = 1, #functions do
+ local fn = functions[i]
+ if fn.impl_name == nil then
+ local args = {}
+
+ output:write('Object handle_'..fn.name..'(uint64_t channel_id, Array args, Error *error)')
+ output:write('\n{')
+ output:write('\n Object ret = NIL;')
+ -- Declare/initialize variables that will hold converted arguments
+ for j = 1, #fn.parameters do
+ local param = fn.parameters[j]
+ local converted = 'arg_'..j
+ output:write('\n '..param[1]..' '..converted..';')
+ end
+ output:write('\n')
+ output:write('\n if (args.size != '..#fn.parameters..') {')
+ output:write('\n api_set_error(error, kErrorTypeException, "Wrong number of arguments: expecting '..#fn.parameters..' but got %zu", args.size);')
+ output:write('\n goto cleanup;')
+ output:write('\n }\n')
+
+ -- Validation/conversion for each argument
+ for j = 1, #fn.parameters do
+ local converted, convert_arg, param, arg
+ param = fn.parameters[j]
+ converted = 'arg_'..j
+ local rt = real_type(param[1])
+ if rt ~= 'Object' then
+ if rt:match('^Buffer$') or rt:match('^Window$') or rt:match('^Tabpage$') then
+ -- Buffer, Window, and Tabpage have a specific type, but are stored in integer
+ output:write('\n if (args.items['..(j - 1)..'].type == kObjectType'..rt..' && args.items['..(j - 1)..'].data.integer >= 0) {')
+ output:write('\n '..converted..' = (handle_T)args.items['..(j - 1)..'].data.integer;')
+ else
+ output:write('\n if (args.items['..(j - 1)..'].type == kObjectType'..rt..') {')
+ output:write('\n '..converted..' = args.items['..(j - 1)..'].data.'..attr_name(rt)..';')
+ end
+ if rt:match('^Buffer$') or rt:match('^Window$') or rt:match('^Tabpage$') or rt:match('^Boolean$') then
+ -- accept nonnegative integers for Booleans, Buffers, Windows and Tabpages
+ output:write('\n } else if (args.items['..(j - 1)..'].type == kObjectTypeInteger && args.items['..(j - 1)..'].data.integer >= 0) {')
+ output:write('\n '..converted..' = (handle_T)args.items['..(j - 1)..'].data.integer;')
+ end
+ output:write('\n } else {')
+ output:write('\n api_set_error(error, kErrorTypeException, "Wrong type for argument '..j..', expecting '..param[1]..'");')
+ output:write('\n goto cleanup;')
+ output:write('\n }\n')
+ else
+ output:write('\n '..converted..' = args.items['..(j - 1)..'];\n')
+ end
+
+ args[#args + 1] = converted
+ end
+
+ -- function call
+ local call_args = table.concat(args, ', ')
+ output:write('\n ')
+ if fn.return_type ~= 'void' then
+ -- has a return value, prefix the call with a declaration
+ output:write(fn.return_type..' rv = ')
+ end
+
+ -- write the function name and the opening parenthesis
+ output:write(fn.name..'(')
+
+ if fn.receives_channel_id then
+ -- if the function receives the channel id, pass it as first argument
+ if #args > 0 or fn.can_fail then
+ output:write('channel_id, '..call_args)
+ else
+ output:write('channel_id')
+ end
+ else
+ output:write(call_args)
+ end
+
+ if fn.can_fail then
+ -- if the function can fail, also pass a pointer to the local error object
+ if #args > 0 then
+ output:write(', error);\n')
+ else
+ output:write('error);\n')
+ end
+ -- and check for the error
+ output:write('\n if (ERROR_SET(error)) {')
+ output:write('\n goto cleanup;')
+ output:write('\n }\n')
+ else
+ output:write(');\n')
+ end
+
+ if fn.return_type ~= 'void' then
+ output:write('\n ret = '..string.upper(real_type(fn.return_type))..'_OBJ(rv);')
+ end
+ output:write('\n\ncleanup:');
+
+ output:write('\n return ret;\n}\n\n');
+ end
+end
+
+-- Generate a function that initializes method names with handler functions
+output:write([[
+void msgpack_rpc_init_method_table(void)
+{
+ methods = map_new(String, MsgpackRpcRequestHandler)();
+
+]])
+
+for i = 1, #functions do
+ local fn = functions[i]
+ output:write(' msgpack_rpc_add_method_handler('..
+ '(String) {.data = "'..fn.name..'", '..
+ '.size = sizeof("'..fn.name..'") - 1}, '..
+ '(MsgpackRpcRequestHandler) {.fn = handle_'.. (fn.impl_name or fn.name)..
+ ', .async = '..tostring(fn.async)..'});\n')
+
+end
+
+output:write('\n}\n\n')
+output:close()
+
+mpack_output = io.open(mpack_outputf, 'wb')
+mpack_output:write(mpack.pack(functions))
+mpack_output:close()
+
+local function include_headers(output, headers)
+ for i = 1, #headers do
+ if headers[i]:sub(-12) ~= '.generated.h' then
+ output:write('\n#include "nvim/'..headers[i]..'"')
+ end
+ end
+end
+
+local function write_shifted_output(output, str)
+ str = str:gsub('\n ', '\n')
+ str = str:gsub('^ ', '')
+ str = str:gsub(' +$', '')
+ output:write(str)
+end
+
+-- start building lua output
+output = io.open(lua_c_bindings_outputf, 'wb')
+
+output:write([[
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "nvim/func_attr.h"
+#include "nvim/api/private/defs.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/lua/converter.h"
+]])
+include_headers(output, headers)
+output:write('\n')
+
+lua_c_functions = {}
+
+local function process_function(fn)
+ lua_c_function_name = ('nlua_msgpack_%s'):format(fn.name)
+ write_shifted_output(output, string.format([[
+
+ static int %s(lua_State *lstate)
+ {
+ Error err = ERROR_INIT;
+ if (lua_gettop(lstate) != %i) {
+ api_set_error(&err, kErrorTypeValidation, "Expected %i argument%s");
+ goto exit_0;
+ }
+ ]], lua_c_function_name, #fn.parameters, #fn.parameters,
+ (#fn.parameters == 1) and '' or 's'))
+ lua_c_functions[#lua_c_functions + 1] = {
+ binding=lua_c_function_name,
+ api=fn.name
+ }
+ local cparams = ''
+ local free_code = {}
+ for j = #fn.parameters,1,-1 do
+ param = fn.parameters[j]
+ cparam = string.format('arg%u', j)
+ param_type = real_type(param[1])
+ lc_param_type = param_type:lower()
+ write_shifted_output(output, string.format([[
+ const %s %s = nlua_pop_%s(lstate, &err);
+
+ if (ERROR_SET(&err)) {
+ goto exit_%u;
+ }
+ ]], param[1], cparam, param_type, #fn.parameters - j))
+ free_code[#free_code + 1] = ('api_free_%s(%s);'):format(
+ lc_param_type, cparam)
+ cparams = cparam .. ', ' .. cparams
+ end
+ if fn.receives_channel_id then
+ cparams = 'LUA_INTERNAL_CALL, ' .. cparams
+ end
+ if fn.can_fail then
+ cparams = cparams .. '&err'
+ else
+ cparams = cparams:gsub(', $', '')
+ end
+ local free_at_exit_code = ''
+ for i = 1, #free_code do
+ local rev_i = #free_code - i + 1
+ local code = free_code[rev_i]
+ if i == 1 then
+ free_at_exit_code = free_at_exit_code .. ('\n %s'):format(code)
+ else
+ free_at_exit_code = free_at_exit_code .. ('\n exit_%u:\n %s'):format(
+ rev_i, code)
+ end
+ end
+ local err_throw_code = [[
+
+ exit_0:
+ if (ERROR_SET(&err)) {
+ luaL_where(lstate, 1);
+ lua_pushstring(lstate, err.msg);
+ api_clear_error(&err);
+ lua_concat(lstate, 2);
+ return lua_error(lstate);
+ }
+ ]]
+ if fn.return_type ~= 'void' then
+ if fn.return_type:match('^ArrayOf') then
+ return_type = 'Array'
+ else
+ return_type = fn.return_type
+ end
+ write_shifted_output(output, string.format([[
+ const %s ret = %s(%s);
+ nlua_push_%s(lstate, ret);
+ api_free_%s(ret);
+ %s
+ %s
+ return 1;
+ ]], fn.return_type, fn.name, cparams, return_type, return_type:lower(),
+ free_at_exit_code, err_throw_code))
+ else
+ write_shifted_output(output, string.format([[
+ %s(%s);
+ %s
+ %s
+ return 0;
+ ]], fn.name, cparams, free_at_exit_code, err_throw_code))
+ end
+ write_shifted_output(output, [[
+ }
+ ]])
+end
+
+for _, fn in ipairs(functions) do
+ if not fn.remote_only or fn.name:sub(1, 4) == '_vim' then
+ process_function(fn)
+ end
+end
+
+output:write(string.format([[
+void nlua_add_api_functions(lua_State *lstate)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_createtable(lstate, 0, %u);
+]], #lua_c_functions))
+for _, func in ipairs(lua_c_functions) do
+ output:write(string.format([[
+
+ lua_pushcfunction(lstate, &%s);
+ lua_setfield(lstate, -2, "%s");]], func.binding, func.api))
+end
+output:write([[
+
+ lua_setfield(lstate, -2, "api");
+}
+]])
+
+output:close()
diff --git a/src/nvim/generators/gen_api_ui_events.lua b/src/nvim/generators/gen_api_ui_events.lua
new file mode 100644
index 0000000000..d2b90db707
--- /dev/null
+++ b/src/nvim/generators/gen_api_ui_events.lua
@@ -0,0 +1,166 @@
+mpack = require('mpack')
+
+local nvimdir = arg[1]
+package.path = nvimdir .. '/?.lua;' .. package.path
+
+assert(#arg == 7)
+input = io.open(arg[2], 'rb')
+proto_output = io.open(arg[3], 'wb')
+call_output = io.open(arg[4], 'wb')
+remote_output = io.open(arg[5], 'wb')
+bridge_output = io.open(arg[6], 'wb')
+metadata_output = io.open(arg[7], 'wb')
+
+c_grammar = require('generators.c_grammar')
+local events = c_grammar.grammar:match(input:read('*all'))
+
+function write_signature(output, ev, prefix, notype)
+ output:write('('..prefix)
+ if prefix == "" and #ev.parameters == 0 then
+ output:write('void')
+ end
+ for j = 1, #ev.parameters do
+ if j > 1 or prefix ~= '' then
+ output:write(', ')
+ end
+ local param = ev.parameters[j]
+ if not notype then
+ output:write(param[1]..' ')
+ end
+ output:write(param[2])
+ end
+ output:write(')')
+end
+
+function write_arglist(output, ev, need_copy)
+ output:write(' Array args = ARRAY_DICT_INIT;\n')
+ for j = 1, #ev.parameters do
+ local param = ev.parameters[j]
+ local kind = string.upper(param[1])
+ local do_copy = need_copy and (kind == "ARRAY" or kind == "DICTIONARY" or kind == "STRING")
+ output:write(' ADD(args, ')
+ if do_copy then
+ output:write('copy_object(')
+ end
+ output:write(kind..'_OBJ('..param[2]..')')
+ if do_copy then
+ output:write(')')
+ end
+ output:write(');\n')
+ end
+end
+
+for i = 1, #events do
+ ev = events[i]
+ assert(ev.return_type == 'void')
+
+ if ev.since == nil then
+ print("Ui event "..ev.name.." lacks since field.\n")
+ os.exit(1)
+ end
+ ev.since = tonumber(ev.since)
+
+ if not ev.remote_only then
+ proto_output:write(' void (*'..ev.name..')')
+ write_signature(proto_output, ev, 'UI *ui')
+ proto_output:write(';\n')
+
+ if not ev.remote_impl then
+ remote_output:write('static void remote_ui_'..ev.name)
+ write_signature(remote_output, ev, 'UI *ui')
+ remote_output:write('\n{\n')
+ write_arglist(remote_output, ev, true)
+ remote_output:write(' push_call(ui, "'..ev.name..'", args);\n')
+ remote_output:write('}\n\n')
+ end
+
+ if not ev.bridge_impl then
+
+ send, argv, recv, recv_argv, recv_cleanup = '', '', '', '', ''
+ argc = 1
+ for j = 1, #ev.parameters do
+ local param = ev.parameters[j]
+ copy = 'copy_'..param[2]
+ if param[1] == 'String' then
+ send = send..' String copy_'..param[2]..' = copy_string('..param[2]..');\n'
+ argv = argv..', '..copy..'.data, INT2PTR('..copy..'.size)'
+ recv = (recv..' String '..param[2]..
+ ' = (String){.data = argv['..argc..'],'..
+ '.size = (size_t)argv['..(argc+1)..']};\n')
+ recv_argv = recv_argv..', '..param[2]
+ recv_cleanup = recv_cleanup..' api_free_string('..param[2]..');\n'
+ argc = argc+2
+ elseif param[1] == 'Array' then
+ send = send..' Array copy_'..param[2]..' = copy_array('..param[2]..');\n'
+ argv = argv..', '..copy..'.items, INT2PTR('..copy..'.size)'
+ recv = (recv..' Array '..param[2]..
+ ' = (Array){.items = argv['..argc..'],'..
+ '.size = (size_t)argv['..(argc+1)..']};\n')
+ recv_argv = recv_argv..', '..param[2]
+ recv_cleanup = recv_cleanup..' api_free_array('..param[2]..');\n'
+ argc = argc+2
+ elseif param[1] == 'Integer' or param[1] == 'Boolean' then
+ argv = argv..', INT2PTR('..param[2]..')'
+ recv_argv = recv_argv..', PTR2INT(argv['..argc..'])'
+ argc = argc+1
+ else
+ assert(false)
+ end
+ end
+ bridge_output:write('static void ui_bridge_'..ev.name..
+ '_event(void **argv)\n{\n')
+ bridge_output:write(' UI *ui = UI(argv[0]);\n')
+ bridge_output:write(recv)
+ bridge_output:write(' ui->'..ev.name..'(ui'..recv_argv..');\n')
+ bridge_output:write(recv_cleanup)
+ bridge_output:write('}\n\n')
+
+ bridge_output:write('static void ui_bridge_'..ev.name)
+ write_signature(bridge_output, ev, 'UI *ui')
+ bridge_output:write('\n{\n')
+ bridge_output:write(send)
+ bridge_output:write(' UI_BRIDGE_CALL(ui, '..ev.name..', '..argc..', ui'..argv..');\n}\n')
+ end
+ end
+
+ call_output:write('void ui_call_'..ev.name)
+ write_signature(call_output, ev, '')
+ call_output:write('\n{\n')
+ if ev.remote_only then
+ write_arglist(call_output, ev, false)
+ call_output:write(' UI_LOG('..ev.name..', 0);\n')
+ call_output:write(' ui_event("'..ev.name..'", args);\n')
+ else
+ call_output:write(' UI_CALL')
+ write_signature(call_output, ev, ev.name, true)
+ call_output:write(";\n")
+ end
+ call_output:write("}\n\n")
+
+end
+
+proto_output:close()
+call_output:close()
+remote_output:close()
+
+-- don't expose internal attributes like "impl_name" in public metadata
+exported_attributes = {'name', 'parameters',
+ 'since', 'deprecated_since'}
+exported_events = {}
+for _,ev in ipairs(events) do
+ local ev_exported = {}
+ for _,attr in ipairs(exported_attributes) do
+ ev_exported[attr] = ev[attr]
+ end
+ for _,p in ipairs(ev_exported.parameters) do
+ if p[1] == 'HlAttrs' then
+ p[1] = 'Dictionary'
+ end
+ end
+ exported_events[#exported_events+1] = ev_exported
+end
+
+packed = mpack.pack(exported_events)
+dump_bin_array = require("generators.dump_bin_array")
+dump_bin_array(metadata_output, 'ui_events_metadata', packed)
+metadata_output:close()
diff --git a/src/nvim/generators/gen_char_blob.lua b/src/nvim/generators/gen_char_blob.lua
new file mode 100644
index 0000000000..d860375e26
--- /dev/null
+++ b/src/nvim/generators/gen_char_blob.lua
@@ -0,0 +1,48 @@
+if arg[1] == '--help' then
+ print('Usage:')
+ print(' gencharblob.lua source target varname')
+ print('')
+ print('Generates C file with big uint8_t blob.')
+ print('Blob will be stored in a static const array named varname.')
+ os.exit()
+end
+
+assert(#arg == 3)
+
+local source_file = arg[1]
+local target_file = arg[2]
+local varname = arg[3]
+
+source = io.open(source_file, 'r')
+target = io.open(target_file, 'w')
+
+target:write('#include <stdint.h>\n\n')
+target:write(('static const uint8_t %s[] = {\n'):format(varname))
+
+num_bytes = 0
+MAX_NUM_BYTES = 15 -- 78 / 5: maximum number of bytes on one line
+target:write(' ')
+
+increase_num_bytes = function()
+ num_bytes = num_bytes + 1
+ if num_bytes == MAX_NUM_BYTES then
+ num_bytes = 0
+ target:write('\n ')
+ end
+end
+
+for line in source:lines() do
+ for i = 1,string.len(line) do
+ byte = string.byte(line, i)
+ assert(byte ~= 0)
+ target:write(string.format(' %3u,', byte))
+ increase_num_bytes()
+ end
+ target:write(string.format(' %3u,', string.byte('\n', 1)))
+ increase_num_bytes()
+end
+
+target:write(' 0};\n')
+
+source:close()
+target:close()
diff --git a/src/nvim/generators/gen_declarations.lua b/src/nvim/generators/gen_declarations.lua
new file mode 100755
index 0000000000..e999e53e4a
--- /dev/null
+++ b/src/nvim/generators/gen_declarations.lua
@@ -0,0 +1,287 @@
+#!/usr/bin/lua
+
+local fname = arg[1]
+local static_fname = arg[2]
+local non_static_fname = arg[3]
+local preproc_fname = arg[4]
+
+
+local lpeg = require('lpeg')
+
+local fold = function (func, ...)
+ local result = nil
+ for i, v in ipairs({...}) do
+ if result == nil then
+ result = v
+ else
+ result = func(result, v)
+ end
+ end
+ return result
+end
+
+local folder = function (func)
+ return function (...)
+ return fold(func, ...)
+ end
+end
+
+local lit = lpeg.P
+local set = function(...)
+ return lpeg.S(fold(function (a, b) return a .. b end, ...))
+end
+local any_character = lpeg.P(1)
+local rng = function(s, e) return lpeg.R(s .. e) end
+local concat = folder(function (a, b) return a * b end)
+local branch = folder(function (a, b) return a + b end)
+local one_or_more = function(v) return v ^ 1 end
+local two_or_more = function(v) return v ^ 2 end
+local any_amount = function(v) return v ^ 0 end
+local one_or_no = function(v) return v ^ -1 end
+local look_behind = lpeg.B
+local look_ahead = function(v) return #v end
+local neg_look_ahead = function(v) return -v end
+local neg_look_behind = function(v) return -look_behind(v) end
+
+local w = branch(
+ rng('a', 'z'),
+ rng('A', 'Z'),
+ lit('_')
+)
+local aw = branch(
+ w,
+ rng('0', '9')
+)
+local s = set(' ', '\n', '\t')
+local raw_word = concat(w, any_amount(aw))
+local right_word = concat(
+ raw_word,
+ neg_look_ahead(aw)
+)
+local word = branch(
+ concat(
+ branch(lit('ArrayOf('), lit('DictionaryOf(')), -- typed container macro
+ one_or_more(any_character - lit(')')),
+ lit(')')
+ ),
+ concat(
+ neg_look_behind(aw),
+ right_word
+ )
+)
+local inline_comment = concat(
+ lit('/*'),
+ any_amount(concat(
+ neg_look_ahead(lit('*/')),
+ any_character
+ )),
+ lit('*/')
+)
+local spaces = any_amount(branch(
+ s,
+ -- Comments are really handled by preprocessor, so the following is not needed
+ inline_comment,
+ concat(
+ lit('//'),
+ any_amount(concat(
+ neg_look_ahead(lit('\n')),
+ any_character
+ )),
+ lit('\n')
+ ),
+ -- Linemarker inserted by preprocessor
+ concat(
+ lit('# '),
+ any_amount(concat(
+ neg_look_ahead(lit('\n')),
+ any_character
+ )),
+ lit('\n')
+ )
+))
+local typ_part = concat(
+ word,
+ any_amount(concat(
+ spaces,
+ lit('*')
+ )),
+ spaces
+)
+local typ = one_or_more(typ_part)
+local typ_id = two_or_more(typ_part)
+local arg = typ_id -- argument name is swallowed by typ
+local pattern = concat(
+ any_amount(branch(set(' ', '\t'), inline_comment)),
+ typ_id, -- return type with function name
+ spaces,
+ lit('('),
+ spaces,
+ one_or_no(branch( -- function arguments
+ concat(
+ arg, -- first argument, does not require comma
+ any_amount(concat( -- following arguments, start with a comma
+ spaces,
+ lit(','),
+ spaces,
+ arg,
+ any_amount(concat(
+ lit('['),
+ spaces,
+ any_amount(aw),
+ spaces,
+ lit(']')
+ ))
+ )),
+ one_or_no(concat(
+ spaces,
+ lit(','),
+ spaces,
+ lit('...')
+ ))
+ ),
+ lit('void') -- also accepts just void
+ )),
+ spaces,
+ lit(')'),
+ any_amount(concat( -- optional attributes
+ spaces,
+ lit('FUNC_'),
+ any_amount(aw),
+ one_or_no(concat( -- attribute argument
+ spaces,
+ lit('('),
+ any_amount(concat(
+ neg_look_ahead(lit(')')),
+ any_character
+ )),
+ lit(')')
+ ))
+ )),
+ look_ahead(concat( -- definition must be followed by "{"
+ spaces,
+ lit('{')
+ ))
+)
+
+if fname == '--help' then
+ print'Usage:'
+ print()
+ print' gendeclarations.lua definitions.c static.h non-static.h preprocessor.i'
+ os.exit()
+end
+
+local preproc_f = io.open(preproc_fname)
+local text = preproc_f:read("*all")
+preproc_f:close()
+
+
+local header = [[
+#ifndef DEFINE_FUNC_ATTRIBUTES
+# define DEFINE_FUNC_ATTRIBUTES
+#endif
+#include "nvim/func_attr.h"
+#undef DEFINE_FUNC_ATTRIBUTES
+]]
+
+local footer = [[
+#include "nvim/func_attr.h"
+]]
+
+local non_static = header
+local static = header
+
+local filepattern = '^#%a* (%d+) "([^"]-)/?([^"/]+)"'
+local curfile
+
+local init = 0
+local curfile = nil
+local neededfile = fname:match('[^/]+$')
+local declline = 0
+local declendpos = 0
+local curdir = nil
+local is_needed_file = false
+while init ~= nil do
+ init = text:find('[\n;}]', init)
+ if init == nil then
+ break
+ end
+ local init_is_nl = text:sub(init, init) == '\n'
+ init = init + 1
+ if init_is_nl and is_needed_file then
+ declline = declline + 1
+ end
+ if init_is_nl and text:sub(init, init) == '#' then
+ local line, dir, file = text:match(filepattern, init)
+ if file ~= nil then
+ curfile = file
+ is_needed_file = (curfile == neededfile)
+ declline = tonumber(line) - 1
+ local curdir_start = dir:find('src/nvim/')
+ if curdir_start ~= nil then
+ curdir = dir:sub(curdir_start + #('src/nvim/'))
+ else
+ curdir = dir
+ end
+ else
+ declline = declline - 1
+ end
+ elseif init < declendpos then
+ -- Skipping over declaration
+ elseif is_needed_file then
+ s = init
+ e = pattern:match(text, init)
+ if e ~= nil then
+ local declaration = text:sub(s, e - 1)
+ -- Comments are really handled by preprocessor, so the following is not
+ -- needed
+ declaration = declaration:gsub('/%*.-%*/', '')
+ declaration = declaration:gsub('//.-\n', '\n')
+
+ declaration = declaration:gsub('# .-\n', '')
+
+ declaration = declaration:gsub('\n', ' ')
+ declaration = declaration:gsub('%s+', ' ')
+ declaration = declaration:gsub(' ?%( ?', '(')
+ -- declaration = declaration:gsub(' ?%) ?', ')')
+ declaration = declaration:gsub(' ?, ?', ', ')
+ declaration = declaration:gsub(' ?(%*+) ?', ' %1')
+ declaration = declaration:gsub(' ?(FUNC_ATTR_)', ' %1')
+ declaration = declaration:gsub(' $', '')
+ declaration = declaration:gsub('^ ', '')
+ declaration = declaration .. ';'
+ declaration = declaration .. (' // %s/%s:%u'):format(
+ curdir, curfile, declline)
+ declaration = declaration .. '\n'
+ if declaration:sub(1, 6) == 'static' then
+ static = static .. declaration
+ else
+ non_static = non_static .. declaration
+ end
+ declendpos = e
+ end
+ end
+end
+
+non_static = non_static .. footer
+static = static .. footer
+
+local F
+F = io.open(static_fname, 'w')
+F:write(static)
+F:close()
+
+-- Before generating the non-static headers, check if the current file(if
+-- exists) is different from the new one. If they are the same, we won't touch
+-- the current version to avoid triggering an unnecessary rebuilds of modules
+-- that depend on this one
+F = io.open(non_static_fname, 'r')
+if F ~= nil then
+ if F:read('*a') == non_static then
+ os.exit(0)
+ end
+ io.close(F)
+end
+
+F = io.open(non_static_fname, 'w')
+F:write(non_static)
+F:close()
diff --git a/src/nvim/generators/gen_eval.lua b/src/nvim/generators/gen_eval.lua
new file mode 100644
index 0000000000..23435a1d0b
--- /dev/null
+++ b/src/nvim/generators/gen_eval.lua
@@ -0,0 +1,67 @@
+mpack = require('mpack')
+
+local nvimsrcdir = arg[1]
+local autodir = arg[2]
+local metadata_file = arg[3]
+local funcs_file = arg[4]
+
+if nvimsrcdir == '--help' then
+ print([[
+Usage:
+ lua geneval.lua src/nvim build/src/nvim/auto
+
+Will generate build/src/nvim/auto/funcs.generated.h with definition of functions
+static const array.
+]])
+ os.exit(0)
+end
+
+package.path = nvimsrcdir .. '/?.lua;' .. package.path
+
+local funcsfname = autodir .. '/funcs.generated.h'
+
+local gperfpipe = io.open(funcsfname .. '.gperf', 'wb')
+
+local funcs = require('eval').funcs
+local metadata = mpack.unpack(io.open(arg[3], 'rb'):read("*all"))
+for i,fun in ipairs(metadata) do
+ if not fun.remote_only then
+ funcs[fun.name] = {
+ args=#fun.parameters,
+ func='api_wrapper',
+ data='&handle_'..fun.name,
+ }
+ end
+end
+
+local funcsdata = io.open(funcs_file, 'w')
+funcsdata:write(mpack.pack(funcs))
+funcsdata:close()
+
+gperfpipe:write([[
+%language=ANSI-C
+%global-table
+%readonly-tables
+%define initializer-suffix ,0,0,NULL,NULL
+%define word-array-name functions
+%define hash-function-name hash_internal_func_gperf
+%define lookup-function-name find_internal_func_gperf
+%omit-struct-type
+%struct-type
+VimLFuncDef;
+%%
+]])
+
+for name, def in pairs(funcs) do
+ args = def.args or 0
+ if type(args) == 'number' then
+ args = {args, args}
+ elseif #args == 1 then
+ args[2] = 'MAX_FUNC_ARGS'
+ end
+ func = def.func or ('f_' .. name)
+ data = def.data or "NULL"
+ gperfpipe:write(('%s, %s, %s, &%s, (FunPtr)%s\n')
+ :format(name, args[1], args[2], func, data))
+end
+gperfpipe:close()
diff --git a/src/nvim/generators/gen_events.lua b/src/nvim/generators/gen_events.lua
new file mode 100644
index 0000000000..75e0b3da3a
--- /dev/null
+++ b/src/nvim/generators/gen_events.lua
@@ -0,0 +1,65 @@
+if arg[1] == '--help' then
+ print('Usage: gen_events.lua src/nvim enum_file event_names_file')
+ os.exit(0)
+end
+
+local nvimsrcdir = arg[1]
+local fileio_enum_file = arg[2]
+local names_file = arg[3]
+
+package.path = nvimsrcdir .. '/?.lua;' .. package.path
+
+local auevents = require('auevents')
+local events = auevents.events
+local aliases = auevents.aliases
+
+enum_tgt = io.open(fileio_enum_file, 'w')
+names_tgt = io.open(names_file, 'w')
+
+enum_tgt:write('typedef enum auto_event {')
+names_tgt:write([[
+static const struct event_name {
+ size_t len;
+ char *name;
+ event_T event;
+} event_names[] = {]])
+
+for i, event in ipairs(events) do
+ if i > 1 then
+ comma = ',\n'
+ else
+ comma = '\n'
+ end
+ enum_tgt:write(('%s EVENT_%s = %u'):format(comma, event:upper(), i - 1))
+ names_tgt:write(('%s {%u, "%s", EVENT_%s}'):format(comma, #event, event, event:upper()))
+end
+
+for alias, event in pairs(aliases) do
+ names_tgt:write((',\n {%u, "%s", EVENT_%s}'):format(#alias, alias, event:upper()))
+end
+
+names_tgt:write(',\n {0, NULL, (event_T)0}')
+
+enum_tgt:write('\n} event_T;\n')
+names_tgt:write('\n};\n')
+
+enum_tgt:write(('\n#define NUM_EVENTS %u\n'):format(#events))
+names_tgt:write('\nstatic AutoPat *first_autopat[NUM_EVENTS] = {\n ')
+line_len = 1
+for i = 1,((#events) - 1) do
+ line_len = line_len + #(' NULL,')
+ if line_len > 80 then
+ names_tgt:write('\n ')
+ line_len = 1 + #(' NULL,')
+ end
+ names_tgt:write(' NULL,')
+end
+if line_len + #(' NULL') > 80 then
+ names_tgt:write('\n NULL')
+else
+ names_tgt:write(' NULL')
+end
+names_tgt:write('\n};\n')
+
+enum_tgt:close()
+names_tgt:close()
diff --git a/src/nvim/generators/gen_ex_cmds.lua b/src/nvim/generators/gen_ex_cmds.lua
new file mode 100644
index 0000000000..cb566d46ca
--- /dev/null
+++ b/src/nvim/generators/gen_ex_cmds.lua
@@ -0,0 +1,88 @@
+local nvimsrcdir = arg[1]
+local includedir = arg[2]
+local autodir = arg[3]
+
+if nvimsrcdir == '--help' then
+ print ([[
+Usage:
+ lua genex_cmds.lua src/nvim build/include build/src/nvim/auto
+
+Will generate files build/include/ex_cmds_enum.generated.h with cmdidx_T
+enum and build/src/nvim/auto/ex_cmds_defs.generated.h with main Ex commands
+definitions.
+]])
+ os.exit(0)
+end
+
+package.path = nvimsrcdir .. '/?.lua;' .. package.path
+
+local enumfname = includedir .. '/ex_cmds_enum.generated.h'
+local defsfname = autodir .. '/ex_cmds_defs.generated.h'
+
+local enumfile = io.open(enumfname, 'w')
+local defsfile = io.open(defsfname, 'w')
+
+local defs = require('ex_cmds')
+local lastchar = nil
+
+local i
+local cmd
+local first = true
+local prevfirstchar = nil
+
+local byte_a = string.byte('a')
+local byte_z = string.byte('z')
+
+local cmdidxs = string.format([[
+static const cmdidx_T cmdidxs[%u] = {
+]], byte_z - byte_a + 2)
+
+enumfile:write([[
+typedef enum CMD_index {
+]])
+defsfile:write(string.format([[
+static CommandDefinition cmdnames[%u] = {
+]], #defs))
+for i, cmd in ipairs(defs) do
+ local enumname = cmd.enum or ('CMD_' .. cmd.command)
+ firstchar = string.byte(cmd.command)
+ if firstchar ~= prevfirstchar then
+ if (not prevfirstchar
+ or (byte_a <= firstchar and firstchar <= byte_z)
+ or (byte_a <= prevfirstchar and prevfirstchar <= byte_z)) then
+ if not first then
+ cmdidxs = cmdidxs .. ',\n'
+ end
+ cmdidxs = cmdidxs .. ' ' .. enumname
+ end
+ prevfirstchar = firstchar
+ end
+ if first then
+ first = false
+ else
+ defsfile:write(',\n')
+ end
+ enumfile:write(' ' .. enumname .. ',\n')
+ defsfile:write(string.format([[
+ [%s] = {
+ .cmd_name = (char_u *) "%s",
+ .cmd_func = (ex_func_T)&%s,
+ .cmd_argt = %uL,
+ .cmd_addr_type = %i
+ }]], enumname, cmd.command, cmd.func, cmd.flags, cmd.addr_type))
+end
+defsfile:write([[
+
+};
+]])
+enumfile:write([[
+ CMD_SIZE,
+ CMD_USER = -1,
+ CMD_USER_BUF = -2
+} cmdidx_T;
+]])
+cmdidxs = cmdidxs .. [[
+
+};
+]]
+defsfile:write(cmdidxs)
diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua
new file mode 100644
index 0000000000..ca0134043c
--- /dev/null
+++ b/src/nvim/generators/gen_options.lua
@@ -0,0 +1,190 @@
+if arg[1] == '--help' then
+ print('Usage: genoptions.lua src/nvim options_file')
+ os.exit(0)
+end
+
+local nvimsrcdir = arg[1]
+local options_file = arg[2]
+
+package.path = nvimsrcdir .. '/?.lua;' .. package.path
+
+local opt_fd = io.open(options_file, 'w')
+
+local w = function(s)
+ if s:match('^ %.') then
+ opt_fd:write(s .. ',\n')
+ else
+ opt_fd:write(s .. '\n')
+ end
+end
+
+local options = require('options')
+
+cstr = options.cstr
+
+local type_flags={
+ bool='P_BOOL',
+ number='P_NUM',
+ string='P_STRING',
+}
+
+local redraw_flags={
+ statuslines='P_RSTAT',
+ current_window='P_RWIN',
+ current_window_only='P_RWINONLY',
+ current_buffer='P_RBUF',
+ all_windows='P_RALL',
+ everything='P_RCLR',
+ curswant='P_CURSWANT',
+}
+
+local list_flags={
+ comma='P_COMMA',
+ onecomma='P_ONECOMMA',
+ flags='P_FLAGLIST',
+ flagscomma='P_COMMA|P_FLAGLIST',
+}
+
+local get_flags = function(o)
+ local ret = {type_flags[o.type]}
+ local add_flag = function(f)
+ ret[1] = ret[1] .. '|' .. f
+ end
+ if o.list then
+ add_flag(list_flags[o.list])
+ end
+ if o.redraw then
+ for _, r_flag in ipairs(o.redraw) do
+ add_flag(redraw_flags[r_flag])
+ end
+ end
+ if o.expand then
+ add_flag('P_EXPAND')
+ if o.expand == 'nodefault' then
+ add_flag('P_NO_DEF_EXP')
+ end
+ end
+ for _, flag_desc in ipairs({
+ {'alloced'},
+ {'nodefault'},
+ {'no_mkrc'},
+ {'vi_def'},
+ {'vim'},
+ {'secure'},
+ {'gettext'},
+ {'noglob'},
+ {'normal_fname_chars', 'P_NFNAME'},
+ {'pri_mkrc'},
+ {'deny_in_modelines', 'P_NO_ML'},
+ {'deny_duplicates', 'P_NODUP'},
+ }) do
+ local key_name = flag_desc[1]
+ local def_name = flag_desc[2] or ('P_' .. key_name:upper())
+ if o[key_name] then
+ add_flag(def_name)
+ end
+ end
+ return ret[1]
+end
+
+local get_cond
+get_cond = function(c, base_string)
+ local cond_string = base_string or '#if '
+ if type(c) == 'table' then
+ cond_string = cond_string .. get_cond(c[1], '')
+ for i, subc in ipairs(c) do
+ if i > 1 then
+ cond_string = cond_string .. ' && ' .. get_cond(subc, '')
+ end
+ end
+ elseif c:sub(1, 1) == '!' then
+ cond_string = cond_string .. '!defined(' .. c:sub(2) .. ')'
+ else
+ cond_string = cond_string .. 'defined(' .. c .. ')'
+ end
+ return cond_string
+end
+
+value_dumpers = {
+ ['function']=function(v) return v() end,
+ string=cstr,
+ boolean=function(v) return v and 'true' or 'false' end,
+ number=function(v) return ('%iL'):format(v) end,
+ ['nil']=function(v) return '0L' end,
+}
+
+local get_value = function(v)
+ return '(char_u *) ' .. value_dumpers[type(v)](v)
+end
+
+local get_defaults = function(d)
+ return ('{' .. get_value(d.vi) .. ', ' .. get_value(d.vim) .. '}')
+end
+
+local defines = {}
+
+local dump_option = function(i, o)
+ w(' [' .. ('%u'):format(i - 1) .. ']={')
+ w(' .fullname=' .. cstr(o.full_name))
+ if o.abbreviation then
+ w(' .shortname=' .. cstr(o.abbreviation))
+ end
+ w(' .flags=' .. get_flags(o))
+ if o.enable_if then
+ w(get_cond(o.enable_if))
+ end
+ if o.varname then
+ w(' .var=(char_u *)&' .. o.varname)
+ elseif #o.scope == 1 and o.scope[1] == 'window' then
+ w(' .var=VAR_WIN')
+ end
+ if o.enable_if then
+ w('#endif')
+ end
+ if #o.scope == 1 and o.scope[1] == 'global' then
+ w(' .indir=PV_NONE')
+ else
+ assert (#o.scope == 1 or #o.scope == 2)
+ assert (#o.scope == 1 or o.scope[1] == 'global')
+ local min_scope = o.scope[#o.scope]
+ local varname = o.pv_name or o.varname or (
+ 'p_' .. (o.abbreviation or o.full_name))
+ local pv_name = (
+ 'OPT_' .. min_scope:sub(1, 3):upper() .. '(' .. (
+ min_scope:sub(1, 1):upper() .. 'V_' .. varname:sub(3):upper()
+ ) .. ')'
+ )
+ if #o.scope == 2 then
+ pv_name = 'OPT_BOTH(' .. pv_name .. ')'
+ end
+ defines['PV_' .. varname:sub(3):upper()] = pv_name
+ w(' .indir=' .. pv_name)
+ end
+ if o.defaults then
+ if o.defaults.condition then
+ w(get_cond(o.defaults.condition))
+ end
+ w(' .def_val=' .. get_defaults(o.defaults.if_true))
+ if o.defaults.condition then
+ if o.defaults.if_false then
+ w('#else')
+ w(' .def_val=' .. get_defaults(o.defaults.if_false))
+ end
+ w('#endif')
+ end
+ end
+ w(' },')
+end
+
+w('static vimoption_T options[] = {')
+for i, o in ipairs(options.options) do
+ dump_option(i, o)
+end
+w(' [' .. ('%u'):format(#options.options) .. ']={.fullname=NULL}')
+w('};')
+w('')
+
+for k, v in pairs(defines) do
+ w('#define ' .. k .. ' ' .. v)
+end
+opt_fd:close()
diff --git a/src/nvim/generators/gen_unicode_tables.lua b/src/nvim/generators/gen_unicode_tables.lua
new file mode 100644
index 0000000000..66430ba26e
--- /dev/null
+++ b/src/nvim/generators/gen_unicode_tables.lua
@@ -0,0 +1,327 @@
+-- Script creates the following tables in unicode_tables.generated.h:
+--
+-- 1. doublewidth and ambiguous tables: sorted list of non-overlapping closed
+-- intervals. Codepoints in these intervals have double (W or F) or ambiguous
+-- (A) east asian width respectively.
+-- 2. combining table: same as the above, but characters inside are combining
+-- characters (i.e. have general categories equal to Mn, Mc or Me).
+-- 3. foldCase, toLower and toUpper tables used to convert characters to
+-- folded/lower/upper variants. In these tables first two values are
+-- character ranges: like in previous tables they are sorted and must be
+-- non-overlapping. Third value means step inside the range: e.g. if it is
+-- 2 then interval applies only to first, third, fifth, … character in range.
+-- Fourth value is number that should be added to the codepoint to yield
+-- folded/lower/upper codepoint.
+-- 4. emoji_width and emoji_all tables: sorted lists of non-overlapping closed
+-- intervals of Emoji characters. emoji_width contains all the characters
+-- which don't have ambiguous or double width, and emoji_all has all Emojis.
+if arg[1] == '--help' then
+ print('Usage:')
+ print(' genunicodetables.lua unicode/ unicode_tables.generated.h')
+ os.exit(0)
+end
+
+local basedir = arg[1]
+local pathsep = package.config:sub(1, 1)
+local get_path = function(fname)
+ return basedir .. pathsep .. fname
+end
+
+local unicodedata_fname = get_path('UnicodeData.txt')
+local casefolding_fname = get_path('CaseFolding.txt')
+local eastasianwidth_fname = get_path('EastAsianWidth.txt')
+local emoji_fname = get_path('emoji-data.txt')
+
+local utf_tables_fname = arg[2]
+
+local split_on_semicolons = function(s)
+ local ret = {}
+ local idx = 1
+ while idx <= #s + 1 do
+ item = s:match('^[^;]*', idx)
+ idx = idx + #item + 1
+ if idx <= #s + 1 then
+ assert(s:sub(idx - 1, idx - 1) == ';')
+ end
+ item = item:gsub('^%s*', '')
+ item = item:gsub('%s*$', '')
+ table.insert(ret, item)
+ end
+ return ret
+end
+
+local fp_lines_to_lists = function(fp, n, has_comments)
+ local ret = {}
+ local line
+ local i = 0
+ while true do
+ i = i + 1
+ line = fp:read('*l')
+ if not line then
+ break
+ end
+ if (not has_comments
+ or (line:sub(1, 1) ~= '#' and not line:match('^%s*$'))) then
+ local l = split_on_semicolons(line)
+ if #l ~= n then
+ io.stderr:write(('Found %s items in line %u, expected %u\n'):format(
+ #l, i, n))
+ io.stderr:write('Line: ' .. line .. '\n')
+ return nil
+ end
+ table.insert(ret, l)
+ end
+ end
+ return ret
+end
+
+local parse_data_to_props = function(ud_fp)
+ return fp_lines_to_lists(ud_fp, 15, false)
+end
+
+local parse_fold_props = function(cf_fp)
+ return fp_lines_to_lists(cf_fp, 4, true)
+end
+
+local parse_width_props = function(eaw_fp)
+ return fp_lines_to_lists(eaw_fp, 2, true)
+end
+
+local parse_emoji_props = function(emoji_fp)
+ return fp_lines_to_lists(emoji_fp, 2, true)
+end
+
+local make_range = function(start, end_, step, add)
+ if step and add then
+ return (' {0x%x, 0x%x, %d, %d},\n'):format(
+ start, end_, step == 0 and -1 or step, add)
+ else
+ return (' {0x%04x, 0x%04x},\n'):format(start, end_)
+ end
+end
+
+local build_convert_table = function(ut_fp, props, cond_func, nl_index,
+ table_name)
+ ut_fp:write('static const convertStruct ' .. table_name .. '[] = {\n')
+ local start = -1
+ local end_ = -1
+ local step = 0
+ local add = -1
+ for _, p in ipairs(props) do
+ if cond_func(p) then
+ local n = tonumber(p[1], 16)
+ local nl = tonumber(p[nl_index], 16)
+ if start >= 0 and add == (nl - n) and (step == 0 or n - end_ == step) then
+ -- Continue with the same range.
+ step = n - end_
+ end_ = n
+ else
+ if start >= 0 then
+ -- Produce previous range.
+ ut_fp:write(make_range(start, end_, step, add))
+ end
+ start = n
+ end_ = n
+ step = 0
+ add = nl - n
+ end
+ end
+ end
+ if start >= 0 then
+ ut_fp:write(make_range(start, end_, step, add))
+ end
+ ut_fp:write('};\n')
+end
+
+local build_case_table = function(ut_fp, dataprops, table_name, index)
+ local cond_func = function(p)
+ return p[index] ~= ''
+ end
+ return build_convert_table(ut_fp, dataprops, cond_func, index,
+ 'to' .. table_name)
+end
+
+local build_fold_table = function(ut_fp, foldprops)
+ local cond_func = function(p)
+ return (p[2] == 'C' or p[2] == 'S')
+ end
+ return build_convert_table(ut_fp, foldprops, cond_func, 3, 'foldCase')
+end
+
+local build_combining_table = function(ut_fp, dataprops)
+ ut_fp:write('static const struct interval combining[] = {\n')
+ local start = -1
+ local end_ = -1
+ for _, p in ipairs(dataprops) do
+ if (({Mn=true, Mc=true, Me=true})[p[3]]) then
+ local n = tonumber(p[1], 16)
+ if start >= 0 and end_ + 1 == n then
+ -- Continue with the same range.
+ end_ = n
+ else
+ if start >= 0 then
+ -- Produce previous range.
+ ut_fp:write(make_range(start, end_))
+ end
+ start = n
+ end_ = n
+ end
+ end
+ end
+ if start >= 0 then
+ ut_fp:write(make_range(start, end_))
+ end
+ ut_fp:write('};\n')
+end
+
+local build_width_table = function(ut_fp, dataprops, widthprops, widths,
+ table_name)
+ ut_fp:write('static const struct interval ' .. table_name .. '[] = {\n')
+ local start = -1
+ local end_ = -1
+ local dataidx = 1
+ local ret = {}
+ for _, p in ipairs(widthprops) do
+ if widths[p[2]:sub(1, 1)] then
+ local rng_start, rng_end = p[1]:find('%.%.')
+ local n, n_last
+ if rng_start then
+ -- It is a range. We don’t check for composing char then.
+ n = tonumber(p[1]:sub(1, rng_start - 1), 16)
+ n_last = tonumber(p[1]:sub(rng_end + 1), 16)
+ else
+ n = tonumber(p[1], 16)
+ n_last = n
+ end
+ local dn
+ while true do
+ dn = tonumber(dataprops[dataidx][1], 16)
+ if dn >= n then
+ break
+ end
+ dataidx = dataidx + 1
+ end
+ if dn ~= n and n_last == n then
+ io.stderr:write('Cannot find character ' .. n .. ' in data table.\n')
+ end
+ -- Only use the char when it’s not a composing char.
+ -- But use all chars from a range.
+ local dp = dataprops[dataidx]
+ if (n_last > n) or (not (({Mn=true, Mc=true, Me=true})[dp[3]])) then
+ if start >= 0 and end_ + 1 == n then
+ -- Continue with the same range.
+ else
+ if start >= 0 then
+ ut_fp:write(make_range(start, end_))
+ table.insert(ret, {start, end_})
+ end
+ start = n
+ end
+ end_ = n_last
+ end
+ end
+ end
+ if start >= 0 then
+ ut_fp:write(make_range(start, end_))
+ table.insert(ret, {start, end_})
+ end
+ ut_fp:write('};\n')
+ return ret
+end
+
+local build_emoji_table = function(ut_fp, emojiprops, doublewidth, ambiwidth)
+ local emojiwidth = {}
+ local emoji = {}
+ for _, p in ipairs(emojiprops) do
+ if p[2]:match('Emoji%s+#') then
+ local rng_start, rng_end = p[1]:find('%.%.')
+ if rng_start then
+ n = tonumber(p[1]:sub(1, rng_start - 1), 16)
+ n_last = tonumber(p[1]:sub(rng_end + 1), 16)
+ else
+ n = tonumber(p[1], 16)
+ n_last = n
+ end
+ if #emoji > 0 and n - 1 == emoji[#emoji][2] then
+ emoji[#emoji][2] = n_last
+ else
+ table.insert(emoji, { n, n_last })
+ end
+
+ -- Characters below 1F000 may be considered single width traditionally,
+ -- making them double width causes problems.
+ if n >= 0x1f000 then
+ -- exclude characters that are in the ambiguous/doublewidth table
+ for _, ambi in ipairs(ambiwidth) do
+ if n >= ambi[1] and n <= ambi[2] then
+ n = ambi[2] + 1
+ end
+ if n_last >= ambi[1] and n_last <= ambi[2] then
+ n_last = ambi[1] - 1
+ end
+ end
+ for _, double in ipairs(doublewidth) do
+ if n >= double[1] and n <= double[2] then
+ n = double[2] + 1
+ end
+ if n_last >= double[1] and n_last <= double[2] then
+ n_last = double[1] - 1
+ end
+ end
+
+ if n <= n_last then
+ if #emojiwidth > 0 and n - 1 == emojiwidth[#emojiwidth][2] then
+ emojiwidth[#emojiwidth][2] = n_last
+ else
+ table.insert(emojiwidth, { n, n_last })
+ end
+ end
+ end
+ end
+ end
+
+ ut_fp:write('static const struct interval emoji_all[] = {\n')
+ for _, p in ipairs(emoji) do
+ ut_fp:write(make_range(p[1], p[2]))
+ end
+ ut_fp:write('};\n')
+
+ ut_fp:write('static const struct interval emoji_width[] = {\n')
+ for _, p in ipairs(emojiwidth) do
+ ut_fp:write(make_range(p[1], p[2]))
+ end
+ ut_fp:write('};\n')
+end
+
+local ud_fp = io.open(unicodedata_fname, 'r')
+local dataprops = parse_data_to_props(ud_fp)
+ud_fp:close()
+
+local ut_fp = io.open(utf_tables_fname, 'w')
+
+build_case_table(ut_fp, dataprops, 'Lower', 14)
+build_case_table(ut_fp, dataprops, 'Upper', 13)
+build_combining_table(ut_fp, dataprops)
+
+local cf_fp = io.open(casefolding_fname, 'r')
+local foldprops = parse_fold_props(cf_fp)
+cf_fp:close()
+
+build_fold_table(ut_fp, foldprops)
+
+local eaw_fp = io.open(eastasianwidth_fname, 'r')
+local widthprops = parse_width_props(eaw_fp)
+eaw_fp:close()
+
+local doublewidth = build_width_table(ut_fp, dataprops, widthprops,
+ {W=true, F=true}, 'doublewidth')
+local ambiwidth = build_width_table(ut_fp, dataprops, widthprops,
+ {A=true}, 'ambiguous')
+
+local emoji_fp = io.open(emoji_fname, 'r')
+local emojiprops = parse_emoji_props(emoji_fp)
+emoji_fp:close()
+
+build_emoji_table(ut_fp, emojiprops, doublewidth, ambiwidth)
+
+ut_fp:close()
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index fccbd69dbf..a22b716bb6 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* getchar.c
*
@@ -15,6 +18,7 @@
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/getchar.h"
+#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/edit.h"
@@ -44,6 +48,7 @@
#include "nvim/event/loop.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
+#include "nvim/api/private/handle.h"
/*
* These buffers are used for storing:
@@ -99,11 +104,10 @@ static int block_redo = FALSE;
(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;
+// Each mapping is put in one of the MAX_MAPHASH hash lists,
+// to speed up finding it.
+static mapblock_T *(maphash[MAX_MAPHASH]);
+static bool maphash_valid = false;
/*
* List used for abbreviations.
@@ -235,19 +239,18 @@ char_u *get_inserted(void)
return get_buffcont(&redobuff, FALSE);
}
-/*
- * Add string "s" after the current block of buffer "buf".
- * K_SPECIAL and CSI should have been escaped already.
- */
-static void
-add_buff (
- buffheader_T *buf,
- char_u *s,
- ssize_t slen // length of "s" or -1
-)
+/// Add string after the current block of the given buffer
+///
+/// K_SPECIAL and CSI should have been escaped already.
+///
+/// @param[out] buf Buffer to add to.
+/// @param[in] s String to add.
+/// @param[in] slen String length or -1 for NUL-terminated string.
+static void add_buff(buffheader_T *const buf, const char *const s,
+ ptrdiff_t slen)
{
if (slen < 0) {
- slen = (ssize_t)STRLEN(s);
+ slen = (ptrdiff_t)strlen(s);
}
if (slen == 0) { // don't add empty strings
return;
@@ -292,9 +295,8 @@ add_buff (
*/
static void add_num_buff(buffheader_T *buf, long n)
{
- char_u number[32];
-
- sprintf((char *)number, "%" PRId64, (int64_t)n);
+ char number[32];
+ snprintf(number, sizeof(number), "%ld", n);
add_buff(buf, number, -1L);
}
@@ -304,27 +306,29 @@ static void add_num_buff(buffheader_T *buf, long n)
*/
static void add_char_buff(buffheader_T *buf, int c)
{
- char_u bytes[MB_MAXBYTES + 1];
- int len;
- int i;
- char_u temp[4];
+ uint8_t bytes[MB_MAXBYTES + 1];
- if (IS_SPECIAL(c))
+ int len;
+ if (IS_SPECIAL(c)) {
len = 1;
- else
- len = (*mb_char2bytes)(c, bytes);
- for (i = 0; i < len; ++i) {
- if (!IS_SPECIAL(c))
+ } else {
+ len = mb_char2bytes(c, bytes);
+ }
+
+ for (int i = 0; i < len; i++) {
+ if (!IS_SPECIAL(c)) {
c = bytes[i];
+ }
+ char temp[4];
if (IS_SPECIAL(c) || c == K_SPECIAL || c == NUL) {
- /* translate special key code into three byte sequence */
- temp[0] = K_SPECIAL;
- temp[1] = (char_u)K_SECOND(c);
- temp[2] = (char_u)K_THIRD(c);
+ // Translate special key code into three byte sequence.
+ temp[0] = (char)K_SPECIAL;
+ temp[1] = (char)K_SECOND(c);
+ temp[2] = (char)K_THIRD(c);
temp[3] = NUL;
} else {
- temp[0] = (char_u)c;
+ temp[0] = (char)c;
temp[1] = NUL;
}
add_buff(buf, temp, -1L);
@@ -479,16 +483,14 @@ static int save_level = 0;
void saveRedobuff(void)
{
- 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);
+ // Make a copy, so that ":normal ." in a function works.
+ char *const s = (char *)get_buffcont(&save_redobuff, false);
if (s != NULL) {
add_buff(&redobuff, s, -1L);
xfree(s);
@@ -514,10 +516,11 @@ void restoreRedobuff(void)
* Append "s" to the redo buffer.
* K_SPECIAL and CSI should already have been escaped.
*/
-void AppendToRedobuff(char_u *s)
+void AppendToRedobuff(const char *s)
{
- if (!block_redo)
- add_buff(&redobuff, s, -1L);
+ if (!block_redo) {
+ add_buff(&redobuff, (const char *)s, -1L);
+ }
}
/*
@@ -530,44 +533,47 @@ AppendToRedobuffLit (
int len /* length of "str" or -1 for up to the NUL */
)
{
- char_u *s = str;
- int c;
- char_u *start;
-
- if (block_redo)
+ if (block_redo) {
return;
+ }
+
+ const char *s = (const char *)str;
+ while (len < 0 ? *s != NUL : s - (const char *)str < len) {
+ // Put a string of normal characters in the redo buffer (that's
+ // faster).
+ const char *start = s;
+ while (*s >= ' ' && *s < DEL && (len < 0 || s - (const char *)str < len)) {
+ s++;
+ }
- while (len < 0 ? *s != NUL : s - str < len) {
- /* Put a string of normal characters in the redo buffer (that's
- * faster). */
- start = s;
- while (*s >= ' ' && *s < DEL && (len < 0 || s - str < len))
- ++s;
-
- /* Don't put '0' or '^' as last character, just in case a CTRL-D is
- * typed next. */
- if (*s == NUL && (s[-1] == '0' || s[-1] == '^'))
- --s;
- if (s > start)
+ // Don't put '0' or '^' as last character, just in case a CTRL-D is
+ // typed next.
+ if (*s == NUL && (s[-1] == '0' || s[-1] == '^')) {
+ s--;
+ }
+ if (s > start) {
add_buff(&redobuff, start, (long)(s - start));
+ }
- if (*s == NUL || (len >= 0 && s - str >= len))
+ if (*s == NUL || (len >= 0 && s - (const char *)str >= len)) {
break;
+ }
- /* Handle a special or multibyte character. */
- if (has_mbyte)
- /* Handle composing chars separately. */
- c = mb_cptr2char_adv(&s);
- else
- c = *s++;
- if (c < ' ' || c == DEL || (*s == NUL && (c == '0' || c == '^')))
+ // Handle a special or multibyte character.
+ // Composing chars separately are handled separately.
+ const int c = (has_mbyte
+ ? mb_cptr2char_adv((const char_u **)&s)
+ : (uint8_t)(*s++));
+ if (c < ' ' || c == DEL || (*s == NUL && (c == '0' || c == '^'))) {
add_char_buff(&redobuff, Ctrl_V);
+ }
- /* CTRL-V '0' must be inserted as CTRL-V 048 */
- if (*s == NUL && c == '0')
- add_buff(&redobuff, (char_u *)"048", 3L);
- else
+ // CTRL-V '0' must be inserted as CTRL-V 048.
+ if (*s == NUL && c == '0') {
+ add_buff(&redobuff, "048", 3L);
+ } else {
add_char_buff(&redobuff, c);
+ }
}
}
@@ -594,19 +600,19 @@ void AppendNumberToRedobuff(long n)
* Append string "s" to the stuff buffer.
* CSI and K_SPECIAL must already have been escaped.
*/
-void stuffReadbuff(char_u *s)
+void stuffReadbuff(const char *s)
{
add_buff(&readbuf1, s, -1L);
}
/// Append string "s" to the redo stuff buffer.
/// @remark CSI and K_SPECIAL must already have been escaped.
-void stuffRedoReadbuff(char_u *s)
+void stuffRedoReadbuff(const char *s)
{
add_buff(&readbuf2, s, -1L);
}
-void stuffReadbuffLen(char_u *s, long len)
+void stuffReadbuffLen(const char *s, long len)
{
add_buff(&readbuf1, s, len);
}
@@ -616,19 +622,18 @@ void stuffReadbuffLen(char_u *s, long len)
* escaping other K_SPECIAL and CSI bytes.
* Change CR, LF and ESC into a space.
*/
-void stuffReadbuffSpec(char_u *s)
+void stuffReadbuffSpec(const char *s)
{
- int c;
-
while (*s != NUL) {
- if (*s == K_SPECIAL && s[1] != NUL && s[2] != NUL) {
- /* Insert special key literally. */
- stuffReadbuffLen(s, 3L);
+ if ((uint8_t)(*s) == K_SPECIAL && s[1] != NUL && s[2] != NUL) {
+ // Insert special key literally.
+ stuffReadbuffLen(s, 3);
s += 3;
} else {
- c = mb_ptr2char_adv(&s);
- if (c == CAR || c == NL || c == ESC)
+ int c = mb_ptr2char_adv((const char_u **)&s);
+ if (c == CAR || c == NL || c == ESC) {
c = ' ';
+ }
stuffcharReadbuff(c);
}
}
@@ -747,8 +752,8 @@ int start_redo(long count, int old_redo)
/* copy the buffer name, if present */
if (c == '"') {
- add_buff(&readbuf2, (char_u *)"\"", 1L);
- c = read_redo(FALSE, old_redo);
+ add_buff(&readbuf2, "\"", 1L);
+ c = read_redo(false, old_redo);
/* if a numbered buffer is used, increment the number */
if (c >= '1' && c < '9')
@@ -1091,21 +1096,19 @@ static void gotchars(char_u *chars, size_t len)
{
char_u *s = chars;
int c;
- char_u buf[2];
// remember how many chars were last recorded
if (Recording) {
last_recorded_len += len;
}
- buf[1] = NUL;
while (len--) {
// Handle one byte at a time; no translation to be done.
c = *s++;
updatescript(c);
if (Recording) {
- buf[0] = (char_u)c;
+ char buf[2] = { (char)c, NUL };
add_buff(&recordbuff, buf, 1L);
}
}
@@ -1327,8 +1330,9 @@ int using_script(void)
void before_blocking(void)
{
updatescript(0);
- if (may_garbage_collect)
- garbage_collect();
+ if (may_garbage_collect) {
+ garbage_collect(false);
+ }
}
/*
@@ -1366,10 +1370,11 @@ int vgetc(void)
char_u buf[MB_MAXBYTES + 1];
int i;
- /* Do garbage collection when garbagecollect() was called previously and
- * we are now at the toplevel. */
- if (may_garbage_collect && want_garbage_collect)
- garbage_collect();
+ // Do garbage collection when garbagecollect() was called previously and
+ // we are now at the toplevel.
+ if (may_garbage_collect && want_garbage_collect) {
+ garbage_collect(false);
+ }
/*
* If a character was put back with vungetc, it was already processed.
@@ -1387,27 +1392,20 @@ int vgetc(void)
for (;; ) { // this is done twice if there are modifiers
bool did_inc = false;
if (mod_mask) { // no mapping after modifier has been read
- ++no_mapping;
- ++allow_keys;
+ no_mapping++;
did_inc = true; // mod_mask may change value
}
c = vgetorpeek(true);
if (did_inc) {
- --no_mapping;
- --allow_keys;
+ no_mapping--;
}
- /* Get two extra bytes for special keys */
- if (c == K_SPECIAL
- ) {
- int save_allow_keys = allow_keys;
-
- ++no_mapping;
- allow_keys = 0; /* make sure BS is not found */
- c2 = vgetorpeek(TRUE); /* no mapping for these chars */
- c = vgetorpeek(TRUE);
- --no_mapping;
- allow_keys = save_allow_keys;
+ // Get two extra bytes for special keys
+ if (c == K_SPECIAL) {
+ no_mapping++;
+ c2 = vgetorpeek(true); // no mapping for these chars
+ c = vgetorpeek(true);
+ no_mapping--;
if (c2 == KS_MODIFIER) {
mod_mask = c;
continue;
@@ -1485,7 +1483,7 @@ int vgetc(void)
buf[i] = CSI;
}
}
- --no_mapping;
+ no_mapping--;
c = (*mb_ptr2char)(buf);
}
@@ -1568,7 +1566,7 @@ int char_avail(void)
no_mapping++;
retval = vpeekc();
- --no_mapping;
+ no_mapping--;
return retval != NUL;
}
@@ -1595,7 +1593,7 @@ vungetc ( /* unget one character (can only be done once!) */
/// This may do a blocking wait if "advance" is TRUE.
///
/// if "advance" is TRUE (vgetc()):
-/// really get the character.
+/// 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()):
@@ -1808,7 +1806,7 @@ static int vgetorpeek(int advance)
* <M-a> and then changing 'encoding'. Beware
* that 0x80 is escaped. */
char_u *p1 = mp->m_keys;
- char_u *p2 = mb_unescape(&p1);
+ char_u *p2 = (char_u *)mb_unescape((const char **)&p1);
if (has_mbyte && p2 != NULL && MB_BYTE2LEN(c1) > MB_PTR2LEN(p2))
mlen = 0;
@@ -1855,11 +1853,12 @@ static int vgetorpeek(int advance)
mp_match = mp;
mp_match_len = keylen;
}
- } else
- /* No match; may have to check for
- * termcode at next character. */
- if (max_mlen < mlen)
- max_mlen = mlen;
+ } else {
+ // No match; may have to check for termcode at next character.
+ if (max_mlen < mlen) {
+ max_mlen = mlen;
+ }
+ }
}
}
@@ -1886,9 +1885,8 @@ static int vgetorpeek(int advance)
(size_t)(mlen - typebuf.tb_maplen));
}
- del_typebuf(mlen, 0); /* remove the chars */
- set_option_value((char_u *)"paste",
- (long)!p_paste, NULL, 0);
+ del_typebuf(mlen, 0); // Remove the chars.
+ set_option_value("paste", !p_paste, NULL, 0);
if (!(State & INSERT)) {
msg_col = 0;
msg_row = (int)Rows - 1;
@@ -1911,63 +1909,30 @@ static int vgetorpeek(int advance)
if ((mp == NULL || max_mlen >= mp_match_len)
&& keylen != KEYLEN_PART_MAP) {
- /*
- * When no matching mapping found or found a
- * non-matching mapping that matches at least what the
- * matching mapping matched:
- * Check if we have a terminal code, when:
- * mapping is allowed,
- * keys have not been mapped,
- * and not an ESC sequence, not in insert mode or
- * p_ek is on,
- * and when not timed out,
- */
- if ((no_mapping == 0 || allow_keys != 0)
- && (typebuf.tb_maplen == 0
- || (p_remap && typebuf.tb_noremap[
- typebuf.tb_off] == RM_YES))
- && !timedout) {
- keylen = 0;
- } else
- keylen = 0;
- if (keylen == 0) { /* no matching terminal code */
- /* When there was a matching mapping and no
- * termcode could be replaced after another one,
- * use that mapping (loop around). If there was
- * no mapping use the character from the
- * typeahead buffer right here. */
- if (mp == NULL) {
- /*
- * get a character: 2. from the typeahead buffer
- */
- c = typebuf.tb_buf[typebuf.tb_off] & 255;
- if (advance) { /* remove chars from tb_buf */
- cmd_silent = (typebuf.tb_silent > 0);
- if (typebuf.tb_maplen > 0)
- KeyTyped = FALSE;
- else {
- KeyTyped = TRUE;
- /* write char to script file(s) */
- gotchars(typebuf.tb_buf
- + typebuf.tb_off, 1);
- }
- KeyNoremap = typebuf.tb_noremap[
- typebuf.tb_off];
- del_typebuf(1, 0);
+ // No matching mapping found or found a non-matching mapping that
+ // matches at least what the matching mapping matched
+ keylen = 0;
+ // If there was no mapping, use the character from the typeahead
+ // buffer right here. Otherwise, use the mapping (loop around).
+ if (mp == NULL) {
+ // get a character: 2. from the typeahead buffer
+ c = typebuf.tb_buf[typebuf.tb_off] & 255;
+ if (advance) { // remove chars from tb_buf
+ cmd_silent = (typebuf.tb_silent > 0);
+ if (typebuf.tb_maplen > 0) {
+ KeyTyped = false;
+ } else {
+ KeyTyped = true;
+ // write char to script file(s)
+ gotchars(typebuf.tb_buf + typebuf.tb_off, 1);
}
- break; /* got character, break for loop */
+ KeyNoremap = typebuf.tb_noremap[typebuf.tb_off];
+ del_typebuf(1, 0);
}
- }
- if (keylen > 0) { /* full matching terminal code */
- continue; /* try mapping again */
- }
-
- /* Partial match: get some more characters. When a
- * matching mapping was found use that one. */
- if (mp == NULL || keylen < 0)
- keylen = KEYLEN_PART_KEY;
- else
+ break; // got character, break for loop
+ } else {
keylen = mp_match_len;
+ }
}
/* complete match */
@@ -2462,7 +2427,7 @@ inchar (
if (typebuf_changed(tb_change_cnt))
return 0;
- return fix_input_buffer(buf, len, script_char >= 0);
+ return fix_input_buffer(buf, len);
}
/*
@@ -2470,12 +2435,7 @@ inchar (
* buf[] must have room to triple the number of bytes!
* Returns the new length.
*/
-int
-fix_input_buffer (
- char_u *buf,
- int len,
- int script /* TRUE when reading from a script */
-)
+int fix_input_buffer(char_u *buf, int len)
{
if (!using_script()) {
// Should not escape K_SPECIAL/CSI reading input from the user because vim
@@ -2492,12 +2452,10 @@ fix_input_buffer (
// Replace NUL by K_SPECIAL KS_ZERO KE_FILLER
// Replace K_SPECIAL by K_SPECIAL KS_SPECIAL KE_FILLER
// Replace CSI by K_SPECIAL KS_EXTRA KE_CSI
- // Don't replace K_SPECIAL when reading a script file.
for (i = len; --i >= 0; ++p) {
if (p[0] == NUL
|| (p[0] == K_SPECIAL
- && !script
- && (i < 2 || p[1] != KS_EXTRA))) {
+ && (i < 2 || p[1] != KS_EXTRA))) {
memmove(p + 3, p + 1, (size_t)i);
p[2] = (char_u)K_THIRD(p[0]);
p[1] = (char_u)K_SECOND(p[0]);
@@ -2579,7 +2537,6 @@ do_map (
bool unique = false;
bool nowait = false;
bool silent = false;
- bool special = false;
bool expr = false;
int noremap;
char_u *orig_rhs;
@@ -2625,12 +2582,9 @@ do_map (
continue;
}
- /*
- * Check for "<special>": accept special keys in <>
- */
+ // Ignore obsolete "<special>" modifier.
if (STRNCMP(keys, "<special>", 9) == 0) {
keys = skipwhite(keys + 9);
- special = true;
continue;
}
@@ -2699,7 +2653,7 @@ do_map (
// needs to be freed later (*keys_buf and *arg_buf).
// replace_termcodes() also removes CTRL-Vs and sometimes backslashes.
if (haskey) {
- keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, special,
+ keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, true,
CPO_TO_CPO_FLAGS);
}
orig_rhs = rhs;
@@ -2707,7 +2661,7 @@ do_map (
if (STRICMP(rhs, "<nop>") == 0) { // "<Nop>" means nothing
rhs = (char_u *)"";
} else {
- rhs = replace_termcodes(rhs, STRLEN(rhs), &arg_buf, false, true, special,
+ rhs = replace_termcodes(rhs, STRLEN(rhs), &arg_buf, false, true, true,
CPO_TO_CPO_FLAGS);
}
}
@@ -3163,11 +3117,11 @@ map_clear_int (
}
}
-/*
- * Return characters to represent the map mode in an allocated string.
- * Returns NULL when out of memory.
- */
-char_u *map_mode_to_chars(int mode)
+/// Return characters to represent the map mode in an allocated string
+///
+/// @return [allocated] NUL-terminated string with characters.
+char *map_mode_to_chars(int mode)
+ FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_RET
{
garray_T mapmode;
@@ -3200,7 +3154,7 @@ char_u *map_mode_to_chars(int mode)
}
ga_append(&mapmode, NUL);
- return (char_u *)mapmode.ga_data;
+ return (char *)mapmode.ga_data;
}
static void
@@ -3209,8 +3163,11 @@ showmap (
int local /* TRUE for buffer-local map */
)
{
- int len = 1;
- char_u *mapchars;
+ size_t len = 1;
+
+ if (message_filtered(mp->m_keys) && message_filtered(mp->m_str)) {
+ return;
+ }
if (msg_didout || msg_silent != 0) {
msg_putchar('\n');
@@ -3218,29 +3175,30 @@ showmap (
return;
}
- mapchars = map_mode_to_chars(mp->m_mode);
- if (mapchars != NULL) {
+ {
+ char *const mapchars = map_mode_to_chars(mp->m_mode);
msg_puts(mapchars);
- len = (int)STRLEN(mapchars);
+ len = strlen(mapchars);
xfree(mapchars);
}
while (++len <= 3)
msg_putchar(' ');
- /* Display the LHS. Get length of what we write. */
- len = msg_outtrans_special(mp->m_keys, TRUE);
+ // Display the LHS. Get length of what we write.
+ len = (size_t)msg_outtrans_special(mp->m_keys, true);
do {
msg_putchar(' '); /* padd with blanks */
++len;
} while (len < 12);
- if (mp->m_noremap == REMAP_NONE)
- msg_puts_attr((char_u *)"*", hl_attr(HLF_8));
- else if (mp->m_noremap == REMAP_SCRIPT)
- msg_puts_attr((char_u *)"&", hl_attr(HLF_8));
- else
+ if (mp->m_noremap == REMAP_NONE) {
+ msg_puts_attr("*", hl_attr(HLF_8));
+ } else if (mp->m_noremap == REMAP_SCRIPT) {
+ msg_puts_attr("&", hl_attr(HLF_8));
+ } else {
msg_putchar(' ');
+ }
if (local)
msg_putchar('@');
@@ -3249,11 +3207,11 @@ showmap (
/* Use FALSE below if we only want things like <Up> to show up as such on
* the rhs, and not M-x etc, TRUE gets both -- webb */
- if (*mp->m_str == NUL)
- msg_puts_attr((char_u *)"<Nop>", hl_attr(HLF_8));
- else {
- /* Remove escaping of CSI, because "m_str" is in a format to be used
- * as typeahead. */
+ if (*mp->m_str == NUL) {
+ msg_puts_attr("<Nop>", hl_attr(HLF_8));
+ } else {
+ // Remove escaping of CSI, because "m_str" is in a format to be used
+ // as typeahead.
char_u *s = vim_strsave(mp->m_str);
vim_unescape_csi(s);
msg_outtrans_special(s, FALSE);
@@ -3264,82 +3222,99 @@ showmap (
ui_flush(); /* show one line at a time */
}
-/*
- * Return TRUE if a map exists that has "str" in the rhs for mode "modechars".
- * Recognize termcap codes in "str".
- * Also checks mappings local to the current buffer.
- */
-int map_to_exists(char_u *str, char_u *modechars, int abbr)
+/// Check if a map exists that has given string in the rhs
+///
+/// Also checks mappings local to the current buffer.
+///
+/// @param[in] str String which mapping must have in the rhs. Termcap codes
+/// are recognized in this argument.
+/// @param[in] modechars Mode(s) in which mappings are checked.
+/// @param[in] abbr true if checking abbreviations in place of mappings.
+///
+/// @return true if there is at least one mapping with given parameters.
+bool map_to_exists(const char *const str, const char *const modechars,
+ const bool abbr)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
{
int mode = 0;
- char_u *rhs;
- char_u *buf;
int retval;
- rhs = replace_termcodes(str, STRLEN(str), &buf, false, true, false,
- CPO_TO_CPO_FLAGS);
-
- if (vim_strchr(modechars, 'n') != NULL)
- mode |= NORMAL;
- if (vim_strchr(modechars, 'v') != NULL)
- mode |= VISUAL + SELECTMODE;
- if (vim_strchr(modechars, 'x') != NULL)
- mode |= VISUAL;
- if (vim_strchr(modechars, 's') != NULL)
- mode |= SELECTMODE;
- if (vim_strchr(modechars, 'o') != NULL)
- mode |= OP_PENDING;
- if (vim_strchr(modechars, 'i') != NULL)
- mode |= INSERT;
- if (vim_strchr(modechars, 'l') != NULL)
- mode |= LANGMAP;
- if (vim_strchr(modechars, 'c') != NULL)
- mode |= CMDLINE;
-
- retval = map_to_exists_mode(rhs, mode, abbr);
+ char_u *buf;
+ char_u *const rhs = replace_termcodes((const char_u *)str, strlen(str), &buf,
+ false, true, true,
+ CPO_TO_CPO_FLAGS);
+
+#define MAPMODE(mode, modechars, chr, modeflags) \
+ do { \
+ if (strchr(modechars, chr) != NULL) { \
+ mode |= modeflags; \
+ } \
+ } while (0)
+ MAPMODE(mode, modechars, 'n', NORMAL);
+ MAPMODE(mode, modechars, 'v', VISUAL|SELECTMODE);
+ MAPMODE(mode, modechars, 'x', VISUAL);
+ MAPMODE(mode, modechars, 's', SELECTMODE);
+ MAPMODE(mode, modechars, 'o', OP_PENDING);
+ MAPMODE(mode, modechars, 'i', INSERT);
+ MAPMODE(mode, modechars, 'l', LANGMAP);
+ MAPMODE(mode, modechars, 'c', CMDLINE);
+#undef MAPMODE
+
+ retval = map_to_exists_mode((const char *)rhs, mode, abbr);
xfree(buf);
return retval;
}
-/*
- * Return TRUE if a map exists that has "str" in the rhs for mode "mode".
- * Also checks mappings local to the current buffer.
- */
-int map_to_exists_mode(char_u *rhs, int mode, int abbr)
+/// Check if a map exists that has given string in the rhs
+///
+/// Also checks mappings local to the current buffer.
+///
+/// @param[in] rhs String which mapping must have in the rhs. Termcap codes
+/// are recognized in this argument.
+/// @param[in] mode Mode(s) in which mappings are checked.
+/// @param[in] abbr true if checking abbreviations in place of mappings.
+///
+/// @return true if there is at least one mapping with given parameters.
+int map_to_exists_mode(const char *const rhs, const int mode, const bool abbr)
{
mapblock_T *mp;
int hash;
- int expand_buffer = FALSE;
+ bool expand_buffer = false;
validate_maphash();
- /* Do it twice: once for global maps and once for local maps. */
- for (;; ) {
- for (hash = 0; hash < 256; ++hash) {
+ // Do it twice: once for global maps and once for local maps.
+ for (;;) {
+ for (hash = 0; hash < 256; hash++) {
if (abbr) {
- if (hash > 0) /* there is only one abbr list */
+ if (hash > 0) { // There is only one abbr list.
break;
- if (expand_buffer)
+ }
+ if (expand_buffer) {
mp = curbuf->b_first_abbr;
- else
+ } else {
mp = first_abbr;
- } else if (expand_buffer)
+ }
+ } else if (expand_buffer) {
mp = curbuf->b_maphash[hash];
- else
+ } else {
mp = maphash[hash];
+ }
for (; mp; mp = mp->m_next) {
if ((mp->m_mode & mode)
- && strstr((char *)mp->m_str, (char *)rhs) != NULL)
- return TRUE;
+ && strstr((char *)mp->m_str, rhs) != NULL) {
+ return true;
+ }
}
}
- if (expand_buffer)
+ if (expand_buffer) {
break;
- expand_buffer = TRUE;
+ }
+ expand_buffer = true;
}
- return FALSE;
+ return false;
}
/*
@@ -3618,8 +3593,8 @@ int check_abbr(int c, char_u *ptr, int col, int mincol)
char_u *q = mp->m_keys;
int match;
- if (vim_strbyte(mp->m_keys, K_SPECIAL) != NULL) {
- /* might have CSI escaped mp->m_keys */
+ if (strchr((const char *)mp->m_keys, K_SPECIAL) != NULL) {
+ // Might have CSI escaped mp->m_keys.
q = vim_strsave(mp->m_keys);
vim_unescape_csi(q);
qlen = (int)STRLEN(q);
@@ -3755,8 +3730,10 @@ eval_map_expr (
*/
char_u *vim_strsave_escape_csi(char_u *p)
{
- /* Need a buffer to hold up to three times as much. */
- char_u *res = xmalloc(STRLEN(p) * 3 + 1);
+ // Need a buffer to hold up to three times as much. Four in case of an
+ // illegal utf-8 byte:
+ // 0xc0 -> 0xc3 - 0x80 -> 0xc3 K_SPECIAL KS_SPECIAL KE_FILLER
+ char_u *res = xmalloc(STRLEN(p) * 4 + 1);
char_u *d = res;
for (char_u *s = p; *s != NUL; ) {
if (s[0] == K_SPECIAL && s[1] != NUL && s[2] != NUL) {
@@ -3765,17 +3742,10 @@ char_u *vim_strsave_escape_csi(char_u *p)
*d++ = *s++;
*d++ = *s++;
} else {
- int len = mb_char2len(PTR2CHAR(s));
- int len2 = mb_ptr2len(s);
- /* Add character, possibly multi-byte to destination, escaping
- * CSI and K_SPECIAL. */
+ // Add character, possibly multi-byte to destination, escaping
+ // CSI and K_SPECIAL. Be careful, it can be an illegal byte!
d = add_char2buf(PTR2CHAR(s), d);
- while (len < len2) {
- /* add following combining char */
- d = add_char2buf(PTR2CHAR(s + len), d);
- len += mb_char2len(PTR2CHAR(s + len));
- }
- mb_ptr_adv(s);
+ s += MB_CPTR2LEN(s);
}
}
*d = NUL;
@@ -3821,8 +3791,7 @@ makemap (
char *cmd;
int abbr;
int hash;
- int did_cpo = FALSE;
- int i;
+ bool did_cpo = false;
validate_maphash();
@@ -3950,13 +3919,15 @@ makemap (
/* When outputting <> form, need to make sure that 'cpo'
* is set to the Vim default. */
if (!did_cpo) {
- if (*mp->m_str == NUL) /* will use <Nop> */
- did_cpo = TRUE;
- else
- for (i = 0; i < 2; ++i)
- for (p = (i ? mp->m_str : mp->m_keys); *p; ++p)
- if (*p == K_SPECIAL || *p == NL)
- did_cpo = TRUE;
+ if (*mp->m_str == NUL) { // Will use <Nop>.
+ did_cpo = true;
+ } else {
+ const char specials[] = { (char)(uint8_t)K_SPECIAL, NL, NUL };
+ if (strpbrk((const char *)mp->m_str, specials) != NULL
+ || strpbrk((const char *)mp->m_keys, specials) != NULL) {
+ did_cpo = true;
+ }
+ }
if (did_cpo) {
if (fprintf(fd, "let s:cpo_save=&cpo") < 0
|| put_eol(fd) < 0
@@ -4024,12 +3995,10 @@ int put_escstr(FILE *fd, char_u *strstart, int what)
return OK;
}
- for (; *str != NUL; ++str) {
- char_u *p;
-
- /* Check for a multi-byte character, which may contain escaped
- * K_SPECIAL and CSI bytes */
- p = mb_unescape(&str);
+ for (; *str != NUL; str++) {
+ // Check for a multi-byte character, which may contain escaped
+ // K_SPECIAL and CSI bytes.
+ const char *p = mb_unescape((const char **)&str);
if (p != NULL) {
while (*p != NUL)
if (fputc(*p++, fd) < 0)
@@ -4185,8 +4154,7 @@ void add_map(char_u *map, int mode)
}
// Translate an internal mapping/abbreviation representation into the
-// corresponding external one recognized by :map/:abbrev commands;
-// respects the current B/k/< settings of 'cpoption'.
+// corresponding external one recognized by :map/:abbrev commands.
//
// This function is called when expanding mappings/abbreviations on the
// command-line, and for building the "Ambiguous mapping..." error message.
@@ -4206,7 +4174,6 @@ static char_u * translate_mapping (
ga_init(&ga, 1, 40);
bool cpo_bslash = !(cpo_flags&FLAG_CPO_BSLASH);
- bool cpo_special = !(cpo_flags&FLAG_CPO_SPECI);
for (; *str; ++str) {
int c = *str;
@@ -4219,7 +4186,7 @@ static char_u * translate_mapping (
}
if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL) {
- if (expmap && cpo_special) {
+ if (expmap) {
ga_clear(&ga);
return NULL;
}
@@ -4230,8 +4197,8 @@ static char_u * translate_mapping (
}
str += 2;
}
- if (IS_SPECIAL(c) || modifiers) { /* special key */
- if (expmap && cpo_special) {
+ if (IS_SPECIAL(c) || modifiers) { // special key
+ if (expmap) {
ga_clear(&ga);
return NULL;
}
@@ -4241,7 +4208,7 @@ static char_u * translate_mapping (
}
if (c == ' ' || c == '\t' || c == Ctrl_J || c == Ctrl_V
- || (c == '<' && !cpo_special) || (c == '\\' && !cpo_bslash)) {
+ || (c == '\\' && !cpo_bslash)) {
ga_append(&ga, cpo_bslash ? Ctrl_V : '\\');
}
@@ -4263,3 +4230,17 @@ static bool typebuf_match_len(const uint8_t *str, int *mlen)
*mlen = i;
return str[i] == NUL; // matched the whole string
}
+
+/// Retrieve the mapblock at the index either globally or for a certain buffer
+///
+/// @param index The index in the maphash[]
+/// @param buf The buffer to get the maphash from. NULL for global
+mapblock_T *get_maphash(int index, buf_T *buf)
+ FUNC_ATTR_PURE
+{
+ if (index > MAX_MAPHASH) {
+ return NULL;
+ }
+
+ return (buf == NULL) ? maphash[index] : buf->b_maphash[index];
+}
diff --git a/src/nvim/getchar.h b/src/nvim/getchar.h
index bdf65909b6..e634273e0d 100644
--- a/src/nvim/getchar.h
+++ b/src/nvim/getchar.h
@@ -1,17 +1,25 @@
#ifndef NVIM_GETCHAR_H
#define NVIM_GETCHAR_H
-/* Values for "noremap" argument of ins_typebuf(). Also used for
- * map->m_noremap and menu->noremap[]. */
-#define REMAP_YES 0 /* allow remapping */
-#define REMAP_NONE -1 /* no remapping */
-#define REMAP_SCRIPT -2 /* remap script-local mappings only */
-#define REMAP_SKIP -3 /* no remapping for first char */
+#include "nvim/types.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/ex_cmds_defs.h"
+
+/// Values for "noremap" argument of ins_typebuf(). Also used for
+/// map->m_noremap and menu->noremap[].
+/// @addtogroup REMAP_VALUES
+/// @{
+#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
+/// @}
#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 */
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "getchar.h.generated.h"
#endif
diff --git a/src/nvim/gettext.h b/src/nvim/gettext.h
new file mode 100644
index 0000000000..aa0e97233e
--- /dev/null
+++ b/src/nvim/gettext.h
@@ -0,0 +1,21 @@
+#ifndef NVIM_GETTEXT_H
+#define NVIM_GETTEXT_H
+
+#ifdef HAVE_WORKING_LIBINTL
+# include <libintl.h>
+# define _(x) gettext((char *)(x))
+// XXX do we actually need this?
+# ifdef gettext_noop
+# define N_(x) gettext_noop(x)
+# else
+# define N_(x) x
+# endif
+#else
+# define _(x) ((char *)(x))
+# define N_(x) x
+# define bindtextdomain(x, y) // empty
+# define bind_textdomain_codeset(x, y) // empty
+# define textdomain(x) // empty
+#endif
+
+#endif // NVIM_GETTEXT_H
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 463f4fcd8d..2ee72cdb6a 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -12,10 +12,7 @@
#include "nvim/syntax_defs.h"
#include "nvim/types.h"
#include "nvim/event/loop.h"
-
-/*
- * definition of global variables
- */
+#include "nvim/os/os_defs.h"
#define IOSIZE (1024+1) // file I/O and sprintf buffer size
@@ -25,19 +22,6 @@
# define MSG_BUF_CLEN (MSG_BUF_LEN / 6) // cell length (worst case: utf-8
// takes 6 bytes for one cell)
-/*
- * Maximum length of a path (for non-unix systems) Make it a bit long, to stay
- * on the safe side. But not too long to put on the stack.
- * TODO(metrix78): Move this to os_defs.h
- */
-#ifndef MAXPATHL
-# ifdef MAXPATHLEN
-# define MAXPATHL MAXPATHLEN
-# else
-# define MAXPATHL 256
-# endif
-#endif
-
#ifdef WIN32
# define _PATHSEPSTR "\\"
#else
@@ -108,14 +92,39 @@ typedef enum {
* They may have different values when the screen wasn't (re)allocated yet
* after setting Rows or Columns (e.g., when starting up).
*/
-
-#define DFLT_COLS 80 /* default value for 'columns' */
-#define DFLT_ROWS 24 /* default value for 'lines' */
-
+#define DFLT_COLS 80 // default value for 'columns'
+#define DFLT_ROWS 24 // default value for 'lines'
EXTERN long Rows INIT(= DFLT_ROWS); // nr of rows in the screen
-
EXTERN long Columns INIT(= DFLT_COLS); // nr of columns in the screen
+// We use 64-bit file functions here, if available. E.g. ftello() returns
+// off_t instead of long, which helps if long is 32 bit and off_t is 64 bit.
+// We assume that when fseeko() is available then ftello() is too.
+// Note that Windows has different function names.
+#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__)
+typedef __int64 off_T;
+# ifdef __MINGW32__
+# define vim_lseek lseek64
+# define vim_fseek fseeko64
+# define vim_ftell ftello64
+# else
+# define vim_lseek _lseeki64
+# define vim_fseek _fseeki64
+# define vim_ftell _ftelli64
+# endif
+#else
+typedef off_t off_T;
+# ifdef HAVE_FSEEKO
+# define vim_lseek lseek
+# define vim_ftell ftello
+# define vim_fseek fseeko
+# else
+# define vim_lseek lseek
+# define vim_ftell ftell
+# define vim_fseek(a, b, c) fseek(a, (long)b, c)
+# endif
+#endif
+
/*
* The characters and attributes cached for the screen.
*/
@@ -398,6 +407,9 @@ 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);
+
+EXTERN bool did_source_packages INIT(= false);
+
// Scope information for the code that indirectly triggered the current
// provider function call
EXTERN struct caller_scope {
@@ -430,79 +442,6 @@ EXTERN int did_check_timestamps INIT(= FALSE); /* did check timestamps
recently */
EXTERN int no_check_timestamps INIT(= 0); /* Don't check timestamps */
-/*
- * Values for index in highlight_attr[].
- * When making changes, also update HL_FLAGS below! And update the default
- * value of 'highlight' in option.c.
- */
-typedef enum {
- HLF_8 = 0 /* Meta & special keys listed with ":map", text that is
- displayed different from what it is */
- , HLF_EOB // after the last line in the buffer
- , HLF_TERM // terminal cursor focused
- , HLF_TERMNC // terminal cursor unfocused
- , HLF_AT // @ characters at end of screen, characters that
- // don't really exist in the text
- , HLF_D // directories in CTRL-D listing
- , HLF_E // error messages
- , HLF_I // incremental search
- , HLF_L // last search string
- , HLF_M // "--More--" message
- , HLF_CM // Mode (e.g., "-- INSERT --")
- , HLF_N // line number for ":number" and ":#" commands
- , HLF_CLN // current line number
- , HLF_R // return to continue message and yes/no questions
- , HLF_S // status lines
- , HLF_SNC // status lines of not-current windows
- , HLF_C // column to separate vertically split windows
- , HLF_T // Titles for output from ":set all", ":autocmd" etc.
- , HLF_V // Visual mode
- , HLF_VNC // Visual mode, autoselecting and not clipboard owner
- , HLF_W // warning messages
- , HLF_WM // Wildmenu highlight
- , HLF_FL // Folded line
- , HLF_FC // Fold column
- , HLF_ADD // Added diff line
- , HLF_CHD // Changed diff line
- , HLF_DED // Deleted diff line
- , HLF_TXD // Text Changed in diff line
- , HLF_CONCEAL // Concealed text
- , HLF_SC // Sign column
- , HLF_SPB // SpellBad
- , HLF_SPC // SpellCap
- , HLF_SPR // SpellRare
- , HLF_SPL // SpellLocal
- , HLF_PNI // popup menu normal item
- , HLF_PSI // popup menu selected item
- , HLF_PSB // popup menu scrollbar
- , HLF_PST // popup menu scrollbar thumb
- , HLF_TP // tabpage line
- , HLF_TPS // tabpage line selected
- , HLF_TPF // tabpage line filler
- , HLF_CUC // 'cursurcolumn'
- , HLF_CUL // 'cursurline'
- , HLF_MC // 'colorcolumn'
- , HLF_QFL // selected quickfix line
- , HLF_COUNT // MUST be the last one
-} hlf_T;
-
-/* The HL_FLAGS must be in the same order as the HLF_ enums!
- * When changing this also adjust the default for 'highlight'. */
-#define HL_FLAGS { '8', '~', 'z', 'Z', '@', 'd', 'e', 'i', 'l', 'm', 'M', 'n', \
- 'N', 'r', 's', 'S', 'c', 't', 'v', 'V', 'w', 'W', 'f', 'F', \
- 'A', 'C', 'D', 'T', '-', '>', 'B', 'P', 'R', 'L', '+', '=', \
- 'x', 'X', '*', '#', '_', '!', '.', 'o', 'q' }
-
-EXTERN int highlight_attr[HLF_COUNT]; /* Highl. attr for each context. */
-EXTERN int highlight_user[9]; /* User[1-9] attributes */
-EXTERN int highlight_stlnc[9]; /* On top of user */
-EXTERN int cterm_normal_fg_color INIT(= 0);
-EXTERN int cterm_normal_fg_bold INIT(= 0);
-EXTERN int cterm_normal_bg_color INIT(= 0);
-EXTERN RgbValue normal_fg INIT(= -1);
-EXTERN RgbValue normal_bg INIT(= -1);
-EXTERN RgbValue normal_sp INIT(= -1);
-
EXTERN int autocmd_busy INIT(= FALSE); /* Is apply_autocmds() busy? */
EXTERN int autocmd_no_enter INIT(= FALSE); /* *Enter autocmds disabled */
EXTERN int autocmd_no_leave INIT(= FALSE); /* *Leave autocmds disabled */
@@ -512,9 +451,9 @@ EXTERN int keep_filetype INIT(= FALSE); /* value for did_filetype when
starting to execute
autocommands */
-/* When deleting the current buffer, another one must be loaded. If we know
- * which one is preferred, au_new_curbuf is set to it */
-EXTERN buf_T *au_new_curbuf INIT(= NULL);
+// When deleting the current buffer, another one must be loaded.
+// If we know which one is preferred, au_new_curbuf is set to it.
+EXTERN bufref_T au_new_curbuf INIT(= { NULL, 0, 0 });
// When deleting a buffer/window and autocmd_busy is TRUE, do not free the
// buffer/window. but link it in the list starting with
@@ -558,6 +497,7 @@ EXTERN int updating_screen INIT(= FALSE);
EXTERN win_T *firstwin; /* first window */
EXTERN win_T *lastwin; /* last window */
EXTERN win_T *prevwin INIT(= NULL); /* previous window */
+# define ONE_WINDOW (firstwin == lastwin)
/*
* When using this macro "break" only breaks out of the inner loop. Use "goto"
* to break out of the tabpage loop.
@@ -566,7 +506,7 @@ EXTERN win_T *prevwin INIT(= NULL); /* previous window */
FOR_ALL_TABS(tp) \
FOR_ALL_WINDOWS_IN_TAB(wp, tp)
-# define FOR_ALL_WINDOWS(wp) for (wp = firstwin; wp != NULL; wp = wp->w_next)
+// -V:FOR_ALL_WINDOWS_IN_TAB:501
# define FOR_ALL_WINDOWS_IN_TAB(wp, tp) \
for (win_T *wp = ((tp) == curtab) \
? firstwin : (tp)->tp_firstwin; wp != NULL; wp = wp->w_next)
@@ -602,7 +542,10 @@ EXTERN buf_T *lastbuf INIT(= NULL); // last buffer
EXTERN buf_T *curbuf INIT(= NULL); // currently active buffer
// Iterates over all buffers in the buffer list.
-# define FOR_ALL_BUFFERS(buf) for (buf_T *buf = firstbuf; buf != NULL; buf = buf->b_next)
+#define FOR_ALL_BUFFERS(buf) \
+ for (buf_T *buf = firstbuf; buf != NULL; buf = buf->b_next)
+#define FOR_ALL_BUFFERS_BACKWARDS(buf) \
+ for (buf_T *buf = lastbuf; buf != NULL; buf = buf->b_prev)
/* Flag that is set when switching off 'swapfile'. It means that all blocks
* are to be loaded into memory. Shouldn't be global... */
@@ -840,13 +783,11 @@ 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 no_mapping INIT(= false); // currently no mapping allowed
+EXTERN int no_zero_mapping INIT(= 0); // mapping zero not allowed
+EXTERN int no_u_sync INIT(= 0); // Don't call u_sync()
+EXTERN int u_sync_once INIT(= 0); // Call u_sync() once when evaluating
+ // an expression.
EXTERN bool force_restart_edit INIT(= false); // force restart_edit after
// ex_normal returns
@@ -886,9 +827,16 @@ EXTERN int swap_exists_action INIT(= SEA_NONE);
EXTERN int swap_exists_did_quit INIT(= FALSE);
/* Selected "quit" at the dialog. */
-EXTERN char_u IObuff[IOSIZE]; /* sprintf's are done in this buffer */
-EXTERN char_u NameBuff[MAXPATHL]; /* buffer for expanding file names */
-EXTERN char_u msg_buf[MSG_BUF_LEN]; /* small buffer for messages */
+EXTERN char_u IObuff[IOSIZE]; ///< Buffer for sprintf, I/O, etc.
+EXTERN char_u NameBuff[MAXPATHL]; ///< Buffer for expanding file names
+EXTERN char_u msg_buf[MSG_BUF_LEN]; ///< Small buffer for messages
+EXTERN char os_buf[ ///< Buffer for the os/ layer
+#if MAXPATHL > IOSIZE
+MAXPATHL
+#else
+IOSIZE
+#endif
+];
/* When non-zero, postpone redrawing. */
EXTERN int RedrawingDisabled INIT(= 0);
@@ -953,7 +901,7 @@ EXTERN int did_cursorhold INIT(= false); // set when CursorHold t'gerd
// for CursorMoved event
EXTERN pos_T last_cursormoved INIT(= INIT_POS_T(0, 0, 0));
-EXTERN int last_changedtick INIT(= 0); // for TextChanged event
+EXTERN varnumber_T 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 */
@@ -986,8 +934,11 @@ EXTERN char_u langmap_mapchar[256]; /* mapping for language keys */
EXTERN int save_p_ls INIT(= -1); /* Save 'laststatus' setting */
EXTERN int save_p_wmh INIT(= -1); /* Save 'winminheight' setting */
EXTERN int wild_menu_showing INIT(= 0);
-# define WM_SHOWN 1 /* wildmenu showing */
-# define WM_SCROLLED 2 /* wildmenu showing with scroll */
+enum {
+ WM_SHOWN = 1, ///< wildmenu showing
+ WM_SCROLLED = 2, ///< wildmenu showing with scroll
+ WM_LIST = 3, ///< cmdline CTRL-D
+};
EXTERN char breakat_flags[256]; /* which characters are in 'breakat' */
@@ -1124,7 +1075,7 @@ EXTERN char_u e_isadir2[] INIT(= N_("E17: \"%s\" is a directory"));
EXTERN char_u e_invjob[] INIT(= N_("E900: Invalid job id"));
EXTERN char_u e_jobtblfull[] INIT(= N_("E901: Job table is full"));
EXTERN char_u e_jobspawn[] INIT(= N_(
- "E903: Process for command \"%s\" could not be spawned"));
+ "E903: Process failed to start: %s: \"%s\""));
EXTERN char_u e_jobnotpty[] INIT(= N_("E904: Job is not connected to a pty"));
EXTERN char_u e_libcall[] INIT(= N_("E364: Library call failed for \"%s()\""));
EXTERN char_u e_mkdir[] INIT(= N_("E739: Cannot create directory %s: %s"));
@@ -1150,7 +1101,6 @@ 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"));
@@ -1172,11 +1122,7 @@ EXTERN char_u e_loclist[] INIT(= N_("E776: No location list"));
EXTERN char_u e_re_damg[] INIT(= N_("E43: Damaged match string"));
EXTERN char_u e_re_corr[] INIT(= N_("E44: Corrupted regexp program"));
EXTERN char_u e_readonly[] INIT(= N_(
- "E45: 'readonly' option is set (add ! to override)"));
-EXTERN char_u e_readonlyvar[] INIT(= N_(
- "E46: Cannot change read-only variable \"%s\""));
-EXTERN char_u e_readonlysbx[] INIT(= N_(
- "E794: Cannot set variable in the sandbox: \"%s\""));
+ "E45: 'readonly' option is set (add ! to override)"));
EXTERN char_u e_readerrf[] INIT(= N_("E47: Error while reading errorfile"));
EXTERN char_u e_sandbox[] INIT(= N_("E48: Not allowed in sandbox"));
EXTERN char_u e_secure[] INIT(= N_("E523: Not allowed here"));
@@ -1192,6 +1138,7 @@ EXTERN char_u e_longname[] INIT(= N_("E75: Name too long"));
EXTERN char_u e_toomsbra[] INIT(= N_("E76: Too many ["));
EXTERN char_u e_toomany[] INIT(= N_("E77: Too many file names"));
EXTERN char_u e_trailing[] INIT(= N_("E488: Trailing characters"));
+EXTERN char_u e_trailing2[] INIT(= N_("E488: Trailing characters: %s"));
EXTERN char_u e_umark[] INIT(= N_("E78: Unknown mark"));
EXTERN char_u e_wildexpand[] INIT(= N_("E79: Cannot expand wildcards"));
EXTERN char_u e_winheight[] INIT(= N_(
@@ -1215,6 +1162,8 @@ EXTERN char_u e_invalidreg[] INIT(= N_("E850: Invalid register name"));
EXTERN char_u e_dirnotf[] INIT(= N_(
"E919: Directory not found in '%s': \"%s\""));
EXTERN char_u e_unsupportedoption[] INIT(= N_("E519: Option not supported"));
+EXTERN char_u e_fnametoolong[] INIT(= N_("E856: Filename too long"));
+EXTERN char_u e_float_as_string[] INIT(= N_("E806: using Float as a String"));
EXTERN char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM"));
@@ -1233,8 +1182,6 @@ EXTERN FILE *time_fd INIT(= NULL); /* where to write startup timing */
EXTERN int ignored;
EXTERN char *ignoredp;
-EXTERN bool in_free_unref_items INIT(= false);
-
// If a msgpack-rpc channel should be started over stdin/stdout
EXTERN bool embedded_mode INIT(= false);
@@ -1249,4 +1196,20 @@ typedef enum {
kBroken
} WorkingStatus;
+/// The scope of a working-directory command like `:cd`.
+///
+/// Scopes are enumerated from lowest to highest. When adding a scope make sure
+/// to update all functions using scopes as well, such as the implementation of
+/// `getcwd()`. When using scopes as limits (e.g. in loops) don't use the scopes
+/// directly, use `MIN_CD_SCOPE` and `MAX_CD_SCOPE` instead.
+typedef enum {
+ kCdScopeInvalid = -1,
+ kCdScopeWindow, ///< Affects one window.
+ kCdScopeTab, ///< Affects one tab page.
+ kCdScopeGlobal, ///< Affects the entire Nvim instance.
+} CdScope;
+
+#define MIN_CD_SCOPE kCdScopeWindow
+#define MAX_CD_SCOPE kCdScopeGlobal
+
#endif /* NVIM_GLOBALS_H */
diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c
index cb0415a486..abc4773d84 100644
--- a/src/nvim/hardcopy.c
+++ b/src/nvim/hardcopy.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* hardcopy.c: printing to paper
*/
@@ -369,7 +372,6 @@ static void prt_get_attr(int hl_id, prt_text_attr_T *pattr, int modec)
{
int colorindex;
uint32_t fg_color;
- char *color;
pattr->bold = (highlight_has_attr(hl_id, HL_BOLD, modec) != NULL);
pattr->italic = (highlight_has_attr(hl_id, HL_ITALIC, modec) != NULL);
@@ -377,11 +379,12 @@ static void prt_get_attr(int hl_id, prt_text_attr_T *pattr, int modec)
pattr->undercurl = (highlight_has_attr(hl_id, HL_UNDERCURL, modec) != NULL);
{
- color = (char *)highlight_color(hl_id, (char_u *)"fg", modec);
- if (color == NULL)
+ const char *color = highlight_color(hl_id, "fg", modec);
+ if (color == NULL) {
colorindex = 0;
- else
+ } else {
colorindex = atoi(color);
+ }
if (colorindex >= 0 && colorindex < t_colors)
fg_color = prt_get_term_color(colorindex);
@@ -845,12 +848,10 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
* Loop over the columns until the end of the file line or right margin.
*/
for (col = ppos->column; line[col] != NUL && !need_break; col += outputlen) {
- outputlen = 1;
- if (has_mbyte && (outputlen = (*mb_ptr2len)(line + col)) < 1)
+ if ((outputlen = (*mb_ptr2len)(line + col)) < 1) {
outputlen = 1;
- /*
- * syntax highlighting stuff.
- */
+ }
+ // syntax highlighting stuff.
if (psettings->do_syntax) {
id = syn_get_id(curwin, ppos->file_line, col, 1, NULL, FALSE);
if (id > 0)
@@ -1544,8 +1545,8 @@ static int prt_find_resource(char *name, struct prt_ps_resource_S *resource)
/* Look for named resource file in runtimepath */
STRCPY(buffer, "print");
add_pathsep((char *)buffer);
- vim_strcat(buffer, (char_u *)name, MAXPATHL);
- vim_strcat(buffer, (char_u *)".ps", MAXPATHL);
+ xstrlcat((char *)buffer, name, MAXPATHL);
+ xstrlcat((char *)buffer, ".ps", MAXPATHL);
resource->filename[0] = NUL;
retval = (do_in_runtimepath(buffer, 0, prt_resource_name, resource->filename)
&& resource->filename[0] != NUL);
@@ -2578,13 +2579,12 @@ int mch_print_begin(prt_settings_T *psettings)
prt_conv.vc_type = CONV_NONE;
if (!(enc_canon_props(p_enc) & enc_canon_props(p_encoding) & ENC_8BIT)) {
- /* Set up encoding conversion if required */
- if (FAIL == convert_setup(&prt_conv, p_enc, p_encoding)) {
- EMSG2(_("E620: Unable to convert to print encoding \"%s\""),
- p_encoding);
- return FALSE;
+ // Set up encoding conversion if required
+ if (convert_setup(&prt_conv, p_enc, p_encoding) == FAIL) {
+ emsgf(_("E620: Unable to convert to print encoding \"%s\""),
+ p_encoding);
+ return false;
}
- prt_do_conv = TRUE;
}
prt_do_conv = prt_conv.vc_type != CONV_NONE;
diff --git a/src/nvim/hardcopy.h b/src/nvim/hardcopy.h
index 4ead8dd5d4..a70b20e6f5 100644
--- a/src/nvim/hardcopy.h
+++ b/src/nvim/hardcopy.h
@@ -2,6 +2,10 @@
#define NVIM_HARDCOPY_H
#include <stdint.h>
+#include <stdlib.h> // for size_t
+
+#include "nvim/types.h" // for char_u
+#include "nvim/ex_cmds_defs.h" // for exarg_T
/*
* Structure to hold printing color and font attributes.
diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c
index 376f33e23e..3397788b00 100644
--- a/src/nvim/hashtab.c
+++ b/src/nvim/hashtab.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// @file hashtab.c
///
/// Handling of a hashtable with Vim-specific properties.
@@ -82,22 +85,43 @@ void hash_clear_all(hashtab_T *ht, unsigned int off)
/// used for that key.
/// WARNING: Returned pointer becomes invalid as soon as the hash table
/// is changed in any way.
-hashitem_T* hash_find(hashtab_T *ht, char_u *key)
+hashitem_T *hash_find(const hashtab_T *const ht, const char_u *const key)
{
- return hash_lookup(ht, key, hash_hash(key));
+ return hash_lookup(ht, (const char *)key, STRLEN(key), hash_hash(key));
+}
+
+/// Like hash_find, but key is not NUL-terminated
+///
+/// @param[in] ht Hashtab to look in.
+/// @param[in] key Key of the looked-for item. Must not be NULL.
+/// @param[in] len Key length.
+///
+/// @return Pointer to the hash item corresponding to the given key.
+/// If not found, then return pointer to the empty item that would be
+/// used for that key.
+///
+/// @warning Returned pointer becomes invalid as soon as the hash table
+/// is changed in any way.
+hashitem_T *hash_find_len(const hashtab_T *const ht, const char *const key,
+ const size_t len)
+{
+ return hash_lookup(ht, key, len, hash_hash_len(key, len));
}
/// Like hash_find(), but caller computes "hash".
///
-/// @param key The key of the looked-for item. Must not be NULL.
-/// @param hash The precomputed hash for the key.
+/// @param[in] key The key of the looked-for item. Must not be NULL.
+/// @param[in] key_len Key length.
+/// @param[in] hash The precomputed hash for the key.
///
/// @return Pointer to the hashitem corresponding to the given key.
/// If not found, then return pointer to the empty item that would be
/// used for that key.
/// WARNING: Returned pointer becomes invalid as soon as the hash table
/// is changed in any way.
-hashitem_T* hash_lookup(hashtab_T *ht, char_u *key, hash_T hash)
+hashitem_T *hash_lookup(const hashtab_T *const ht,
+ const char *const key, const size_t key_len,
+ const hash_T hash)
{
#ifdef HT_DEBUG
hash_count_lookup++;
@@ -117,7 +141,9 @@ hashitem_T* hash_lookup(hashtab_T *ht, char_u *key, hash_T hash)
hashitem_T *freeitem = NULL;
if (hi->hi_key == HI_KEY_REMOVED) {
freeitem = hi;
- } else if ((hi->hi_hash == hash) && (STRCMP(hi->hi_key, key) == 0)) {
+ } else if ((hi->hi_hash == hash)
+ && (STRNCMP(hi->hi_key, key, key_len) == 0)
+ && hi->hi_key[key_len] == NUL) {
return hi;
}
@@ -142,7 +168,8 @@ hashitem_T* hash_lookup(hashtab_T *ht, char_u *key, hash_T hash)
if ((hi->hi_hash == hash)
&& (hi->hi_key != HI_KEY_REMOVED)
- && (STRCMP(hi->hi_key, key) == 0)) {
+ && (STRNCMP(hi->hi_key, key, key_len) == 0)
+ && hi->hi_key[key_len] == NUL) {
return hi;
}
@@ -179,7 +206,7 @@ void hash_debug_results(void)
int hash_add(hashtab_T *ht, char_u *key)
{
hash_T hash = hash_hash(key);
- hashitem_T *hi = hash_lookup(ht, key, hash);
+ hashitem_T *hi = hash_lookup(ht, (const char *)key, STRLEN(key), hash);
if (!HASHITEM_EMPTY(hi)) {
EMSG2(_(e_intern2), "hash_add()");
return FAIL;
@@ -359,13 +386,16 @@ static void hash_may_resize(hashtab_T *ht, size_t minitems)
ht->ht_filled = ht->ht_used;
}
+#define HASH_CYCLE_BODY(hash, p) \
+ hash = hash * 101 + *p++
+
/// Get the hash number for a key.
///
/// If you think you know a better hash function: Compile with HT_DEBUG set and
/// run a script that uses hashtables a lot. Vim will then print statistics
/// when exiting. Try that with the current hash algorithm and yours. The
/// lower the percentage the better.
-hash_T hash_hash(char_u *key)
+hash_T hash_hash(const char_u *key)
{
hash_T hash = *key;
@@ -375,14 +405,43 @@ hash_T hash_hash(char_u *key)
// A simplistic algorithm that appears to do very well.
// Suggested by George Reilly.
- char_u *p = key + 1;
+ const uint8_t *p = key + 1;
while (*p != NUL) {
- hash = hash * 101 + *p++;
+ HASH_CYCLE_BODY(hash, p);
+ }
+
+ return hash;
+}
+
+/// Get the hash number for a key that is not a NUL-terminated string
+///
+/// @warning Function does not check whether key contains NUL. But you will not
+/// be able to get hash entry in this case.
+///
+/// @param[in] key Key.
+/// @param[in] len Key length.
+///
+/// @return Key hash.
+hash_T hash_hash_len(const char *key, const size_t len)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (len == 0) {
+ return 0;
+ }
+
+ hash_T hash = *(uint8_t *)key;
+ const uint8_t *end = (uint8_t *)key + len;
+
+ const uint8_t *p = (const uint8_t *)key + 1;
+ while (p < end) {
+ HASH_CYCLE_BODY(hash, p);
}
return hash;
}
+#undef HASH_CYCLE_BODY
+
/// Function to get HI_KEY_REMOVED value
///
/// Used for testing because luajit ffi does not allow getting addresses of
diff --git a/src/nvim/hashtab.h b/src/nvim/hashtab.h
index 0da2b13f2e..973b97d476 100644
--- a/src/nvim/hashtab.h
+++ b/src/nvim/hashtab.h
@@ -70,6 +70,25 @@ typedef struct hashtable_S {
hashitem_T ht_smallarray[HT_INIT_SIZE]; /// initial array
} hashtab_T;
+/// Iterate over a hashtab
+///
+/// @param[in] ht Hashtab to iterate over.
+/// @param hi Name of the variable with current hashtab entry.
+/// @param code Cycle body.
+#define HASHTAB_ITER(ht, hi, code) \
+ do { \
+ hashtab_T *const hi##ht_ = (ht); \
+ size_t hi##todo_ = hi##ht_->ht_used; \
+ for (hashitem_T *hi = hi##ht_->ht_array; hi##todo_; hi++) { \
+ if (!HASHITEM_EMPTY(hi)) { \
+ { \
+ code \
+ } \
+ hi##todo_--; \
+ } \
+ } \
+ } while (0)
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "hashtab.h.generated.h"
#endif
diff --git a/src/nvim/highlight_defs.h b/src/nvim/highlight_defs.h
new file mode 100644
index 0000000000..927fc94bbe
--- /dev/null
+++ b/src/nvim/highlight_defs.h
@@ -0,0 +1,126 @@
+#ifndef NVIM_HIGHLIGHT_DEFS_H
+#define NVIM_HIGHLIGHT_DEFS_H
+
+#include <inttypes.h>
+
+#include "nvim/macros.h"
+
+typedef int32_t RgbValue;
+
+/// Values for index in highlight_attr[].
+/// When making changes, also update hlf_names below!
+typedef enum {
+ HLF_8 = 0 // Meta & special keys listed with ":map", text that is
+ // displayed different from what it is
+ , HLF_EOB // after the last line in the buffer
+ , HLF_TERM // terminal cursor focused
+ , HLF_TERMNC // terminal cursor unfocused
+ , HLF_AT // @ characters at end of screen, characters that
+ // don't really exist in the text
+ , HLF_D // directories in CTRL-D listing
+ , HLF_E // error messages
+ , HLF_I // incremental search
+ , HLF_L // last search string
+ , HLF_M // "--More--" message
+ , HLF_CM // Mode (e.g., "-- INSERT --")
+ , HLF_N // line number for ":number" and ":#" commands
+ , HLF_CLN // current line number
+ , HLF_R // return to continue message and yes/no questions
+ , HLF_S // status lines
+ , HLF_SNC // status lines of not-current windows
+ , HLF_C // column to separate vertically split windows
+ , HLF_T // Titles for output from ":set all", ":autocmd" etc.
+ , HLF_V // Visual mode
+ , HLF_VNC // Visual mode, autoselecting and not clipboard owner
+ , HLF_W // warning messages
+ , HLF_WM // Wildmenu highlight
+ , HLF_FL // Folded line
+ , HLF_FC // Fold column
+ , HLF_ADD // Added diff line
+ , HLF_CHD // Changed diff line
+ , HLF_DED // Deleted diff line
+ , HLF_TXD // Text Changed in diff line
+ , HLF_SC // Sign column
+ , HLF_CONCEAL // Concealed text
+ , HLF_SPB // SpellBad
+ , HLF_SPC // SpellCap
+ , HLF_SPR // SpellRare
+ , HLF_SPL // SpellLocal
+ , HLF_PNI // popup menu normal item
+ , HLF_PSI // popup menu selected item
+ , HLF_PSB // popup menu scrollbar
+ , HLF_PST // popup menu scrollbar thumb
+ , HLF_TP // tabpage line
+ , HLF_TPS // tabpage line selected
+ , HLF_TPF // tabpage line filler
+ , HLF_CUC // 'cursurcolumn'
+ , HLF_CUL // 'cursurline'
+ , HLF_MC // 'colorcolumn'
+ , HLF_QFL // selected quickfix line
+ , HLF_0 // Whitespace
+ , HLF_INACTIVE // NormalNC: Normal text in non-current windows
+ , HLF_COUNT // MUST be the last one
+} hlf_T;
+
+EXTERN const char *hlf_names[] INIT(= {
+ [HLF_8] = "SpecialKey",
+ [HLF_EOB] = "EndOfBuffer",
+ [HLF_TERM] = "TermCursor",
+ [HLF_TERMNC] = "TermCursorNC",
+ [HLF_AT] = "NonText",
+ [HLF_D] = "Directory",
+ [HLF_E] = "ErrorMsg",
+ [HLF_I] = "IncSearch",
+ [HLF_L] = "Search",
+ [HLF_M] = "MoreMsg",
+ [HLF_CM] = "ModeMsg",
+ [HLF_N] = "LineNr",
+ [HLF_CLN] = "CursorLineNr",
+ [HLF_R] = "Question",
+ [HLF_S] = "StatusLine",
+ [HLF_SNC] = "StatusLineNC",
+ [HLF_C] = "VertSplit",
+ [HLF_T] = "Title",
+ [HLF_V] = "Visual",
+ [HLF_VNC] = "VisualNC",
+ [HLF_W] = "WarningMsg",
+ [HLF_WM] = "WildMenu",
+ [HLF_FL] = "Folded",
+ [HLF_FC] = "FoldColumn",
+ [HLF_ADD] = "DiffAdd",
+ [HLF_CHD] = "DiffChange",
+ [HLF_DED] = "DiffDelete",
+ [HLF_TXD] = "DiffText",
+ [HLF_SC] = "SignColumn",
+ [HLF_CONCEAL] = "Conceal",
+ [HLF_SPB] = "SpellBad",
+ [HLF_SPC] = "SpellCap",
+ [HLF_SPR] = "SpellRare",
+ [HLF_SPL] = "SpellLocal",
+ [HLF_PNI] = "Pmenu",
+ [HLF_PSI] = "PmenuSel",
+ [HLF_PSB] = "PmenuSbar",
+ [HLF_PST] = "PmenuThumb",
+ [HLF_TP] = "TabLine",
+ [HLF_TPS] = "TabLineSel",
+ [HLF_TPF] = "TabLineFill",
+ [HLF_CUC] = "CursorColumn",
+ [HLF_CUL] = "CursorLine",
+ [HLF_MC] = "ColorColumn",
+ [HLF_QFL] = "QuickFixLine",
+ [HLF_0] = "Whitespace",
+ [HLF_INACTIVE] = "NormalNC"
+});
+
+
+EXTERN int highlight_attr[HLF_COUNT]; // Highl. attr for each context.
+EXTERN int highlight_user[9]; // User[1-9] attributes
+EXTERN int highlight_stlnc[9]; // On top of user
+EXTERN int cterm_normal_fg_color INIT(= 0);
+EXTERN int cterm_normal_fg_bold INIT(= 0);
+EXTERN int cterm_normal_bg_color INIT(= 0);
+EXTERN RgbValue normal_fg INIT(= -1);
+EXTERN RgbValue normal_bg INIT(= -1);
+EXTERN RgbValue normal_sp INIT(= -1);
+
+#endif // NVIM_HIGHLIGHT_DEFS_H
diff --git a/src/nvim/iconv.h b/src/nvim/iconv.h
index bf29b15247..d7234090c4 100644
--- a/src/nvim/iconv.h
+++ b/src/nvim/iconv.h
@@ -10,9 +10,7 @@
// USE_ICONV, or to put the USE_ICONV definition in config.h.in directly. As
// it stands, globals.h needs to be included alongside iconv.h.
-#ifdef HAVE_CONFIG_H
-# include "auto/config.h"
-#endif
+#include "auto/config.h"
// Use iconv() when it's available, either by linking to the library at
// compile time or by loading it at runtime.
diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c
index 0b20647771..0f9ecdf2d7 100644
--- a/src/nvim/if_cscope.c
+++ b/src/nvim/if_cscope.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* CSCOPE support for Vim added by Andy Kahn <kahn@zk3.dec.com>
* Ported to Win32 by Sergey Khorev <sergey.khorev@gmail.com>
@@ -140,44 +143,39 @@ char_u *get_cscope_name(expand_T *xp, int idx)
/*
* Handle command line completion for :cscope command.
*/
-void set_context_in_cscope_cmd(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
+void set_context_in_cscope_cmd(expand_T *xp, const char *arg, cmdidx_T cmdidx)
{
- char_u *p;
-
- /* Default: expand subcommands */
+ // Default: expand subcommands.
xp->xp_context = EXPAND_CSCOPE;
- xp->xp_pattern = arg;
- expand_what = (cmdidx == CMD_scscope)
- ? EXP_SCSCOPE_SUBCMD : EXP_CSCOPE_SUBCMD;
+ xp->xp_pattern = (char_u *)arg;
+ expand_what = ((cmdidx == CMD_scscope)
+ ? EXP_SCSCOPE_SUBCMD : EXP_CSCOPE_SUBCMD);
/* (part of) subcommand already typed */
if (*arg != NUL) {
- p = skiptowhite(arg);
- if (*p != NUL) { /* past first word */
- xp->xp_pattern = skipwhite(p);
- if (*skiptowhite(xp->xp_pattern) != NUL)
+ const char *p = (const char *)skiptowhite((const char_u *)arg);
+ if (*p != NUL) { // Past first word.
+ xp->xp_pattern = skipwhite((const char_u *)p);
+ if (*skiptowhite(xp->xp_pattern) != NUL) {
xp->xp_context = EXPAND_NOTHING;
- else if (STRNICMP(arg, "add", p - arg) == 0)
+ } else if (STRNICMP(arg, "add", p - arg) == 0) {
xp->xp_context = EXPAND_FILES;
- else if (STRNICMP(arg, "kill", p - arg) == 0)
+ } else if (STRNICMP(arg, "kill", p - arg) == 0) {
expand_what = EXP_CSCOPE_KILL;
- else if (STRNICMP(arg, "find", p - arg) == 0)
+ } else if (STRNICMP(arg, "find", p - arg) == 0) {
expand_what = EXP_CSCOPE_FIND;
- else
+ } else {
xp->xp_context = EXPAND_NOTHING;
+ }
}
}
}
-/*
- * PRIVATE: do_cscope_general
- *
- * Find the command, print help if invalid, and then call the corresponding
- * command function.
- */
-static void
-do_cscope_general (
+/// Find the command, print help if invalid, and then call the corresponding
+/// command function.
+static void
+do_cscope_general(
exarg_T *eap,
int make_split /* whether to split window */
)
@@ -206,29 +204,20 @@ do_cscope_general (
postponed_split_tab = 0;
}
-/*
- * PUBLIC: do_cscope
- */
-void do_cscope(exarg_T *eap)
+/// Implementation of ":cscope" and ":lcscope"
+void ex_cscope(exarg_T *eap)
{
do_cscope_general(eap, FALSE);
}
-/*
- * PUBLIC: do_scscope
- *
- * same as do_cscope, but splits window, too.
- */
-void do_scscope(exarg_T *eap)
+/// Implementation of ":scscope". Same as ex_cscope(), but splits window, too.
+void ex_scscope(exarg_T *eap)
{
do_cscope_general(eap, TRUE);
}
-/*
- * PUBLIC: do_cstag
- *
- */
-void do_cstag(exarg_T *eap)
+/// Implementation of ":cstag"
+void ex_cstag(exarg_T *eap)
{
int ret = FALSE;
@@ -283,18 +272,13 @@ void do_cstag(exarg_T *eap)
(void)EMSG(_("E257: cstag: tag not found"));
g_do_tagpreview = 0;
}
-
-} /* do_cscope */
+}
-/*
- * PUBLIC: cs_find
- *
- * this simulates a vim_fgets(), but for cscope, returns the next line
- * from the cscope output. should only be called from find_tags()
- *
- * returns TRUE if eof, FALSE otherwise
- */
+/// This simulates a vim_fgets(), but for cscope, returns the next line
+/// from the cscope output. should only be called from find_tags()
+///
+/// @return TRUE if eof, FALSE otherwise
int cs_fgets(char_u *buf, int size)
{
char *p;
@@ -307,21 +291,13 @@ int cs_fgets(char_u *buf, int size)
} /* cs_fgets */
-/*
- * PUBLIC: cs_free_tags
- *
- * called only from do_tag(), when popping the tag stack
- */
+/// Called only from do_tag(), when popping the tag stack.
void cs_free_tags(void)
{
cs_manage_matches(NULL, NULL, 0, Free);
}
-/*
- * PUBLIC: cs_print_tags
- *
- * called from do_tag()
- */
+/// Called from do_tag().
void cs_print_tags(void)
{
cs_manage_matches(NULL, NULL, 0, Print);
@@ -402,14 +378,8 @@ int cs_connection(int num, char_u *dbpath, char_u *ppath)
* PRIVATE functions
****************************************************************************/
-/*
- * PRIVATE: cs_add
- *
- * add cscope database or a directory name (to look for cscope.out)
- * to the cscope connection list
- *
- * MAXPATHL 256
- */
+/// Add cscope database or a directory name (to look for cscope.out)
+/// to the cscope connection list.
static int cs_add(exarg_T *eap)
{
char *fname, *ppath, *flags = NULL;
@@ -435,17 +405,13 @@ static void cs_stat_emsg(char *fname)
}
-/*
- * PRIVATE: cs_add_common
- *
- * the common routine to add a new cscope connection. called by
- * cs_add() and cs_reset(). i really don't like to do this, but this
- * routine uses a number of goto statements.
- */
-static int
-cs_add_common (
- char *arg1, /* filename - may contain environment variables */
- char *arg2, /* prepend path - may contain environment variables */
+/// The common routine to add a new cscope connection. Called by
+/// cs_add() and cs_reset(). I really don't like to do this, but this
+/// routine uses a number of goto statements.
+static int
+cs_add_common(
+ char *arg1, // filename - may contain environment variables
+ char *arg2, // prepend path - may contain environment variables
char *flags
)
{
@@ -559,11 +525,7 @@ static int cs_check_for_tags(void)
return p_tags[0] != NUL && curbuf->b_p_tags != NULL;
} /* cs_check_for_tags */
-/*
- * PRIVATE: cs_cnt_connections
- *
- * count the number of cscope connections
- */
+/// Count the number of cscope connections.
static size_t cs_cnt_connections(void)
{
size_t cnt = 0;
@@ -583,11 +545,7 @@ static void cs_reading_emsg(
}
#define CSREAD_BUFSIZE 2048
-/*
- * PRIVATE: cs_cnt_matches
- *
- * count the number of matches for a given cscope connection.
- */
+/// Count the number of matches for a given cscope connection.
static int cs_cnt_matches(size_t idx)
{
char *stok;
@@ -637,11 +595,7 @@ static int cs_cnt_matches(size_t idx)
} /* cs_cnt_matches */
-/*
- * PRIVATE: cs_create_cmd
- *
- * Creates the actual cscope command query from what the user entered.
- */
+/// Creates the actual cscope command query from what the user entered.
static char *cs_create_cmd(char *csoption, char *pattern)
{
char *cmd;
@@ -697,12 +651,8 @@ static char *cs_create_cmd(char *csoption, char *pattern)
} /* cs_create_cmd */
-/*
- * PRIVATE: cs_create_connection
- *
- * This piece of code was taken/adapted from nvi. do we need to add
- * the BSD license notice?
- */
+/// This piece of code was taken/adapted from nvi. do we need to add
+/// the BSD license notice?
static int cs_create_connection(size_t i)
{
#ifdef UNIX
@@ -891,14 +841,10 @@ err_closing:
} /* cs_create_connection */
-/*
- * PRIVATE: cs_find
- *
- * query cscope using command line interface. parse the output and use tselect
- * to allow choices. like Nvi, creates a pipe to send to/from query/cscope.
- *
- * returns TRUE if we jump to a tag or abort, FALSE if not.
- */
+/// Query cscope using command line interface. Parse the output and use tselect
+/// to allow choices. Like Nvi, creates a pipe to send to/from query/cscope.
+///
+/// @return TRUE if we jump to a tag or abort, FALSE if not.
static int cs_find(exarg_T *eap)
{
char *opt, *pat;
@@ -932,11 +878,7 @@ static int cs_find(exarg_T *eap)
} /* cs_find */
-/*
- * PRIVATE: cs_find_common
- *
- * common code for cscope find, shared by cs_find() and do_cstag()
- */
+/// Common code for cscope find, shared by cs_find() and ex_cstag().
static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
int use_ll, char_u *cmdline)
{
@@ -994,11 +936,12 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
return FALSE;
}
- if (*qfpos != '0') {
- apply_autocmds(EVENT_QUICKFIXCMDPRE, (char_u *)"cscope",
- curbuf->b_fname, TRUE, curbuf);
- if (did_throw || force_abort)
- return FALSE;
+ if (*qfpos != '0'
+ && apply_autocmds(EVENT_QUICKFIXCMDPRE, (char_u *)"cscope",
+ curbuf->b_fname, true, curbuf)) {
+ if (aborting()) {
+ return false;
+ }
}
}
@@ -1108,11 +1051,7 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
} /* cs_find_common */
-/*
- * PRIVATE: cs_help
- *
- * print help
- */
+/// Print help.
static int cs_help(exarg_T *eap)
{
cscmd_T *cmdp = cs_cmds;
@@ -1160,11 +1099,7 @@ static void clear_csinfo(size_t i)
csinfo[i].to_fp = NULL;
}
-/*
- * PRIVATE: cs_insert_filelist
- *
- * insert a new cscope database filename into the filelist
- */
+/// Insert a new cscope database filename into the filelist.
static int cs_insert_filelist(char *fname, char *ppath, char *flags,
FileInfo *file_info)
{
@@ -1224,11 +1159,7 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags,
} /* cs_insert_filelist */
-/*
- * PRIVATE: cs_lookup_cmd
- *
- * find cscope command in command table
- */
+/// Find cscope command in command table.
static cscmd_T * cs_lookup_cmd(exarg_T *eap)
{
cscmd_T *cmdp;
@@ -1253,11 +1184,7 @@ static cscmd_T * cs_lookup_cmd(exarg_T *eap)
} /* cs_lookup_cmd */
-/*
- * PRIVATE: cs_kill
- *
- * nuke em
- */
+/// Nuke em.
static int cs_kill(exarg_T *eap)
{
char *stok;
@@ -1294,9 +1221,10 @@ static int cs_kill(exarg_T *eap)
}
}
- if (i >= csinfo_size || csinfo[i].fname == NULL) {
- if (p_csverbose)
+ if (!killall && (i >= csinfo_size || csinfo[i].fname == NULL)) {
+ if (p_csverbose) {
(void)EMSG2(_("E261: cscope connection %s not found"), stok);
+ }
return CSCOPE_FAILURE;
} else {
if (killall) {
@@ -1313,11 +1241,7 @@ static int cs_kill(exarg_T *eap)
} /* cs_kill */
-/*
- * PRIVATE: cs_kill_execute
- *
- * Actually kills a specific cscope connection.
- */
+/// Actually kills a specific cscope connection.
static void cs_kill_execute(
size_t i, /* cscope table index */
char *cname /* cscope database name */
@@ -1332,26 +1256,22 @@ static void cs_kill_execute(
}
-/*
- * PRIVATE: cs_make_vim_style_matches
- *
- * convert the cscope output into a ctags style entry (as might be found
- * in a ctags tags file). there's one catch though: cscope doesn't tell you
- * the type of the tag you are looking for. for example, in Darren Hiebert's
- * ctags (the one that comes with vim), #define's use a line number to find the
- * tag in a file while function definitions use a regexp search pattern.
- *
- * i'm going to always use the line number because cscope does something
- * quirky (and probably other things i don't know about):
- *
- * if you have "# define" in your source file, which is
- * perfectly legal, cscope thinks you have "#define". this
- * will result in a failed regexp search. :(
- *
- * besides, even if this particular case didn't happen, the search pattern
- * would still have to be modified to escape all the special regular expression
- * characters to comply with ctags formatting.
- */
+/// Convert the cscope output into a ctags style entry (as might be found
+/// in a ctags tags file). there's one catch though: cscope doesn't tell you
+/// the type of the tag you are looking for. for example, in Darren Hiebert's
+/// ctags (the one that comes with vim), #define's use a line number to find the
+/// tag in a file while function definitions use a regexp search pattern.
+///
+/// I'm going to always use the line number because cscope does something
+/// quirky (and probably other things i don't know about):
+///
+/// if you have "# define" in your source file, which is
+/// perfectly legal, cscope thinks you have "#define". this
+/// will result in a failed regexp search. :(
+///
+/// Besides, even if this particular case didn't happen, the search pattern
+/// would still have to be modified to escape all the special regular expression
+/// characters to comply with ctags formatting.
static char *cs_make_vim_style_matches(char *fname, char *slno, char *search,
char *tagstr)
{
@@ -1385,24 +1305,20 @@ static char *cs_make_vim_style_matches(char *fname, char *slno, char *search,
} /* cs_make_vim_style_matches */
-/*
- * PRIVATE: cs_manage_matches
- *
- * this is kind of hokey, but i don't see an easy way round this..
- *
- * Store: keep a ptr to the (malloc'd) memory of matches originally
- * generated from cs_find(). the matches are originally lines directly
- * from cscope output, but transformed to look like something out of a
- * ctags. see cs_make_vim_style_matches for more details.
- *
- * Get: used only from cs_fgets(), this simulates a vim_fgets() to return
- * the next line from the cscope output. it basically keeps track of which
- * lines have been "used" and returns the next one.
- *
- * Free: frees up everything and resets
- *
- * Print: prints the tags
- */
+/// This is kind of hokey, but i don't see an easy way round this.
+///
+/// Store: keep a ptr to the (malloc'd) memory of matches originally
+/// generated from cs_find(). the matches are originally lines directly
+/// from cscope output, but transformed to look like something out of a
+/// ctags. see cs_make_vim_style_matches for more details.
+///
+/// Get: used only from cs_fgets(), this simulates a vim_fgets() to return
+/// the next line from the cscope output. it basically keeps track of which
+/// lines have been "used" and returns the next one.
+///
+/// Free: frees up everything and resets
+///
+/// Print: prints the tags
static char *cs_manage_matches(char **matches, char **contexts,
size_t totmatches, mcmd_e cmd)
{
@@ -1457,11 +1373,7 @@ static char *cs_manage_matches(char **matches, char **contexts,
} /* cs_manage_matches */
-/*
- * PRIVATE: cs_parse_results
- *
- * parse cscope output
- */
+/// Parse cscope output.
static char *cs_parse_results(size_t cnumber, char *buf, int bufsize,
char **context, char **linenumber, char **search)
{
@@ -1511,11 +1423,7 @@ static char *cs_parse_results(size_t cnumber, char *buf, int bufsize,
return name;
}
-/*
- * PRIVATE: cs_file_results
- *
- * write cscope find results to file
- */
+/// Write cscope find results to file.
static void cs_file_results(FILE *f, int *nummatches_a)
{
char *search, *slno;
@@ -1556,13 +1464,9 @@ static void cs_file_results(FILE *f, int *nummatches_a)
xfree(buf);
}
-/*
- * PRIVATE: cs_fill_results
- *
- * get parsed cscope output and calls cs_make_vim_style_matches to convert
- * into ctags format
- * When there are no matches sets "*matches_p" to NULL.
- */
+/// Get parsed cscope output and calls cs_make_vim_style_matches to convert
+/// into ctags format.
+/// When there are no matches sets "*matches_p" to NULL.
static void cs_fill_results(char *tagstr, size_t totmatches, int *nummatches_a,
char ***matches_p, char ***cntxts_p,
size_t *matched)
@@ -1754,11 +1658,7 @@ static void cs_print_tags_priv(char **matches, char **cntxts,
xfree(buf);
}
-/*
- * PRIVATE: cs_read_prompt
- *
- * read a cscope prompt (basically, skip over the ">> ")
- */
+/// Read a cscope prompt (basically, skip over the ">> ").
static int cs_read_prompt(size_t i)
{
int ch;
@@ -1843,12 +1743,8 @@ static void sig_handler(int s) {
#endif
-/*
- * PRIVATE: cs_release_csp
- *
- * Does the actual free'ing for the cs ptr with an optional flag of whether
- * or not to free the filename. Called by cs_kill and cs_reset.
- */
+/// Does the actual free'ing for the cs ptr with an optional flag of whether
+/// or not to free the filename. Called by cs_kill and cs_reset.
static void cs_release_csp(size_t i, int freefnpp)
{
// Trying to exit normally (not sure whether it is fit to Unix cscope)
@@ -1960,15 +1856,11 @@ static void cs_release_csp(size_t i, int freefnpp)
} /* cs_release_csp */
-/*
- * PRIVATE: cs_reset
- *
- * calls cs_kill on all cscope connections then reinits
- */
+/// Calls cs_kill on all cscope connections then reinits.
static int cs_reset(exarg_T *eap)
{
char **dblist = NULL, **pplist = NULL, **fllist = NULL;
- char buf[20]; /* for snprintf " (#%zu)" */
+ char buf[25]; // for snprintf " (#%zu)"
if (csinfo_size == 0)
return CSCOPE_SUCCESS;
@@ -2007,23 +1899,20 @@ static int cs_reset(exarg_T *eap)
xfree(pplist);
xfree(fllist);
- if (p_csverbose)
- MSG_ATTR(_("All cscope databases reset"), hl_attr(HLF_R) | MSG_HIST);
+ if (p_csverbose) {
+ msg_attr(_("All cscope databases reset"), hl_attr(HLF_R) | MSG_HIST);
+ }
return CSCOPE_SUCCESS;
} /* cs_reset */
-/*
- * PRIVATE: cs_resolve_file
- *
- * Construct the full pathname to a file found in the cscope database.
- * (Prepends ppath, if there is one and if it's not already prepended,
- * otherwise just uses the name found.)
- *
- * We need to prepend the prefix because on some cscope's (e.g., the one that
- * ships with Solaris 2.6), the output never has the prefix prepended.
- * Contrast this with my development system (Digital Unix), which does.
- */
+/// Construct the full pathname to a file found in the cscope database.
+/// (Prepends ppath, if there is one and if it's not already prepended,
+/// otherwise just uses the name found.)
+///
+/// We need to prepend the prefix because on some cscope's (e.g., the one that
+/// ships with Solaris 2.6), the output never has the prefix prepended.
+/// Contrast this with my development system (Digital Unix), which does.
static char *cs_resolve_file(size_t i, char *name)
{
char *fullname;
@@ -2069,11 +1958,7 @@ static char *cs_resolve_file(size_t i, char *name)
}
-/*
- * PRIVATE: cs_show
- *
- * show all cscope connections
- */
+/// Show all cscope connections.
static int cs_show(exarg_T *eap)
{
if (cs_cnt_connections() == 0)
@@ -2101,11 +1986,7 @@ static int cs_show(exarg_T *eap)
} /* cs_show */
-/*
- * PUBLIC: cs_end
- *
- * Only called when VIM exits to quit any cscope sessions.
- */
+/// Only called when VIM exits to quit any cscope sessions.
void cs_end(void)
{
for (size_t i = 0; i < csinfo_size; i++)
diff --git a/src/nvim/if_cscope.h b/src/nvim/if_cscope.h
index 351d9caef6..e20462576a 100644
--- a/src/nvim/if_cscope.h
+++ b/src/nvim/if_cscope.h
@@ -1,6 +1,9 @@
#ifndef NVIM_IF_CSCOPE_H
#define NVIM_IF_CSCOPE_H
+#include "nvim/types.h" // for char_u and expand_T
+#include "nvim/ex_cmds_defs.h" // for exarg_T
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "if_cscope.h.generated.h"
#endif
diff --git a/src/nvim/if_cscope_defs.h b/src/nvim/if_cscope_defs.h
index f9d06eaea3..fa18866840 100644
--- a/src/nvim/if_cscope_defs.h
+++ b/src/nvim/if_cscope_defs.h
@@ -18,6 +18,7 @@
#include "nvim/os/os_defs.h"
#include "nvim/os/fs_defs.h"
+#include "nvim/ex_cmds_defs.h"
#define CSCOPE_SUCCESS 0
#define CSCOPE_FAILURE -1
diff --git a/src/nvim/indent.c b/src/nvim/indent.c
index 7f31bb8c5c..efca739c2d 100644
--- a/src/nvim/indent.c
+++ b/src/nvim/indent.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
@@ -7,6 +10,7 @@
#include "nvim/eval.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/mark.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/misc1.h"
@@ -467,7 +471,7 @@ int get_breakindent_win(win_T *wp, char_u *line) {
|| prev_tick != wp->w_buffer->b_changedtick) {
prev_line = line;
prev_ts = wp->w_buffer->b_p_ts;
- prev_tick = wp->w_buffer->b_changedtick;
+ prev_tick = (int)wp->w_buffer->b_changedtick;
prev_indent = get_indent_str(line,
(int)wp->w_buffer->b_p_ts, wp->w_p_list);
}
@@ -534,7 +538,7 @@ int get_expr_indent(void)
sandbox++;
}
textlock++;
- indent = eval_to_number(curbuf->b_p_inde);
+ indent = (int)eval_to_number(curbuf->b_p_inde);
if (use_sandbox) {
sandbox--;
@@ -598,7 +602,7 @@ int get_lisp_indent(void)
paren = *pos;
pos = findmatch(NULL, '[');
- if ((pos == NULL) || ltp(pos, &paren)) {
+ if ((pos == NULL) || lt(*pos, paren)) {
pos = &paren;
}
}
diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c
index 6f03cf6037..4a6393ac36 100644
--- a/src/nvim/indent_c.c
+++ b/src/nvim/indent_c.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <inttypes.h>
#include <stdint.h>
@@ -10,6 +13,7 @@
#include "nvim/edit.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
+#include "nvim/mark.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/option.h"
@@ -173,9 +177,8 @@ static char_u *skip_string(char_u *p)
char_u *delim = p + 2;
char_u *paren = vim_strchr(delim, '(');
- if (paren != NULL)
- {
- long delim_len = paren - delim;
+ if (paren != NULL) {
+ const ptrdiff_t delim_len = paren - delim;
for (p += 3; *p; ++p)
if (p[0] == ')' && STRNCMP(p + 1, delim, delim_len) == 0
@@ -512,34 +515,41 @@ int cin_isscopedecl(char_u *s)
/* Maximum number of lines to search back for a "namespace" line. */
#define FIND_NAMESPACE_LIM 20
-/*
- * Recognize a "namespace" scope declaration.
- */
-static int cin_is_cpp_namespace(char_u *s)
+// Recognize a "namespace" scope declaration.
+static bool cin_is_cpp_namespace(char_u *s)
{
- char_u *p;
- int has_name = FALSE;
+ char_u *p;
+ bool has_name = false;
+ bool has_name_start = false;
s = cin_skipcomment(s);
if (STRNCMP(s, "namespace", 9) == 0 && (s[9] == NUL || !vim_iswordc(s[9]))) {
p = cin_skipcomment(skipwhite(s + 9));
while (*p != NUL) {
if (ascii_iswhite(*p)) {
- has_name = TRUE; /* found end of a name */
+ has_name = true; // found end of a name
p = cin_skipcomment(skipwhite(p));
} else if (*p == '{') {
break;
} else if (vim_iswordc(*p)) {
- if (has_name)
- return FALSE; /* word character after skipping past name */
- ++p;
+ has_name_start = true;
+ if (has_name) {
+ return false; // word character after skipping past name
+ }
+ p++;
+ } else if (p[0] == ':' && p[1] == ':' && vim_iswordc(p[2])) {
+ if (!has_name_start || has_name) {
+ return false;
+ }
+ // C++ 17 nested namespace
+ p += 3;
} else {
- return FALSE;
+ return false;
}
}
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
/*
@@ -819,21 +829,22 @@ cin_isterminated (
return found_start;
}
-/*
- * Recognize the basic picture of a function declaration -- it needs to
- * have an open paren somewhere and a close paren at the end of the line and
- * no semicolons anywhere.
- * When a line ends in a comma we continue looking in the next line.
- * "sp" points to a string with the line. When looking at other lines it must
- * be restored to the line. When it's NULL fetch lines here.
- * "lnum" is where we start looking.
- * "min_lnum" is the line before which we will not be looking.
- */
+/// Recognizes the basic picture of a function declaration -- it needs to
+/// have an open paren somewhere and a close paren at the end of the line and
+/// no semicolons anywhere.
+/// When a line ends in a comma we continue looking in the next line.
+///
+/// @param[in] sp Points to a string with the line. When looking at other
+/// lines it must be restored to the line. When it's NULL fetch
+/// lines here.
+/// @param[in] first_lnum Where to start looking.
+/// @param[in] min_lnum The line before which we will not be looking.
static int cin_isfuncdecl(char_u **sp, linenr_T first_lnum, linenr_T min_lnum)
{
char_u *s;
linenr_T lnum = first_lnum;
- int retval = FALSE;
+ linenr_T save_lnum = curwin->w_cursor.lnum;
+ int retval = false;
pos_T *trypos;
int just_started = TRUE;
@@ -842,18 +853,22 @@ static int cin_isfuncdecl(char_u **sp, linenr_T first_lnum, linenr_T min_lnum)
else
s = *sp;
+ curwin->w_cursor.lnum = lnum;
if (find_last_paren(s, '(', ')')
&& (trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL) {
lnum = trypos->lnum;
- if (lnum < min_lnum)
- return FALSE;
-
+ if (lnum < min_lnum) {
+ curwin->w_cursor.lnum = save_lnum;
+ return false;
+ }
s = ml_get(lnum);
}
- /* Ignore line starting with #. */
- if (cin_ispreproc(s))
- return FALSE;
+ curwin->w_cursor.lnum = save_lnum;
+ // Ignore line starting with #.
+ if (cin_ispreproc(s)) {
+ return false;
+ }
while (*s && *s != '(' && *s != ';' && *s != '\'' && *s != '"') {
// ignore comments
diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c
index 99e94fc60f..3d7ebb6382 100644
--- a/src/nvim/keymap.c
+++ b/src/nvim/keymap.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <inttypes.h>
#include <limits.h>
@@ -490,17 +493,19 @@ char_u *get_special_key_name(int c, int modifiers)
/// @param[out] dst Location where translation result will be kept. Must have
/// at least six bytes.
/// @param[in] keycode Prefer key code, e.g. K_DEL in place of DEL.
+/// @param[in] in_string Inside a double quoted string
///
/// @return Number of characters added to dst, zero for no match.
unsigned int trans_special(const char_u **srcp, const size_t src_len,
- char_u *const dst, const bool keycode)
+ char_u *const dst, const bool keycode,
+ const bool in_string)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
int modifiers = 0;
int key;
unsigned int dlen = 0;
- key = find_special_key(srcp, src_len, &modifiers, keycode, false);
+ key = find_special_key(srcp, src_len, &modifiers, keycode, false, in_string);
if (key == 0) {
return 0;
}
@@ -536,10 +541,12 @@ unsigned int trans_special(const char_u **srcp, const size_t src_len,
/// @param[out] modp Location where information about modifiers is saved.
/// @param[in] keycode Prefer key code, e.g. K_DEL in place of DEL.
/// @param[in] keep_x_key Don’t translate xHome to Home key.
+/// @param[in] in_string In string, double quote is escaped
///
/// @return Key and modifiers or 0 if there is no match.
int find_special_key(const char_u **srcp, const size_t src_len, int *const modp,
- const bool keycode, const bool keep_x_key)
+ const bool keycode, const bool keep_x_key,
+ const bool in_string)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
const char_u *last_dash;
@@ -550,7 +557,7 @@ int find_special_key(const char_u **srcp, const size_t src_len, int *const modp,
int modifiers;
int bit;
int key;
- unsigned long n;
+ uvarnumber_T n;
int l;
if (src_len == 0) {
@@ -573,8 +580,14 @@ int find_special_key(const char_u **srcp, const size_t src_len, int *const modp,
} else {
l = 1;
}
- if (end - bp > l && bp[l + 1] == '>') {
- bp += l; // anything accepted, like <C-?>
+ // Anything accepted, like <C-?>.
+ // <C-"> or <M-"> are not special in strings as " is
+ // the string delimiter. With a backslash it works: <M-\">
+ if (end - bp > l && !(in_string && bp[1] == '"') && bp[2] == '>') {
+ bp += l;
+ } else if (end - bp > 2 && in_string && bp[1] == '\\'
+ && bp[2] == '"' && bp[3] == '>') {
+ bp += 2;
}
}
}
@@ -610,18 +623,17 @@ int find_special_key(const char_u **srcp, const size_t src_len, int *const modp,
vim_str2nr(last_dash + 6, NULL, NULL, STR2NR_ALL, NULL, &n, 0);
key = (int)n;
} else {
- /*
- * Modifier with single letter, or special key name.
- */
- if (has_mbyte) {
- l = mb_ptr2len(last_dash + 1);
- } else {
- l = 1;
+ int off = 1;
+
+ // Modifier with single letter, or special key name.
+ if (in_string && last_dash[1] == '\\' && last_dash[2] == '"') {
+ off = 2;
}
+ l = mb_ptr2len(last_dash + 1);
if (modifiers != 0 && last_dash[l + 1] == '>') {
- key = PTR2CHAR(last_dash + 1);
+ key = PTR2CHAR(last_dash + off);
} else {
- key = get_special_key_code(last_dash + 1);
+ key = get_special_key_code(last_dash + off);
if (!keep_x_key) {
key = handle_x_keys(key);
}
@@ -744,9 +756,9 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag)
/// Replace any terminal code strings with the equivalent internal
/// representation
///
-/// This is used for the "from" and "to" part of a mapping, and the "to" part of
+/// Used for the "from" and "to" part of a mapping, and the "to" part of
/// a menu command. Any strings like "<C-UP>" are also replaced, unless
-/// 'cpoptions' contains '<'. K_SPECIAL by itself is replaced by K_SPECIAL
+/// `special` is false. K_SPECIAL by itself is replaced by K_SPECIAL
/// KS_SPECIAL KE_FILLER.
///
/// @param[in] from What characters to replace.
@@ -759,7 +771,7 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag)
/// When cpo_flags contains #FLAG_CPO_BSLASH, a backslash
/// can be used in place of <C-v>. All other <C-v>
/// characters are removed.
-/// @param[in] special If true, always accept <key> notation.
+/// @param[in] special Replace keycodes, e.g. <CR> becomes a "\n" char.
/// @param[in] cpo_flags Relevant flags derived from p_cpo, see
/// #CPO_TO_CPO_FLAGS.
///
@@ -778,11 +790,9 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
const char_u *src;
const char_u *const end = from + from_len - 1;
int do_backslash; // backslash is a special character
- int do_special; // recognize <> key codes
char_u *result; // buffer for resulting string
do_backslash = !(cpo_flags&FLAG_CPO_BSLASH);
- do_special = !(cpo_flags&FLAG_CPO_SPECI) || special;
// Allocate space for the translation. Worst case a single character is
// replaced by 6 bytes (shifted special key), plus a NUL at the end.
@@ -805,10 +815,9 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
// Copy each byte from *from to result[dlen]
while (src <= end) {
- // If 'cpoptions' does not contain '<', check for special key codes,
- // like "<C-S-LeftMouse>"
- if (do_special && (do_lt || ((end - src) >= 3
- && STRNCMP(src, "<lt>", 4) != 0))) {
+ // Check for special <> keycodes, like "<C-S-LeftMouse>"
+ if (special && (do_lt || ((end - src) >= 3
+ && STRNCMP(src, "<lt>", 4) != 0))) {
// Replace <SID> by K_SNR <script-nr> _.
// (room: 5 * 6 = 30 bytes; needed: 3 + <nr> + 1 <= 14)
if (end - src >= 4 && STRNICMP(src, "<SID>", 5) == 0) {
@@ -826,14 +835,15 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
}
}
- slen = trans_special(&src, (size_t) (end - src) + 1, result + dlen, true);
+ slen = trans_special(&src, (size_t)(end - src) + 1, result + dlen, true,
+ true);
if (slen) {
dlen += slen;
continue;
}
}
- if (do_special) {
+ if (special) {
char_u *p, *s, len;
// Replace <Leader> by the value of "mapleader".
@@ -841,10 +851,10 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
// If "mapleader" or "maplocalleader" isn't set use a backslash.
if (end - src >= 7 && STRNICMP(src, "<Leader>", 8) == 0) {
len = 8;
- p = get_var_value((char_u *)"g:mapleader");
+ p = get_var_value("g:mapleader");
} else if (end - src >= 12 && STRNICMP(src, "<LocalLeader>", 13) == 0) {
len = 13;
- p = get_var_value((char_u *)"g:maplocalleader");
+ p = get_var_value("g:maplocalleader");
} else {
len = 0;
p = NULL;
diff --git a/src/nvim/keymap.h b/src/nvim/keymap.h
index bb8ba84a6a..b8fed77a90 100644
--- a/src/nvim/keymap.h
+++ b/src/nvim/keymap.h
@@ -464,13 +464,9 @@ enum key_extra {
#define MAX_KEY_CODE_LEN 6
#define FLAG_CPO_BSLASH 0x01
-#define FLAG_CPO_SPECI 0x02
-#define CPO_TO_CPO_FLAGS (((vim_strchr(p_cpo, CPO_BSLASH) == NULL) \
- ? 0 \
- : FLAG_CPO_BSLASH)| \
- (vim_strchr(p_cpo, CPO_SPECI) == NULL \
- ? 0 \
- : FLAG_CPO_SPECI))
+#define CPO_TO_CPO_FLAGS ((vim_strchr(p_cpo, CPO_BSLASH) == NULL) \
+ ? 0 \
+ : FLAG_CPO_BSLASH)
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "keymap.h.generated.h"
diff --git a/src/nvim/lib/kbtree.h b/src/nvim/lib/kbtree.h
new file mode 100644
index 0000000000..a3943054e6
--- /dev/null
+++ b/src/nvim/lib/kbtree.h
@@ -0,0 +1,451 @@
+/*-
+ * Copyright 1997-1999, 2001, John-Mark Gurney.
+ * 2008-2009, Attractive Chaos <attractor@live.co.uk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef NVIM_LIB_KBTREE_H
+#define NVIM_LIB_KBTREE_H
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "nvim/memory.h"
+
+#define KB_MAX_DEPTH 64
+
+#define __KB_KEY(type, x) (x->key)
+#define __KB_PTR(btr, x) (x->ptr)
+
+#define __KB_TREE_T(name,key_t,T) \
+ typedef struct kbnode_##name##_s kbnode_##name##_t; \
+ struct kbnode_##name##_s { \
+ int32_t n; \
+ bool is_internal; \
+ key_t key[2*T-1]; \
+ kbnode_##name##_t *ptr[]; \
+ } ; \
+ \
+ typedef struct { \
+ kbnode_##name##_t *root; \
+ int n_keys, n_nodes; \
+ } kbtree_##name##_t; \
+ \
+ typedef struct { \
+ kbnode_##name##_t *x; \
+ int i; \
+ } kbpos_##name##_t; \
+ typedef struct { \
+ kbpos_##name##_t stack[KB_MAX_DEPTH], *p; \
+ } kbitr_##name##_t; \
+
+
+#define __kb_destroy(kbnode_t,b) do { \
+ int i; \
+ unsigned int max = 8; \
+ kbnode_t *x, **top, **stack = 0; \
+ if (b->root) { \
+ top = stack = (kbnode_t**)xcalloc(max, sizeof(kbnode_t*)); \
+ *top++ = (b)->root; \
+ while (top != stack) { \
+ x = *--top; \
+ if (x->is_internal == 0) { xfree(x); continue; } \
+ for (i = 0; i <= x->n; ++i) \
+ if (__KB_PTR(b, x)[i]) { \
+ if (top - stack == (int)max) { \
+ max <<= 1; \
+ stack = (kbnode_t**)xrealloc(stack, max * sizeof(kbnode_t*)); \
+ top = stack + (max>>1); \
+ } \
+ *top++ = __KB_PTR(b, x)[i]; \
+ } \
+ xfree(x); \
+ } \
+ } \
+ xfree(stack); \
+ } while (0)
+
+#define __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \
+ static inline int __kb_getp_aux_##name(const kbnode_t * __restrict x, key_t * __restrict k, int *r) \
+ { \
+ int tr, *rr, begin = 0, end = x->n; \
+ if (x->n == 0) return -1; \
+ rr = r? r : &tr; \
+ while (begin < end) { \
+ int mid = (begin + end) >> 1; \
+ if (__cmp(__KB_KEY(key_t, x)[mid], *k) < 0) begin = mid + 1; \
+ else end = mid; \
+ } \
+ if (begin == x->n) { *rr = 1; return x->n - 1; } \
+ if ((*rr = __cmp(*k, __KB_KEY(key_t, x)[begin])) < 0) --begin; \
+ return begin; \
+ }
+
+#define __KB_GET(name, key_t, kbnode_t) \
+ static key_t *kb_getp_##name(kbtree_##name##_t *b, key_t * __restrict k) \
+ { \
+ if (!b->root) { \
+ return 0; \
+ } \
+ int i, r = 0; \
+ kbnode_t *x = b->root; \
+ while (x) { \
+ i = __kb_getp_aux_##name(x, k, &r); \
+ if (i >= 0 && r == 0) return &__KB_KEY(key_t, x)[i]; \
+ if (x->is_internal == 0) return 0; \
+ x = __KB_PTR(b, x)[i + 1]; \
+ } \
+ return 0; \
+ } \
+ static inline key_t *kb_get_##name(kbtree_##name##_t *b, key_t k) \
+ { \
+ return kb_getp_##name(b, &k); \
+ }
+
+#define __KB_INTERVAL(name, key_t, kbnode_t) \
+ static inline void kb_intervalp_##name(kbtree_##name##_t *b, key_t * __restrict k, key_t **lower, key_t **upper) \
+ { \
+ if (!b->root) { \
+ return; \
+ } \
+ int i, r = 0; \
+ kbnode_t *x = b->root; \
+ *lower = *upper = 0; \
+ while (x) { \
+ i = __kb_getp_aux_##name(x, k, &r); \
+ if (i >= 0 && r == 0) { \
+ *lower = *upper = &__KB_KEY(key_t, x)[i]; \
+ return; \
+ } \
+ if (i >= 0) *lower = &__KB_KEY(key_t, x)[i]; \
+ if (i < x->n - 1) *upper = &__KB_KEY(key_t, x)[i + 1]; \
+ if (x->is_internal == 0) return; \
+ x = __KB_PTR(b, x)[i + 1]; \
+ } \
+ } \
+ static inline void kb_interval_##name(kbtree_##name##_t *b, key_t k, key_t **lower, key_t **upper) \
+ { \
+ kb_intervalp_##name(b, &k, lower, upper); \
+ }
+
+#define __KB_PUT(name, key_t, kbnode_t, __cmp, T, ILEN) \
+ /* x must be an internal node */ \
+ static inline void __kb_split_##name(kbtree_##name##_t *b, kbnode_t *x, int i, kbnode_t *y) \
+ { \
+ kbnode_t *z; \
+ z = (kbnode_t*)xcalloc(1, y->is_internal? ILEN : sizeof(kbnode_##name##_t)); \
+ ++b->n_nodes; \
+ z->is_internal = y->is_internal; \
+ z->n = T - 1; \
+ memcpy(__KB_KEY(key_t, z), &__KB_KEY(key_t, y)[T], sizeof(key_t) * (T - 1)); \
+ if (y->is_internal) memcpy(__KB_PTR(b, z), &__KB_PTR(b, y)[T], sizeof(void*) * T); \
+ y->n = T - 1; \
+ memmove(&__KB_PTR(b, x)[i + 2], &__KB_PTR(b, x)[i + 1], sizeof(void*) * (unsigned int)(x->n - i)); \
+ __KB_PTR(b, x)[i + 1] = z; \
+ memmove(&__KB_KEY(key_t, x)[i + 1], &__KB_KEY(key_t, x)[i], sizeof(key_t) * (unsigned int)(x->n - i)); \
+ __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[T - 1]; \
+ ++x->n; \
+ } \
+ static inline key_t *__kb_putp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, key_t * __restrict k) \
+ { \
+ int i = x->n - 1; \
+ key_t *ret; \
+ if (x->is_internal == 0) { \
+ i = __kb_getp_aux_##name(x, k, 0); \
+ if (i != x->n - 1) \
+ memmove(&__KB_KEY(key_t, x)[i + 2], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
+ ret = &__KB_KEY(key_t, x)[i + 1]; \
+ *ret = *k; \
+ ++x->n; \
+ } else { \
+ i = __kb_getp_aux_##name(x, k, 0) + 1; \
+ if (__KB_PTR(b, x)[i]->n == 2 * T - 1) { \
+ __kb_split_##name(b, x, i, __KB_PTR(b, x)[i]); \
+ if (__cmp(*k, __KB_KEY(key_t, x)[i]) > 0) ++i; \
+ } \
+ ret = __kb_putp_aux_##name(b, __KB_PTR(b, x)[i], k); \
+ } \
+ return ret; \
+ } \
+ static inline key_t *kb_putp_##name(kbtree_##name##_t *b, key_t * __restrict k) \
+ { \
+ if (!b->root) { \
+ b->root = (kbnode_t*)xcalloc(1, ILEN); \
+ ++b->n_nodes; \
+ } \
+ kbnode_t *r, *s; \
+ ++b->n_keys; \
+ r = b->root; \
+ if (r->n == 2 * T - 1) { \
+ ++b->n_nodes; \
+ s = (kbnode_t*)xcalloc(1, ILEN); \
+ b->root = s; s->is_internal = 1; s->n = 0; \
+ __KB_PTR(b, s)[0] = r; \
+ __kb_split_##name(b, s, 0, r); \
+ r = s; \
+ } \
+ return __kb_putp_aux_##name(b, r, k); \
+ } \
+ static inline void kb_put_##name(kbtree_##name##_t *b, key_t k) \
+ { \
+ kb_putp_##name(b, &k); \
+ }
+
+
+#define __KB_DEL(name, key_t, kbnode_t, T) \
+ static inline key_t __kb_delp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, key_t * __restrict k, int s) \
+ { \
+ int yn, zn, i, r = 0; \
+ kbnode_t *xp, *y, *z; \
+ key_t kp; \
+ if (x == 0) return *k; \
+ if (s) { /* s can only be 0, 1 or 2 */ \
+ r = x->is_internal == 0? 0 : s == 1? 1 : -1; \
+ i = s == 1? x->n - 1 : -1; \
+ } else i = __kb_getp_aux_##name(x, k, &r); \
+ if (x->is_internal == 0) { \
+ if (s == 2) ++i; \
+ kp = __KB_KEY(key_t, x)[i]; \
+ memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
+ --x->n; \
+ return kp; \
+ } \
+ if (r == 0) { \
+ if ((yn = __KB_PTR(b, x)[i]->n) >= T) { \
+ xp = __KB_PTR(b, x)[i]; \
+ kp = __KB_KEY(key_t, x)[i]; \
+ __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 1); \
+ return kp; \
+ } else if ((zn = __KB_PTR(b, x)[i + 1]->n) >= T) { \
+ xp = __KB_PTR(b, x)[i + 1]; \
+ kp = __KB_KEY(key_t, x)[i]; \
+ __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 2); \
+ return kp; \
+ } else if (yn == T - 1 && zn == T - 1) { \
+ y = __KB_PTR(b, x)[i]; z = __KB_PTR(b, x)[i + 1]; \
+ __KB_KEY(key_t, y)[y->n++] = *k; \
+ memmove(&__KB_KEY(key_t, y)[y->n], __KB_KEY(key_t, z), (unsigned int)z->n * sizeof(key_t)); \
+ if (y->is_internal) memmove(&__KB_PTR(b, y)[y->n], __KB_PTR(b, z), (unsigned int)(z->n + 1) * sizeof(void*)); \
+ y->n += z->n; \
+ memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
+ memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, x)[i + 2], (unsigned int)(x->n - i - 1) * sizeof(void*)); \
+ --x->n; \
+ xfree(z); \
+ return __kb_delp_aux_##name(b, y, k, s); \
+ } \
+ } \
+ ++i; \
+ if ((xp = __KB_PTR(b, x)[i])->n == T - 1) { \
+ if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n >= T) { \
+ memmove(&__KB_KEY(key_t, xp)[1], __KB_KEY(key_t, xp), (unsigned int)xp->n * sizeof(key_t)); \
+ if (xp->is_internal) memmove(&__KB_PTR(b, xp)[1], __KB_PTR(b, xp), (unsigned int)(xp->n + 1) * sizeof(void*)); \
+ __KB_KEY(key_t, xp)[0] = __KB_KEY(key_t, x)[i - 1]; \
+ __KB_KEY(key_t, x)[i - 1] = __KB_KEY(key_t, y)[y->n - 1]; \
+ if (xp->is_internal) __KB_PTR(b, xp)[0] = __KB_PTR(b, y)[y->n]; \
+ --y->n; ++xp->n; \
+ } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n >= T) { \
+ __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \
+ __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[0]; \
+ if (xp->is_internal) __KB_PTR(b, xp)[xp->n] = __KB_PTR(b, y)[0]; \
+ --y->n; \
+ memmove(__KB_KEY(key_t, y), &__KB_KEY(key_t, y)[1], (unsigned int)y->n * sizeof(key_t)); \
+ if (y->is_internal) memmove(__KB_PTR(b, y), &__KB_PTR(b, y)[1], (unsigned int)(y->n + 1) * sizeof(void*)); \
+ } else if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n == T - 1) { \
+ __KB_KEY(key_t, y)[y->n++] = __KB_KEY(key_t, x)[i - 1]; \
+ memmove(&__KB_KEY(key_t, y)[y->n], __KB_KEY(key_t, xp), (unsigned int)xp->n * sizeof(key_t)); \
+ if (y->is_internal) memmove(&__KB_PTR(b, y)[y->n], __KB_PTR(b, xp), (unsigned int)(xp->n + 1) * sizeof(void*)); \
+ y->n += xp->n; \
+ memmove(&__KB_KEY(key_t, x)[i - 1], &__KB_KEY(key_t, x)[i], (unsigned int)(x->n - i) * sizeof(key_t)); \
+ memmove(&__KB_PTR(b, x)[i], &__KB_PTR(b, x)[i + 1], (unsigned int)(x->n - i) * sizeof(void*)); \
+ --x->n; \
+ xfree(xp); \
+ xp = y; \
+ } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n == T - 1) { \
+ __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \
+ memmove(&__KB_KEY(key_t, xp)[xp->n], __KB_KEY(key_t, y), (unsigned int)y->n * sizeof(key_t)); \
+ if (xp->is_internal) memmove(&__KB_PTR(b, xp)[xp->n], __KB_PTR(b, y), (unsigned int)(y->n + 1) * sizeof(void*)); \
+ xp->n += y->n; \
+ memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
+ memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, x)[i + 2], (unsigned int)(x->n - i - 1) * sizeof(void*)); \
+ --x->n; \
+ xfree(y); \
+ } \
+ } \
+ return __kb_delp_aux_##name(b, xp, k, s); \
+ } \
+ static inline key_t kb_delp_##name(kbtree_##name##_t *b, key_t * __restrict k) \
+ { \
+ kbnode_t *x; \
+ key_t ret; \
+ ret = __kb_delp_aux_##name(b, b->root, k, 0); \
+ --b->n_keys; \
+ if (b->root->n == 0 && b->root->is_internal) { \
+ --b->n_nodes; \
+ x = b->root; \
+ b->root = __KB_PTR(b, x)[0]; \
+ xfree(x); \
+ } \
+ return ret; \
+ } \
+ static inline key_t kb_del_##name(kbtree_##name##_t *b, key_t k) \
+ { \
+ return kb_delp_##name(b, &k); \
+ }
+
+#define __KB_ITR(name, key_t, kbnode_t) \
+ static inline void kb_itr_first_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
+ { \
+ itr->p = 0; \
+ if (b->n_keys == 0) return; \
+ itr->p = itr->stack; \
+ itr->p->x = b->root; itr->p->i = 0; \
+ while (itr->p->x->is_internal && __KB_PTR(b, itr->p->x)[0] != 0) { \
+ kbnode_t *x = itr->p->x; \
+ ++itr->p; \
+ itr->p->x = __KB_PTR(b, x)[0]; itr->p->i = 0; \
+ } \
+ } \
+ static inline int kb_itr_next_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
+ { \
+ if (itr->p < itr->stack) return 0; \
+ for (;;) { \
+ ++itr->p->i; \
+ while (itr->p->x && itr->p->i <= itr->p->x->n) { \
+ itr->p[1].i = 0; \
+ itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \
+ ++itr->p; \
+ } \
+ --itr->p; \
+ if (itr->p < itr->stack) return 0; \
+ if (itr->p->x && itr->p->i < itr->p->x->n) return 1; \
+ } \
+ } \
+ static inline int kb_itr_prev_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
+ { \
+ if (itr->p < itr->stack) return 0; \
+ for (;;) { \
+ while (itr->p->x && itr->p->i >= 0) { \
+ itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \
+ itr->p[1].i = itr->p[1].x ? itr->p[1].x->n : -1; \
+ ++itr->p; \
+ } \
+ --itr->p; \
+ if (itr->p < itr->stack) return 0; \
+ --itr->p->i; \
+ if (itr->p->x && itr->p->i >= 0) return 1; \
+ } \
+ } \
+ static inline int kb_itr_getp_##name(kbtree_##name##_t *b, key_t * __restrict k, kbitr_##name##_t *itr) \
+ { \
+ if (b->n_keys == 0) { \
+ itr->p = NULL; \
+ return 0; \
+ } \
+ int i, r = 0; \
+ itr->p = itr->stack; \
+ itr->p->x = b->root; \
+ while (itr->p->x) { \
+ i = __kb_getp_aux_##name(itr->p->x, k, &r); \
+ itr->p->i = i; \
+ if (i >= 0 && r == 0) return 1; \
+ ++itr->p->i; \
+ itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[i + 1] : 0; \
+ ++itr->p; \
+ } \
+ return 0; \
+ } \
+ static inline int kb_itr_get_##name(kbtree_##name##_t *b, key_t k, kbitr_##name##_t *itr) \
+ { \
+ return kb_itr_getp_##name(b,&k,itr); \
+ } \
+ static inline void kb_del_itr_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
+ { \
+ key_t k = kb_itr_key(itr); \
+ kb_delp_##name(b, &k); \
+ kb_itr_getp_##name(b, &k, itr); \
+ }
+
+#define KBTREE_INIT(name, key_t, __cmp, T) \
+ KBTREE_INIT_IMPL(name, key_t, kbnode_##name##_t, __cmp, T, (sizeof(kbnode_##name##_t)+(2*T)*sizeof(void *)))
+
+#if (!defined(__clang__) && !defined(__INTEL_COMPILER)) && (__GNUC__ > 4 )
+
+// The index trickery shouldn't be UB anymore,
+// still it is to much for gcc:s -Werror=array-bounds
+# define __KB_PRAGMA_START \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Warray-bounds\"")
+
+# define __KB_PRAGMA_END \
+ _Pragma("GCC diagnostic pop") \
+
+#else
+
+# define __KB_PRAGMA_START
+# define __KB_PRAGMA_END
+
+#endif
+
+#define KBTREE_INIT_IMPL(name, key_t, kbnode_t, __cmp, T, ILEN) \
+ __KB_PRAGMA_START \
+ __KB_TREE_T(name, key_t, T) \
+ __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \
+ __KB_GET(name, key_t, kbnode_t) \
+ __KB_INTERVAL(name, key_t, kbnode_t) \
+ __KB_PUT(name, key_t, kbnode_t, __cmp, T, ILEN) \
+ __KB_DEL(name, key_t, kbnode_t, T) \
+ __KB_ITR(name, key_t, kbnode_t) \
+ __KB_PRAGMA_END
+
+#define KB_DEFAULT_SIZE 512
+
+#define kbtree_t(name) kbtree_##name##_t
+#define kbitr_t(name) kbitr_##name##_t
+#define kb_init(b) ((b)->n_keys = (b)->n_nodes = 0, (b)->root = 0)
+#define kb_destroy(name, b) __kb_destroy(kbnode_##name##_t, b)
+#define kb_get(name, b, k) kb_get_##name(b, k)
+#define kb_put(name, b, k) kb_put_##name(b, k)
+#define kb_del(name, b, k) kb_del_##name(b, k)
+#define kb_interval(name, b, k, l, u) kb_interval_##name(b, k, l, u)
+#define kb_getp(name, b, k) kb_getp_##name(b, k)
+#define kb_putp(name, b, k) kb_putp_##name(b, k)
+#define kb_delp(name, b, k) kb_delp_##name(b, k)
+#define kb_intervalp(name, b, k, l, u) kb_intervalp_##name(b, k, l, u)
+
+#define kb_itr_first(name, b, i) kb_itr_first_##name(b, i)
+#define kb_itr_get(name, b, k, i) kb_itr_get_##name(b, k, i)
+#define kb_itr_getp(name, b, k, i) kb_itr_getp_##name(b, k, i)
+#define kb_itr_next(name, b, i) kb_itr_next_##name(b, i)
+#define kb_itr_prev(name, b, i) kb_itr_prev_##name(b, i)
+#define kb_del_itr(name, b, i) kb_del_itr_##name(b, i)
+#define kb_itr_key(itr) __KB_KEY(dummy, (itr)->p->x)[(itr)->p->i]
+#define kb_itr_valid(itr) ((itr)->p >= (itr)->stack)
+
+#define kb_size(b) ((b)->n_keys)
+
+#define kb_generic_cmp(a, b) (((b) < (a)) - ((a) < (b)))
+#define kb_str_cmp(a, b) strcmp(a, b)
+
+#endif // NVIM_LIB_KBTREE_H
diff --git a/src/nvim/log.c b/src/nvim/log.c
index bbb4dfb944..436a8a4079 100644
--- a/src/nvim/log.c
+++ b/src/nvim/log.c
@@ -1,23 +1,23 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
+#include <uv.h>
#include "nvim/log.h"
#include "nvim/types.h"
#include "nvim/os/os.h"
#include "nvim/os/time.h"
-/// First location of the log file used by log_path_init()
-#define USR_LOG_FILE "$NVIM_LOG_FILE"
-
-/// Fall back location of the log file used by log_path_init()
-#define USR_LOG_FILE_2 "$HOME" _PATHSEPSTR ".nvimlog"
+#define LOG_FILE_ENV "NVIM_LOG_FILE"
-/// Cached location of the log file set by log_path_init()
-static char expanded_log_file_path[MAXPATHL + 1] = { 0 };
+/// Cached location of the expanded log file path decided by log_path_init().
+static char log_file_path[MAXPATHL + 1] = { 0 };
static uv_mutex_t mutex;
@@ -25,31 +25,57 @@ static uv_mutex_t mutex;
# include "log.c.generated.h"
#endif
-/// Initialize path to log file
+#ifdef HAVE_EXECINFO_BACKTRACE
+# include <execinfo.h>
+#endif
+
+static bool log_try_create(char *fname)
+{
+ if (fname == NULL || fname[0] == '\0') {
+ return false;
+ }
+ FILE *log_file = fopen(fname, "a");
+ if (log_file == NULL) {
+ return false;
+ }
+ fclose(log_file);
+ return true;
+}
+
+/// Initializes path to log file. Sets $NVIM_LOG_FILE if empty.
///
-/// Tries to use #USR_LOG_FILE, then falls back #USR_LOG_FILE_2. Path to log
+/// Tries $NVIM_LOG_FILE, or falls back to $XDG_DATA_HOME/nvim/log. Path to log
/// file is cached, so only the first call has effect, unless first call was not
-/// successful. To make initialization not succeed either a bug in expand_env()
-/// is needed or both `$NVIM_LOG_FILE` and `$HOME` environment variables
-/// undefined.
+/// successful. Failed initialization indicates either a bug in expand_env()
+/// or both $NVIM_LOG_FILE and $HOME environment variables are undefined.
///
/// @return true if path was initialized, false otherwise.
static bool log_path_init(void)
{
- if (expanded_log_file_path[0]) {
+ if (log_file_path[0]) {
return true;
}
- expand_env((char_u *)USR_LOG_FILE, (char_u *)expanded_log_file_path,
- sizeof(expanded_log_file_path) - 1);
- // if the log file path expansion failed then fall back to stderr
- if (strcmp(USR_LOG_FILE, expanded_log_file_path) == 0) {
- memset(expanded_log_file_path, 0, sizeof(expanded_log_file_path));
- expand_env((char_u *)USR_LOG_FILE_2, (char_u *)expanded_log_file_path,
- sizeof(expanded_log_file_path) - 1);
- if (strcmp(USR_LOG_FILE_2, expanded_log_file_path) == 0) {
- memset(expanded_log_file_path, 0, sizeof(expanded_log_file_path));
+ size_t size = sizeof(log_file_path);
+ expand_env((char_u *)"$" LOG_FILE_ENV, (char_u *)log_file_path,
+ (int)size - 1);
+ if (strequal("$" LOG_FILE_ENV, log_file_path)
+ || log_file_path[0] == '\0'
+ || os_isdir((char_u *)log_file_path)
+ || !log_try_create(log_file_path)) {
+ // Invalid $NVIM_LOG_FILE or failed to expand; fall back to default.
+ char *defaultpath = stdpaths_user_data_subpath("log", 0, true);
+ size_t len = xstrlcpy(log_file_path, defaultpath, size);
+ xfree(defaultpath);
+ // Fall back to .nvimlog
+ if (len >= size || !log_try_create(log_file_path)) {
+ len = xstrlcpy(log_file_path, ".nvimlog", size);
+ }
+ // Fall back to stderr
+ if (len >= size || !log_try_create(log_file_path)) {
+ log_file_path[0] = '\0';
return false;
}
+ os_setenv(LOG_FILE_ENV, log_file_path, true);
}
return true;
}
@@ -72,6 +98,10 @@ void log_unlock(void)
bool do_log(int log_level, const char *func_name, int line_num, bool eol,
const char* fmt, ...) FUNC_ATTR_UNUSED
{
+ if (log_level < MIN_LOG_LEVEL) {
+ return false;
+ }
+
log_lock();
bool ret = false;
FILE *log_file = open_log_file();
@@ -94,26 +124,42 @@ end:
return ret;
}
+void log_uv_handles(void *loop)
+{
+ uv_loop_t *l = loop;
+ log_lock();
+ FILE *log_file = open_log_file();
+
+ if (log_file == NULL) {
+ goto end;
+ }
+
+ uv_print_all_handles(l, log_file);
+
+ if (log_file != stderr && log_file != stdout) {
+ fclose(log_file);
+ }
+end:
+ log_unlock();
+}
+
/// Open the log file for appending.
///
-/// @return The FILE* specified by the USR_LOG_FILE path or stderr in case of
-/// error
+/// @return FILE* decided by log_path_init() or stderr in case of error
FILE *open_log_file(void)
{
static bool opening_log_file = false;
-
// check if it's a recursive call
if (opening_log_file) {
do_log_to_file(stderr, ERROR_LOG_LEVEL, __func__, __LINE__, true,
- "Trying to LOG() recursively! Please fix it.");
+ "Cannot LOG() recursively.");
return stderr;
}
- // expand USR_LOG_FILE if needed and open the file
FILE *log_file = NULL;
opening_log_file = true;
if (log_path_init()) {
- log_file = fopen(expanded_log_file_path, "a");
+ log_file = fopen(log_file_path, "a");
}
opening_log_file = false;
@@ -121,13 +167,69 @@ FILE *open_log_file(void)
return log_file;
}
+ // May happen if:
+ // - LOG() is called before early_init()
+ // - Directory does not exist
+ // - File is not writable
do_log_to_file(stderr, ERROR_LOG_LEVEL, __func__, __LINE__, true,
- "Couldn't open USR_LOG_FILE, logging to stderr! This may be "
- "caused by attempting to LOG() before initialization "
- "functions are called (e.g. init_homedir()).");
+ "Logging to stderr, failed to open $" LOG_FILE_ENV ": %s",
+ log_file_path);
return stderr;
}
+#ifdef HAVE_EXECINFO_BACKTRACE
+void log_callstack_to_file(FILE *log_file, const char *const func_name,
+ const int line_num)
+{
+ void *trace[100];
+ int trace_size = backtrace(trace, ARRAY_SIZE(trace));
+
+ char exepath[MAXPATHL] = { 0 };
+ size_t exepathlen = MAXPATHL;
+ if (os_exepath(exepath, &exepathlen) != 0) {
+ abort();
+ }
+ assert(24 + exepathlen < IOSIZE); // Must fit in `cmdbuf` below.
+
+ char cmdbuf[IOSIZE + (20 * ARRAY_SIZE(trace))];
+ snprintf(cmdbuf, sizeof(cmdbuf), "addr2line -e %s -f -p", exepath);
+ for (int i = 1; i < trace_size; i++) {
+ char buf[20]; // 64-bit pointer 0xNNNNNNNNNNNNNNNN with leading space.
+ snprintf(buf, sizeof(buf), " %p", trace[i]);
+ xstrlcat(cmdbuf, buf, sizeof(cmdbuf));
+ }
+ // Now we have a command string like:
+ // addr2line -e /path/to/exe -f -p 0x123 0x456 ...
+
+ do_log_to_file(log_file, DEBUG_LOG_LEVEL, func_name, line_num, true,
+ "trace:");
+ FILE *fp = popen(cmdbuf, "r");
+ char linebuf[IOSIZE];
+ while (fgets(linebuf, sizeof(linebuf) - 1, fp) != NULL) {
+ fprintf(log_file, " %s", linebuf);
+ }
+ pclose(fp);
+
+ if (log_file != stderr && log_file != stdout) {
+ fclose(log_file);
+ }
+}
+
+void log_callstack(const char *const func_name, const int line_num)
+{
+ log_lock();
+ FILE *log_file = open_log_file();
+ if (log_file == NULL) {
+ goto end;
+ }
+
+ log_callstack_to_file(log_file, func_name, line_num);
+
+end:
+ log_unlock();
+}
+#endif
+
static bool do_log_to_file(FILE *log_file, int log_level,
const char *func_name, int line_num, bool eol,
const char* fmt, ...)
@@ -148,8 +250,8 @@ static bool v_do_log_to_file(FILE *log_file, int log_level,
static const char *log_levels[] = {
[DEBUG_LOG_LEVEL] = "DEBUG",
[INFO_LOG_LEVEL] = "INFO ",
- [WARNING_LOG_LEVEL] = "WARN ",
- [ERROR_LOG_LEVEL] = "ERROR"
+ [WARN_LOG_LEVEL] = "WARN ",
+ [ERROR_LOG_LEVEL] = "ERROR",
};
assert(log_level >= DEBUG_LOG_LEVEL && log_level <= ERROR_LOG_LEVEL);
diff --git a/src/nvim/log.h b/src/nvim/log.h
index 32b7276f14..d63bcc366c 100644
--- a/src/nvim/log.h
+++ b/src/nvim/log.h
@@ -6,7 +6,7 @@
#define DEBUG_LOG_LEVEL 0
#define INFO_LOG_LEVEL 1
-#define WARNING_LOG_LEVEL 2
+#define WARN_LOG_LEVEL 2
#define ERROR_LOG_LEVEL 3
#define DLOG(...)
@@ -18,55 +18,52 @@
#define ELOG(...)
#define ELOGN(...)
-// Logging is disabled if NDEBUG or DISABLE_LOG is defined.
-#if !defined(DISABLE_LOG) && defined(NDEBUG)
-# define DISABLE_LOG
-#endif
-
-// MIN_LOG_LEVEL can be defined during compilation to adjust the desired level
-// of logging. INFO_LOG_LEVEL is used by default.
#ifndef MIN_LOG_LEVEL
# define MIN_LOG_LEVEL INFO_LOG_LEVEL
#endif
-#ifndef DISABLE_LOG
+#define LOG(level, ...) do_log((level), __func__, __LINE__, true, \
+ __VA_ARGS__)
-# if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL
-# undef DLOG
-# undef DLOGN
-# define DLOG(...) do_log(DEBUG_LOG_LEVEL, __func__, __LINE__, true, \
- __VA_ARGS__)
-# define DLOGN(...) do_log(DEBUG_LOG_LEVEL, __func__, __LINE__, false, \
- __VA_ARGS__)
-# endif
+#if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL
+# undef DLOG
+# undef DLOGN
+# define DLOG(...) do_log(DEBUG_LOG_LEVEL, __func__, __LINE__, true, \
+ __VA_ARGS__)
+# define DLOGN(...) do_log(DEBUG_LOG_LEVEL, __func__, __LINE__, false, \
+ __VA_ARGS__)
+#endif
-# if MIN_LOG_LEVEL <= INFO_LOG_LEVEL
-# undef ILOG
-# undef ILOGN
-# define ILOG(...) do_log(INFO_LOG_LEVEL, __func__, __LINE__, true, \
- __VA_ARGS__)
-# define ILOGN(...) do_log(INFO_LOG_LEVEL, __func__, __LINE__, false, \
- __VA_ARGS__)
-# endif
+#if MIN_LOG_LEVEL <= INFO_LOG_LEVEL
+# undef ILOG
+# undef ILOGN
+# define ILOG(...) do_log(INFO_LOG_LEVEL, __func__, __LINE__, true, \
+ __VA_ARGS__)
+# define ILOGN(...) do_log(INFO_LOG_LEVEL, __func__, __LINE__, false, \
+ __VA_ARGS__)
+#endif
-# if MIN_LOG_LEVEL <= WARNING_LOG_LEVEL
-# undef WLOG
-# undef WLOGN
-# define WLOG(...) do_log(WARNING_LOG_LEVEL, __func__, __LINE__, true, \
- __VA_ARGS__)
-# define WLOGN(...) do_log(WARNING_LOG_LEVEL, __func__, __LINE__, false, \
- __VA_ARGS__)
-# endif
+#if MIN_LOG_LEVEL <= WARN_LOG_LEVEL
+# undef WLOG
+# undef WLOGN
+# define WLOG(...) do_log(WARN_LOG_LEVEL, __func__, __LINE__, true, \
+ __VA_ARGS__)
+# define WLOGN(...) do_log(WARN_LOG_LEVEL, __func__, __LINE__, false, \
+ __VA_ARGS__)
+#endif
-# if MIN_LOG_LEVEL <= ERROR_LOG_LEVEL
-# undef ELOG
-# undef ELOGN
-# define ELOG(...) do_log(ERROR_LOG_LEVEL, __func__, __LINE__, true, \
- __VA_ARGS__)
-# define ELOGN(...) do_log(ERROR_LOG_LEVEL, __func__, __LINE__, false, \
- __VA_ARGS__)
-# endif
+#if MIN_LOG_LEVEL <= ERROR_LOG_LEVEL
+# undef ELOG
+# undef ELOGN
+# define ELOG(...) do_log(ERROR_LOG_LEVEL, __func__, __LINE__, true, \
+ __VA_ARGS__)
+# define ELOGN(...) do_log(ERROR_LOG_LEVEL, __func__, __LINE__, false, \
+ __VA_ARGS__)
+#endif
+#ifdef HAVE_EXECINFO_BACKTRACE
+# define LOG_CALLSTACK() log_callstack(__func__, __LINE__)
+# define LOG_CALLSTACK_TO_FILE(fp) log_callstack_to_file(fp, __func__, __LINE__)
#endif
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c
new file mode 100644
index 0000000000..cacba3ce87
--- /dev/null
+++ b/src/nvim/lua/converter.c
@@ -0,0 +1,1189 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+#include <assert.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nvim/api/private/defs.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/func_attr.h"
+#include "nvim/memory.h"
+#include "nvim/assert.h"
+// FIXME: vim.h is not actually needed, but otherwise it states MAXPATHL is
+// redefined
+#include "nvim/vim.h"
+#include "nvim/globals.h"
+#include "nvim/message.h"
+#include "nvim/eval/typval.h"
+#include "nvim/ascii.h"
+#include "nvim/macros.h"
+
+#include "nvim/lib/kvec.h"
+#include "nvim/eval/decode.h"
+
+#include "nvim/lua/converter.h"
+#include "nvim/lua/executor.h"
+
+/// Determine, which keys lua table contains
+typedef struct {
+ size_t maxidx; ///< Maximum positive integral value found.
+ size_t string_keys_num; ///< Number of string keys.
+ bool has_string_with_nul; ///< True if there is string key with NUL byte.
+ ObjectType type; ///< If has_type_key is true then attached value. Otherwise
+ ///< either kObjectTypeNil, kObjectTypeDictionary or
+ ///< kObjectTypeArray, depending on other properties.
+ lua_Number val; ///< If has_val_key and val_type == LUA_TNUMBER: value.
+ bool has_type_key; ///< True if type key is present.
+} LuaTableProps;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "lua/converter.c.generated.h"
+#endif
+
+#define TYPE_IDX_VALUE true
+#define VAL_IDX_VALUE false
+
+#define LUA_PUSH_STATIC_STRING(lstate, s) \
+ lua_pushlstring(lstate, s, sizeof(s) - 1)
+
+static LuaTableProps nlua_traverse_table(lua_State *const lstate)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ size_t tsize = 0; // Total number of keys.
+ int val_type = 0; // If has_val_key: lua type of the value.
+ bool has_val_key = false; // True if val key was found,
+ // @see nlua_push_val_idx().
+ size_t other_keys_num = 0; // Number of keys that are not string, integral
+ // or type keys.
+ LuaTableProps ret;
+ memset(&ret, 0, sizeof(ret));
+ if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
+ emsgf(_("E1502: Lua failed to grow stack to %i"), lua_gettop(lstate) + 2);
+ ret.type = kObjectTypeNil;
+ return ret;
+ }
+ lua_pushnil(lstate);
+ while (lua_next(lstate, -2)) {
+ switch (lua_type(lstate, -2)) {
+ case LUA_TSTRING: {
+ size_t len;
+ const char *s = lua_tolstring(lstate, -2, &len);
+ if (memchr(s, NUL, len) != NULL) {
+ ret.has_string_with_nul = true;
+ }
+ ret.string_keys_num++;
+ break;
+ }
+ case LUA_TNUMBER: {
+ const lua_Number n = lua_tonumber(lstate, -2);
+ if (n > (lua_Number)SIZE_MAX || n <= 0
+ || ((lua_Number)((size_t)n)) != n) {
+ other_keys_num++;
+ } else {
+ const size_t idx = (size_t)n;
+ if (idx > ret.maxidx) {
+ ret.maxidx = idx;
+ }
+ }
+ break;
+ }
+ case LUA_TBOOLEAN: {
+ const bool b = lua_toboolean(lstate, -2);
+ if (b == TYPE_IDX_VALUE) {
+ if (lua_type(lstate, -1) == LUA_TNUMBER) {
+ lua_Number n = lua_tonumber(lstate, -1);
+ if (n == (lua_Number)kObjectTypeFloat
+ || n == (lua_Number)kObjectTypeArray
+ || n == (lua_Number)kObjectTypeDictionary) {
+ ret.has_type_key = true;
+ ret.type = (ObjectType)n;
+ } else {
+ other_keys_num++;
+ }
+ } else {
+ other_keys_num++;
+ }
+ } else {
+ has_val_key = true;
+ val_type = lua_type(lstate, -1);
+ if (val_type == LUA_TNUMBER) {
+ ret.val = lua_tonumber(lstate, -1);
+ }
+ }
+ break;
+ }
+ default: {
+ other_keys_num++;
+ break;
+ }
+ }
+ tsize++;
+ lua_pop(lstate, 1);
+ }
+ if (ret.has_type_key) {
+ if (ret.type == kObjectTypeFloat
+ && (!has_val_key || val_type != LUA_TNUMBER)) {
+ ret.type = kObjectTypeNil;
+ } else if (ret.type == kObjectTypeArray) {
+ // Determine what is the last number in a *sequence* of keys.
+ // This condition makes sure that Neovim will not crash when it gets table
+ // {[vim.type_idx]=vim.types.array, [SIZE_MAX]=1}: without it maxidx will
+ // be SIZE_MAX, with this condition it should be zero and [SIZE_MAX] key
+ // should be ignored.
+ if (ret.maxidx != 0
+ && ret.maxidx != (tsize
+ - ret.has_type_key
+ - other_keys_num
+ - has_val_key
+ - ret.string_keys_num)) {
+ for (ret.maxidx = 0;; ret.maxidx++) {
+ lua_rawgeti(lstate, -1, (int)ret.maxidx + 1);
+ if (lua_isnil(lstate, -1)) {
+ lua_pop(lstate, 1);
+ break;
+ }
+ lua_pop(lstate, 1);
+ }
+ }
+ }
+ } else {
+ if (tsize == 0
+ || (tsize == ret.maxidx
+ && other_keys_num == 0
+ && ret.string_keys_num == 0)) {
+ ret.type = kObjectTypeArray;
+ } else if (ret.string_keys_num == tsize) {
+ ret.type = kObjectTypeDictionary;
+ } else {
+ ret.type = kObjectTypeNil;
+ }
+ }
+ return ret;
+}
+
+/// Helper structure for nlua_pop_typval
+typedef struct {
+ typval_T *tv; ///< Location where conversion result is saved.
+ bool container; ///< True if tv is a container.
+ bool special; ///< If true then tv is a _VAL part of special dictionary
+ ///< that represents mapping.
+ int idx; ///< Container index (used to detect self-referencing structures).
+} TVPopStackItem;
+
+/// Convert lua object to VimL typval_T
+///
+/// Should pop exactly one value from lua stack.
+///
+/// @param lstate Lua state.
+/// @param[out] ret_tv Where to put the result.
+///
+/// @return `true` in case of success, `false` in case of failure. Error is
+/// reported automatically.
+bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
+{
+ bool ret = true;
+ const int initial_size = lua_gettop(lstate);
+ kvec_t(TVPopStackItem) stack = KV_INITIAL_VALUE;
+ kv_push(stack, ((TVPopStackItem) { ret_tv, false, false, 0 }));
+ while (ret && kv_size(stack)) {
+ if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
+ emsgf(_("E1502: Lua failed to grow stack to %i"), lua_gettop(lstate) + 3);
+ ret = false;
+ break;
+ }
+ TVPopStackItem cur = kv_pop(stack);
+ if (cur.container) {
+ if (cur.special || cur.tv->v_type == VAR_DICT) {
+ assert(cur.tv->v_type == (cur.special ? VAR_LIST : VAR_DICT));
+ bool next_key_found = false;
+ while (lua_next(lstate, -2)) {
+ if (lua_type(lstate, -2) == LUA_TSTRING) {
+ next_key_found = true;
+ break;
+ }
+ lua_pop(lstate, 1);
+ }
+ if (next_key_found) {
+ size_t len;
+ const char *s = lua_tolstring(lstate, -2, &len);
+ if (cur.special) {
+ list_T *const kv_pair = tv_list_alloc();
+ tv_list_append_list(cur.tv->vval.v_list, kv_pair);
+ listitem_T *const key = tv_list_item_alloc();
+ key->li_tv = decode_string(s, len, kTrue, false, false);
+ tv_list_append(kv_pair, key);
+ if (key->li_tv.v_type == VAR_UNKNOWN) {
+ ret = false;
+ tv_list_unref(kv_pair);
+ continue;
+ }
+ listitem_T *const val = tv_list_item_alloc();
+ tv_list_append(kv_pair, val);
+ kv_push(stack, cur);
+ cur = (TVPopStackItem) { &val->li_tv, false, false, 0 };
+ } else {
+ dictitem_T *const di = tv_dict_item_alloc_len(s, len);
+ if (tv_dict_add(cur.tv->vval.v_dict, di) == FAIL) {
+ assert(false);
+ }
+ kv_push(stack, cur);
+ cur = (TVPopStackItem) { &di->di_tv, false, false, 0 };
+ }
+ } else {
+ lua_pop(lstate, 1);
+ continue;
+ }
+ } else {
+ assert(cur.tv->v_type == VAR_LIST);
+ lua_rawgeti(lstate, -1, cur.tv->vval.v_list->lv_len + 1);
+ if (lua_isnil(lstate, -1)) {
+ lua_pop(lstate, 2);
+ continue;
+ }
+ listitem_T *const li = tv_list_item_alloc();
+ tv_list_append(cur.tv->vval.v_list, li);
+ kv_push(stack, cur);
+ cur = (TVPopStackItem) { &li->li_tv, false, false, 0 };
+ }
+ }
+ assert(!cur.container);
+ *cur.tv = (typval_T) {
+ .v_type = VAR_NUMBER,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_number = 0 },
+ };
+ switch (lua_type(lstate, -1)) {
+ case LUA_TNIL: {
+ cur.tv->v_type = VAR_SPECIAL;
+ cur.tv->vval.v_special = kSpecialVarNull;
+ break;
+ }
+ case LUA_TBOOLEAN: {
+ cur.tv->v_type = VAR_SPECIAL;
+ cur.tv->vval.v_special = (lua_toboolean(lstate, -1)
+ ? kSpecialVarTrue
+ : kSpecialVarFalse);
+ break;
+ }
+ case LUA_TSTRING: {
+ size_t len;
+ const char *s = lua_tolstring(lstate, -1, &len);
+ *cur.tv = decode_string(s, len, kNone, true, false);
+ if (cur.tv->v_type == VAR_UNKNOWN) {
+ ret = false;
+ }
+ break;
+ }
+ case LUA_TNUMBER: {
+ const lua_Number n = lua_tonumber(lstate, -1);
+ if (n > (lua_Number)VARNUMBER_MAX || n < (lua_Number)VARNUMBER_MIN
+ || ((lua_Number)((varnumber_T)n)) != n) {
+ cur.tv->v_type = VAR_FLOAT;
+ cur.tv->vval.v_float = (float_T)n;
+ } else {
+ cur.tv->v_type = VAR_NUMBER;
+ cur.tv->vval.v_number = (varnumber_T)n;
+ }
+ break;
+ }
+ case LUA_TTABLE: {
+ const LuaTableProps table_props = nlua_traverse_table(lstate);
+
+ for (size_t i = 0; i < kv_size(stack); i++) {
+ const TVPopStackItem item = kv_A(stack, i);
+ if (item.container && lua_rawequal(lstate, -1, item.idx)) {
+ tv_copy(item.tv, cur.tv);
+ cur.container = false;
+ goto nlua_pop_typval_table_processing_end;
+ }
+ }
+
+ switch (table_props.type) {
+ case kObjectTypeArray: {
+ cur.tv->v_type = VAR_LIST;
+ cur.tv->vval.v_list = tv_list_alloc();
+ cur.tv->vval.v_list->lv_refcount++;
+ if (table_props.maxidx != 0) {
+ cur.container = true;
+ cur.idx = lua_gettop(lstate);
+ kv_push(stack, cur);
+ }
+ break;
+ }
+ case kObjectTypeDictionary: {
+ if (table_props.string_keys_num == 0) {
+ cur.tv->v_type = VAR_DICT;
+ cur.tv->vval.v_dict = tv_dict_alloc();
+ cur.tv->vval.v_dict->dv_refcount++;
+ } else {
+ cur.special = table_props.has_string_with_nul;
+ if (table_props.has_string_with_nul) {
+ decode_create_map_special_dict(cur.tv);
+ assert(cur.tv->v_type == VAR_DICT);
+ dictitem_T *const val_di = tv_dict_find(cur.tv->vval.v_dict,
+ S_LEN("_VAL"));
+ assert(val_di != NULL);
+ cur.tv = &val_di->di_tv;
+ assert(cur.tv->v_type == VAR_LIST);
+ } else {
+ cur.tv->v_type = VAR_DICT;
+ cur.tv->vval.v_dict = tv_dict_alloc();
+ cur.tv->vval.v_dict->dv_refcount++;
+ }
+ cur.container = true;
+ cur.idx = lua_gettop(lstate);
+ kv_push(stack, cur);
+ lua_pushnil(lstate);
+ }
+ break;
+ }
+ case kObjectTypeFloat: {
+ cur.tv->v_type = VAR_FLOAT;
+ cur.tv->vval.v_float = (float_T)table_props.val;
+ break;
+ }
+ case kObjectTypeNil: {
+ EMSG(_("E5100: Cannot convert given lua table: table "
+ "should either have a sequence of positive integer keys "
+ "or contain only string keys"));
+ ret = false;
+ break;
+ }
+ default: {
+ assert(false);
+ }
+ }
+nlua_pop_typval_table_processing_end:
+ break;
+ }
+ default: {
+ EMSG(_("E5101: Cannot convert given lua type"));
+ ret = false;
+ break;
+ }
+ }
+ if (!cur.container) {
+ lua_pop(lstate, 1);
+ }
+ }
+ kv_destroy(stack);
+ if (!ret) {
+ tv_clear(ret_tv);
+ *ret_tv = (typval_T) {
+ .v_type = VAR_NUMBER,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_number = 0 },
+ };
+ lua_pop(lstate, lua_gettop(lstate) - initial_size + 1);
+ }
+ assert(lua_gettop(lstate) == initial_size - 1);
+ return ret;
+}
+
+#define TYPVAL_ENCODE_ALLOW_SPECIALS true
+
+#define TYPVAL_ENCODE_CONV_NIL(tv) \
+ lua_pushnil(lstate)
+
+#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
+ lua_pushboolean(lstate, (bool)(num))
+
+#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
+ lua_pushnumber(lstate, (lua_Number)(num))
+
+#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER TYPVAL_ENCODE_CONV_NUMBER
+
+#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
+ TYPVAL_ENCODE_CONV_NUMBER(tv, flt)
+
+#define TYPVAL_ENCODE_CONV_STRING(tv, str, len) \
+ lua_pushlstring(lstate, (const char *)(str), (len))
+
+#define TYPVAL_ENCODE_CONV_STR_STRING TYPVAL_ENCODE_CONV_STRING
+
+#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, str, len, type) \
+ TYPVAL_ENCODE_CONV_NIL()
+
+#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
+ do { \
+ TYPVAL_ENCODE_CONV_NIL(tv); \
+ goto typval_encode_stop_converting_one_item; \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
+#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
+#define TYPVAL_ENCODE_CONV_FUNC_END(tv)
+
+#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
+ lua_createtable(lstate, 0, 0)
+
+#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
+ nlua_create_typed_table(lstate, 0, 0, kObjectTypeDictionary)
+
+#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
+ do { \
+ if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) { \
+ emsgf(_("E5102: Lua failed to grow stack to %i"), \
+ lua_gettop(lstate) + 3); \
+ return false; \
+ } \
+ lua_createtable(lstate, (int)(len), 0); \
+ lua_pushnumber(lstate, 1); \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
+
+#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv) \
+ do { \
+ lua_Number idx = lua_tonumber(lstate, -2); \
+ lua_rawset(lstate, -3); \
+ lua_pushnumber(lstate, idx + 1); \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_LIST_END(tv) \
+ lua_rawset(lstate, -3)
+
+#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
+ do { \
+ if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) { \
+ emsgf(_("E5102: Lua failed to grow stack to %i"), \
+ lua_gettop(lstate) + 3); \
+ return false; \
+ } \
+ lua_createtable(lstate, 0, (int)(len)); \
+ } while (0)
+
+#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, kv_pair)
+
+#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv)
+
+#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict)
+
+#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict) \
+ lua_rawset(lstate, -3)
+
+#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
+ TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict)
+
+#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
+ do { \
+ for (size_t backref = kv_size(*mpstack); backref; backref--) { \
+ const MPConvStackVal mpval = kv_A(*mpstack, backref - 1); \
+ if (mpval.type == conv_type) { \
+ if (conv_type == kMPConvDict \
+ ? (void *)mpval.data.d.dict == (void *)(val) \
+ : (void *)mpval.data.l.list == (void *)(val)) { \
+ lua_pushvalue(lstate, \
+ -((int)((kv_size(*mpstack) - backref + 1) * 2))); \
+ break; \
+ } \
+ } \
+ } \
+ } while (0)
+
+#define TYPVAL_ENCODE_SCOPE static
+#define TYPVAL_ENCODE_NAME lua
+#define TYPVAL_ENCODE_FIRST_ARG_TYPE lua_State *const
+#define TYPVAL_ENCODE_FIRST_ARG_NAME lstate
+#include "nvim/eval/typval_encode.c.h"
+#undef TYPVAL_ENCODE_SCOPE
+#undef TYPVAL_ENCODE_NAME
+#undef TYPVAL_ENCODE_FIRST_ARG_TYPE
+#undef TYPVAL_ENCODE_FIRST_ARG_NAME
+
+#undef TYPVAL_ENCODE_CONV_STRING
+#undef TYPVAL_ENCODE_CONV_STR_STRING
+#undef TYPVAL_ENCODE_CONV_EXT_STRING
+#undef TYPVAL_ENCODE_CONV_NUMBER
+#undef TYPVAL_ENCODE_CONV_FLOAT
+#undef TYPVAL_ENCODE_CONV_FUNC_START
+#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS
+#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF
+#undef TYPVAL_ENCODE_CONV_FUNC_END
+#undef TYPVAL_ENCODE_CONV_EMPTY_LIST
+#undef TYPVAL_ENCODE_CONV_LIST_START
+#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
+#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
+#undef TYPVAL_ENCODE_CONV_NIL
+#undef TYPVAL_ENCODE_CONV_BOOL
+#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
+#undef TYPVAL_ENCODE_CONV_DICT_START
+#undef TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START
+#undef TYPVAL_ENCODE_CONV_DICT_END
+#undef TYPVAL_ENCODE_CONV_DICT_AFTER_KEY
+#undef TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS
+#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
+#undef TYPVAL_ENCODE_CONV_LIST_END
+#undef TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
+#undef TYPVAL_ENCODE_CONV_RECURSE
+#undef TYPVAL_ENCODE_ALLOW_SPECIALS
+
+/// Convert VimL typval_T to lua value
+///
+/// Should leave single value in lua stack. May only fail if lua failed to grow
+/// stack.
+///
+/// @param lstate Lua interpreter state.
+/// @param[in] tv typval_T to convert.
+///
+/// @return true in case of success, false otherwise.
+bool nlua_push_typval(lua_State *lstate, typval_T *const tv)
+{
+ const int initial_size = lua_gettop(lstate);
+ if (!lua_checkstack(lstate, initial_size + 2)) {
+ emsgf(_("E1502: Lua failed to grow stack to %i"), initial_size + 4);
+ return false;
+ }
+ if (encode_vim_to_lua(lstate, tv, "nlua_push_typval argument") == FAIL) {
+ return false;
+ }
+ assert(lua_gettop(lstate) == initial_size + 1);
+ return true;
+}
+
+/// Push value which is a type index
+///
+/// Used for all “typed†tables: i.e. for all tables which represent VimL
+/// values.
+static inline void nlua_push_type_idx(lua_State *lstate)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_pushboolean(lstate, TYPE_IDX_VALUE);
+}
+
+/// Push value which is a value index
+///
+/// Used for tables which represent scalar values, like float value.
+static inline void nlua_push_val_idx(lua_State *lstate)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_pushboolean(lstate, VAL_IDX_VALUE);
+}
+
+/// Push type
+///
+/// Type is a value in vim.types table.
+///
+/// @param[out] lstate Lua state.
+/// @param[in] type Type to push.
+static inline void nlua_push_type(lua_State *lstate, ObjectType type)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_pushnumber(lstate, (lua_Number)type);
+}
+
+/// Create lua table which has an entry that determines its VimL type
+///
+/// @param[out] lstate Lua state.
+/// @param[in] narr Number of “array†entries to be populated later.
+/// @param[in] nrec Number of “dictionary†entries to be populated later.
+/// @param[in] type Type of the table.
+static inline void nlua_create_typed_table(lua_State *lstate,
+ const size_t narr,
+ const size_t nrec,
+ const ObjectType type)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_createtable(lstate, (int)narr, (int)(1 + nrec));
+ nlua_push_type_idx(lstate);
+ nlua_push_type(lstate, type);
+ lua_rawset(lstate, -3);
+}
+
+
+/// Convert given String to lua string
+///
+/// Leaves converted string on top of the stack.
+void nlua_push_String(lua_State *lstate, const String s)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_pushlstring(lstate, s.data, s.size);
+}
+
+/// Convert given Integer to lua number
+///
+/// Leaves converted number on top of the stack.
+void nlua_push_Integer(lua_State *lstate, const Integer n)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_pushnumber(lstate, (lua_Number)n);
+}
+
+/// Convert given Float to lua table
+///
+/// Leaves converted table on top of the stack.
+void nlua_push_Float(lua_State *lstate, const Float f)
+ FUNC_ATTR_NONNULL_ALL
+{
+ nlua_create_typed_table(lstate, 0, 1, kObjectTypeFloat);
+ nlua_push_val_idx(lstate);
+ lua_pushnumber(lstate, (lua_Number)f);
+ lua_rawset(lstate, -3);
+}
+
+/// Convert given Float to lua boolean
+///
+/// Leaves converted value on top of the stack.
+void nlua_push_Boolean(lua_State *lstate, const Boolean b)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_pushboolean(lstate, b);
+}
+
+/// Convert given Dictionary to lua table
+///
+/// Leaves converted table on top of the stack.
+void nlua_push_Dictionary(lua_State *lstate, const Dictionary dict)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (dict.size == 0) {
+ nlua_create_typed_table(lstate, 0, 0, kObjectTypeDictionary);
+ } else {
+ lua_createtable(lstate, 0, (int)dict.size);
+ }
+ for (size_t i = 0; i < dict.size; i++) {
+ nlua_push_String(lstate, dict.items[i].key);
+ nlua_push_Object(lstate, dict.items[i].value);
+ lua_rawset(lstate, -3);
+ }
+}
+
+/// Convert given Array to lua table
+///
+/// Leaves converted table on top of the stack.
+void nlua_push_Array(lua_State *lstate, const Array array)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_createtable(lstate, (int)array.size, 0);
+ for (size_t i = 0; i < array.size; i++) {
+ nlua_push_Object(lstate, array.items[i]);
+ lua_rawseti(lstate, -2, (int)i + 1);
+ }
+}
+
+#define GENERATE_INDEX_FUNCTION(type) \
+void nlua_push_##type(lua_State *lstate, const type item) \
+ FUNC_ATTR_NONNULL_ALL \
+{ \
+ lua_pushnumber(lstate, (lua_Number)(item)); \
+}
+
+GENERATE_INDEX_FUNCTION(Buffer)
+GENERATE_INDEX_FUNCTION(Window)
+GENERATE_INDEX_FUNCTION(Tabpage)
+
+#undef GENERATE_INDEX_FUNCTION
+
+/// Convert given Object to lua value
+///
+/// Leaves converted value on top of the stack.
+void nlua_push_Object(lua_State *lstate, const Object obj)
+ FUNC_ATTR_NONNULL_ALL
+{
+ switch (obj.type) {
+ case kObjectTypeNil: {
+ lua_pushnil(lstate);
+ break;
+ }
+#define ADD_TYPE(type, data_key) \
+ case kObjectType##type: { \
+ nlua_push_##type(lstate, obj.data.data_key); \
+ break; \
+ }
+ ADD_TYPE(Boolean, boolean)
+ ADD_TYPE(Integer, integer)
+ ADD_TYPE(Float, floating)
+ ADD_TYPE(String, string)
+ ADD_TYPE(Array, array)
+ ADD_TYPE(Dictionary, dictionary)
+#undef ADD_TYPE
+#define ADD_REMOTE_TYPE(type) \
+ case kObjectType##type: { \
+ nlua_push_##type(lstate, (type)obj.data.integer); \
+ break; \
+ }
+ ADD_REMOTE_TYPE(Buffer)
+ ADD_REMOTE_TYPE(Window)
+ ADD_REMOTE_TYPE(Tabpage)
+#undef ADD_REMOTE_TYPE
+ }
+}
+
+
+/// Convert lua value to string
+///
+/// Always pops one value from the stack.
+String nlua_pop_String(lua_State *lstate, Error *err)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (lua_type(lstate, -1) != LUA_TSTRING) {
+ lua_pop(lstate, 1);
+ api_set_error(err, kErrorTypeValidation, "Expected lua string");
+ return (String) { .size = 0, .data = NULL };
+ }
+ String ret;
+
+ ret.data = (char *)lua_tolstring(lstate, -1, &(ret.size));
+ assert(ret.data != NULL);
+ ret.data = xmemdupz(ret.data, ret.size);
+ lua_pop(lstate, 1);
+
+ return ret;
+}
+
+/// Convert lua value to integer
+///
+/// Always pops one value from the stack.
+Integer nlua_pop_Integer(lua_State *lstate, Error *err)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (lua_type(lstate, -1) != LUA_TNUMBER) {
+ lua_pop(lstate, 1);
+ api_set_error(err, kErrorTypeValidation, "Expected lua number");
+ return 0;
+ }
+ const lua_Number n = lua_tonumber(lstate, -1);
+ lua_pop(lstate, 1);
+ if (n > (lua_Number)API_INTEGER_MAX || n < (lua_Number)API_INTEGER_MIN
+ || ((lua_Number)((Integer)n)) != n) {
+ api_set_error(err, kErrorTypeException, "Number is not integral");
+ return 0;
+ }
+ return (Integer)n;
+}
+
+/// Convert lua value to boolean
+///
+/// Always pops one value from the stack.
+Boolean nlua_pop_Boolean(lua_State *lstate, Error *err)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const Boolean ret = lua_toboolean(lstate, -1);
+ lua_pop(lstate, 1);
+ return ret;
+}
+
+/// Check whether typed table on top of the stack has given type
+///
+/// @param[in] lstate Lua state.
+/// @param[out] err Location where error will be saved. May be NULL.
+/// @param[in] type Type to check.
+///
+/// @return @see nlua_traverse_table().
+static inline LuaTableProps nlua_check_type(lua_State *const lstate,
+ Error *const err,
+ const ObjectType type)
+ FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (lua_type(lstate, -1) != LUA_TTABLE) {
+ if (err) {
+ api_set_error(err, kErrorTypeValidation, "Expected lua table");
+ }
+ return (LuaTableProps) { .type = kObjectTypeNil };
+ }
+ LuaTableProps table_props = nlua_traverse_table(lstate);
+
+ if (type == kObjectTypeDictionary && table_props.type == kObjectTypeArray
+ && table_props.maxidx == 0 && !table_props.has_type_key) {
+ table_props.type = kObjectTypeDictionary;
+ }
+
+ if (table_props.type != type) {
+ if (err) {
+ api_set_error(err, kErrorTypeValidation, "Unexpected type");
+ }
+ }
+
+ return table_props;
+}
+
+/// Convert lua table to float
+///
+/// Always pops one value from the stack.
+Float nlua_pop_Float(lua_State *lstate, Error *err)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (lua_type(lstate, -1) == LUA_TNUMBER) {
+ const Float ret = (Float)lua_tonumber(lstate, -1);
+ lua_pop(lstate, 1);
+ return ret;
+ }
+
+ const LuaTableProps table_props = nlua_check_type(lstate, err,
+ kObjectTypeFloat);
+ lua_pop(lstate, 1);
+ if (table_props.type != kObjectTypeFloat) {
+ return 0;
+ } else {
+ return (Float)table_props.val;
+ }
+}
+
+/// Convert lua table to array without determining whether it is array
+///
+/// @param lstate Lua state.
+/// @param[in] table_props nlua_traverse_table() output.
+/// @param[out] err Location where error will be saved.
+static Array nlua_pop_Array_unchecked(lua_State *const lstate,
+ const LuaTableProps table_props,
+ Error *const err)
+{
+ Array ret = { .size = table_props.maxidx, .items = NULL };
+
+ if (ret.size == 0) {
+ lua_pop(lstate, 1);
+ return ret;
+ }
+
+ ret.items = xcalloc(ret.size, sizeof(*ret.items));
+ for (size_t i = 1; i <= ret.size; i++) {
+ Object val;
+
+ lua_rawgeti(lstate, -1, (int)i);
+
+ val = nlua_pop_Object(lstate, err);
+ if (ERROR_SET(err)) {
+ ret.size = i - 1;
+ lua_pop(lstate, 1);
+ api_free_array(ret);
+ return (Array) { .size = 0, .items = NULL };
+ }
+ ret.items[i - 1] = val;
+ }
+ lua_pop(lstate, 1);
+
+ return ret;
+}
+
+/// Convert lua table to array
+///
+/// Always pops one value from the stack.
+Array nlua_pop_Array(lua_State *lstate, Error *err)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const LuaTableProps table_props = nlua_check_type(lstate, err,
+ kObjectTypeArray);
+ if (table_props.type != kObjectTypeArray) {
+ return (Array) { .size = 0, .items = NULL };
+ }
+ return nlua_pop_Array_unchecked(lstate, table_props, err);
+}
+
+/// Convert lua table to dictionary
+///
+/// Always pops one value from the stack. Does not check whether whether topmost
+/// value on the stack is a table.
+///
+/// @param lstate Lua interpreter state.
+/// @param[in] table_props nlua_traverse_table() output.
+/// @param[out] err Location where error will be saved.
+static Dictionary nlua_pop_Dictionary_unchecked(lua_State *lstate,
+ const LuaTableProps table_props,
+ Error *err)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ Dictionary ret = { .size = table_props.string_keys_num, .items = NULL };
+
+ if (ret.size == 0) {
+ lua_pop(lstate, 1);
+ return ret;
+ }
+ ret.items = xcalloc(ret.size, sizeof(*ret.items));
+
+ lua_pushnil(lstate);
+ for (size_t i = 0; lua_next(lstate, -2) && i < ret.size;) {
+ // stack: dict, key, value
+
+ if (lua_type(lstate, -2) == LUA_TSTRING) {
+ lua_pushvalue(lstate, -2);
+ // stack: dict, key, value, key
+
+ ret.items[i].key = nlua_pop_String(lstate, err);
+ // stack: dict, key, value
+
+ if (!ERROR_SET(err)) {
+ ret.items[i].value = nlua_pop_Object(lstate, err);
+ // stack: dict, key
+ } else {
+ lua_pop(lstate, 1);
+ // stack: dict, key
+ }
+
+ if (ERROR_SET(err)) {
+ ret.size = i;
+ api_free_dictionary(ret);
+ lua_pop(lstate, 2);
+ // stack:
+ return (Dictionary) { .size = 0, .items = NULL };
+ }
+ i++;
+ } else {
+ lua_pop(lstate, 1);
+ // stack: dict, key
+ }
+ }
+ lua_pop(lstate, 1);
+
+ return ret;
+}
+
+/// Convert lua table to dictionary
+///
+/// Always pops one value from the stack.
+Dictionary nlua_pop_Dictionary(lua_State *lstate, Error *err)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const LuaTableProps table_props = nlua_check_type(lstate, err,
+ kObjectTypeDictionary);
+ if (table_props.type != kObjectTypeDictionary) {
+ lua_pop(lstate, 1);
+ return (Dictionary) { .size = 0, .items = NULL };
+ }
+
+ return nlua_pop_Dictionary_unchecked(lstate, table_props, err);
+}
+
+/// Helper structure for nlua_pop_Object
+typedef struct {
+ Object *obj; ///< Location where conversion result is saved.
+ bool container; ///< True if tv is a container.
+} ObjPopStackItem;
+
+/// Convert lua table to object
+///
+/// Always pops one value from the stack.
+Object nlua_pop_Object(lua_State *const lstate, Error *const err)
+{
+ Object ret = NIL;
+ const int initial_size = lua_gettop(lstate);
+ kvec_t(ObjPopStackItem) stack = KV_INITIAL_VALUE;
+ kv_push(stack, ((ObjPopStackItem) { &ret, false }));
+ while (!ERROR_SET(err) && kv_size(stack)) {
+ if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
+ api_set_error(err, kErrorTypeException, "Lua failed to grow stack");
+ break;
+ }
+ ObjPopStackItem cur = kv_pop(stack);
+ if (cur.container) {
+ if (cur.obj->type == kObjectTypeDictionary) {
+ // stack: …, dict, key
+ if (cur.obj->data.dictionary.size
+ == cur.obj->data.dictionary.capacity) {
+ lua_pop(lstate, 2);
+ continue;
+ }
+ bool next_key_found = false;
+ while (lua_next(lstate, -2)) {
+ // stack: …, dict, new key, val
+ if (lua_type(lstate, -2) == LUA_TSTRING) {
+ next_key_found = true;
+ break;
+ }
+ lua_pop(lstate, 1);
+ // stack: …, dict, new key
+ }
+ if (next_key_found) {
+ // stack: …, dict, new key, val
+ size_t len;
+ const char *s = lua_tolstring(lstate, -2, &len);
+ const size_t idx = cur.obj->data.dictionary.size++;
+ cur.obj->data.dictionary.items[idx].key = (String) {
+ .data = xmemdupz(s, len),
+ .size = len,
+ };
+ kv_push(stack, cur);
+ cur = (ObjPopStackItem) {
+ .obj = &cur.obj->data.dictionary.items[idx].value,
+ .container = false,
+ };
+ } else {
+ // stack: …, dict
+ lua_pop(lstate, 1);
+ // stack: …
+ continue;
+ }
+ } else {
+ if (cur.obj->data.array.size == cur.obj->data.array.capacity) {
+ lua_pop(lstate, 1);
+ continue;
+ }
+ const size_t idx = cur.obj->data.array.size++;
+ lua_rawgeti(lstate, -1, (int)idx + 1);
+ if (lua_isnil(lstate, -1)) {
+ lua_pop(lstate, 2);
+ continue;
+ }
+ kv_push(stack, cur);
+ cur = (ObjPopStackItem) {
+ .obj = &cur.obj->data.array.items[idx],
+ .container = false,
+ };
+ }
+ }
+ assert(!cur.container);
+ *cur.obj = NIL;
+ switch (lua_type(lstate, -1)) {
+ case LUA_TNIL: {
+ break;
+ }
+ case LUA_TBOOLEAN: {
+ *cur.obj = BOOLEAN_OBJ(lua_toboolean(lstate, -1));
+ break;
+ }
+ case LUA_TSTRING: {
+ size_t len;
+ const char *s = lua_tolstring(lstate, -1, &len);
+ *cur.obj = STRING_OBJ(((String) {
+ .data = xmemdupz(s, len),
+ .size = len,
+ }));
+ break;
+ }
+ case LUA_TNUMBER: {
+ const lua_Number n = lua_tonumber(lstate, -1);
+ if (n > (lua_Number)API_INTEGER_MAX || n < (lua_Number)API_INTEGER_MIN
+ || ((lua_Number)((Integer)n)) != n) {
+ *cur.obj = FLOAT_OBJ((Float)n);
+ } else {
+ *cur.obj = INTEGER_OBJ((Integer)n);
+ }
+ break;
+ }
+ case LUA_TTABLE: {
+ const LuaTableProps table_props = nlua_traverse_table(lstate);
+
+ switch (table_props.type) {
+ case kObjectTypeArray: {
+ *cur.obj = ARRAY_OBJ(((Array) {
+ .items = NULL,
+ .size = 0,
+ .capacity = 0,
+ }));
+ if (table_props.maxidx != 0) {
+ cur.obj->data.array.items =
+ xcalloc(table_props.maxidx,
+ sizeof(cur.obj->data.array.items[0]));
+ cur.obj->data.array.capacity = table_props.maxidx;
+ cur.container = true;
+ kv_push(stack, cur);
+ }
+ break;
+ }
+ case kObjectTypeDictionary: {
+ *cur.obj = DICTIONARY_OBJ(((Dictionary) {
+ .items = NULL,
+ .size = 0,
+ .capacity = 0,
+ }));
+ if (table_props.string_keys_num != 0) {
+ cur.obj->data.dictionary.items =
+ xcalloc(table_props.string_keys_num,
+ sizeof(cur.obj->data.dictionary.items[0]));
+ cur.obj->data.dictionary.capacity = table_props.string_keys_num;
+ cur.container = true;
+ kv_push(stack, cur);
+ lua_pushnil(lstate);
+ }
+ break;
+ }
+ case kObjectTypeFloat: {
+ *cur.obj = FLOAT_OBJ((Float)table_props.val);
+ break;
+ }
+ case kObjectTypeNil: {
+ api_set_error(err, kErrorTypeValidation,
+ "Cannot convert given lua table");
+ break;
+ }
+ default: {
+ assert(false);
+ }
+ }
+ break;
+ }
+ default: {
+ api_set_error(err, kErrorTypeValidation,
+ "Cannot convert given lua type");
+ break;
+ }
+ }
+ if (!cur.container) {
+ lua_pop(lstate, 1);
+ }
+ }
+ kv_destroy(stack);
+ if (ERROR_SET(err)) {
+ api_free_object(ret);
+ ret = NIL;
+ lua_pop(lstate, lua_gettop(lstate) - initial_size + 1);
+ }
+ assert(lua_gettop(lstate) == initial_size - 1);
+ return ret;
+}
+
+#define GENERATE_INDEX_FUNCTION(type) \
+type nlua_pop_##type(lua_State *lstate, Error *err) \
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT \
+{ \
+ type ret; \
+ ret = (type)lua_tonumber(lstate, -1); \
+ lua_pop(lstate, 1); \
+ return ret; \
+}
+
+GENERATE_INDEX_FUNCTION(Buffer)
+GENERATE_INDEX_FUNCTION(Window)
+GENERATE_INDEX_FUNCTION(Tabpage)
+
+#undef GENERATE_INDEX_FUNCTION
+
+/// Record some auxilary values in vim module
+///
+/// Assumes that module table is on top of the stack.
+///
+/// Recorded values:
+///
+/// `vim.type_idx`: @see nlua_push_type_idx()
+/// `vim.val_idx`: @see nlua_push_val_idx()
+/// `vim.types`: table mapping possible values of `vim.type_idx` to string
+/// names (i.e. `array`, `float`, `dictionary`) and back.
+void nlua_init_types(lua_State *const lstate)
+{
+ LUA_PUSH_STATIC_STRING(lstate, "type_idx");
+ nlua_push_type_idx(lstate);
+ lua_rawset(lstate, -3);
+
+ LUA_PUSH_STATIC_STRING(lstate, "val_idx");
+ nlua_push_val_idx(lstate);
+ lua_rawset(lstate, -3);
+
+ LUA_PUSH_STATIC_STRING(lstate, "types");
+ lua_createtable(lstate, 0, 3);
+
+ LUA_PUSH_STATIC_STRING(lstate, "float");
+ lua_pushnumber(lstate, (lua_Number)kObjectTypeFloat);
+ lua_rawset(lstate, -3);
+ lua_pushnumber(lstate, (lua_Number)kObjectTypeFloat);
+ LUA_PUSH_STATIC_STRING(lstate, "float");
+ lua_rawset(lstate, -3);
+
+ LUA_PUSH_STATIC_STRING(lstate, "array");
+ lua_pushnumber(lstate, (lua_Number)kObjectTypeArray);
+ lua_rawset(lstate, -3);
+ lua_pushnumber(lstate, (lua_Number)kObjectTypeArray);
+ LUA_PUSH_STATIC_STRING(lstate, "array");
+ lua_rawset(lstate, -3);
+
+ LUA_PUSH_STATIC_STRING(lstate, "dictionary");
+ lua_pushnumber(lstate, (lua_Number)kObjectTypeDictionary);
+ lua_rawset(lstate, -3);
+ lua_pushnumber(lstate, (lua_Number)kObjectTypeDictionary);
+ LUA_PUSH_STATIC_STRING(lstate, "dictionary");
+ lua_rawset(lstate, -3);
+
+ lua_rawset(lstate, -3);
+}
diff --git a/src/nvim/lua/converter.h b/src/nvim/lua/converter.h
new file mode 100644
index 0000000000..542c56ea3e
--- /dev/null
+++ b/src/nvim/lua/converter.h
@@ -0,0 +1,15 @@
+#ifndef NVIM_LUA_CONVERTER_H
+#define NVIM_LUA_CONVERTER_H
+
+#include <lua.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nvim/api/private/defs.h"
+#include "nvim/func_attr.h"
+#include "nvim/eval.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "lua/converter.h.generated.h"
+#endif
+#endif // NVIM_LUA_CONVERTER_H
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
new file mode 100644
index 0000000000..eb821f7831
--- /dev/null
+++ b/src/nvim/lua/executor.c
@@ -0,0 +1,662 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "nvim/misc1.h"
+#include "nvim/getchar.h"
+#include "nvim/garray.h"
+#include "nvim/func_attr.h"
+#include "nvim/api/private/defs.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/vim.h"
+#include "nvim/vim.h"
+#include "nvim/ex_getln.h"
+#include "nvim/ex_cmds2.h"
+#include "nvim/message.h"
+#include "nvim/memline.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/macros.h"
+#include "nvim/screen.h"
+#include "nvim/cursor.h"
+#include "nvim/undo.h"
+#include "nvim/ascii.h"
+
+#include "nvim/lua/executor.h"
+#include "nvim/lua/converter.h"
+
+typedef struct {
+ Error err;
+ String lua_err_str;
+} LuaError;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "lua/vim_module.generated.h"
+# include "lua/executor.c.generated.h"
+#endif
+
+/// Name of the run code for use in messages
+#define NLUA_EVAL_NAME "<VimL compiled string>"
+
+/// Call C function which does not expect any arguments
+///
+/// @param function Called function
+/// @param numret Number of returned arguments
+#define NLUA_CALL_C_FUNCTION_0(lstate, function, numret) \
+ do { \
+ lua_pushcfunction(lstate, &function); \
+ lua_call(lstate, 0, numret); \
+ } while (0)
+/// Call C function which expects one argument
+///
+/// @param function Called function
+/// @param numret Number of returned arguments
+/// @param a… Supplied argument (should be a void* pointer)
+#define NLUA_CALL_C_FUNCTION_1(lstate, function, numret, a1) \
+ do { \
+ lua_pushcfunction(lstate, &function); \
+ lua_pushlightuserdata(lstate, a1); \
+ lua_call(lstate, 1, numret); \
+ } while (0)
+/// Call C function which expects two arguments
+///
+/// @param function Called function
+/// @param numret Number of returned arguments
+/// @param a… Supplied argument (should be a void* pointer)
+#define NLUA_CALL_C_FUNCTION_2(lstate, function, numret, a1, a2) \
+ do { \
+ lua_pushcfunction(lstate, &function); \
+ lua_pushlightuserdata(lstate, a1); \
+ lua_pushlightuserdata(lstate, a2); \
+ lua_call(lstate, 2, numret); \
+ } while (0)
+/// Call C function which expects three arguments
+///
+/// @param function Called function
+/// @param numret Number of returned arguments
+/// @param a… Supplied argument (should be a void* pointer)
+#define NLUA_CALL_C_FUNCTION_3(lstate, function, numret, a1, a2, a3) \
+ do { \
+ lua_pushcfunction(lstate, &function); \
+ lua_pushlightuserdata(lstate, a1); \
+ lua_pushlightuserdata(lstate, a2); \
+ lua_pushlightuserdata(lstate, a3); \
+ lua_call(lstate, 3, numret); \
+ } while (0)
+/// Call C function which expects five arguments
+///
+/// @param function Called function
+/// @param numret Number of returned arguments
+/// @param a… Supplied argument (should be a void* pointer)
+#define NLUA_CALL_C_FUNCTION_4(lstate, function, numret, a1, a2, a3, a4) \
+ do { \
+ lua_pushcfunction(lstate, &function); \
+ lua_pushlightuserdata(lstate, a1); \
+ lua_pushlightuserdata(lstate, a2); \
+ lua_pushlightuserdata(lstate, a3); \
+ lua_pushlightuserdata(lstate, a4); \
+ lua_call(lstate, 4, numret); \
+ } while (0)
+
+/// Convert lua error into a Vim error message
+///
+/// @param lstate Lua interpreter state.
+/// @param[in] msg Message base, must contain one `%s`.
+static void nlua_error(lua_State *const lstate, const char *const msg)
+ FUNC_ATTR_NONNULL_ALL
+{
+ size_t len;
+ const char *const str = lua_tolstring(lstate, -1, &len);
+
+ emsgf(msg, (int)len, str);
+
+ lua_pop(lstate, 1);
+}
+
+/// Compare two strings, ignoring case
+///
+/// Expects two values on the stack: compared strings. Returns one of the
+/// following numbers: 0, -1 or 1.
+///
+/// Does no error handling: never call it with non-string or with some arguments
+/// omitted.
+static int nlua_stricmp(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
+{
+ const char *s1 = luaL_checklstring(lstate, 1, NULL);
+ const char *s2 = luaL_checklstring(lstate, 2, NULL);
+ const int ret = STRICMP(s1, s2);
+ lua_pop(lstate, 2);
+ lua_pushnumber(lstate, (lua_Number)((ret > 0) - (ret < 0)));
+ return 1;
+}
+
+/// Evaluate lua string
+///
+/// Expects two values on the stack: string to evaluate, pointer to the
+/// location where result is saved. Always returns nothing (from the lua point
+/// of view).
+static int nlua_exec_lua_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
+{
+ const String *const str = (const String *)lua_touserdata(lstate, 1);
+ typval_T *const ret_tv = (typval_T *)lua_touserdata(lstate, 2);
+ lua_pop(lstate, 2);
+
+ if (luaL_loadbuffer(lstate, str->data, str->size, NLUA_EVAL_NAME)) {
+ nlua_error(lstate, _("E5104: Error while creating lua chunk: %.*s"));
+ return 0;
+ }
+ if (lua_pcall(lstate, 0, 1, 0)) {
+ nlua_error(lstate, _("E5105: Error while calling lua chunk: %.*s"));
+ return 0;
+ }
+ if (!nlua_pop_typval(lstate, ret_tv)) {
+ return 0;
+ }
+ return 0;
+}
+
+/// Evaluate lua string for each line in range
+///
+/// Expects two values on the stack: string to evaluate and pointer to integer
+/// array with line range. Always returns nothing (from the lua point of view).
+static int nlua_exec_luado_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
+{
+ const String *const str = (const String *)lua_touserdata(lstate, 1);
+ const linenr_T *const range = (const linenr_T *)lua_touserdata(lstate, 2);
+ lua_pop(lstate, 2);
+
+#define DOSTART "return function(line, linenr) "
+#define DOEND " end"
+ const size_t lcmd_len = (str->size
+ + (sizeof(DOSTART) - 1)
+ + (sizeof(DOEND) - 1));
+ char *lcmd;
+ if (lcmd_len < IOSIZE) {
+ lcmd = (char *)IObuff;
+ } else {
+ lcmd = xmalloc(lcmd_len + 1);
+ }
+ memcpy(lcmd, DOSTART, sizeof(DOSTART) - 1);
+ memcpy(lcmd + sizeof(DOSTART) - 1, str->data, str->size);
+ memcpy(lcmd + sizeof(DOSTART) - 1 + str->size, DOEND, sizeof(DOEND) - 1);
+#undef DOSTART
+#undef DOEND
+
+ if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) {
+ nlua_error(lstate, _("E5109: Error while creating lua chunk: %.*s"));
+ if (lcmd_len >= IOSIZE) {
+ xfree(lcmd);
+ }
+ return 0;
+ }
+ if (lcmd_len >= IOSIZE) {
+ xfree(lcmd);
+ }
+ if (lua_pcall(lstate, 0, 1, 0)) {
+ nlua_error(lstate, _("E5110: Error while creating lua function: %.*s"));
+ return 0;
+ }
+ for (linenr_T l = range[0]; l <= range[1]; l++) {
+ if (l > curbuf->b_ml.ml_line_count) {
+ break;
+ }
+ lua_pushvalue(lstate, -1);
+ lua_pushstring(lstate, (const char *)ml_get_buf(curbuf, l, false));
+ lua_pushnumber(lstate, (lua_Number)l);
+ if (lua_pcall(lstate, 2, 1, 0)) {
+ nlua_error(lstate, _("E5111: Error while calling lua function: %.*s"));
+ break;
+ }
+ if (lua_isstring(lstate, -1)) {
+ size_t new_line_len;
+ const char *const new_line = lua_tolstring(lstate, -1, &new_line_len);
+ char *const new_line_transformed = xmemdupz(new_line, new_line_len);
+ for (size_t i = 0; i < new_line_len; i++) {
+ if (new_line_transformed[i] == NUL) {
+ new_line_transformed[i] = '\n';
+ }
+ }
+ ml_replace(l, (char_u *)new_line_transformed, false);
+ changed_bytes(l, 0);
+ }
+ lua_pop(lstate, 1);
+ }
+ lua_pop(lstate, 1);
+ check_cursor();
+ update_screen(NOT_VALID);
+ return 0;
+}
+
+/// Evaluate lua file
+///
+/// Expects one value on the stack: file to evaluate. Always returns nothing
+/// (from the lua point of view).
+static int nlua_exec_lua_file(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
+{
+ const char *const filename = (const char *)lua_touserdata(lstate, 1);
+ lua_pop(lstate, 1);
+
+ if (luaL_loadfile(lstate, filename)) {
+ nlua_error(lstate, _("E5112: Error while creating lua chunk: %.*s"));
+ return 0;
+ }
+ if (lua_pcall(lstate, 0, 0, 0)) {
+ nlua_error(lstate, _("E5113: Error while calling lua chunk: %.*s"));
+ return 0;
+ }
+ return 0;
+}
+
+/// Initialize lua interpreter state
+///
+/// Called by lua interpreter itself to initialize state.
+static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
+{
+ // stricmp
+ lua_pushcfunction(lstate, &nlua_stricmp);
+ lua_setglobal(lstate, "stricmp");
+
+ // print
+ lua_pushcfunction(lstate, &nlua_print);
+ lua_setglobal(lstate, "print");
+
+ // debug.debug
+ lua_getglobal(lstate, "debug");
+ lua_pushcfunction(lstate, &nlua_debug);
+ lua_setfield(lstate, -2, "debug");
+ lua_pop(lstate, 1);
+
+ // vim
+ if (luaL_dostring(lstate, (char *)&vim_module[0])) {
+ nlua_error(lstate, _("E5106: Error while creating vim module: %.*s"));
+ return 1;
+ }
+ // vim.api
+ nlua_add_api_functions(lstate);
+ // vim.types, vim.type_idx, vim.val_idx
+ nlua_init_types(lstate);
+ lua_setglobal(lstate, "vim");
+ return 0;
+}
+
+/// Initialize lua interpreter
+///
+/// Crashes NeoVim if initialization fails. Should be called once per lua
+/// interpreter instance.
+///
+/// @return New lua interpreter instance.
+static lua_State *nlua_init(void)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ lua_State *lstate = luaL_newstate();
+ if (lstate == NULL) {
+ EMSG(_("E970: Failed to initialize lua interpreter"));
+ preserve_exit();
+ }
+ luaL_openlibs(lstate);
+ NLUA_CALL_C_FUNCTION_0(lstate, nlua_state_init, 0);
+ return lstate;
+}
+
+/// Enter lua interpreter
+///
+/// Calls nlua_init() if needed. Is responsible for pre-lua call initalization
+/// like updating `package.[c]path` with directories derived from &runtimepath.
+///
+/// @return Interprter instance to use. Will either be initialized now or taken
+/// from previous initalization.
+static lua_State *nlua_enter(void)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ static lua_State *global_lstate = NULL;
+ if (global_lstate == NULL) {
+ global_lstate = nlua_init();
+ }
+ lua_State *const lstate = global_lstate;
+ // Last used p_rtp value. Must not be dereferenced because value pointed to
+ // may already be freed. Used to check whether &runtimepath option value
+ // changed.
+ static const void *last_p_rtp = NULL;
+ if (last_p_rtp != (const void *)p_rtp) {
+ // stack: (empty)
+ lua_getglobal(lstate, "vim");
+ // stack: vim
+ lua_getfield(lstate, -1, "_update_package_paths");
+ // stack: vim, vim._update_package_paths
+ if (lua_pcall(lstate, 0, 0, 0)) {
+ // stack: vim, error
+ nlua_error(lstate, _("E5117: Error while updating package paths: %.*s"));
+ // stack: vim
+ }
+ // stack: vim
+ lua_pop(lstate, 1);
+ // stack: (empty)
+ last_p_rtp = (const void *)p_rtp;
+ }
+ return lstate;
+}
+
+/// Execute lua string
+///
+/// @param[in] str String to execute.
+/// @param[out] ret_tv Location where result will be saved.
+///
+/// @return Result of the execution.
+void executor_exec_lua(const String str, typval_T *const ret_tv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ NLUA_CALL_C_FUNCTION_2(nlua_enter(), nlua_exec_lua_string, 0,
+ (void *)&str, ret_tv);
+}
+
+/// Evaluate lua string
+///
+/// Used for luaeval(). Expects three values on the stack:
+///
+/// 1. String to evaluate.
+/// 2. _A value.
+/// 3. Pointer to location where result is saved.
+///
+/// @param[in,out] lstate Lua interpreter state.
+static int nlua_eval_lua_string(lua_State *const lstate)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const String *const str = (const String *)lua_touserdata(lstate, 1);
+ typval_T *const arg = (typval_T *)lua_touserdata(lstate, 2);
+ typval_T *const ret_tv = (typval_T *)lua_touserdata(lstate, 3);
+ lua_pop(lstate, 3);
+
+ garray_T str_ga;
+ ga_init(&str_ga, 1, 80);
+#define EVALHEADER "local _A=select(1,...) return ("
+ const size_t lcmd_len = sizeof(EVALHEADER) - 1 + str->size + 1;
+ char *lcmd;
+ if (lcmd_len < IOSIZE) {
+ lcmd = (char *)IObuff;
+ } else {
+ lcmd = xmalloc(lcmd_len);
+ }
+ memcpy(lcmd, EVALHEADER, sizeof(EVALHEADER) - 1);
+ memcpy(lcmd + sizeof(EVALHEADER) - 1, str->data, str->size);
+ lcmd[lcmd_len - 1] = ')';
+#undef EVALHEADER
+ if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) {
+ nlua_error(lstate,
+ _("E5107: Error while creating lua chunk for luaeval(): %.*s"));
+ if (lcmd != (char *)IObuff) {
+ xfree(lcmd);
+ }
+ return 0;
+ }
+ if (lcmd != (char *)IObuff) {
+ xfree(lcmd);
+ }
+
+ if (arg == NULL || arg->v_type == VAR_UNKNOWN) {
+ lua_pushnil(lstate);
+ } else {
+ nlua_push_typval(lstate, arg);
+ }
+ if (lua_pcall(lstate, 1, 1, 0)) {
+ nlua_error(lstate,
+ _("E5108: Error while calling lua chunk for luaeval(): %.*s"));
+ return 0;
+ }
+ if (!nlua_pop_typval(lstate, ret_tv)) {
+ return 0;
+ }
+
+ return 0;
+}
+
+/// Evaluate lua string
+///
+/// Expects four values on the stack: string to evaluate, pointer to args array,
+/// and locations where result and error are saved, respectively. Always
+/// returns nothing (from the lua point of view).
+static int nlua_exec_lua_string_api(lua_State *const lstate)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const String *str = (const String *)lua_touserdata(lstate, 1);
+ const Array *args = (const Array *)lua_touserdata(lstate, 2);
+ Object *retval = (Object *)lua_touserdata(lstate, 3);
+ Error *err = (Error *)lua_touserdata(lstate, 4);
+
+ lua_pop(lstate, 4);
+
+ if (luaL_loadbuffer(lstate, str->data, str->size, "<nvim>")) {
+ size_t len;
+ const char *str = lua_tolstring(lstate, -1, &len);
+ api_set_error(err, kErrorTypeValidation,
+ "Error loading lua: %.*s", (int)len, str);
+ return 0;
+ }
+
+ for (size_t i = 0; i < args->size; i++) {
+ nlua_push_Object(lstate, args->items[i]);
+ }
+
+ if (lua_pcall(lstate, (int)args->size, 1, 0)) {
+ size_t len;
+ const char *str = lua_tolstring(lstate, -1, &len);
+ api_set_error(err, kErrorTypeException,
+ "Error executing lua: %.*s", (int)len, str);
+ return 0;
+ }
+
+ *retval = nlua_pop_Object(lstate, err);
+
+ return 0;
+}
+
+/// Print as a Vim message
+///
+/// @param lstate Lua interpreter state.
+static int nlua_print(lua_State *const lstate)
+ FUNC_ATTR_NONNULL_ALL
+{
+#define PRINT_ERROR(msg) \
+ do { \
+ errmsg = msg; \
+ errmsg_len = sizeof(msg) - 1; \
+ goto nlua_print_error; \
+ } while (0)
+ const int nargs = lua_gettop(lstate);
+ lua_getglobal(lstate, "tostring");
+ const char *errmsg = NULL;
+ size_t errmsg_len = 0;
+ garray_T msg_ga;
+ ga_init(&msg_ga, 1, 80);
+ int curargidx = 1;
+ for (; curargidx <= nargs; curargidx++) {
+ lua_pushvalue(lstate, -1); // tostring
+ lua_pushvalue(lstate, curargidx); // arg
+ if (lua_pcall(lstate, 1, 1, 0)) {
+ errmsg = lua_tolstring(lstate, -1, &errmsg_len);
+ goto nlua_print_error;
+ }
+ size_t len;
+ const char *const s = lua_tolstring(lstate, -1, &len);
+ if (s == NULL) {
+ PRINT_ERROR(
+ "<Unknown error: lua_tolstring returned NULL for tostring result>");
+ }
+ ga_concat_len(&msg_ga, s, len);
+ if (curargidx < nargs) {
+ ga_append(&msg_ga, ' ');
+ }
+ lua_pop(lstate, 1);
+ }
+#undef PRINT_ERROR
+ lua_pop(lstate, nargs + 1);
+ ga_append(&msg_ga, NUL);
+ {
+ const size_t len = (size_t)msg_ga.ga_len - 1;
+ char *const str = (char *)msg_ga.ga_data;
+
+ for (size_t i = 0; i < len;) {
+ const size_t start = i;
+ while (i < len) {
+ switch (str[i]) {
+ case NUL: {
+ str[i] = NL;
+ i++;
+ continue;
+ }
+ case NL: {
+ str[i] = NUL;
+ i++;
+ break;
+ }
+ default: {
+ i++;
+ continue;
+ }
+ }
+ break;
+ }
+ msg((char_u *)str + start);
+ }
+ if (len && str[len - 1] == NUL) { // Last was newline
+ msg((char_u *)"");
+ }
+ }
+ ga_clear(&msg_ga);
+ return 0;
+nlua_print_error:
+ emsgf(_("E5114: Error while converting print argument #%i: %.*s"),
+ curargidx, errmsg_len, errmsg);
+ ga_clear(&msg_ga);
+ lua_pop(lstate, lua_gettop(lstate));
+ return 0;
+}
+
+/// debug.debug implementation: interaction with user while debugging
+///
+/// @param lstate Lua interpreter state.
+int nlua_debug(lua_State *lstate)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const typval_T input_args[] = {
+ {
+ .v_lock = VAR_FIXED,
+ .v_type = VAR_STRING,
+ .vval.v_string = (char_u *)"lua_debug> ",
+ },
+ {
+ .v_type = VAR_UNKNOWN,
+ },
+ };
+ for (;;) {
+ lua_settop(lstate, 0);
+ typval_T input;
+ get_user_input(input_args, &input, false);
+ msg_putchar('\n'); // Avoid outputting on input line.
+ if (input.v_type != VAR_STRING
+ || input.vval.v_string == NULL
+ || *input.vval.v_string == NUL
+ || STRCMP(input.vval.v_string, "cont") == 0) {
+ tv_clear(&input);
+ return 0;
+ }
+ if (luaL_loadbuffer(lstate, (const char *)input.vval.v_string,
+ STRLEN(input.vval.v_string), "=(debug command)")) {
+ nlua_error(lstate, _("E5115: Error while loading debug string: %.*s"));
+ }
+ tv_clear(&input);
+ if (lua_pcall(lstate, 0, 0, 0)) {
+ nlua_error(lstate, _("E5116: Error while calling debug string: %.*s"));
+ }
+ }
+ return 0;
+}
+
+/// Evaluate lua string
+///
+/// Used for luaeval().
+///
+/// @param[in] str String to execute.
+/// @param[in] arg Second argument to `luaeval()`.
+/// @param[out] ret_tv Location where result will be saved.
+///
+/// @return Result of the execution.
+void executor_eval_lua(const String str, typval_T *const arg,
+ typval_T *const ret_tv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ NLUA_CALL_C_FUNCTION_3(nlua_enter(), nlua_eval_lua_string, 0,
+ (void *)&str, arg, ret_tv);
+}
+
+/// Execute lua string
+///
+/// Used for nvim_execute_lua().
+///
+/// @param[in] str String to execute.
+/// @param[in] args array of ... args
+/// @param[out] err Location where error will be saved.
+///
+/// @return Return value of the execution.
+Object executor_exec_lua_api(const String str, const Array args, Error *err)
+{
+ Object retval = NIL;
+ NLUA_CALL_C_FUNCTION_4(nlua_enter(), nlua_exec_lua_string_api, 0,
+ (void *)&str, (void *)&args, &retval, err);
+ return retval;
+}
+
+
+/// Run lua string
+///
+/// Used for :lua.
+///
+/// @param eap VimL command being run.
+void ex_lua(exarg_T *const eap)
+ FUNC_ATTR_NONNULL_ALL
+{
+ size_t len;
+ char *const code = script_get(eap, &len);
+ if (eap->skip) {
+ xfree(code);
+ return;
+ }
+ typval_T tv = { .v_type = VAR_UNKNOWN };
+ executor_exec_lua((String) { .data = code, .size = len }, &tv);
+ tv_clear(&tv);
+ xfree(code);
+}
+
+/// Run lua string for each line in range
+///
+/// Used for :luado.
+///
+/// @param eap VimL command being run.
+void ex_luado(exarg_T *const eap)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL) {
+ EMSG(_("cannot save undo information"));
+ return;
+ }
+ const String cmd = {
+ .size = STRLEN(eap->arg),
+ .data = (char *)eap->arg,
+ };
+ const linenr_T range[] = { eap->line1, eap->line2 };
+ NLUA_CALL_C_FUNCTION_2(nlua_enter(), nlua_exec_luado_string, 0,
+ (void *)&cmd, (void *)range);
+}
+
+/// Run lua file
+///
+/// Used for :luafile.
+///
+/// @param eap VimL command being run.
+void ex_luafile(exarg_T *const eap)
+ FUNC_ATTR_NONNULL_ALL
+{
+ NLUA_CALL_C_FUNCTION_1(nlua_enter(), nlua_exec_lua_file, 0,
+ (void *)eap->arg);
+}
diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h
new file mode 100644
index 0000000000..0cbf290f64
--- /dev/null
+++ b/src/nvim/lua/executor.h
@@ -0,0 +1,25 @@
+#ifndef NVIM_LUA_EXECUTOR_H
+#define NVIM_LUA_EXECUTOR_H
+
+#include <lua.h>
+
+#include "nvim/api/private/defs.h"
+#include "nvim/func_attr.h"
+#include "nvim/eval/typval.h"
+#include "nvim/ex_cmds_defs.h"
+
+// Generated by msgpack-gen.lua
+void nlua_add_api_functions(lua_State *lstate) REAL_FATTR_NONNULL_ALL;
+
+#define set_api_error(s, err) \
+ do { \
+ Error *err_ = (err); \
+ err_->type = kErrorTypeException; \
+ err_->set = true; \
+ memcpy(&err_->msg[0], s, sizeof(s)); \
+ } while (0)
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "lua/executor.h.generated.h"
+#endif
+#endif // NVIM_LUA_EXECUTOR_H
diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua
new file mode 100644
index 0000000000..c7952520b0
--- /dev/null
+++ b/src/nvim/lua/vim.lua
@@ -0,0 +1,64 @@
+-- TODO(ZyX-I): Create compatibility layer.
+--{{{1 package.path updater function
+-- Last inserted paths. Used to clear out items from package.[c]path when they
+-- are no longer in &runtimepath.
+local last_nvim_paths = {}
+local function _update_package_paths()
+ local cur_nvim_paths = {}
+ local rtps = vim.api.nvim_list_runtime_paths()
+ local sep = package.config:sub(1, 1)
+ for _, key in ipairs({'path', 'cpath'}) do
+ local orig_str = package[key] .. ';'
+ local pathtrails_ordered = {}
+ local orig = {}
+ -- Note: ignores trailing item without trailing `;`. Not using something
+ -- simpler in order to preserve empty items (stand for default path).
+ for s in orig_str:gmatch('[^;]*;') do
+ s = s:sub(1, -2) -- Strip trailing semicolon
+ orig[#orig + 1] = s
+ end
+ if key == 'path' then
+ -- /?.lua and /?/init.lua
+ pathtrails_ordered = {sep .. '?.lua', sep .. '?' .. sep .. 'init.lua'}
+ else
+ local pathtrails = {}
+ for _, s in ipairs(orig) do
+ -- Find out path patterns. pathtrail should contain something like
+ -- /?.so, \?.dll. This allows not to bother determining what correct
+ -- suffixes are.
+ local pathtrail = s:match('[/\\][^/\\]*%?.*$')
+ if pathtrail and not pathtrails[pathtrail] then
+ pathtrails[pathtrail] = true
+ pathtrails_ordered[#pathtrails_ordered + 1] = pathtrail
+ end
+ end
+ end
+ local new = {}
+ for _, rtp in ipairs(rtps) do
+ if not rtp:match(';') then
+ for _, pathtrail in pairs(pathtrails_ordered) do
+ local new_path = rtp .. sep .. 'lua' .. pathtrail
+ -- Always keep paths from &runtimepath at the start:
+ -- append them here disregarding orig possibly containing one of them.
+ new[#new + 1] = new_path
+ cur_nvim_paths[new_path] = true
+ end
+ end
+ end
+ for _, orig_path in ipairs(orig) do
+ -- Handle removing obsolete paths originating from &runtimepath: such
+ -- paths either belong to cur_nvim_paths and were already added above or
+ -- to last_nvim_paths and should not be added at all if corresponding
+ -- entry was removed from &runtimepath list.
+ if not (cur_nvim_paths[orig_path] or last_nvim_paths[orig_path]) then
+ new[#new + 1] = orig_path
+ end
+ end
+ package[key] = table.concat(new, ';')
+ end
+ last_nvim_paths = cur_nvim_paths
+end
+--{{{1 Module definition
+return {
+ _update_package_paths = _update_package_paths,
+}
diff --git a/src/nvim/macros.h b/src/nvim/macros.h
index df2b431e92..26d4f74b6a 100644
--- a/src/nvim/macros.h
+++ b/src/nvim/macros.h
@@ -19,24 +19,14 @@
# define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
#endif
-/*
- * Position comparisons
- */
-# define lt(a, b) (((a).lnum != (b).lnum) \
- ? (a).lnum < (b).lnum \
- : (a).col != (b).col \
- ? (a).col < (b).col \
- : (a).coladd < (b).coladd)
-# define ltp(a, b) (((a)->lnum != (b)->lnum) \
- ? (a)->lnum < (b)->lnum \
- : (a)->col != (b)->col \
- ? (a)->col < (b)->col \
- : (a)->coladd < (b)->coladd)
-# define equalpos(a, b) (((a).lnum == (b).lnum) && ((a).col == (b).col) && \
- ((a).coladd == (b).coladd))
-# define clearpos(a) {(a)->lnum = 0; (a)->col = 0; (a)->coladd = 0; }
-
-#define ltoreq(a, b) (lt(a, b) || equalpos(a, b))
+/// String with length
+///
+/// For use in functions which accept (char *s, size_t len) pair in arguments.
+///
+/// @param[in] s Static string.
+///
+/// @return `s, sizeof(s) - 1`
+#define S_LEN(s) (s), (sizeof(s) - 1)
/*
* lineempty() - return TRUE if the line is empty
@@ -53,7 +43,7 @@
* toupper() and tolower() that use the current locale.
* Careful: Only call TOUPPER_LOC() and TOLOWER_LOC() with a character in the
* range 0 - 255. toupper()/tolower() on some systems can't handle others.
- * Note: It is often better to use vim_tolower() and vim_toupper(), because many
+ * Note: It is often better to use mb_tolower() and mb_toupper(), because many
* toupper() and tolower() implementations only work for ASCII.
*/
#define TOUPPER_LOC toupper
@@ -85,7 +75,7 @@
do { \
if (*p_langmap \
&& (condition) \
- && (!p_lnr || (p_lnr && typebuf_maplen() == 0)) \
+ && (p_lrm || KeyTyped) \
&& !KeyStuffed \
&& (c) >= 0) \
{ \
@@ -111,8 +101,10 @@
/* mch_open_rw(): invoke os_open() with third argument for user R/W. */
#if defined(UNIX) /* open in rw------- mode */
# define mch_open_rw(n, f) os_open((n), (f), (mode_t)0600)
+#elif defined(WIN32)
+# define mch_open_rw(n, f) os_open((n), (f), S_IREAD | S_IWRITE)
#else
-# define mch_open_rw(n, f) os_open((n), (f), 0)
+# define mch_open_rw(n, f) os_open((n), (f), 0)
#endif
# define REPLACE_NORMAL(s) (((s) & REPLACE_FLAG) && !((s) & VREPLACE_FLAG))
@@ -138,7 +130,7 @@
// Backup multi-byte pointer. Only use with "p" > "s" !
# define mb_ptr_back(s, p) (p -= mb_head_off((char_u *)s, (char_u *)p - 1) + 1)
// get length of multi-byte char, not including composing chars
-# define mb_cptr2len(p) utf_ptr2len(p)
+# define MB_CPTR2LEN(p) utf_ptr2len(p)
# define MB_COPY_CHAR(f, t) mb_copy_char((const char_u **)(&f), &t);
@@ -161,4 +153,34 @@
#define STR_(x) #x
#define STR(x) STR_(x)
+#ifndef __has_attribute
+# define NVIM_HAS_ATTRIBUTE(x) 0
+#elif defined(__clang__) && __clang__ == 1 \
+ && (__clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ <= 5))
+// Starting in Clang 3.6, __has_attribute was fixed to only report true for
+// GNU-style attributes. Prior to that, it reported true if _any_ backend
+// supported the attribute.
+# define NVIM_HAS_ATTRIBUTE(x) 0
+#else
+# define NVIM_HAS_ATTRIBUTE __has_attribute
+#endif
+
+#if NVIM_HAS_ATTRIBUTE(fallthrough)
+# define FALLTHROUGH __attribute__((fallthrough))
+#else
+# define FALLTHROUGH
+#endif
+
+// -V:STRUCT_CAST:641
+
+/// Change type of structure pointers: cast `struct a *` to `struct b *`
+///
+/// Used to silence PVS errors.
+///
+/// @param Type Structure to cast to.
+/// @param obj Object to cast.
+///
+/// @return ((Type *)obj).
+#define STRUCT_CAST(Type, obj) ((Type *)(obj))
+
#endif // NVIM_MACROS_H
diff --git a/src/nvim/main.c b/src/nvim/main.c
index c7a60d07c1..024c56dd05 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -1,9 +1,17 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#define EXTERN
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
+#ifdef WIN32
+# include <wchar.h>
+# include <winnls.h>
+#endif
+
#include <msgpack.h>
#include "nvim/ascii.h"
@@ -54,6 +62,7 @@
#include "nvim/os/input.h"
#include "nvim/os/os.h"
#include "nvim/os/time.h"
+#include "nvim/os/fileio.h"
#include "nvim/event/loop.h"
#include "nvim/os/signal.h"
#include "nvim/event/process.h"
@@ -94,10 +103,8 @@ typedef struct {
bool input_isatty; // stdin is a terminal
bool output_isatty; // stdout is a terminal
bool err_isatty; // stderr is a terminal
- bool headless; // Dont try to start an user interface
- // or read/write to stdio(unless
- // embedding)
- int no_swap_file; /* "-n" argument used */
+ bool headless; // Do not start the builtin UI.
+ 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 */
@@ -121,7 +128,7 @@ typedef struct {
Loop main_loop;
-static char *argv0;
+static char *argv0 = NULL;
// Error messages
static const char *err_arg_missing = N_("Argument missing after");
@@ -150,10 +157,11 @@ void event_init(void)
terminal_init();
}
-void event_teardown(void)
+/// @returns false if main_loop could not be closed gracefully
+bool event_teardown(void)
{
if (!main_loop.events) {
- return;
+ return true;
}
multiqueue_process_events(main_loop.events);
@@ -165,7 +173,7 @@ void event_teardown(void)
signal_teardown();
terminal_teardown();
- loop_close(&main_loop, true);
+ return loop_close(&main_loop, true);
}
/// Performs early initialization.
@@ -176,11 +184,9 @@ void early_init(void)
log_init();
fs_init();
handle_init();
-
eval_init(); // init global variables
-
- // Init the table of Normal mode commands.
- init_normal_cmds();
+ init_path(argv0 ? argv0 : "nvim");
+ init_normal_cmds(); // Init the table of Normal mode commands.
#if defined(HAVE_LOCALE_H)
// Setup to use the current locale (for ctype() and many other things).
@@ -214,11 +220,23 @@ void early_init(void)
#ifdef MAKE_LIB
int nvim_main(int argc, char **argv)
+#elif defined(WIN32)
+int wmain(int argc, wchar_t **argv_w) // multibyte args on Windows. #7060
#else
int main(int argc, char **argv)
#endif
{
- argv0 = (char *)path_tail((char_u *)argv[0]);
+#if defined(WIN32) && !defined(MAKE_LIB)
+ char *argv[argc];
+ for (int i = 0; i < argc; i++) {
+ char *buf = NULL;
+ utf16_to_utf8(argv_w[i], &buf);
+ assert(buf);
+ argv[i] = buf;
+ }
+#endif
+
+ argv0 = argv[0];
char_u *fname = NULL; // file name from command line
mparm_T params; // various parameters passed between
@@ -238,10 +256,6 @@ int main(int argc, char **argv)
// Check if we have an interactive window.
check_and_set_isatty(&params);
- // Get the name with which Nvim was invoked, with and without path.
- set_vim_var_string(VV_PROGPATH, argv[0], -1);
- set_vim_var_string(VV_PROGNAME, (char *) path_tail((char_u *) argv[0]), -1);
-
event_init();
/*
* Process the command line arguments. File names are put in the global
@@ -285,7 +299,7 @@ int main(int argc, char **argv)
cmdline_row = (int)(Rows - p_ch);
msg_row = cmdline_row;
screenalloc(false); /* allocate screen buffers */
- set_init_2();
+ set_init_2(params.headless);
TIME_MSG("inits 2");
msg_scroll = TRUE;
@@ -328,6 +342,12 @@ int main(int argc, char **argv)
do_cmdline_cmd("augroup END");
#undef PROTO
+ // Reset 'loadplugins' for "-u NONE" before "--cmd" arguments.
+ // Allows for setting 'loadplugins' there.
+ if (params.use_vimrc != NULL && strcmp(params.use_vimrc, "NONE") == 0) {
+ p_lpl = false;
+ }
+
/* Execute --cmd arguments. */
exe_pre_commands(&params);
@@ -387,9 +407,10 @@ int main(int argc, char **argv)
shada_read_everything(NULL, false, true);
TIME_MSG("reading ShaDa");
}
- /* It's better to make v:oldfiles an empty list than NULL. */
- if (get_vim_var_list(VV_OLDFILES) == NULL)
- set_vim_var_list(VV_OLDFILES, list_alloc());
+ // It's better to make v:oldfiles an empty list than NULL.
+ if (get_vim_var_list(VV_OLDFILES) == NULL) {
+ set_vim_var_list(VV_OLDFILES, tv_list_alloc());
+ }
/*
* "-q errorfile": Load the error file now.
@@ -515,6 +536,12 @@ int main(int argc, char **argv)
apply_autocmds(EVENT_VIMENTER, NULL, NULL, false, curbuf);
TIME_MSG("VimEnter autocommands");
+ // Adjust default register name for "unnamed" in 'clipboard'. Can only be
+ // done after the clipboard is available and all initial commands that may
+ // modify the 'clipboard' setting have run; i.e. just before entering the
+ // main loop.
+ set_reg_var(get_default_register_name());
+
/* When a startup script or session file setup for diff'ing and
* scrollbind, sync the scrollbind now. */
if (curwin->w_p_diff && curwin->w_p_scb) {
@@ -578,9 +605,9 @@ void getout(int exitval)
buf_T *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 */
+ buf->b_fname, false, buf);
+ buf_set_changedtick(buf, -1); // note that we did it already
+ // start all over, autocommands may mess up the lists
next_tp = first_tabpage;
break;
}
@@ -590,10 +617,13 @@ void getout(int exitval)
/* Trigger BufUnload for buffers that are loaded */
FOR_ALL_BUFFERS(buf) {
if (buf->b_ml.ml_mfp != NULL) {
- apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname,
- FALSE, buf);
- if (!buf_valid(buf)) /* autocmd may delete the buffer */
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, false, buf);
+ if (!bufref_valid(&bufref)) {
+ // Autocmd deleted the buffer.
break;
+ }
}
}
apply_autocmds(EVENT_VIMLEAVEPRE, NULL, NULL, FALSE, curbuf);
@@ -623,8 +653,9 @@ void getout(int exitval)
iconv_end();
#endif
cs_end();
- if (garbage_collect_at_exit)
- garbage_collect();
+ if (garbage_collect_at_exit) {
+ garbage_collect(false);
+ }
mch_exit(exitval);
}
@@ -642,8 +673,9 @@ void getout(int exitval)
///
/// @return argument's numeric value otherwise
static int get_number_arg(const char *p, int *idx, int def)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
- if (ascii_isdigit(p[*idx])) {
+ if (ascii_isdigit(p[*idx])) { // -V522
def = atoi(&(p[*idx]));
while (ascii_isdigit(p[*idx])) {
*idx = *idx + 1;
@@ -750,16 +782,26 @@ static void command_line_scan(mparm_T *parmp)
version();
mch_exit(0);
} else if (STRICMP(argv[0] + argv_idx, "api-info") == 0) {
- msgpack_sbuffer* b = msgpack_sbuffer_new();
- msgpack_packer* p = msgpack_packer_new(b, msgpack_sbuffer_write);
- Object md = DICTIONARY_OBJ(api_metadata());
- msgpack_rpc_from_object(md, p);
+ FileDescriptor fp;
+ const int fof_ret = file_open_fd(&fp, OS_STDOUT_FILENO, true);
+ msgpack_packer *p = msgpack_packer_new(&fp, msgpack_file_write);
+
+ if (fof_ret != 0) {
+ emsgf(_("E5421: Failed to open stdin: %s"), os_strerror(fof_ret));
+ }
- for (size_t i = 0; i < b->size; i++) {
- putchar(b->data[i]);
+ if (p == NULL) {
+ emsgf(_(e_outofmem));
}
+ Object md = DICTIONARY_OBJ(api_metadata());
+ msgpack_rpc_from_object(md, p);
+
msgpack_packer_free(p);
+ const int ff_ret = file_flush(&fp);
+ if (ff_ret < 0) {
+ msgpack_file_write_error(ff_ret);
+ }
mch_exit(0);
} else if (STRICMP(argv[0] + argv_idx, "headless") == 0) {
parmp->headless = true;
@@ -788,17 +830,18 @@ static void command_line_scan(mparm_T *parmp)
argv_idx = -1; /* skip to next argument */
break;
- case 'A': /* "-A" start in Arabic mode */
- set_option_value((char_u *)"arabic", 1L, NULL, 0);
+ case 'A': { // "-A" start in Arabic mode.
+ set_option_value("arabic", 1L, NULL, 0);
break;
-
- case 'b': /* "-b" binary mode */
- /* Needs to be effective before expanding file names, because
- * for Win32 this makes us edit a shortcut file itself,
- * instead of the file it links to. */
+ }
+ case 'b': { // "-b" binary mode.
+ // Needs to be effective before expanding file names, because
+ // for Win32 this makes us edit a shortcut file itself,
+ // instead of the file it links to.
set_options_bin(curbuf->b_p_bin, 1, 0);
- curbuf->b_p_bin = 1; /* binary file I/O */
+ curbuf->b_p_bin = 1; // Binary file I/O.
break;
+ }
case 'e': /* "-e" Ex mode */
exmode_active = EXMODE_NORMAL;
@@ -815,24 +858,27 @@ static void command_line_scan(mparm_T *parmp)
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);
+ case 'F': { // "-F" start in Farsi mode: rl + fkmap set.
+ p_fkmap = true;
+ set_option_value("rl", 1L, NULL, 0);
break;
+ }
case 'h': /* "-h" give help message */
usage();
mch_exit(0);
- case 'H': /* "-H" start in Hebrew mode: rl + hkmap set */
- p_hkmap = TRUE;
- set_option_value((char_u *)"rl", 1L, NULL, 0);
+ case 'H': { // "-H" start in Hebrew mode: rl + hkmap set.
+ p_hkmap = true;
+ set_option_value("rl", 1L, NULL, 0);
break;
+ }
- case 'l': /* "-l" lisp mode, 'lisp' and 'showmatch' on */
- set_option_value((char_u *)"lisp", 1L, NULL, 0);
- p_sm = TRUE;
+ case 'l': { // "-l" lisp mode, 'lisp' and 'showmatch' on.
+ set_option_value("lisp", 1L, NULL, 0);
+ p_sm = true;
break;
+ }
case 'M': /* "-M" no changes or writing of files */
reset_modifiable();
@@ -901,10 +947,11 @@ static void command_line_scan(mparm_T *parmp)
break;
case 's':
- if (exmode_active) /* "-s" silent (batch) mode */
- silent_mode = TRUE;
- else /* "-s {scriptin}" read from script file */
- want_argument = TRUE;
+ if (exmode_active) { // "-es" 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 */
@@ -931,8 +978,7 @@ static void command_line_scan(mparm_T *parmp)
/* default is 10: a little bit verbose */
p_verbose = get_number_arg(argv[0], &argv_idx, 10);
if (argv[0][argv_idx] != NUL) {
- set_option_value((char_u *)"verbosefile", 0L,
- (char_u *)argv[0] + argv_idx, 0);
+ set_option_value("verbosefile", 0L, argv[0] + argv_idx, 0);
argv_idx = (int)STRLEN(argv[0]);
}
break;
@@ -941,7 +987,7 @@ static void command_line_scan(mparm_T *parmp)
/* "-w {scriptout}" write to script */
if (ascii_isdigit(((char_u *)argv[0])[argv_idx])) {
n = get_number_arg(argv[0], &argv_idx, 10);
- set_option_value((char_u *)"window", n, NULL, 0);
+ set_option_value("window", n, NULL, 0);
break;
}
want_argument = TRUE;
@@ -1073,7 +1119,7 @@ scripterror:
if (ascii_isdigit(*((char_u *)argv[0]))) {
argv_idx = 0;
n = get_number_arg(argv[0], &argv_idx, 10);
- set_option_value((char_u *)"window", n, NULL, 0);
+ set_option_value("window", n, NULL, 0);
argv_idx = -1;
break;
}
@@ -1194,9 +1240,29 @@ static void check_and_set_isatty(mparm_T *paramp)
paramp->err_isatty = os_isatty(fileno(stderr));
TIME_MSG("window checked");
}
-/*
- * Get filename from command line, given that there is one.
- */
+
+// Sets v:progname and v:progpath. Also modifies $PATH on Windows.
+static void init_path(const char *exename)
+ FUNC_ATTR_NONNULL_ALL
+{
+ char exepath[MAXPATHL] = { 0 };
+ size_t exepathlen = MAXPATHL;
+ // Make v:progpath absolute.
+ if (os_exepath(exepath, &exepathlen) != 0) {
+ // Fall back to argv[0]. Missing procfs? #6734
+ path_guess_exepath(exename, exepath, sizeof(exepath));
+ }
+ set_vim_var_string(VV_PROGPATH, exepath, -1);
+ set_vim_var_string(VV_PROGNAME, (char *)path_tail((char_u *)exename), -1);
+
+#ifdef WIN32
+ // Append the process start directory to $PATH, so that ":!foo" finds tools
+ // shipped with Windows package. This also mimics SearchPath().
+ os_setenv_append_path(exepath);
+#endif
+}
+
+/// Get filename from command line, if any.
static char_u *get_fname(mparm_T *parmp, char_u *cwd)
{
#if !defined(UNIX)
@@ -1242,11 +1308,33 @@ static void set_window_layout(mparm_T *paramp)
static void load_plugins(void)
{
if (p_lpl) {
- source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL); // NOLINT
+ char_u *rtp_copy = NULL;
+
+ // First add all package directories to 'runtimepath', so that their
+ // autoload directories can be found. Only if not done already with a
+ // :packloadall command.
+ // Make a copy of 'runtimepath', so that source_runtime does not use the
+ // pack directories.
+ if (!did_source_packages) {
+ rtp_copy = vim_strsave(p_rtp);
+ add_pack_start_dirs();
+ }
+
+ source_in_path(rtp_copy == NULL ? p_rtp : rtp_copy,
+ (char_u *)"plugin/**/*.vim", // NOLINT
+ DIP_ALL | DIP_NOAFTER);
TIME_MSG("loading plugins");
+ xfree(rtp_copy);
- ex_packloadall(NULL);
+ // Only source "start" packages if not done already with a :packloadall
+ // command.
+ if (!did_source_packages) {
+ load_start_packages();
+ }
TIME_MSG("loading packages");
+
+ source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL | DIP_AFTER);
+ TIME_MSG("loading after plugins");
}
}
@@ -1261,8 +1349,8 @@ static void handle_quickfix(mparm_T *paramp)
set_string_option_direct((char_u *)"ef", -1,
paramp->use_ef, OPT_FREE, SID_CARG);
vim_snprintf((char *)IObuff, IOSIZE, "cfile %s", p_ef);
- if (qf_init(NULL, p_ef, p_efm, TRUE, IObuff) < 0) {
- ui_putc('\n');
+ if (qf_init(NULL, p_ef, p_efm, true, IObuff) < 0) {
+ ui_linefeed();
mch_exit(3);
}
TIME_MSG("reading errorfile");
@@ -1642,7 +1730,7 @@ static bool do_user_initialization(void)
do {
const char *dir;
size_t dir_len;
- iter = vim_colon_env_iter(config_dirs, iter, &dir, &dir_len);
+ iter = vim_env_iter(':', config_dirs, iter, &dir, &dir_len);
if (dir == NULL || dir_len == 0) {
break;
}
@@ -1682,8 +1770,6 @@ static void source_startup_scripts(const mparm_T *const parmp)
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((char_u *)parmp->use_vimrc, FALSE, DOSO_NONE) != OK)
EMSG2(_("E282: Cannot read from \"%s\""), parmp->use_vimrc);
@@ -1775,6 +1861,7 @@ static int process_env(char *env, bool is_viminit)
/// os_fileinfo_link() respectively for extra security.
static bool file_owned(const char *fname)
{
+ assert(fname != NULL);
uid_t uid = getuid();
FileInfo file_info;
bool file_owned = os_fileinfo(fname, &file_info)
@@ -1793,9 +1880,11 @@ static bool file_owned(const char *fname)
/// @param str string to append to the primary error message, or NULL
static void mainerr(const char *errstr, const char *str)
{
+ char *prgname = (char *)path_tail((char_u *)argv0);
+
signal_stop(); // kill us with CTRL-C here, if you like
- mch_errmsg(argv0);
+ mch_errmsg(prgname);
mch_errmsg(": ");
mch_errmsg(_(errstr));
if (str != NULL) {
@@ -1804,7 +1893,7 @@ static void mainerr(const char *errstr, const char *str)
mch_errmsg("\"");
}
mch_errmsg(_("\nMore info with \""));
- mch_errmsg(argv0);
+ mch_errmsg(prgname);
mch_errmsg(" -h\"\n");
mch_exit(1);
@@ -1825,54 +1914,47 @@ static void usage(void)
signal_stop(); // kill us with CTRL-C here, if you like
mch_msg(_("Usage:\n"));
- mch_msg(_(" nvim [arguments] [file ...] Edit specified file(s)\n"));
- mch_msg(_(" nvim [arguments] - Read text from stdin\n"));
- mch_msg(_(" nvim [arguments] -t <tag> Edit file where tag is defined\n"));
- mch_msg(_(" nvim [arguments] -q [errorfile] Edit file with first error\n"));
- mch_msg(_("\nArguments:\n"));
+ mch_msg(_(" nvim [options] [file ...] Edit file(s)\n"));
+ mch_msg(_(" nvim [options] - Read text from stdin\n"));
+ mch_msg(_(" nvim [options] -t <tag> Edit file where tag is defined\n"));
+ mch_msg(_(" nvim [options] -q [errorfile] Edit file with first error\n"));
+ mch_msg(_("\nOptions:\n"));
mch_msg(_(" -- Only file names after this\n"));
-#if !defined(UNIX)
- mch_msg(_(" --literal Don't expand wildcards\n"));
-#endif
- mch_msg(_(" -e Ex mode\n"));
- mch_msg(_(" -E Improved Ex mode\n"));
- mch_msg(_(" -s Silent (batch) mode (only for ex mode)\n"));
+ mch_msg(_(" + Start at end of file\n"));
+ mch_msg(_(" --cmd <cmd> Execute <cmd> before any config\n"));
+ mch_msg(_(" +<cmd>, -c <cmd> Execute <cmd> after config and first file\n"));
+ mch_msg("\n");
+ mch_msg(_(" -b Binary mode\n"));
mch_msg(_(" -d Diff mode\n"));
- mch_msg(_(" -R Read-only mode\n"));
- mch_msg(_(" -Z Restricted mode\n"));
+ mch_msg(_(" -e, -E Ex mode, Improved Ex mode\n"));
+ mch_msg(_(" -es Silent (batch) mode\n"));
+ mch_msg(_(" -h, --help Print this help message\n"));
+ mch_msg(_(" -i <shada> Use this shada file\n"));
mch_msg(_(" -m Modifications (writing files) not allowed\n"));
mch_msg(_(" -M Modifications in text not allowed\n"));
- mch_msg(_(" -b Binary mode\n"));
- mch_msg(_(" -l Lisp mode\n"));
- mch_msg(_(" -A Arabic mode\n"));
- mch_msg(_(" -F Farsi mode\n"));
- mch_msg(_(" -H Hebrew mode\n"));
- mch_msg(_(" -V[N][file] Be verbose [level N][log messages to file]\n"));
- mch_msg(_(" -D Debugging mode\n"));
mch_msg(_(" -n No swap file, use memory only\n"));
- mch_msg(_(" -r, -L List swap files and exit\n"));
- mch_msg(_(" -r <file> Recover crashed session\n"));
- mch_msg(_(" -u <vimrc> Use <vimrc> instead of the default\n"));
- mch_msg(_(" -i <shada> Use <shada> instead of the default\n"));
- mch_msg(_(" --noplugin Don't load plugin scripts\n"));
- mch_msg(_(" -o[N] Open N windows (default: one for each file)\n"));
- mch_msg(_(" -O[N] Like -o but split vertically\n"));
- mch_msg(_(" -p[N] Open N tab pages (default: one for each file)\n"));
- mch_msg(_(" + Start at end of file\n"));
- mch_msg(_(" +<linenum> Start at line <linenum>\n"));
- mch_msg(_(" +/<pattern> Start at first occurrence of <pattern>\n"));
- mch_msg(_(" --cmd <command> Execute <command> before loading any vimrc\n"));
- mch_msg(_(" -c <command> Execute <command> after loading the first file\n"));
+ mch_msg(_(" -o[N] Open N windows (default: one per file)\n"));
+ mch_msg(_(" -O[N] Open N vertical windows (default: one per file)\n"));
+ mch_msg(_(" -p[N] Open N tab pages (default: one per file)\n"));
+ mch_msg(_(" -r, -L List swap files\n"));
+ mch_msg(_(" -r <file> Recover edit state for this file\n"));
+ mch_msg(_(" -R Read-only mode\n"));
mch_msg(_(" -S <session> Source <session> after loading the first file\n"));
mch_msg(_(" -s <scriptin> Read Normal mode commands from <scriptin>\n"));
- mch_msg(_(" -w <scriptout> Append all typed characters to <scriptout>\n"));
- mch_msg(_(" -W <scriptout> Write all typed characters to <scriptout>\n"));
- mch_msg(_(" --startuptime <file> Write startup timing messages to <file>\n"));
- mch_msg(_(" --api-info Dump API metadata serialized to msgpack and exit\n"));
+ mch_msg(_(" -u <config> Use this config file\n"));
+ mch_msg(_(" -v, --version Print version information\n"));
+ mch_msg(_(" -V[N][file] Verbose [level][file]\n"));
+ mch_msg(_(" -Z Restricted mode\n"));
+ mch_msg("\n");
+ mch_msg(_(" --api-info Write msgpack-encoded API metadata to stdout\n"));
mch_msg(_(" --embed Use stdin/stdout as a msgpack-rpc channel\n"));
mch_msg(_(" --headless Don't start a user interface\n"));
- mch_msg(_(" -v, --version Print version information and exit\n"));
- mch_msg(_(" -h, --help Print this help message and exit\n"));
+#if !defined(UNIX)
+ mch_msg(_(" --literal Don't expand wildcards\n"));
+#endif
+ mch_msg(_(" --noplugin Don't load plugins\n"));
+ mch_msg(_(" --startuptime <file> Write startup timing messages to <file>\n"));
+ mch_msg(_("\nSee \":help startup-options\" for all options.\n"));
}
diff --git a/src/nvim/map.c b/src/nvim/map.c
index 73af487f90..537b6751e2 100644
--- a/src/nvim/map.c
+++ b/src/nvim/map.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
@@ -139,7 +142,6 @@ static inline bool String_eq(String a, String b)
MAP_IMPL(int, int, DEFAULT_INITIALIZER)
-MAP_IMPL(cstr_t, uint64_t, DEFAULT_INITIALIZER)
MAP_IMPL(cstr_t, ptr_t, DEFAULT_INITIALIZER)
MAP_IMPL(ptr_t, ptr_t, DEFAULT_INITIALIZER)
MAP_IMPL(uint64_t, ptr_t, DEFAULT_INITIALIZER)
@@ -147,4 +149,3 @@ MAP_IMPL(handle_T, ptr_t, DEFAULT_INITIALIZER)
#define MSGPACK_HANDLER_INITIALIZER { .fn = NULL, .async = false }
MAP_IMPL(String, MsgpackRpcRequestHandler, MSGPACK_HANDLER_INITIALIZER)
#define KVEC_INITIALIZER { .size = 0, .capacity = 0, .items = NULL }
-MAP_IMPL(linenr_T, bufhl_vec_T, KVEC_INITIALIZER)
diff --git a/src/nvim/map.h b/src/nvim/map.h
index ba3e84cb31..047aa163ce 100644
--- a/src/nvim/map.h
+++ b/src/nvim/map.h
@@ -25,13 +25,11 @@
void map_##T##_##U##_clear(Map(T, U) *map);
MAP_DECLS(int, int)
-MAP_DECLS(cstr_t, uint64_t)
MAP_DECLS(cstr_t, ptr_t)
MAP_DECLS(ptr_t, ptr_t)
MAP_DECLS(uint64_t, ptr_t)
MAP_DECLS(handle_T, ptr_t)
MAP_DECLS(String, MsgpackRpcRequestHandler)
-MAP_DECLS(linenr_T, bufhl_vec_T)
#define map_new(T, U) map_##T##_##U##_new
#define map_free(T, U) map_##T##_##U##_free
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index bb5b8e8178..7889fabd45 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* mark.c: functions for setting marks and jumping to them
*/
@@ -62,7 +65,7 @@ int setmark(int c)
/// Free fmark_T item
void free_fmark(fmark_T fm)
{
- dict_unref(fm.additional_data);
+ tv_dict_unref(fm.additional_data);
}
/// Free xfmark_T item
@@ -130,9 +133,15 @@ int setmark_pos(int c, pos_T *pos, int fnum)
return OK;
}
+ buf_T *buf = buflist_findnr(fnum);
+ // Can't set a mark in a non-existant buffer.
+ if (buf == NULL) {
+ return FAIL;
+ }
+
if (ASCII_ISLOWER(c)) {
i = c - 'a';
- RESET_FMARK(curbuf->b_namedm + i, *pos, curbuf->b_fnum);
+ RESET_FMARK(buf->b_namedm + i, *pos, fnum);
return OK;
}
if (ASCII_ISUPPER(c) || ascii_isdigit(c)) {
@@ -879,7 +888,29 @@ void ex_changes(exarg_T *eap)
* Example: Insert two lines below 55: mark_adjust(56, MAXLNUM, 2, 0);
* or: mark_adjust(56, 55, MAXLNUM, 2);
*/
-void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after)
+void mark_adjust(linenr_T line1,
+ linenr_T line2,
+ long amount,
+ long amount_after,
+ bool end_temp)
+{
+ mark_adjust_internal(line1, line2, amount, amount_after, true, end_temp);
+}
+
+// mark_adjust_nofold() does the same as mark_adjust() but without adjusting
+// folds in any way. Folds must be adjusted manually by the caller.
+// This is only useful when folds need to be moved in a way different to
+// calling foldMarkAdjust() with arguments line1, line2, amount, amount_after,
+// for an example of why this may be necessary, see do_move().
+void mark_adjust_nofold(linenr_T line1, linenr_T line2, long amount,
+ long amount_after, bool end_temp)
+{
+ mark_adjust_internal(line1, line2, amount, amount_after, false, end_temp);
+}
+
+static void mark_adjust_internal(linenr_T line1, linenr_T line2,
+ long amount, long amount_after,
+ bool adjust_folds, bool end_temp)
{
int i;
int fnum = curbuf->b_fnum;
@@ -928,7 +959,7 @@ void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after)
}
sign_mark_adjust(line1, line2, amount, amount_after);
- bufhl_mark_adjust(curbuf, line1, line2, amount, amount_after);
+ bufhl_mark_adjust(curbuf, line1, line2, amount, amount_after, end_temp);
}
/* previous context mark */
@@ -1005,8 +1036,9 @@ void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after)
}
}
- /* adjust folds */
- foldMarkAdjust(win, line1, line2, amount, amount_after);
+ if (adjust_folds) {
+ foldMarkAdjust(win, line1, line2, amount, amount_after);
+ }
}
}
@@ -1407,3 +1439,26 @@ void free_all_marks(void)
memset(&namedfm[0], 0, sizeof(namedfm));
}
#endif
+
+/// Adjust position to point to the first byte of a multi-byte character
+///
+/// If it points to a tail byte it is move backwards to the head byte.
+///
+/// @param[in] buf Buffer to adjust position in.
+/// @param[out] lp Position to adjust.
+void mark_mb_adjustpos(buf_T *buf, pos_T *lp)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (lp->col > 0 || lp->coladd > 1) {
+ const char_u *const p = ml_get_buf(buf, lp->lnum, false);
+ 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;
+ }
+ }
+}
diff --git a/src/nvim/mark.h b/src/nvim/mark.h
index aff6e7273a..ed4e47907b 100644
--- a/src/nvim/mark.h
+++ b/src/nvim/mark.h
@@ -4,10 +4,12 @@
#include "nvim/macros.h"
#include "nvim/ascii.h"
#include "nvim/buffer_defs.h"
+#include "nvim/func_attr.h"
#include "nvim/mark_defs.h"
#include "nvim/memory.h"
#include "nvim/pos.h"
#include "nvim/os/time.h"
+#include "nvim/ex_cmds_defs.h" // for exarg_T
/// Set fmark using given value
#define SET_FMARK(fmarkp_, mark_, fnum_) \
@@ -29,7 +31,7 @@
/// Clear given fmark
#define CLEAR_FMARK(fmarkp_) \
- RESET_FMARK(fmarkp_, ((pos_T) {0, 0, 0}), 0)
+ RESET_FMARK(fmarkp_, ((pos_T) { 0, 0, 0 }), 0)
/// Set given extended mark (regular mark + file name)
#define SET_XFMARK(xfmarkp_, mark_, fnum_, fname_) \
@@ -74,6 +76,46 @@ static inline int mark_local_index(const char name)
: -1))));
}
+static inline bool lt(pos_T, pos_T) REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE;
+static inline bool equalpos(pos_T, pos_T)
+ REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE;
+static inline bool ltoreq(pos_T, pos_T)
+ REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE;
+static inline void clearpos(pos_T *)
+ REAL_FATTR_ALWAYS_INLINE;
+
+/// Return true if position a is before (less than) position b.
+static inline bool lt(pos_T a, pos_T b)
+{
+ if (a.lnum != b.lnum) {
+ return a.lnum < b.lnum;
+ } else if (a.col != b.col) {
+ return a.col < b.col;
+ } else {
+ return a.coladd < b.coladd;
+ }
+}
+
+/// Return true if position a and b are equal.
+static inline bool equalpos(pos_T a, pos_T b)
+{
+ return (a.lnum == b.lnum) && (a.col == b.col) && (a.coladd == b.coladd);
+}
+
+/// Return true if position a is less than or equal to b.
+static inline bool ltoreq(pos_T a, pos_T b)
+{
+ return lt(a, b) || equalpos(a, b);
+}
+
+/// Clear the pos_T structure pointed to by a.
+static inline void clearpos(pos_T *a)
+{
+ a->lnum = 0;
+ a->col = 0;
+ a->coladd = 0;
+}
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "mark.h.generated.h"
#endif
diff --git a/src/nvim/mark_defs.h b/src/nvim/mark_defs.h
index 720b2475ed..2cb489501e 100644
--- a/src/nvim/mark_defs.h
+++ b/src/nvim/mark_defs.h
@@ -3,7 +3,7 @@
#include "nvim/pos.h"
#include "nvim/os/time.h"
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
/*
* marks: positions in a file
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index ec4969d4f6..b24770a409 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// mbyte.c: Code specifically for handling multi-byte characters.
/// Multibyte extensions partly by Sung-Hoon Baek
///
@@ -50,6 +53,7 @@
#include "nvim/strings.h"
#include "nvim/os/os.h"
#include "nvim/arabic.h"
+#include "nvim/mark.h"
typedef struct {
int rangeStart;
@@ -71,7 +75,7 @@ struct interval {
/*
* Like utf8len_tab above, but using a zero for illegal lead bytes.
*/
-static uint8_t utf8len_tab_zero[256] =
+const uint8_t utf8len_tab_zero[256] =
{
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
@@ -355,14 +359,13 @@ int bomb_size(void)
*/
void remove_bom(char_u *s)
{
- if (enc_utf8) {
- char_u *p = s;
+ char *p = (char *)s;
- while ((p = vim_strbyte(p, 0xef)) != NULL) {
- if (p[1] == 0xbb && p[2] == 0xbf)
- STRMOVE(p, p + 3);
- else
- ++p;
+ while ((p = strchr(p, 0xef)) != NULL) {
+ if ((uint8_t)p[1] == 0xbb && (uint8_t)p[2] == 0xbf) {
+ STRMOVE(p, p + 3);
+ } else {
+ p++;
}
}
}
@@ -376,166 +379,21 @@ void remove_bom(char_u *s)
*/
int mb_get_class(const char_u *p)
{
- return mb_get_class_buf(p, curbuf);
+ return mb_get_class_tab(p, curbuf->b_chartab);
}
-int mb_get_class_buf(const char_u *p, buf_T *buf)
+int mb_get_class_tab(const char_u *p, const uint64_t *const chartab)
{
if (MB_BYTE2LEN(p[0]) == 1) {
- if (p[0] == NUL || ascii_iswhite(p[0]))
+ if (p[0] == NUL || ascii_iswhite(p[0])) {
return 0;
- if (vim_iswordc_buf(p[0], buf))
+ }
+ if (vim_iswordc_tab(p[0], chartab)) {
return 2;
+ }
return 1;
}
- if (enc_dbcs != 0 && p[0] != NUL && p[1] != NUL)
- return dbcs_class(p[0], p[1]);
- if (enc_utf8)
- return utf_class(utf_ptr2char(p));
- return 0;
-}
-
-/*
- * Get class of a double-byte character. This always returns 3 or bigger.
- * TODO: Should return 1 for punctuation.
- */
-int dbcs_class(unsigned lead, unsigned trail)
-{
- switch (enc_dbcs) {
- /* please add classify routine for your language in here */
-
- case DBCS_JPNU: /* ? */
- case DBCS_JPN:
- {
- /* JIS code classification */
- unsigned char lb = lead;
- unsigned char tb = trail;
-
- /* convert process code to JIS */
- /*
- * XXX: Code page identification can not use with all
- * system! So, some other encoding information
- * will be needed.
- * In japanese: SJIS,EUC,UNICODE,(JIS)
- * Note that JIS-code system don't use as
- * process code in most system because it uses
- * escape sequences(JIS is context depend encoding).
- */
- /* assume process code is JAPANESE-EUC */
- lb &= 0x7f;
- tb &= 0x7f;
- /* exceptions */
- switch (lb << 8 | tb) {
- case 0x2121: /* ZENKAKU space */
- return 0;
- case 0x2122: /* TOU-TEN (Japanese comma) */
- case 0x2123: /* KU-TEN (Japanese period) */
- case 0x2124: /* ZENKAKU comma */
- case 0x2125: /* ZENKAKU period */
- return 1;
- case 0x213c: /* prolongedsound handled as KATAKANA */
- return 13;
- }
- /* sieved by KU code */
- switch (lb) {
- case 0x21:
- case 0x22:
- /* special symbols */
- return 10;
- case 0x23:
- /* alpha-numeric */
- return 11;
- case 0x24:
- /* hiragana */
- return 12;
- case 0x25:
- /* katakana */
- return 13;
- case 0x26:
- /* greek */
- return 14;
- case 0x27:
- /* russian */
- return 15;
- case 0x28:
- /* lines */
- return 16;
- default:
- /* kanji */
- return 17;
- }
- }
-
- case DBCS_KORU: /* ? */
- case DBCS_KOR:
- {
- /* KS code classification */
- unsigned char c1 = lead;
- unsigned char c2 = trail;
-
- /*
- * 20 : Hangul
- * 21 : Hanja
- * 22 : Symbols
- * 23 : Alpha-numeric/Roman Letter (Full width)
- * 24 : Hangul Letter(Alphabet)
- * 25 : Roman Numeral/Greek Letter
- * 26 : Box Drawings
- * 27 : Unit Symbols
- * 28 : Circled/Parenthesized Letter
- * 29 : Hiragana/Katakana
- * 30 : Cyrillic Letter
- */
-
- if (c1 >= 0xB0 && c1 <= 0xC8)
- /* Hangul */
- return 20;
-
- else if (c1 >= 0xCA && c1 <= 0xFD)
- /* Hanja */
- return 21;
- else switch (c1) {
- case 0xA1:
- case 0xA2:
- /* Symbols */
- return 22;
- case 0xA3:
- /* Alpha-numeric */
- return 23;
- case 0xA4:
- /* Hangul Letter(Alphabet) */
- return 24;
- case 0xA5:
- /* Roman Numeral/Greek Letter */
- return 25;
- case 0xA6:
- /* Box Drawings */
- return 26;
- case 0xA7:
- /* Unit Symbols */
- return 27;
- case 0xA8:
- case 0xA9:
- if (c2 <= 0xAF)
- return 25; /* Roman Letter */
- else if (c2 >= 0xF6)
- return 22; /* Symbols */
- else
- /* Circled/Parenthesized Letter */
- return 28;
- case 0xAA:
- case 0xAB:
- /* Hiragana/Katakana */
- return 29;
- case 0xAC:
- /* Cyrillic Letter */
- return 30;
- }
- }
- default:
- break;
- }
- return 3;
+ return utf_class(utf_ptr2char(p));
}
/*
@@ -728,7 +586,7 @@ int utf_ptr2char(const char_u *p)
* If byte sequence is illegal or incomplete, returns -1 and does not advance
* "s".
*/
-static int utf_safe_read_char_adv(char_u **s, size_t *n)
+static int utf_safe_read_char_adv(const char_u **s, size_t *n)
{
int c;
@@ -770,7 +628,7 @@ static int utf_safe_read_char_adv(char_u **s, size_t *n)
* Get character at **pp and advance *pp to the next character.
* Note: composing characters are skipped!
*/
-int mb_ptr2char_adv(char_u **pp)
+int mb_ptr2char_adv(const char_u **const pp)
{
int c;
@@ -783,15 +641,12 @@ int mb_ptr2char_adv(char_u **pp)
* Get character at **pp and advance *pp to the next character.
* Note: composing characters are returned as separate characters.
*/
-int mb_cptr2char_adv(char_u **pp)
+int mb_cptr2char_adv(const char_u **pp)
{
int c;
c = (*mb_ptr2char)(*pp);
- if (enc_utf8)
- *pp += utf_ptr2len(*pp);
- else
- *pp += (*mb_ptr2len)(*pp);
+ *pp += utf_ptr2len(*pp);
return c;
}
@@ -1077,12 +932,12 @@ int utf_char2len(int c)
return 6;
}
-/*
- * Convert Unicode character "c" to UTF-8 string in "buf[]".
- * Returns the number of bytes.
- * This does not include composing characters.
- */
-int utf_char2bytes(int c, char_u *buf)
+/// Convert Unicode character to UTF-8 string
+///
+/// @param c character to convert to \p buf
+/// @param[out] buf UTF-8 string generated from \p c, does not add \0
+/// @return Number of bytes (1-6). Does not include composing characters.
+int utf_char2bytes(int c, char_u *const buf)
{
if (c < 0x80) { /* 7 bits */
buf[0] = c;
@@ -1322,11 +1177,14 @@ int utf_fold(int a)
return utf_convert(a, foldCase, ARRAY_SIZE(foldCase));
}
-/*
- * Return the upper-case equivalent of "a", which is a UCS-4 character. Use
- * simple case folding.
- */
-int utf_toupper(int a)
+// Vim's own character class functions. These exist because many library
+// islower()/toupper() etc. do not work properly: they crash when used with
+// invalid values or can't handle latin1 when the locale is C.
+// Speed is most important here.
+
+/// Return the upper-case equivalent of "a", which is a UCS-4 character. Use
+/// simple case folding.
+int mb_toupper(int a)
{
/* If 'casemap' contains "keepascii" use ASCII style toupper(). */
if (a < 128 && (cmp_flags & CMP_KEEPASCII))
@@ -1346,17 +1204,15 @@ int utf_toupper(int a)
return utf_convert(a, toUpper, ARRAY_SIZE(toUpper));
}
-bool utf_islower(int a)
+bool mb_islower(int a)
{
- /* German sharp s is lower case but has no upper case equivalent. */
- return (utf_toupper(a) != a) || a == 0xdf;
+ // German sharp s is lower case but has no upper case equivalent.
+ return (mb_toupper(a) != a) || a == 0xdf;
}
-/*
- * Return the lower-case equivalent of "a", which is a UCS-4 character. Use
- * simple case folding.
- */
-int utf_tolower(int a)
+/// Return the lower-case equivalent of "a", which is a UCS-4 character. Use
+/// simple case folding.
+int mb_tolower(int a)
{
/* If 'casemap' contains "keepascii" use ASCII style tolower(). */
if (a < 128 && (cmp_flags & CMP_KEEPASCII))
@@ -1376,12 +1232,13 @@ int utf_tolower(int a)
return utf_convert(a, toLower, ARRAY_SIZE(toLower));
}
-bool utf_isupper(int a)
+bool mb_isupper(int a)
{
- return utf_tolower(a) != a;
+ return mb_tolower(a) != a;
}
-static int utf_strnicmp(char_u *s1, char_u *s2, size_t n1, size_t n2)
+static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1,
+ size_t n2)
{
int c1, c2, cdiff;
char_u buffer[6];
@@ -1451,6 +1308,7 @@ static int utf_strnicmp(char_u *s1, char_u *s2, size_t n1, size_t n2)
# define CP_UTF8 65001 /* magic number from winnls.h */
#endif
+/// Reassigns `strw` to a new, allocated pointer to a UTF16 string.
int utf8_to_utf16(const char *str, WCHAR **strw)
FUNC_ATTR_NONNULL_ALL
{
@@ -1484,42 +1342,48 @@ int utf8_to_utf16(const char *str, WCHAR **strw)
(WCHAR *)pos,
wchar_len);
assert(r == wchar_len);
+ if (r != wchar_len) {
+ EMSG2("MultiByteToWideChar failed: %d", r);
+ }
*strw = (WCHAR *)pos;
return 0;
}
+/// Reassigns `str` to a new, allocated pointer to a UTF8 string.
int utf16_to_utf8(const WCHAR *strw, char **str)
FUNC_ATTR_NONNULL_ALL
{
// Compute the space required to store the string as UTF-8.
- ssize_t utf8_len = WideCharToMultiByte(CP_UTF8,
- 0,
- strw,
- -1,
- NULL,
- 0,
- NULL,
- NULL);
+ DWORD utf8_len = WideCharToMultiByte(CP_UTF8,
+ 0,
+ strw,
+ -1,
+ NULL,
+ 0,
+ NULL,
+ NULL);
if (utf8_len == 0) {
return GetLastError();
}
- ssize_t buf_sz = utf8_len * sizeof(char);
- char *buf = xmalloc(buf_sz);
- char *pos = buf;
+ *str = xmallocz(utf8_len);
- // Convert string to UTF-8.
- int r = WideCharToMultiByte(CP_UTF8,
- 0,
- strw,
- -1,
- (LPSTR *)pos,
- utf8_len,
- NULL,
- NULL);
- assert(r == utf8_len);
- *str = pos;
+ // Convert to UTF-8.
+ utf8_len = WideCharToMultiByte(CP_UTF8,
+ 0,
+ strw,
+ -1,
+ *str,
+ utf8_len,
+ NULL,
+ NULL);
+ if (utf8_len == 0) {
+ free(*str);
+ *str = NULL;
+ return GetLastError();
+ }
+ (*str)[utf8_len] = '\0';
return 0;
}
@@ -1534,48 +1398,26 @@ int utf16_to_utf8(const WCHAR *strw, char **str)
* Returns zero if s1 and s2 are equal (ignoring case), the difference between
* two characters otherwise.
*/
-int mb_strnicmp(char_u *s1, char_u *s2, size_t nn)
-{
- int i, l;
- int cdiff;
- int n = (int)nn;
-
- if (enc_utf8) {
- return utf_strnicmp(s1, s2, nn, nn);
- } else {
- for (i = 0; i < n; i += l) {
- if (s1[i] == NUL && s2[i] == NUL) /* both strings end */
- return 0;
-
- l = (*mb_ptr2len)(s1 + i);
- if (l <= 1) {
- /* Single byte: first check normally, then with ignore case. */
- if (s1[i] != s2[i]) {
- cdiff = vim_tolower(s1[i]) - vim_tolower(s2[i]);
- if (cdiff != 0)
- return cdiff;
- }
- } else {
- /* For non-Unicode multi-byte don't ignore case. */
- if (l > n - i)
- l = n - i;
- cdiff = STRNCMP(s1 + i, s2 + i, l);
- if (cdiff != 0)
- return cdiff;
- }
- }
- }
- return 0;
+int mb_strnicmp(const char_u *s1, const char_u *s2, const size_t nn)
+{
+ return utf_strnicmp(s1, s2, nn, nn);
}
-/* We need to call mb_stricmp() even when we aren't dealing with a multi-byte
- * encoding because mb_stricmp() takes care of all ascii and non-ascii
- * encodings, including characters with umlauts in latin1, etc., while
- * STRICMP() only handles the system locale version, which often does not
- * handle non-ascii properly. */
-int mb_stricmp(char_u *s1, char_u *s2)
+/// Compare strings case-insensitively
+///
+/// @note We need to call mb_stricmp() even when we aren't dealing with
+/// a multi-byte encoding because mb_stricmp() takes care of all ASCII and
+/// non-ascii encodings, including characters with umlauts in latin1,
+/// etc., while STRICMP() only handles the system locale version, which
+/// often does not handle non-ascii properly.
+///
+/// @param[in] s1 First string to compare, not more then #MAXCOL characters.
+/// @param[in] s2 Second string to compare, not more then #MAXCOL characters.
+///
+/// @return 0 if strings are equal, <0 if s1 < s2, >0 if s1 > s2.
+int mb_stricmp(const char *s1, const char *s2)
{
- return mb_strnicmp(s1, s2, MAXCOL);
+ return mb_strnicmp((const char_u *)s1, (const char_u *)s2, MAXCOL);
}
/*
@@ -1693,27 +1535,24 @@ int mb_off_next(char_u *base, char_u *p)
int i;
int j;
- if (enc_utf8) {
- if (*p < 0x80) /* be quick for ASCII */
- return 0;
+ if (*p < 0x80) { // be quick for ASCII
+ return 0;
+ }
- /* Find the next character that isn't 10xx.xxxx */
- for (i = 0; (p[i] & 0xc0) == 0x80; ++i)
- ;
- if (i > 0) {
- /* Check for illegal sequence. */
- for (j = 0; p - j > base; ++j)
- if ((p[-j] & 0xc0) != 0x80)
- break;
- if (utf8len_tab[p[-j]] != i + j)
- return 0;
+ // Find the next character that isn't 10xx.xxxx
+ for (i = 0; (p[i] & 0xc0) == 0x80; i++) {}
+ if (i > 0) {
+ // Check for illegal sequence.
+ for (j = 0; p - j > base; j++) {
+ if ((p[-j] & 0xc0) != 0x80) {
+ break;
+ }
+ }
+ if (utf8len_tab[p[-j]] != i + j) {
+ return 0;
}
- return i;
}
-
- /* Only need to check if we're on a trail byte, it doesn't matter if we
- * want the offset to the next or current character. */
- return (*mb_head_off)(base, p);
+ return i;
}
/*
@@ -1756,10 +1595,10 @@ void utf_find_illegal(void)
char_u *tofree = NULL;
vimconv.vc_type = CONV_NONE;
- if (enc_utf8 && (enc_canon_props(curbuf->b_p_fenc) & ENC_8BIT)) {
- /* 'encoding' is "utf-8" but we are editing a 8-bit encoded file,
- * possibly a utf-8 file with illegal bytes. Setup for conversion
- * from utf-8 to 'fileencoding'. */
+ if (enc_canon_props(curbuf->b_p_fenc) & ENC_8BIT) {
+ // 'encoding' is "utf-8" but we are editing a 8-bit encoded file,
+ // possibly a utf-8 file with illegal bytes. Setup for conversion
+ // from utf-8 to 'fileencoding'.
convert_setup(&vimconv, p_enc, curbuf->b_p_fenc);
}
@@ -1816,29 +1655,42 @@ theend:
*/
void mb_adjust_cursor(void)
{
- mb_adjustpos(curbuf, &curwin->w_cursor);
+ mark_mb_adjustpos(curbuf, &curwin->w_cursor);
}
-/*
- * Adjust position "*lp" to point to the first byte of a multi-byte character.
- * If it points to a tail byte it's moved backwards to the head byte.
- */
-void mb_adjustpos(buf_T *buf, pos_T *lp)
+/// Checks and adjusts cursor column. Not mode-dependent.
+/// @see check_cursor_col_win
+///
+/// @param win_ Places cursor on a valid column for this window.
+void mb_check_adjust_col(void *win_)
{
- char_u *p;
+ win_T *win = (win_T *)win_;
+ colnr_T oldcol = win->w_cursor.col;
+
+ // Column 0 is always valid.
+ if (oldcol != 0) {
+ char_u *p = ml_get_buf(win->w_buffer, win->w_cursor.lnum, false);
+ colnr_T len = (colnr_T)STRLEN(p);
- 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;
+ // Empty line or invalid column?
+ if (len == 0 || oldcol < 0) {
+ win->w_cursor.col = 0;
+ } else {
+ // Cursor column too big for line?
+ if (oldcol > len) {
+ win->w_cursor.col = len - 1;
+ }
+ // Move the cursor to the head byte.
+ win->w_cursor.col -= (*mb_head_off)(p, p + win->w_cursor.col);
+ }
+
+ // Reset `coladd` when the cursor would be on the right half of a
+ // double-wide character.
+ if (win->w_cursor.coladd == 1 && p[win->w_cursor.col] != TAB
+ && vim_isprintc((*mb_ptr2char)(p + win->w_cursor.col))
+ && ptr2cells(p + win->w_cursor.col) > 1) {
+ win->w_cursor.coladd = 0;
+ }
}
}
@@ -1887,52 +1739,55 @@ int mb_charlen_len(char_u *str, int len)
return count;
}
-/*
- * Try to un-escape a multi-byte character.
- * Used for the "to" and "from" part of a mapping.
- * Return the un-escaped string if it is a multi-byte character, and advance
- * "pp" to just after the bytes that formed it.
- * Return NULL if no multi-byte char was found.
- */
-char_u * mb_unescape(char_u **pp)
-{
- static char_u buf[6];
- int n;
- int m = 0;
- char_u *str = *pp;
-
- /* Must translate K_SPECIAL KS_SPECIAL KE_FILLER to K_SPECIAL and CSI
- * KS_EXTRA KE_CSI to CSI.
- * Maximum length of a utf-8 character is 4 bytes. */
- for (n = 0; str[n] != NUL && m < 4; ++n) {
- if (str[n] == K_SPECIAL
- && str[n + 1] == KS_SPECIAL
- && str[n + 2] == KE_FILLER) {
- buf[m++] = K_SPECIAL;
- n += 2;
- } else if ((str[n] == K_SPECIAL
- )
- && str[n + 1] == KS_EXTRA
- && str[n + 2] == (int)KE_CSI) {
- buf[m++] = CSI;
- n += 2;
- } else if (str[n] == K_SPECIAL
- )
- break; /* a special key can't be a multibyte char */
- else
- buf[m++] = str[n];
- buf[m] = NUL;
+/// Try to unescape a multibyte character
+///
+/// Used for the rhs and lhs of the mappings.
+///
+/// @param[in,out] pp String to unescape. Is advanced to just after the bytes
+/// that form a multibyte character.
+///
+/// @return Unescaped string if it is a multibyte character, NULL if no
+/// multibyte character was found. Returns a static buffer, always one
+/// and the same.
+const char *mb_unescape(const char **const pp)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+{
+ static char buf[6];
+ size_t buf_idx = 0;
+ uint8_t *str = (uint8_t *)(*pp);
+
+ // Must translate K_SPECIAL KS_SPECIAL KE_FILLER to K_SPECIAL and CSI
+ // KS_EXTRA KE_CSI to CSI.
+ // Maximum length of a utf-8 character is 4 bytes.
+ for (size_t str_idx = 0; str[str_idx] != NUL && buf_idx < 4; str_idx++) {
+ if (str[str_idx] == K_SPECIAL
+ && str[str_idx + 1] == KS_SPECIAL
+ && str[str_idx + 2] == KE_FILLER) {
+ buf[buf_idx++] = (char)K_SPECIAL;
+ str_idx += 2;
+ } else if ((str[str_idx] == K_SPECIAL)
+ && str[str_idx + 1] == KS_EXTRA
+ && str[str_idx + 2] == KE_CSI) {
+ buf[buf_idx++] = (char)CSI;
+ str_idx += 2;
+ } else if (str[str_idx] == K_SPECIAL) {
+ break; // A special key can't be a multibyte char.
+ } else {
+ buf[buf_idx++] = (char)str[str_idx];
+ }
+ buf[buf_idx] = NUL;
- /* Return a multi-byte character if it's found. An illegal sequence
- * will result in a 1 here. */
- if ((*mb_ptr2len)(buf) > 1) {
- *pp = str + n + 1;
+ // Return a multi-byte character if it's found. An illegal sequence
+ // will result in a 1 here.
+ if (utf_ptr2len((const char_u *)buf) > 1) {
+ *pp = (const char *)str + str_idx + 1;
return buf;
}
- /* Bail out quickly for ASCII. */
- if (buf[0] < 128)
+ // Bail out quickly for ASCII.
+ if ((uint8_t)buf[0] < 128) {
break;
+ }
}
return NULL;
}
@@ -2181,8 +2036,8 @@ void * my_iconv_open(char_u *to, char_u *from)
* Returns the converted string in allocated memory. NULL for an error.
* If resultlenp is not NULL, sets it to the result length in bytes.
*/
-static char_u * iconv_string(vimconv_T *vcp, char_u *str, size_t slen,
- size_t *unconvlenp, size_t *resultlenp)
+static char_u *iconv_string(const vimconv_T *const vcp, char_u *str,
+ size_t slen, size_t *unconvlenp, size_t *resultlenp)
{
const char *from;
size_t fromlen;
@@ -2238,13 +2093,7 @@ static char_u * iconv_string(vimconv_T *vcp, char_u *str, size_t slen,
*to++ = '?';
if ((*mb_ptr2cells)((char_u *)from) > 1)
*to++ = '?';
- if (enc_utf8)
- l = utfc_ptr2len_len((const char_u *)from, (int)fromlen);
- else {
- l = (*mb_ptr2len)((char_u *)from);
- if (l > (int)fromlen)
- l = (int)fromlen;
- }
+ l = utfc_ptr2len_len((const char_u *)from, (int)fromlen);
from += l;
fromlen -= l;
} else if (ICONV_ERRNO != ICONV_E2BIG) {
@@ -2473,7 +2322,7 @@ int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8,
* Illegal chars are often changed to "?", unless vcp->vc_fail is set.
* When something goes wrong, NULL is returned and "*lenp" is unchanged.
*/
-char_u * string_convert(vimconv_T *vcp, char_u *ptr, size_t *lenp)
+char_u *string_convert(const vimconv_T *const vcp, char_u *ptr, size_t *lenp)
{
return string_convert_ext(vcp, ptr, lenp, NULL);
}
@@ -2483,7 +2332,7 @@ char_u * string_convert(vimconv_T *vcp, char_u *ptr, size_t *lenp)
* an incomplete sequence at the end it is not converted and "*unconvlenp" is
* set to the number of remaining bytes.
*/
-char_u * string_convert_ext(vimconv_T *vcp, char_u *ptr,
+char_u * string_convert_ext(const vimconv_T *const vcp, char_u *ptr,
size_t *lenp, size_t *unconvlenp)
{
char_u *retval = NULL;
diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h
index 2c92a0fbb2..bf6ccb13a5 100644
--- a/src/nvim/mbyte.h
+++ b/src/nvim/mbyte.h
@@ -1,7 +1,14 @@
#ifndef NVIM_MBYTE_H
#define NVIM_MBYTE_H
+#include <stdint.h>
#include <stdbool.h>
+#include <string.h>
+
+#include "nvim/iconv.h"
+#include "nvim/func_attr.h"
+#include "nvim/os/os_defs.h" // For WCHAR, indirect
+#include "nvim/types.h" // for char_u
/*
* Return byte length of character that starts with byte "b".
@@ -12,6 +19,9 @@
#define MB_BYTE2LEN(b) utf8len_tab[b]
#define MB_BYTE2LEN_CHECK(b) (((b) < 0 || (b) > 255) ? 1 : utf8len_tab[b])
+// max length of an unicode char
+#define MB_MAXCHAR 6
+
/* properties used in enc_canon_table[] (first three mutually exclusive) */
#define ENC_8BIT 0x01
#define ENC_DBCS 0x02
@@ -40,7 +50,43 @@
#define mb_ptr2char utf_ptr2char
#define mb_head_off utf_head_off
+/// Flags for vimconv_T
+typedef enum {
+ CONV_NONE = 0,
+ CONV_TO_UTF8 = 1,
+ CONV_9_TO_UTF8 = 2,
+ CONV_TO_LATIN1 = 3,
+ CONV_TO_LATIN9 = 4,
+ CONV_ICONV = 5,
+} ConvFlags;
+
+/// Structure used for string conversions
+typedef struct {
+ int vc_type; ///< Zero or more ConvFlags.
+ int vc_factor; ///< Maximal expansion factor.
+# ifdef USE_ICONV
+ iconv_t vc_fd; ///< Value for CONV_ICONV.
+# endif
+ bool vc_fail; ///< What to do with invalid characters: if true, fail,
+ ///< otherwise use '?'.
+} vimconv_T;
+
+extern const uint8_t utf8len_tab_zero[256];
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "mbyte.h.generated.h"
#endif
+
+static inline int mb_strcmp_ic(bool ic, const char *s1, const char *s2)
+ REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Compare strings
+///
+/// @param[in] ic True if case is to be ignored.
+///
+/// @return 0 if s1 == s2, <0 if s1 < s2, >0 if s1 > s2.
+static inline int mb_strcmp_ic(bool ic, const char *s1, const char *s2)
+{
+ return (ic ? mb_stricmp(s1, s2) : strcmp(s1, s2));
+}
#endif // NVIM_MBYTE_H
diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c
index 43412e3916..4428dd42aa 100644
--- a/src/nvim/memfile.c
+++ b/src/nvim/memfile.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// An abstraction to handle blocks of memory which can be stored in a file.
/// This is the implementation of a sort of virtual memory.
///
@@ -51,6 +54,7 @@
#include "nvim/memory.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
+#include "nvim/assert.h"
#include "nvim/os/os.h"
#include "nvim/os/input.h"
@@ -105,23 +109,24 @@ memfile_T *mf_open(char_u *fname, int flags)
if (mfp->mf_fd >= 0 && os_fileinfo_fd(mfp->mf_fd, &file_info)) {
uint64_t blocksize = os_fileinfo_blocksize(&file_info);
if (blocksize >= MIN_SWAP_PAGE_SIZE && blocksize <= MAX_SWAP_PAGE_SIZE) {
- assert(blocksize <= UINT_MAX);
+ STATIC_ASSERT(MAX_SWAP_PAGE_SIZE <= UINT_MAX,
+ "MAX_SWAP_PAGE_SIZE must fit into an unsigned");
mfp->mf_page_size = (unsigned)blocksize;
}
}
- off_t size;
+ off_T size;
// When recovering, the actual block size will be retrieved from block 0
// in ml_recover(). The size used here may be wrong, therefore mf_blocknr_max
// must be rounded up.
if (mfp->mf_fd < 0
|| (flags & (O_TRUNC|O_EXCL))
- || (size = lseek(mfp->mf_fd, (off_t)0L, SEEK_END)) <= 0) {
+ || (size = vim_lseek(mfp->mf_fd, 0L, SEEK_END)) <= 0) {
// no file or empty file
mfp->mf_blocknr_max = 0;
} else {
- assert(sizeof(off_t) <= sizeof(blocknr_T)
+ assert(sizeof(off_T) <= sizeof(blocknr_T)
&& mfp->mf_page_size > 0
&& mfp->mf_page_size - 1 <= INT64_MAX - size);
mfp->mf_blocknr_max = (((blocknr_T)size + mfp->mf_page_size - 1)
@@ -684,9 +689,9 @@ static int mf_read(memfile_T *mfp, bhdr_T *hp)
return FAIL;
unsigned page_size = mfp->mf_page_size;
- // TODO(elmart): Check (page_size * hp->bh_bnum) within off_t bounds.
- off_t offset = (off_t)(page_size * hp->bh_bnum);
- if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset) {
+ // TODO(elmart): Check (page_size * hp->bh_bnum) within off_T bounds.
+ off_T offset = (off_T)(page_size * hp->bh_bnum);
+ if (vim_lseek(mfp->mf_fd, offset, SEEK_SET) != offset) {
PERROR(_("E294: Seek error in swap file read"));
return FAIL;
}
@@ -711,7 +716,7 @@ static int mf_read(memfile_T *mfp, bhdr_T *hp)
/// - Write error in swap file.
static int mf_write(memfile_T *mfp, bhdr_T *hp)
{
- off_t offset; // offset in the file
+ off_T offset; // offset in the file
blocknr_T nr; // block nr which is being written
bhdr_T *hp2;
unsigned page_size; // number of bytes in a page
@@ -740,9 +745,9 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp)
hp2 = hp;
}
- // TODO(elmart): Check (page_size * nr) within off_t bounds.
- offset = (off_t)(page_size * nr);
- if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset) {
+ // TODO(elmart): Check (page_size * nr) within off_T bounds.
+ offset = (off_T)(page_size * nr);
+ if (vim_lseek(mfp->mf_fd, offset, SEEK_SET) != offset) {
PERROR(_("E296: Seek error in swap file write"));
return FAIL;
}
@@ -890,6 +895,7 @@ static bool mf_do_open(memfile_T *mfp, char_u *fname, int flags)
{
// fname cannot be NameBuff, because it must have been allocated.
mf_set_fnames(mfp, fname);
+ assert(mfp->mf_fname != NULL);
/// Extra security check: When creating a swap file it really shouldn't
/// exist yet. If there is a symbolic link, this is most likely an attack.
@@ -909,12 +915,7 @@ static bool mf_do_open(memfile_T *mfp, char_u *fname, int flags)
return false;
}
-#ifdef HAVE_FD_CLOEXEC
- int fdflags = fcntl(mfp->mf_fd, F_GETFD);
- if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0) {
- (void)fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC);
- }
-#endif
+ (void)os_set_cloexec(mfp->mf_fd);
#ifdef HAVE_SELINUX
mch_copy_sec(fname, mfp->mf_fname);
#endif
diff --git a/src/nvim/memfile_defs.h b/src/nvim/memfile_defs.h
index cc71e1a7ff..b3c2f3564c 100644
--- a/src/nvim/memfile_defs.h
+++ b/src/nvim/memfile_defs.h
@@ -3,8 +3,10 @@
#include <stdint.h>
#include <stdbool.h>
+#include <stdlib.h>
#include "nvim/types.h"
+#include "nvim/pos.h"
/// A block number.
///
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index a9a53ebca7..f28a9e60f4 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/* for debugging */
/* #define CHECK(c, s) if (c) EMSG(s) */
#define CHECK(c, s)
@@ -439,14 +442,7 @@ void ml_setname(buf_T *buf)
EMSG(_("E301: Oops, lost the swap file!!!"));
return;
}
-#ifdef HAVE_FD_CLOEXEC
- {
- int fdflags = fcntl(mfp->mf_fd, F_GETFD);
- if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0) {
- (void)fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC);
- }
- }
-#endif
+ (void)os_set_cloexec(mfp->mf_fd);
}
if (!success)
EMSG(_("E302: Could not rename swap file"));
@@ -623,7 +619,7 @@ static bool ml_check_b0_strings(ZERO_BL *b0p)
return (memchr(b0p->b0_version, NUL, 10)
&& memchr(b0p->b0_uname, NUL, B0_UNAME_SIZE)
&& memchr(b0p->b0_hname, NUL, B0_HNAME_SIZE)
- && memchr(b0p->b0_fname, NUL, B0_FNAME_SIZE_CRYPT));
+ && memchr(b0p->b0_fname, NUL, B0_FNAME_SIZE_CRYPT)); // -V512
}
/*
@@ -767,7 +763,7 @@ void ml_recover(void)
int idx;
int top;
int txt_start;
- off_t size;
+ off_T size;
int called_from_main;
int serious_error = TRUE;
long mtime;
@@ -918,10 +914,11 @@ void ml_recover(void)
msg_end();
goto theend;
}
- if ((size = lseek(mfp->mf_fd, (off_t)0L, SEEK_END)) <= 0)
- mfp->mf_blocknr_max = 0; /* no file or empty file */
- else
+ if ((size = vim_lseek(mfp->mf_fd, (off_T)0L, SEEK_END)) <= 0) {
+ mfp->mf_blocknr_max = 0; // no file or empty file
+ } else {
mfp->mf_blocknr_max = size / mfp->mf_page_size;
+ }
mfp->mf_infile_count = mfp->mf_blocknr_max;
/* need to reallocate the memory used to store the data */
@@ -999,7 +996,7 @@ void ml_recover(void)
if (b0_ff != 0)
set_fileformat(b0_ff - 1, OPT_LOCAL);
if (b0_fenc != NULL) {
- set_option_value((char_u *)"fenc", 0L, b0_fenc, OPT_LOCAL);
+ set_option_value("fenc", 0L, (char *)b0_fenc, OPT_LOCAL);
xfree(b0_fenc);
}
unchanged(curbuf, TRUE);
@@ -1063,11 +1060,12 @@ void ml_recover(void)
if (!cannot_open) {
line_count = pp->pb_pointer[idx].pe_line_count;
if (readfile(curbuf->b_ffname, NULL, lnum,
- pp->pb_pointer[idx].pe_old_lnum - 1,
- line_count, NULL, 0) == FAIL)
- cannot_open = TRUE;
- else
+ pp->pb_pointer[idx].pe_old_lnum - 1, line_count,
+ NULL, 0) != OK) {
+ cannot_open = true;
+ } else {
lnum += line_count;
+ }
}
if (cannot_open) {
++error;
@@ -1179,7 +1177,7 @@ void ml_recover(void)
* empty. Don't set the modified flag then. */
if (!(curbuf->b_ml.ml_line_count == 2 && *ml_get(1) == NUL)) {
changed_int();
- ++curbuf->b_changedtick;
+ buf_set_changedtick(curbuf, curbuf->b_changedtick + 1);
}
} else {
for (idx = 1; idx <= lnum; ++idx) {
@@ -1189,7 +1187,7 @@ void ml_recover(void)
xfree(p);
if (i != 0) {
changed_int();
- ++curbuf->b_changedtick;
+ buf_set_changedtick(curbuf, curbuf->b_changedtick + 1);
break;
}
}
@@ -1409,8 +1407,8 @@ recover_names (
for (int i = 0; i < num_files; ++i) {
/* print the swap file name */
msg_outnum((long)++file_count);
- MSG_PUTS(". ");
- msg_puts(path_tail(files[i]));
+ msg_puts(". ");
+ msg_puts((const char *)path_tail(files[i]));
msg_putchar('\n');
(void)swapfile_info(files[i]);
}
@@ -1462,6 +1460,7 @@ static int process_still_running;
*/
static time_t swapfile_info(char_u *fname)
{
+ assert(fname != NULL);
int fd;
struct block0 b0;
time_t x = (time_t)0;
@@ -2317,7 +2316,7 @@ ml_append_int (
*
* return FAIL for failure, OK otherwise
*/
-int ml_replace(linenr_T lnum, char_u *line, int copy)
+int ml_replace(linenr_T lnum, char_u *line, bool copy)
{
if (line == NULL) /* just checking... */
return FAIL;
@@ -3137,6 +3136,7 @@ attention_message (
char_u *fname /* swap file name */
)
{
+ assert(buf->b_fname != NULL);
time_t x, sx;
char *p;
@@ -3368,29 +3368,32 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
}
if (swap_exists_action != SEA_NONE && choice == 0) {
- char *name;
+ const char *const sw_msg_1 = _("Swap file \"");
+ const char *const sw_msg_2 = _("\" already exists!");
const size_t fname_len = strlen(fname);
- name = xmalloc(fname_len
- + strlen(_("Swap file \""))
- + strlen(_("\" already exists!")) + 5);
- STRCPY(name, _("Swap file \""));
- home_replace(NULL, (char_u *) fname, (char_u *)&name[strlen(name)],
- fname_len, true);
- STRCAT(name, _("\" already exists!"));
- choice = do_dialog(VIM_WARNING,
- (char_u *)_("VIM - ATTENTION"),
- (char_u *)(name == NULL
- ? _("Swap file already exists!")
- : name),
+ const size_t sw_msg_1_len = strlen(sw_msg_1);
+ const size_t sw_msg_2_len = strlen(sw_msg_2);
+
+ const size_t name_len = sw_msg_1_len + fname_len + sw_msg_2_len + 5;
+
+ char *const name = xmalloc(name_len);
+ memcpy(name, sw_msg_1, sw_msg_1_len + 1);
+ home_replace(NULL, (char_u *)fname, (char_u *)&name[sw_msg_1_len],
+ fname_len, true);
+ xstrlcat(name, sw_msg_2, name_len);
+ choice = do_dialog(VIM_WARNING, (char_u *)_("VIM - ATTENTION"),
+ (char_u *)name,
# if defined(UNIX)
- process_still_running
- ? (char_u *)_(
- "&Open Read-Only\n&Edit anyway\n&Recover\n&Quit\n&Abort") :
+ process_still_running
+ ? (char_u *)_(
+ "&Open Read-Only\n&Edit anyway\n&Recover"
+ "\n&Quit\n&Abort") :
# endif
- (char_u *)_(
- "&Open Read-Only\n&Edit anyway\n&Recover\n&Delete it\n&Quit\n&Abort"),
- 1, NULL, FALSE);
+ (char_u *)_(
+ "&Open Read-Only\n&Edit anyway\n&Recover"
+ "\n&Delete it\n&Quit\n&Abort"),
+ 1, NULL, false);
# if defined(UNIX)
if (process_still_running && choice >= 4)
diff --git a/src/nvim/memline.h b/src/nvim/memline.h
index f84e86fea0..a239c6a031 100644
--- a/src/nvim/memline.h
+++ b/src/nvim/memline.h
@@ -2,6 +2,8 @@
#define NVIM_MEMLINE_H
#include "nvim/types.h"
+#include "nvim/pos.h" // for pos_T, linenr_T, colnr_T
+#include "nvim/buffer_defs.h" // for buf_T
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "memline.h.generated.h"
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index 92ead873ae..328b96fd5c 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
// Various routines dealing with allocation and deallocation of memory.
#include <assert.h>
@@ -342,10 +345,6 @@ char *xstpcpy(char *restrict dst, const char *restrict src)
/// WARNING: xstpncpy will ALWAYS write maxlen bytes. If src is shorter than
/// maxlen, zeroes will be written to the remaining bytes.
///
-/// TODO(aktau): I don't see a good reason to have this last behaviour, and
-/// it is potentially wasteful. Could we perhaps deviate from the standard
-/// and not zero the rest of the buffer?
-///
/// @param dst
/// @param src
/// @param maxlen
@@ -364,29 +363,58 @@ char *xstpncpy(char *restrict dst, const char *restrict src, size_t maxlen)
}
}
-/// xstrlcpy - Copy a %NUL terminated string into a sized buffer
+/// xstrlcpy - Copy a NUL-terminated string into a sized buffer
///
-/// Compatible with *BSD strlcpy: the result is always a valid
-/// NUL-terminated string that fits in the buffer (unless,
-/// of course, the buffer size is zero). It does not pad
-/// out the result like strncpy() does.
+/// Compatible with *BSD strlcpy: the result is always a valid NUL-terminated
+/// string that fits in the buffer (unless, of course, the buffer size is
+/// zero). It does not pad out the result like strncpy() does.
///
-/// @param dst Where to copy the string to
-/// @param src Where to copy the string from
-/// @param size Size of destination buffer
-/// @return Length of the source string (i.e.: strlen(src))
-size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t size)
+/// @param dst Buffer to store the result
+/// @param src String to be copied
+/// @param dsize Size of `dst`
+/// @return strlen(src). If retval >= dstsize, truncation occurs.
+size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t dsize)
FUNC_ATTR_NONNULL_ALL
{
- size_t ret = strlen(src);
+ size_t slen = strlen(src);
- if (size) {
- size_t len = (ret >= size) ? size - 1 : ret;
+ if (dsize) {
+ size_t len = MIN(slen, dsize - 1);
memcpy(dst, src, len);
dst[len] = '\0';
}
- return ret;
+ return slen; // Does not include NUL.
+}
+
+/// Appends `src` to string `dst` of size `dsize` (unlike strncat, dsize is the
+/// full size of `dst`, not space left). At most dsize-1 characters
+/// will be copied. Always NUL terminates. `src` and `dst` may overlap.
+///
+/// @see vim_strcat from Vim.
+/// @see strlcat from OpenBSD.
+///
+/// @param dst Buffer to be appended-to. Must have a NUL byte.
+/// @param src String to put at the end of `dst`
+/// @param dsize Size of `dst` including NUL byte. Must be greater than 0.
+/// @return strlen(src) + strlen(initial dst)
+/// If retval >= dsize, truncation occurs.
+size_t xstrlcat(char *const dst, const char *const src, const size_t dsize)
+ FUNC_ATTR_NONNULL_ALL
+{
+ assert(dsize > 0);
+ const size_t dlen = strlen(dst);
+ assert(dlen < dsize);
+ const size_t slen = strlen(src);
+
+ if (slen > dsize - dlen - 1) {
+ memmove(dst + dlen, src, dsize - dlen - 1);
+ dst[dsize - 1] = '\0';
+ } else {
+ memmove(dst + dlen, src, slen + 1);
+ }
+
+ return slen + dlen; // Does not include NUL.
}
/// strdup() wrapper
@@ -401,6 +429,19 @@ char *xstrdup(const char *str)
return xmemdupz(str, strlen(str));
}
+/// strdup() wrapper
+///
+/// Unlike xstrdup() allocates a new empty string if it receives NULL.
+char *xstrdupnul(const char *const str)
+ FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
+{
+ if (str == NULL) {
+ return xmallocz(0);
+ } else {
+ return xstrdup(str);
+ }
+}
+
/// A version of memchr that starts the search at `src + len`.
///
/// Based on glibc's memrchr.
@@ -446,6 +487,20 @@ void *xmemdup(const void *data, size_t len)
return memcpy(xmalloc(len), data, len);
}
+/// Returns true if strings `a` and `b` are equal. Arguments may be NULL.
+bool strequal(const char *a, const char *b)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ return (a == NULL && b == NULL) || (a && b && strcmp(a, b) == 0);
+}
+
+/// Case-insensitive `strequal`.
+bool striequal(const char *a, const char *b)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ return (a == NULL && b == NULL) || (a && b && STRICMP(a, b) == 0);
+}
+
/*
* Avoid repeating the error message many times (they take 1 second each).
* Did_outofmem_msg is reset when a character is read.
@@ -530,7 +585,7 @@ void free_all_mem(void)
p_ea = false;
if (first_tabpage->tp_next != NULL)
do_cmdline_cmd("tabonly!");
- if (firstwin != lastwin)
+ if (!ONE_WINDOW)
do_cmdline_cmd("only!");
/* Free all spell info. */
@@ -596,18 +651,6 @@ void free_all_mem(void)
/* Destroy all windows. Must come before freeing buffers. */
win_free_all();
- /* Free all buffers. Reset 'autochdir' to avoid accessing things that
- * were freed already. */
- p_acd = false;
- for (buf = firstbuf; buf != NULL; ) {
- nextbuf = buf->b_next;
- close_buffer(NULL, buf, DOBUF_WIPE, false);
- if (buf_valid(buf))
- buf = nextbuf; /* didn't work, try next one */
- else
- buf = firstbuf;
- }
-
free_cmdline_buf();
/* Clear registers. */
@@ -631,6 +674,20 @@ void free_all_mem(void)
eval_clear();
+ // Free all buffers. Reset 'autochdir' to avoid accessing things that
+ // were freed already.
+ // Must be after eval_clear to avoid it trying to access b:changedtick after
+ // freeing it.
+ p_acd = false;
+ for (buf = firstbuf; buf != NULL; ) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ nextbuf = buf->b_next;
+ close_buffer(NULL, buf, DOBUF_WIPE, false);
+ // Didn't work, try next one.
+ buf = bufref_valid(&bufref) ? nextbuf : firstbuf;
+ }
+
/* screenlines (can't display anything now!) */
free_screenlines();
diff --git a/src/nvim/menu.c b/src/nvim/menu.c
index 7c0eee64dd..0db250d111 100644
--- a/src/nvim/menu.c
+++ b/src/nvim/menu.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* Code for menus. Used for the GUI and 'wildmenu'.
* GUI/Motif support by Robert Webb
@@ -23,7 +26,7 @@
#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
-
+#include "nvim/eval/typval.h"
#define MENUDEPTH 10 /* maximum depth of menus */
@@ -35,8 +38,8 @@
-/* The character for each menu mode */
-static char_u menu_mode_chars[] = {'n', 'v', 's', 'o', 'i', 'c', 't'};
+/// The character for each menu mode
+static char_u menu_mode_chars[] = { 'n', 'v', 's', 'o', 'i', 'c', 't' };
static char_u e_notsubmenu[] = N_(
"E327: Part of menu-item path is not sub-menu");
@@ -44,20 +47,16 @@ static char_u e_othermode[] = N_("E328: Menu only exists in another mode");
static char_u e_nomenu[] = N_("E329: No menu \"%s\"");
-/*
- * Do the :menu command and relatives.
- */
-void
-ex_menu (
- exarg_T *eap /* Ex command arguments */
-)
+/// Do the :menu command and relatives.
+/// @param eap Ex command arguments
+void
+ex_menu(exarg_T *eap)
{
char_u *menu_path;
int modes;
- char_u *map_to;
+ char_u *map_to; // command mapped to the menu entry
int noremap;
bool silent = false;
- bool special = false;
int unmenu;
char_u *map_buf;
char_u *arg;
@@ -83,7 +82,7 @@ ex_menu (
continue;
}
if (STRNCMP(arg, "<special>", 9) == 0) {
- special = true;
+ // Ignore obsolete "<special>" modifier.
arg = skipwhite(arg + 9);
continue;
}
@@ -91,7 +90,8 @@ ex_menu (
}
- /* Locate an optional "icon=filename" argument. */
+ // Locate an optional "icon=filename" argument
+ // TODO(nvim): Currently this is only parsed. Should expose it to UIs.
if (STRNCMP(arg, "icon=", 5) == 0) {
arg += 5;
while (*arg != NUL && *arg != ' ') {
@@ -105,12 +105,12 @@ ex_menu (
}
}
- /*
- * Fill in the priority table.
- */
- for (p = arg; *p; ++p)
- if (!ascii_isdigit(*p) && *p != '.')
+ // Fill in the priority table.
+ for (p = arg; *p; p++) {
+ if (!ascii_isdigit(*p) && *p != '.') {
break;
+ }
+ }
if (ascii_iswhite(*p)) {
for (i = 0; i < MENUDEPTH && !ascii_iswhite(*arg); ++i) {
pri_tab[i] = getdigits_long(&arg);
@@ -219,13 +219,12 @@ ex_menu (
map_buf = NULL; // Menu tips are plain text.
} else {
map_to = replace_termcodes(map_to, STRLEN(map_to), &map_buf, false, true,
- special, CPO_TO_CPO_FLAGS);
+ true, CPO_TO_CPO_FLAGS);
}
menuarg.modes = modes;
menuarg.noremap[0] = noremap;
menuarg.silent[0] = silent;
- add_menu_path(menu_path, &menuarg, pri_tab, map_to
- );
+ add_menu_path(menu_path, &menuarg, pri_tab, map_to);
/*
* For the PopUp menu, add a menu for each mode separately.
@@ -244,22 +243,24 @@ ex_menu (
xfree(map_buf);
}
- ui_update_menu();
+ ui_call_update_menu();
theend:
;
}
-/*
- * Add the menu with the given name to the menu hierarchy
- */
-static int
-add_menu_path (
- char_u *menu_path,
- vimmenu_T *menuarg, /* passes modes, iconfile, iconidx,
- icon_builtin, silent[0], noremap[0] */
- long *pri_tab,
- char_u *call_data
+
+/// Add the menu with the given name to the menu hierarchy
+///
+/// @param[out] menuarg menu entry
+/// @param[] pri_tab priority table
+/// @param[in] call_data Right hand side command
+static int
+add_menu_path(
+ const char_u *const menu_path,
+ vimmenu_T *menuarg,
+ const long *const pri_tab,
+ const char_u *const call_data
)
{
char_u *path_name;
@@ -294,8 +295,9 @@ add_menu_path (
if (map_to != NULL) {
en_name = name;
name = map_to;
- } else
+ } else {
en_name = NULL;
+ }
dname = menu_text(name, NULL, NULL);
if (*dname == NUL) {
/* Only a mnemonic or accelerator is not valid. */
@@ -309,14 +311,15 @@ add_menu_path (
while (menu != NULL) {
if (menu_name_equal(name, menu) || menu_name_equal(dname, menu)) {
if (*next_name == NUL && menu->children != NULL) {
- if (!sys_menu)
+ if (!sys_menu) {
EMSG(_("E330: Menu path must not lead to a sub-menu"));
+ }
goto erret;
}
- if (*next_name != NUL && menu->children == NULL
- ) {
- if (!sys_menu)
+ if (*next_name != NUL && menu->children == NULL) {
+ if (!sys_menu) {
EMSG(_(e_notsubmenu));
+ }
goto erret;
}
break;
@@ -350,7 +353,7 @@ add_menu_path (
menu->modes = modes;
menu->enabled = MENU_ALL_MODES;
menu->name = vim_strsave(name);
- /* separate mnemonic and accelerator text from actual menu name */
+ // separate mnemonic and accelerator text from actual menu name
menu->dname = menu_text(name, &menu->mnemonic, &menu->actext);
if (en_name != NULL) {
menu->en_name = vim_strsave(en_name);
@@ -362,9 +365,7 @@ add_menu_path (
menu->priority = pri_tab[pri_idx];
menu->parent = parent;
- /*
- * Add after menu that has lower priority.
- */
+ // Add after menu that has lower priority.
menu->next = *lower_pri;
*lower_pri = menu;
@@ -390,8 +391,9 @@ add_menu_path (
name = next_name;
xfree(dname);
dname = NULL;
- if (pri_tab[pri_idx + 1] != -1)
- ++pri_idx;
+ if (pri_tab[pri_idx + 1] != -1) {
+ pri_idx++;
+ }
}
xfree(path_name);
@@ -417,8 +419,7 @@ add_menu_path (
// Don't do this for "<Nop>".
c = 0;
d = 0;
- if (amenu && call_data != NULL && *call_data != NUL
- ) {
+ if (amenu && call_data != NULL && *call_data != NUL) {
switch (1 << i) {
case MENU_VISUAL_MODE:
case MENU_SELECT_MODE:
@@ -436,9 +437,9 @@ add_menu_path (
if (c != 0) {
menu->strings[i] = xmalloc(STRLEN(call_data) + 5 );
menu->strings[i][0] = c;
- if (d == 0)
+ if (d == 0) {
STRCPY(menu->strings[i] + 1, call_data);
- else {
+ } else {
menu->strings[i][1] = d;
STRCPY(menu->strings[i] + 2, call_data);
}
@@ -450,8 +451,9 @@ add_menu_path (
menu->strings[i][len + 1] = Ctrl_G;
menu->strings[i][len + 2] = NUL;
}
- } else
+ } else {
menu->strings[i] = p;
+ }
menu->noremap[i] = menuarg->noremap[0];
menu->silent[i] = menuarg->silent[0];
}
@@ -655,20 +657,107 @@ static void free_menu_string(vimmenu_T *menu, int idx)
menu->strings[idx] = NULL;
}
-/*
- * Show the mapping associated with a menu item or hierarchy in a sub-menu.
- */
-static int show_menus(char_u *path_name, int modes)
+/// Export menus
+///
+/// @param[in] menu if null, starts from root_menu
+/// @param modes, a choice of \ref MENU_MODES
+/// @return a dict with name/commands
+/// @see menu_get
+static dict_T *menu_get_recursive(const vimmenu_T *menu, int modes)
+{
+ dict_T *dict;
+
+ if (!menu || (menu->modes & modes) == 0x0) {
+ return NULL;
+ }
+
+ dict = tv_dict_alloc();
+ tv_dict_add_str(dict, S_LEN("name"), (char *)menu->dname);
+ tv_dict_add_nr(dict, S_LEN("priority"), (int)menu->priority);
+ tv_dict_add_nr(dict, S_LEN("hidden"), menu_is_hidden(menu->dname));
+
+ if (menu->mnemonic) {
+ char buf[MB_MAXCHAR + 1] = { 0 }; // > max value of utf8_char2bytes
+ utf_char2bytes(menu->mnemonic, (char_u *)buf);
+ tv_dict_add_str(dict, S_LEN("shortcut"), buf);
+ }
+
+ if (menu->modes & MENU_TIP_MODE && menu->strings[MENU_INDEX_TIP]) {
+ tv_dict_add_str(dict, S_LEN("tooltip"),
+ (char *)menu->strings[MENU_INDEX_TIP]);
+ }
+
+ if (!menu->children) {
+ // leaf menu
+ dict_T *commands = tv_dict_alloc();
+ tv_dict_add_dict(dict, S_LEN("mappings"), commands);
+
+ for (int bit = 0; bit < MENU_MODES; bit++) {
+ if ((menu->modes & modes & (1 << bit)) != 0) {
+ dict_T *impl = tv_dict_alloc();
+ if (*menu->strings[bit] == NUL) {
+ tv_dict_add_str(impl, S_LEN("rhs"), (char *)"<Nop>");
+ } else {
+ tv_dict_add_str(impl, S_LEN("rhs"), (char *)menu->strings[bit]);
+ }
+ tv_dict_add_nr(impl, S_LEN("silent"), menu->silent[bit]);
+ tv_dict_add_nr(impl, S_LEN("enabled"),
+ (menu->enabled & (1 << bit)) ? 1 : 0);
+ tv_dict_add_nr(impl, S_LEN("noremap"),
+ (menu->noremap[bit] & REMAP_NONE) ? 1 : 0);
+ tv_dict_add_nr(impl, S_LEN("sid"),
+ (menu->noremap[bit] & REMAP_SCRIPT) ? 1 : 0);
+ tv_dict_add_dict(commands, (char *)&menu_mode_chars[bit], 1, impl);
+ }
+ }
+ } else {
+ // visit recursively all children
+ list_T *children_list = tv_list_alloc();
+ for (menu = menu->children; menu != NULL; menu = menu->next) {
+ dict_T *dic = menu_get_recursive(menu, modes);
+ if (tv_dict_len(dict) > 0) {
+ tv_list_append_dict(children_list, dic);
+ }
+ }
+ tv_dict_add_list(dict, S_LEN("submenus"), children_list);
+ }
+ return dict;
+}
+
+
+/// Export menus matching path \p path_name
+///
+/// @param path_name
+/// @param modes supported modes, see \ref MENU_MODES
+/// @param[in,out] list must be allocated
+/// @return false if could not find path_name
+bool menu_get(char_u *const path_name, int modes, list_T *list)
{
- char_u *p;
- char_u *name;
vimmenu_T *menu;
- vimmenu_T *parent = NULL;
+ menu = find_menu(root_menu, path_name, modes);
+ if (!menu) {
+ return false;
+ }
+ for (; menu != NULL; menu = menu->next) {
+ dict_T *dict = menu_get_recursive(menu, modes);
+ if (dict && tv_dict_len(dict) > 0) {
+ tv_list_append_dict(list, dict);
+ }
+ }
+ return true;
+}
- menu = root_menu;
- name = path_name = vim_strsave(path_name);
- /* First, find the (sub)menu with the given name */
+/// Find menu matching required name and modes
+///
+/// @param menu top menu to start looking from
+/// @param name path towards the menu
+/// @return menu if \p name is null, found menu or NULL
+vimmenu_T *
+find_menu(vimmenu_T *menu, char_u * name, int modes)
+{
+ char_u *p;
+
while (*name) {
p = menu_name_skip(name);
while (menu != NULL) {
@@ -676,39 +765,46 @@ static int show_menus(char_u *path_name, int modes)
/* Found menu */
if (*p != NUL && menu->children == NULL) {
EMSG(_(e_notsubmenu));
- xfree(path_name);
- return FAIL;
+ return NULL;
} else if ((menu->modes & modes) == 0x0) {
EMSG(_(e_othermode));
- xfree(path_name);
- return FAIL;
+ return NULL;
}
break;
}
menu = menu->next;
}
+
if (menu == NULL) {
EMSG2(_(e_nomenu), name);
- xfree(path_name);
- return FAIL;
+ return NULL;
}
name = p;
- parent = menu;
menu = menu->children;
}
- xfree(path_name);
+ return menu;
+}
+
+/// Show the mapping associated with a menu item or hierarchy in a sub-menu.
+static int show_menus(char_u *const path_name, int modes)
+{
+ vimmenu_T *menu;
+
+ // First, find the (sub)menu with the given name
+ menu = find_menu(root_menu, path_name, modes);
+ if (!menu) {
+ return FAIL;
+ }
/* Now we have found the matching menu, and we list the mappings */
/* Highlight title */
MSG_PUTS_TITLE(_("\n--- Menus ---"));
- show_menus_recursive(parent, modes, 0);
+ show_menus_recursive(menu->parent, modes, 0);
return OK;
}
-/*
- * Recursively show the mappings associated with the menus under the given one
- */
+/// Recursively show the mappings associated with the menus under the given one
static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
{
int i;
@@ -755,10 +851,11 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
else
msg_putchar(' ');
MSG_PUTS(" ");
- if (*menu->strings[bit] == NUL)
- msg_puts_attr((char_u *)"<Nop>", hl_attr(HLF_8));
- else
- msg_outtrans_special(menu->strings[bit], FALSE);
+ if (*menu->strings[bit] == NUL) {
+ msg_puts_attr("<Nop>", hl_attr(HLF_8));
+ } else {
+ msg_outtrans_special(menu->strings[bit], false);
+ }
}
} else {
if (menu == NULL) {
@@ -990,12 +1087,13 @@ char_u *get_menu_names(expand_T *xp, int idx)
return str;
}
-/*
- * Skip over this element of the menu path and return the start of the next
- * element. Any \ and ^Vs are removed from the current element.
- * "name" may be modified.
- */
-char_u *menu_name_skip(char_u *name)
+
+/// Skip over this element of the menu path and return the start of the next
+/// element. Any \ and ^Vs are removed from the current element.
+///
+/// @param name may be modified.
+/// @return start of the next element
+char_u *menu_name_skip(char_u *const name)
{
char_u *p;
@@ -1015,16 +1113,16 @@ char_u *menu_name_skip(char_u *name)
* Return TRUE when "name" matches with menu "menu". The name is compared in
* two ways: raw menu name and menu name without '&'. ignore part after a TAB.
*/
-static int menu_name_equal(char_u *name, vimmenu_T *menu)
+static bool menu_name_equal(const char_u *const name, vimmenu_T *const menu)
{
if (menu->en_name != NULL
&& (menu_namecmp(name, menu->en_name)
|| menu_namecmp(name, menu->en_dname)))
- return TRUE;
+ return true;
return menu_namecmp(name, menu->name) || menu_namecmp(name, menu->dname);
}
-static int menu_namecmp(char_u *name, char_u *mname)
+static bool menu_namecmp(const char_u *const name, const char_u *const mname)
{
int i;
@@ -1035,18 +1133,20 @@ static int menu_namecmp(char_u *name, char_u *mname)
&& (mname[i] == NUL || mname[i] == TAB);
}
-/*
- * Return the modes specified by the given menu command (eg :menu! returns
- * MENU_CMDLINE_MODE | MENU_INSERT_MODE).
- * If "noremap" is not NULL, then the flag it points to is set according to
- * whether the command is a "nore" command.
- * If "unmenu" is not NULL, then the flag it points to is set according to
- * whether the command is an "unmenu" command.
- */
-static int
-get_menu_cmd_modes (
- char_u *cmd,
- int forceit, /* Was there a "!" after the command? */
+
+/// Returns the \ref MENU_MODES specified by menu command `cmd`.
+/// (eg :menu! returns MENU_CMDLINE_MODE | MENU_INSERT_MODE)
+///
+/// @param[in] cmd string like "nmenu", "vmenu", etc.
+/// @param[in] forceit bang (!) was given after the command
+/// @param[out] noremap If not NULL, the flag it points to is set according
+/// to whether the command is a "nore" command.
+/// @param[out] unmenu If not NULL, the flag it points to is set according
+/// to whether the command is an "unmenu" command.
+int
+get_menu_cmd_modes(
+ const char_u * cmd,
+ bool forceit,
int *noremap,
int *unmenu
)
@@ -1087,12 +1187,15 @@ get_menu_cmd_modes (
}
/* FALLTHROUGH */
default:
- --cmd;
- if (forceit) /* menu!! */
+ cmd--;
+ if (forceit) {
+ // menu!!
modes = MENU_INSERT_MODE | MENU_CMDLINE_MODE;
- else /* menu */
+ } else {
+ // menu
modes = MENU_NORMAL_MODE | MENU_VISUAL_MODE | MENU_SELECT_MODE
| MENU_OP_PENDING_MODE;
+ }
}
if (noremap != NULL)
@@ -1198,12 +1301,14 @@ int menu_is_separator(char_u *name)
return name[0] == '-' && name[STRLEN(name) - 1] == '-';
}
-/*
- * Return TRUE if the menu is hidden: Starts with ']'
- */
+
+/// True if a popup menu or starts with \ref MNU_HIDDEN_CHAR
+///
+/// @return true if the menu is hidden
static int menu_is_hidden(char_u *name)
{
- return (name[0] == ']') || (menu_is_popup(name) && name[5] != NUL);
+ return (name[0] == MNU_HIDDEN_CHAR)
+ || (menu_is_popup(name) && name[5] != NUL);
}
/*
diff --git a/src/nvim/menu.h b/src/nvim/menu.h
index 3266c511b4..5ff979f2bf 100644
--- a/src/nvim/menu.h
+++ b/src/nvim/menu.h
@@ -1,7 +1,14 @@
#ifndef NVIM_MENU_H
#define NVIM_MENU_H
-/* Indices into vimmenu_T->strings[] and vimmenu_T->noremap[] for each mode */
+#include <stdbool.h> // for bool
+
+#include "nvim/types.h" // for char_u and expand_T
+#include "nvim/ex_cmds_defs.h" // for exarg_T
+
+/// Indices into vimmenu_T->strings[] and vimmenu_T->noremap[] for each mode
+/// \addtogroup MENU_INDEX
+/// @{
#define MENU_INDEX_INVALID -1
#define MENU_INDEX_NORMAL 0
#define MENU_INDEX_VISUAL 1
@@ -11,8 +18,12 @@
#define MENU_INDEX_CMDLINE 5
#define MENU_INDEX_TIP 6
#define MENU_MODES 7
+/// @}
+/// note MENU_INDEX_TIP is not a 'real' mode
-/* Menu modes */
+/// Menu modes
+/// \addtogroup MENU_MODES
+/// @{
#define MENU_NORMAL_MODE (1 << MENU_INDEX_NORMAL)
#define MENU_VISUAL_MODE (1 << MENU_INDEX_VISUAL)
#define MENU_SELECT_MODE (1 << MENU_INDEX_SELECT)
@@ -21,31 +32,30 @@
#define MENU_CMDLINE_MODE (1 << MENU_INDEX_CMDLINE)
#define MENU_TIP_MODE (1 << MENU_INDEX_TIP)
#define MENU_ALL_MODES ((1 << MENU_INDEX_TIP) - 1)
-/*note MENU_INDEX_TIP is not a 'real' mode*/
+/// @}
-/* Start a menu name with this to not include it on the main menu bar */
+/// Start a menu name with this to not include it on the main menu bar
#define MNU_HIDDEN_CHAR ']'
typedef struct VimMenu vimmenu_T;
struct VimMenu {
- int modes; /* Which modes is this menu visible for? */
- int enabled; /* for which modes the menu is enabled */
- char_u *name; /* Name of menu, possibly translated */
- char_u *dname; /* Displayed Name ("name" without '&') */
- char_u *en_name; /* "name" untranslated, NULL when "name"
- * was not translated */
- char_u *en_dname; /* "dname" untranslated, NULL when "dname"
- * was not translated */
- int mnemonic; /* mnemonic key (after '&') */
- char_u *actext; /* accelerator text (after TAB) */
- long priority; /* Menu order priority */
- char_u *strings[MENU_MODES]; /* Mapped string for each mode */
- int noremap[MENU_MODES]; /* A REMAP_ flag for each mode */
- bool silent[MENU_MODES]; /* A silent flag for each mode */
- vimmenu_T *children; /* Children of sub-menu */
- vimmenu_T *parent; /* Parent of menu */
- vimmenu_T *next; /* Next item in menu */
+ int modes; ///< Which modes is this menu visible for
+ int enabled; ///< for which modes the menu is enabled
+ char_u *name; ///< Name of menu, possibly translated
+ char_u *dname; ///< Displayed Name ("name" without '&')
+ char_u *en_name; ///< "name" untranslated, NULL when
+ ///< was not translated
+ char_u *en_dname; ///< NULL when "dname" untranslated
+ int mnemonic; ///< mnemonic key (after '&')
+ char_u *actext; ///< accelerator text (after TAB)
+ long priority; ///< Menu order priority
+ char_u *strings[MENU_MODES]; ///< Mapped string for each mode
+ int noremap[MENU_MODES]; ///< A \ref REMAP_VALUES flag for each mode
+ bool silent[MENU_MODES]; ///< A silent flag for each mode
+ vimmenu_T *children; ///< Children of sub-menu
+ vimmenu_T *parent; ///< Parent of menu
+ vimmenu_T *next; ///< Next item in menu
};
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 2f8feda6ec..b90c475ede 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* message.c: functions for displaying messages on the command line
*/
@@ -7,10 +10,10 @@
#include <stdbool.h>
#include <stdarg.h>
#include <string.h>
-#include <math.h>
#include "nvim/vim.h"
#include "nvim/ascii.h"
+#include "nvim/assert.h"
#include "nvim/message.h"
#include "nvim/charset.h"
#include "nvim/eval.h"
@@ -28,6 +31,7 @@
#include "nvim/ops.h"
#include "nvim/option.h"
#include "nvim/normal.h"
+#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
@@ -128,9 +132,9 @@ int verb_msg(char_u *s)
return n;
}
-int msg_attr(char_u *s, int attr) FUNC_ATTR_NONNULL_ARG(1)
+int msg_attr(const char *s, const int attr) FUNC_ATTR_NONNULL_ARG(1)
{
- return msg_attr_keep(s, attr, FALSE);
+ return msg_attr_keep((char_u *)s, attr, false);
}
int
@@ -145,6 +149,12 @@ msg_attr_keep (
int retval;
char_u *buf = NULL;
+ // Skip messages not match ":filter pattern".
+ // Don't filter when there is an error.
+ if (!emsg_on_display && message_filtered(s)) {
+ return true;
+ }
+
if (attr == 0) {
set_vim_var_string(VV_STATUSMSG, (char *) s, -1);
}
@@ -164,8 +174,9 @@ msg_attr_keep (
|| (*s != '<'
&& last_msg_hist != NULL
&& last_msg_hist->msg != NULL
- && STRCMP(s, last_msg_hist->msg)))
- add_msg_hist(s, -1, attr);
+ && STRCMP(s, last_msg_hist->msg))) {
+ add_msg_hist((const char *)s, -1, attr);
+ }
/* When displaying keep_msg, don't let msg_start() free it, caller must do
* that. */
@@ -236,17 +247,19 @@ msg_strtrunc (
* Truncate a string "s" to "buf" with cell width "room".
* "s" and "buf" may be equal.
*/
-void trunc_string(char_u *s, char_u *buf, int room, int buflen)
+void trunc_string(char_u *s, char_u *buf, int room_in, int buflen)
{
- int half;
- int len;
+ size_t room = room_in - 3; // "..." takes 3 chars
+ size_t half;
+ size_t len = 0;
int e;
int i;
int n;
- room -= 3;
+ if (room_in < 3) {
+ room = 0;
+ }
half = room / 2;
- len = 0;
/* First part: Start of the string. */
for (e = 0; len < half && e < buflen; ++e) {
@@ -256,8 +269,9 @@ void trunc_string(char_u *s, char_u *buf, int room, int buflen)
return;
}
n = ptr2cells(s + e);
- if (len + n >= half)
+ if (len + n > half) {
break;
+ }
len += n;
buf[e] = s[e];
if (has_mbyte)
@@ -268,45 +282,46 @@ void trunc_string(char_u *s, char_u *buf, int room, int buflen)
}
}
- /* Last part: End of the string. */
- i = e;
- if (enc_dbcs != 0) {
- /* For DBCS going backwards in a string is slow, but
- * computing the cell width isn't too slow: go forward
- * until the rest fits. */
- n = vim_strsize(s + i);
- while (len + n > room) {
- n -= ptr2cells(s + i);
- i += (*mb_ptr2len)(s + i);
- }
- } else if (enc_utf8) {
- /* For UTF-8 we can go backwards easily. */
- half = i = (int)STRLEN(s);
- for (;; ) {
- do
- half = half - (*mb_head_off)(s, s + half - 1) - 1;
- while (utf_iscomposing(utf_ptr2char(s + half)) && half > 0);
- n = ptr2cells(s + half);
- if (len + n > room)
- break;
- len += n;
- i = half;
+ // Last part: End of the string.
+ half = i = (int)STRLEN(s);
+ for (;;) {
+ do {
+ half = half - (*mb_head_off)(s, s + half - 1) - 1;
+ } while (half > 0 && utf_iscomposing(utf_ptr2char(s + half)));
+ n = ptr2cells(s + half);
+ if (len + n > room || half == 0) {
+ break;
}
- } else {
- for (i = (int)STRLEN(s); len + (n = ptr2cells(s + i - 1)) <= room; --i)
- len += n;
+ len += n;
+ i = half;
}
- /* Set the middle and copy the last part. */
- if (e + 3 < buflen) {
+ if (i <= e + 3) {
+ // text fits without truncating
+ if (s != buf) {
+ len = STRLEN(s);
+ if (len >= (size_t)buflen) {
+ len = buflen - 1;
+ }
+ len = len - e + 1;
+ if (len < 1) {
+ buf[e - 1] = NUL;
+ } else {
+ memmove(buf + e, s + e, len);
+ }
+ }
+ } else if (e + 3 < buflen) {
+ // set the middle and copy the last part
memmove(buf + e, "...", (size_t)3);
- len = (int)STRLEN(s + i) + 1;
- if (len >= buflen - e - 3)
+ len = STRLEN(s + i) + 1;
+ if (len >= (size_t)buflen - e - 3) {
len = buflen - e - 3 - 1;
+ }
memmove(buf + e + 3, s + i, len);
buf[e + 3 + len - 1] = NUL;
} else {
- buf[e - 1] = NUL; /* make sure it is truncated */
+ // can't fit in the "...", just truncate it
+ buf[e - 1] = NUL;
}
}
@@ -332,7 +347,7 @@ int smsg_attr(int attr, char *s, ...)
va_start(arglist, s);
vim_vsnprintf((char *)IObuff, IOSIZE, s, arglist, NULL);
va_end(arglist);
- return msg_attr(IObuff, attr);
+ return msg_attr((const char *)IObuff, attr);
}
/*
@@ -366,42 +381,40 @@ static int other_sourcing_name(void)
return FALSE;
}
-/*
- * Get the message about the source, as used for an error message.
- * Returns an allocated string with room for one more character.
- * Returns NULL when no message is to be given.
- */
-static char_u *get_emsg_source(void)
+/// Get the message about the source, as used for an error message
+///
+/// @return [allocated] String with room for one more character. NULL when no
+/// message is to be given.
+static char *get_emsg_source(void)
+ FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
{
- char_u *Buf, *p;
-
if (sourcing_name != NULL && other_sourcing_name()) {
- p = (char_u *)_("Error detected while processing %s:");
- Buf = xmalloc(STRLEN(sourcing_name) + STRLEN(p));
- sprintf((char *)Buf, (char *)p, sourcing_name);
- return Buf;
+ const char *const p = _("Error detected while processing %s:");
+ const size_t buf_len = STRLEN(sourcing_name) + strlen(p) + 1;
+ char *const buf = xmalloc(buf_len);
+ snprintf(buf, buf_len, p, sourcing_name);
+ return buf;
}
return NULL;
}
-/*
- * Get the message about the source lnum, as used for an error message.
- * Returns an allocated string with room for one more character.
- * Returns NULL when no message is to be given.
- */
-static char_u *get_emsg_lnum(void)
+/// Get the message about the source lnum, as used for an error message.
+///
+/// @return [allocated] String with room for one more character. NULL when no
+/// message is to be given.
+static char *get_emsg_lnum(void)
+ FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
{
- char_u *Buf, *p;
-
- /* lnum is 0 when executing a command from the command line
- * argument, we don't want a line number then */
+ // lnum is 0 when executing a command from the command line
+ // argument, we don't want a line number then
if (sourcing_name != NULL
&& (other_sourcing_name() || sourcing_lnum != last_sourcing_lnum)
&& sourcing_lnum != 0) {
- p = (char_u *)_("line %4ld:");
- Buf = xmalloc(STRLEN(p) + 20);
- sprintf((char *)Buf, (char *)p, (long)sourcing_lnum);
- return Buf;
+ const char *const p = _("line %4ld:");
+ const size_t buf_len = 20 + strlen(p);
+ char *const buf = xmalloc(buf_len);
+ snprintf(buf, buf_len, p, (long)sourcing_lnum);
+ return buf;
}
return NULL;
}
@@ -413,10 +426,8 @@ static char_u *get_emsg_lnum(void)
*/
void msg_source(int attr)
{
- char_u *p;
-
- ++no_wait_return;
- p = get_emsg_source();
+ no_wait_return++;
+ char *p = get_emsg_source();
if (p != NULL) {
msg_attr(p, attr);
xfree(p);
@@ -463,10 +474,10 @@ int emsg_not_now(void)
*
* return TRUE if wait_return not called
*/
-int emsg(char_u *s)
+int emsg(const char_u *s_)
{
+ const char *s = (const char *)s_;
int attr;
- char_u *p;
int ignore = false;
int severe;
@@ -493,7 +504,7 @@ int emsg(char_u *s)
* when the message should be ignored completely (used for the
* interrupt message).
*/
- if (cause_errthrow(s, severe, &ignore) == true) {
+ if (cause_errthrow((char_u *)s, severe, &ignore) == true) {
if (!ignore) {
did_emsg = true;
}
@@ -501,7 +512,7 @@ int emsg(char_u *s)
}
// set "v:errmsg", also when using ":silent! cmd"
- set_vim_var_string(VV_ERRMSG, (char *) s, -1);
+ set_vim_var_string(VV_ERRMSG, s, -1);
/*
* When using ":silent! cmd" ignore error messages.
@@ -510,19 +521,21 @@ int emsg(char_u *s)
if (emsg_silent != 0) {
if (!emsg_noredir) {
msg_start();
- p = get_emsg_source();
+ char *p = get_emsg_source();
if (p != NULL) {
- STRCAT(p, "\n");
- redir_write(p, STRLEN(p));
+ const size_t p_len = strlen(p);
+ p[p_len] = '\n';
+ redir_write(p, p_len + 1);
xfree(p);
}
p = get_emsg_lnum();
if (p != NULL) {
- STRCAT(p, "\n");
- redir_write(p, STRLEN(p));
+ const size_t p_len = strlen(p);
+ p[p_len] = '\n';
+ redir_write(p, p_len + 1);
xfree(p);
}
- redir_write(s, STRLEN(s));
+ redir_write(s, strlen(s));
}
return true;
}
@@ -557,10 +570,8 @@ int emsg(char_u *s)
*/
msg_source(attr);
- /*
- * Display the error message itself.
- */
- msg_nowait = FALSE; /* wait for this msg */
+ // Display the error message itself.
+ msg_nowait = false; // Wait for this msg.
return msg_attr(s, attr);
}
@@ -572,16 +583,17 @@ void emsg_invreg(int name)
/// Print an error message with unknown number of arguments
bool emsgf(const char *const fmt, ...)
{
+ static char errbuf[IOSIZE];
if (emsg_not_now()) {
return true;
}
va_list ap;
va_start(ap, fmt);
- vim_vsnprintf((char *) IObuff, IOSIZE, fmt, ap, NULL);
+ vim_vsnprintf(errbuf, sizeof(errbuf), fmt, ap, NULL);
va_end(ap);
- return emsg(IObuff);
+ return emsg((const char_u *)errbuf);
}
static void msg_emsgf_event(void **argv)
@@ -599,7 +611,7 @@ void msg_schedule_emsgf(const char *const fmt, ...)
va_end(ap);
char *s = xstrdup((char *)IObuff);
- loop_schedule(&main_loop, event_create(1, msg_emsgf_event, 1, s));
+ loop_schedule(&main_loop, event_create(msg_emsgf_event, 1, s));
}
/*
@@ -612,14 +624,14 @@ char_u *msg_trunc_attr(char_u *s, int force, int attr)
{
int n;
- /* Add message to history before truncating */
- add_msg_hist(s, -1, attr);
+ // Add message to history before truncating.
+ add_msg_hist((const char *)s, -1, attr);
s = msg_may_trunc(force, s);
- msg_hist_off = TRUE;
- n = msg_attr(s, attr);
- msg_hist_off = FALSE;
+ msg_hist_off = true;
+ n = msg_attr((const char *)s, attr);
+ msg_hist_off = false;
if (n)
return s;
@@ -658,12 +670,8 @@ char_u *msg_may_trunc(int force, char_u *s)
return s;
}
-static void
-add_msg_hist (
- char_u *s,
- int len, /* -1 for undetermined length */
- int attr
-)
+/// @param[in] len Length of s or -1.
+static void add_msg_hist(const char *s, int len, int attr)
{
if (msg_hist_off || msg_silent != 0)
return;
@@ -681,9 +689,10 @@ add_msg_hist (
++s;
--len;
}
- while (len > 0 && s[len - 1] == '\n')
- --len;
- p->msg = vim_strnsave(s, len);
+ while (len > 0 && s[len - 1] == '\n') {
+ len--;
+ }
+ p->msg = (char_u *)xmemdupz(s, (size_t)len);
p->next = NULL;
p->attr = attr;
if (last_msg_hist != NULL)
@@ -716,11 +725,11 @@ int delete_first_msg(void)
return OK;
}
-/*
- * ":messages" command.
- */
-void ex_messages(exarg_T *eap)
+/// :messages command implementation
+void ex_messages(void *const eap_p)
+ FUNC_ATTR_NONNULL_ALL
{
+ const exarg_T *const eap = (const exarg_T *)eap_p;
struct msg_hist *p;
int c = 0;
@@ -758,7 +767,7 @@ void ex_messages(exarg_T *eap)
// Display what was not skipped.
for (; p != NULL && !got_int; p = p->next) {
if (p->msg != NULL) {
- msg_attr(p->msg, p->attr);
+ msg_attr((const char *)p->msg, p->attr);
}
}
@@ -849,23 +858,22 @@ void wait_return(int redraw)
* CTRL-C, but we need to loop then. */
had_got_int = got_int;
- /* Don't do mappings here, we put the character back in the
- * typeahead buffer. */
- ++no_mapping;
- ++allow_keys;
+ // Don't do mappings here, we put the character back in the
+ // typeahead buffer.
+ no_mapping++;
- /* Temporarily disable Recording. If Recording is active, the
- * character will be recorded later, since it will be added to the
- * typebuf after the loop */
+ // Temporarily disable Recording. If Recording is active, the
+ // character will be recorded later, since it will be added to the
+ // typebuf after the loop
save_Recording = Recording;
save_scriptout = scriptout;
Recording = FALSE;
scriptout = NULL;
c = safe_vgetc();
- if (had_got_int && !global_busy)
- got_int = FALSE;
- --no_mapping;
- --allow_keys;
+ if (had_got_int && !global_busy) {
+ got_int = false;
+ }
+ no_mapping--;
Recording = save_Recording;
scriptout = save_scriptout;
@@ -1042,9 +1050,10 @@ void msg_start(void)
msg_didout = FALSE; /* no output on current line yet */
}
- /* when redirecting, may need to start a new line. */
- if (!did_return)
- redir_write((char_u *)"\n", -1);
+ // When redirecting, may need to start a new line.
+ if (!did_return) {
+ redir_write("\n", 1);
+ }
}
/*
@@ -1063,24 +1072,24 @@ void msg_putchar(int c)
void msg_putchar_attr(int c, int attr)
{
- char_u buf[MB_MAXBYTES + 1];
+ char buf[MB_MAXBYTES + 1];
if (IS_SPECIAL(c)) {
- buf[0] = K_SPECIAL;
- buf[1] = K_SECOND(c);
- buf[2] = K_THIRD(c);
+ buf[0] = (char)K_SPECIAL;
+ buf[1] = (char)K_SECOND(c);
+ buf[2] = (char)K_THIRD(c);
buf[3] = NUL;
} else {
- buf[(*mb_char2bytes)(c, buf)] = NUL;
+ buf[(*mb_char2bytes)(c, (char_u *)buf)] = NUL;
}
msg_puts_attr(buf, attr);
}
void msg_outnum(long n)
{
- char_u buf[20];
+ char buf[20];
- sprintf((char *)buf, "%" PRId64, (int64_t)n);
+ snprintf(buf, sizeof(buf), "%ld", n);
msg_puts(buf);
}
@@ -1136,16 +1145,16 @@ char_u *msg_outtrans_one(char_u *p, int attr)
msg_outtrans_len_attr(p, l, attr);
return p + l;
}
- msg_puts_attr(transchar_byte(*p), attr);
+ msg_puts_attr((const char *)transchar_byte(*p), attr);
return p + 1;
}
int msg_outtrans_len_attr(char_u *msgstr, int len, int attr)
{
int retval = 0;
- char_u *str = msgstr;
- char_u *plain_start = msgstr;
- char_u *s;
+ const char *str = (const char *)msgstr;
+ const char *plain_start = (const char *)msgstr;
+ char_u *s;
int mb_l;
int c;
@@ -1155,60 +1164,59 @@ int msg_outtrans_len_attr(char_u *msgstr, int len, int attr)
attr &= ~MSG_HIST;
}
- /* If the string starts with a composing character first draw a space on
- * which the composing char can be drawn. */
- if (enc_utf8 && utf_iscomposing(utf_ptr2char(msgstr)))
- msg_puts_attr((char_u *)" ", attr);
+ // If the string starts with a composing character first draw a space on
+ // which the composing char can be drawn.
+ if (enc_utf8 && utf_iscomposing(utf_ptr2char(msgstr))) {
+ msg_puts_attr(" ", attr);
+ }
/*
* Go over the string. Special characters are translated and printed.
* Normal characters are printed several at a time.
*/
while (--len >= 0) {
- if (enc_utf8)
- /* Don't include composing chars after the end. */
- mb_l = utfc_ptr2len_len(str, len + 1);
- else if (has_mbyte)
- mb_l = (*mb_ptr2len)(str);
- else
- mb_l = 1;
- if (has_mbyte && mb_l > 1) {
- c = (*mb_ptr2char)(str);
- if (vim_isprintc(c))
- /* printable multi-byte char: count the cells. */
- retval += (*mb_ptr2cells)(str);
- else {
- /* unprintable multi-byte char: print the printable chars so
- * far and the translation of the unprintable char. */
- if (str > plain_start)
- msg_puts_attr_len(plain_start, (int)(str - plain_start),
- attr);
+ // Don't include composing chars after the end.
+ mb_l = utfc_ptr2len_len((char_u *)str, len + 1);
+ if (mb_l > 1) {
+ c = (*mb_ptr2char)((char_u *)str);
+ if (vim_isprintc(c)) {
+ // Printable multi-byte char: count the cells.
+ retval += (*mb_ptr2cells)((char_u *)str);
+ } else {
+ // Unprintable multi-byte char: print the printable chars so
+ // far and the translation of the unprintable char.
+ if (str > plain_start) {
+ msg_puts_attr_len(plain_start, str - plain_start, attr);
+ }
plain_start = str + mb_l;
- msg_puts_attr(transchar(c), attr == 0 ? hl_attr(HLF_8) : attr);
+ msg_puts_attr((const char *)transchar(c),
+ (attr == 0 ? hl_attr(HLF_8) : attr));
retval += char2cells(c);
}
len -= mb_l - 1;
str += mb_l;
} else {
- s = transchar_byte(*str);
+ s = transchar_byte((uint8_t)(*str));
if (s[1] != NUL) {
- /* unprintable char: print the printable chars so far and the
- * translation of the unprintable char. */
- if (str > plain_start)
- msg_puts_attr_len(plain_start, (int)(str - plain_start),
- attr);
+ // Unprintable char: print the printable chars so far and the
+ // translation of the unprintable char.
+ if (str > plain_start) {
+ msg_puts_attr_len(plain_start, str - plain_start, attr);
+ }
plain_start = str + 1;
- msg_puts_attr(s, attr == 0 ? hl_attr(HLF_8) : attr);
+ msg_puts_attr((const char *)s, attr == 0 ? hl_attr(HLF_8) : attr);
retval += (int)STRLEN(s);
- } else
- ++retval;
- ++str;
+ } else {
+ retval++;
+ }
+ str++;
}
}
- if (str > plain_start)
- /* print the printable chars at the end */
- msg_puts_attr_len(plain_start, (int)(str - plain_start), attr);
+ if (str > plain_start) {
+ // Print the printable chars at the end.
+ msg_puts_attr_len(plain_start, str - plain_start, attr);
+ }
return retval;
}
@@ -1251,130 +1259,147 @@ msg_outtrans_special (
{
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. */
+ const char *string;
+ // Leading and trailing spaces need to be displayed in <> form.
if ((str == strstart || str[1] == NUL) && *str == ' ') {
- string = (char_u *)"<Space>";
- ++str;
- } else
- string = str2special(&str, from);
- len = vim_strsize(string);
- /* Highlight special keys */
- msg_puts_attr(string, len > 1
- && (*mb_ptr2len)(string) <= 1
- ? attr : 0);
+ string = "<Space>";
+ str++;
+ } else {
+ string = str2special((const char **)&str, from, false);
+ }
+ const int len = vim_strsize((char_u *)string);
+ // Highlight special keys
+ msg_puts_attr(string, (len > 1
+ && (*mb_ptr2len)((char_u *)string) <= 1
+ ? attr : 0));
retval += len;
}
return retval;
}
-/*
- * Return the lhs or rhs of a mapping, with the key codes turned into printable
- * strings, in an allocated string.
- */
-char_u *
-str2special_save (
- char_u *str,
- int is_lhs /* TRUE for lhs, FALSE for rhs */
-)
+/// Convert string, replacing key codes with printables
+///
+/// Used for lhs or rhs of mappings.
+///
+/// @param[in] str String to convert.
+/// @param[in] replace_spaces Convert spaces into `<Space>`, normally used fo
+/// lhs, but not rhs.
+/// @param[in] replace_lt Convert `<` into `<lt>`.
+///
+/// @return [allocated] Converted string.
+char *str2special_save(const char *const str, const bool replace_spaces,
+ const bool replace_lt)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
+ FUNC_ATTR_NONNULL_RET
{
garray_T ga;
- char_u *p = str;
-
ga_init(&ga, 1, 40);
- while (*p != NUL)
- ga_concat(&ga, str2special(&p, is_lhs));
+
+ const char *p = str;
+ while (*p != NUL) {
+ ga_concat(&ga, (const char_u *)str2special(&p, replace_spaces, replace_lt));
+ }
ga_append(&ga, NUL);
- return (char_u *)ga.ga_data;
+ return (char *)ga.ga_data;
}
-/*
- * Return the printable string for the key codes at "*sp".
- * Used for translating the lhs or rhs of a mapping to printable chars.
- * Advances "sp" to the next code.
- */
-char_u *
-str2special (
- char_u **sp,
- int from /* TRUE for lhs of mapping */
-)
-{
- int c;
- static char_u buf[7];
- char_u *str = *sp;
- int modifiers = 0;
- int special = FALSE;
-
- if (has_mbyte) {
- char_u *p;
-
- /* Try to un-escape a multi-byte character. Return the un-escaped
- * string if it is a multi-byte character. */
- p = mb_unescape(sp);
- if (p != NULL)
- return p;
+/// Convert character, replacing key one key code with printable representation
+///
+/// @param[in,out] sp String to convert. Is advanced to the next key code.
+/// @param[in] replace_spaces Convert spaces into <Space>, normally used for
+/// lhs, but not rhs.
+/// @param[in] replace_lt Convert `<` into `<lt>`.
+///
+/// @return Converted key code, in a static buffer. Buffer is always one and the
+/// same, so save converted string somewhere before running str2special
+/// for the second time.
+const char *str2special(const char **const sp, const bool replace_spaces,
+ const bool replace_lt)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
+{
+ static char buf[7];
+
+ // Try to un-escape a multi-byte character. Return the un-escaped
+ // string if it is a multi-byte character.
+ const char *const p = mb_unescape(sp);
+ if (p != NULL) {
+ return p;
}
- c = *str;
+ const char *str = *sp;
+ int c = (uint8_t)(*str);
+ int modifiers = 0;
+ bool special = false;
if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL) {
- if (str[1] == KS_MODIFIER) {
- modifiers = str[2];
+ if ((uint8_t)str[1] == KS_MODIFIER) {
+ modifiers = (uint8_t)str[2];
str += 3;
- c = *str;
+ c = (uint8_t)(*str);
}
if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL) {
- c = TO_SPECIAL(str[1], str[2]);
+ c = TO_SPECIAL((uint8_t)str[1], (uint8_t)str[2]);
str += 2;
- if (c == KS_ZERO) /* display <Nul> as ^@ or <Nul> */
+ if (c == KS_ZERO) { // display <Nul> as ^@ or <Nul>
c = NUL;
+ }
+ }
+ if (IS_SPECIAL(c) || modifiers) { // Special key.
+ special = true;
}
- if (IS_SPECIAL(c) || modifiers) /* special key */
- special = TRUE;
}
- if (has_mbyte && !IS_SPECIAL(c)) {
- int len = (*mb_ptr2len)(str);
+ if (!IS_SPECIAL(c)) {
+ const int len = utf_ptr2len((const char_u *)str);
- /* For multi-byte characters check for an illegal byte. */
- if (has_mbyte && MB_BYTE2LEN(*str) > len) {
- transchar_nonprint(buf, c);
+ // Check for an illegal byte.
+ if (MB_BYTE2LEN((uint8_t)(*str)) > len) {
+ transchar_nonprint((char_u *)buf, c);
*sp = str + 1;
return buf;
}
- /* Since 'special' is TRUE the multi-byte character 'c' will be
- * processed by get_special_key_name() */
- c = (*mb_ptr2char)(str);
+ // Since 'special' is TRUE the multi-byte character 'c' will be
+ // processed by get_special_key_name().
+ c = utf_ptr2char((const char_u *)str);
*sp = str + len;
- } else
+ } else {
*sp = str + 1;
+ }
- /* Make unprintable characters in <> form, also <M-Space> and <Tab>.
- * Use <Space> only for lhs of a mapping. */
- if (special || char2cells(c) > 1 || (from && c == ' '))
- return get_special_key_name(c, modifiers);
+ // Make unprintable characters in <> form, also <M-Space> and <Tab>.
+ if (special
+ || char2cells(c) > 1
+ || (replace_spaces && c == ' ')
+ || (replace_lt && c == '<')) {
+ return (const char *)get_special_key_name(c, modifiers);
+ }
buf[0] = c;
buf[1] = NUL;
return buf;
}
-/*
- * Translate a key sequence into special key names.
- */
-void str2specialbuf(char_u *sp, char_u *buf, int len)
+/// Convert string, replacing key codes with printables
+///
+/// @param[in] str String to convert.
+/// @param[out] buf Buffer to save results to.
+/// @param[in] len Buffer length.
+void str2specialbuf(const char *sp, char *buf, size_t len)
+ FUNC_ATTR_NONNULL_ALL
{
- char_u *s;
-
- *buf = NUL;
while (*sp) {
- s = str2special(&sp, FALSE);
- if ((int)(STRLEN(s) + STRLEN(buf)) < len)
- STRCAT(buf, s);
+ const char *s = str2special(&sp, false, false);
+ const size_t s_len = strlen(s);
+ if (s_len <= len) {
+ break;
+ }
+ memcpy(buf, s, s_len);
+ buf += s_len;
+ len -= s_len;
}
+ *buf = NUL;
}
/*
@@ -1391,7 +1416,6 @@ void msg_prt_line(char_u *s, int list)
int attr = 0;
char_u *trail = NULL;
int l;
- char_u buf[MB_MAXBYTES + 1];
if (curwin->w_p_list)
list = TRUE;
@@ -1417,10 +1441,11 @@ void msg_prt_line(char_u *s, int list)
c = *p_extra++;
} else if (has_mbyte && (l = (*mb_ptr2len)(s)) > 1) {
col += (*mb_ptr2cells)(s);
+ char buf[MB_MAXBYTES + 1];
if (lcs_nbsp != NUL && list
&& (mb_ptr2char(s) == 160 || mb_ptr2char(s) == 0x202f)) {
- mb_char2bytes(lcs_nbsp, buf);
- buf[(*mb_ptr2len)(buf)] = NUL;
+ mb_char2bytes(lcs_nbsp, (char_u *)buf);
+ buf[(*mb_ptr2len)((char_u *)buf)] = NUL;
} else {
memmove(buf, s, (size_t)l);
buf[l] = NUL;
@@ -1517,12 +1542,12 @@ static char_u *screen_puts_mbyte(char_u *s, int l, int attr)
* Output a string to the screen at position msg_row, msg_col.
* Update msg_row and msg_col for the next message.
*/
-void msg_puts(char_u *s)
+void msg_puts(const char *s)
{
msg_puts_attr(s, 0);
}
-void msg_puts_title(char_u *s)
+void msg_puts_title(const char *s)
{
msg_puts_attr(s, hl_attr(HLF_T));
}
@@ -1546,7 +1571,7 @@ void msg_puts_long_len_attr(char_u *longstr, int len, int attr)
if (len > room && room >= 20) {
slen = (room - 3) / 2;
msg_outtrans_len_attr(longstr, slen, attr);
- msg_puts_attr((char_u *)"...", hl_attr(HLF_8));
+ msg_puts_attr("...", hl_attr(HLF_8));
}
msg_outtrans_len_attr(longstr + len - slen, slen, attr);
}
@@ -1554,18 +1579,22 @@ void msg_puts_long_len_attr(char_u *longstr, int len, int attr)
/*
* Basic function for writing a message with highlight attributes.
*/
-void msg_puts_attr(char_u *s, int attr)
+void msg_puts_attr(const char *const s, const int attr)
{
msg_puts_attr_len(s, -1, attr);
}
-/// Like msg_puts_attr(), but with a maximum length "maxlen" (in bytes).
-/// When "maxlen" is -1 there is no maximum length.
-/// When "maxlen" is >= 0 the message is not put in the history.
-static void msg_puts_attr_len(char_u *str, int maxlen, int attr)
+/// Write a message with highlight attributes
+///
+/// @param[in] str NUL-terminated message string.
+/// @param[in] len Length of the string or -1.
+/// @param[in] attr Highlight attribute.
+void msg_puts_attr_len(const char *const str, const ptrdiff_t len, int attr)
+ FUNC_ATTR_NONNULL_ALL
{
+ assert(len < 0 || memchr(str, 0, len) == NULL);
// If redirection is on, also write to the redirection file.
- redir_write(str, maxlen);
+ redir_write(str, len);
// Don't print anything when using ":silent cmd".
if (msg_silent != 0) {
@@ -1573,8 +1602,8 @@ static void msg_puts_attr_len(char_u *str, int maxlen, int attr)
}
// if MSG_HIST flag set, add message to history
- if ((attr & MSG_HIST) && maxlen < 0) {
- add_msg_hist(str, -1, attr);
+ if (attr & MSG_HIST) {
+ add_msg_hist(str, (int)len, attr);
attr &= ~MSG_HIST;
}
@@ -1593,24 +1622,46 @@ static void msg_puts_attr_len(char_u *str, int maxlen, int attr)
// different, e.g. for Win32 console) or we just don't know where the
// cursor is.
if (msg_use_printf()) {
- msg_puts_printf((char *)str, maxlen);
+ msg_puts_printf(str, len);
} else {
- msg_puts_display(str, maxlen, attr, false);
+ msg_puts_display((const char_u *)str, len, attr, false);
}
}
+/// Print a formatted message
+///
+/// Message printed is limited by #IOSIZE. Must not be used from inside
+/// msg_puts_attr().
+///
+/// @param[in] attr Highlight attributes.
+/// @param[in] fmt Format string.
+void msg_printf_attr(const int attr, const char *const fmt, ...)
+ FUNC_ATTR_NONNULL_ARG(2)
+{
+ static char msgbuf[IOSIZE];
+
+ va_list ap;
+ va_start(ap, fmt);
+ const size_t len = vim_vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap, NULL);
+ va_end(ap);
+
+ msg_scroll = true;
+ msg_puts_attr_len(msgbuf, (ptrdiff_t)len, attr);
+}
+
/*
* The display part of msg_puts_attr_len().
* May be called recursively to display scroll-back text.
*/
-static void msg_puts_display(char_u *str, int maxlen, int attr, int recurse)
+static void msg_puts_display(const char_u *str, int maxlen, int attr,
+ int recurse)
{
- char_u *s = str;
- char_u *t_s = str; /* string from "t_s" to "s" is still todo */
- int t_col = 0; /* screen cells todo, 0 when "t_s" not used */
+ const char_u *s = str;
+ const char_u *t_s = str; // String from "t_s" to "s" is still todo.
+ int t_col = 0; // Screen cells todo, 0 when "t_s" not used.
int l;
int cw;
- char_u *sb_str = str;
+ const char_u *sb_str = str;
int sb_col = msg_col;
int wrap;
int did_last_char;
@@ -1652,26 +1703,24 @@ static void msg_puts_display(char_u *str, int maxlen, int attr, int recurse)
if (msg_col >= Columns) /* can happen after screen resize */
msg_col = Columns - 1;
- /* Display char in last column before showing more-prompt. */
- if (*s >= ' '
- && !cmdmsg_rl
- ) {
- if (has_mbyte) {
- if (enc_utf8 && maxlen >= 0)
- /* avoid including composing chars after the end */
- l = utfc_ptr2len_len(s, (int)((str + maxlen) - s));
- else
- l = (*mb_ptr2len)(s);
- s = screen_puts_mbyte(s, l, attr);
- } else
- msg_screen_putchar(*s++, attr);
- did_last_char = TRUE;
- } else
- did_last_char = FALSE;
-
- if (p_more)
- /* store text for scrolling back */
- store_sb_text(&sb_str, s, attr, &sb_col, TRUE);
+ // Display char in last column before showing more-prompt.
+ if (*s >= ' ' && !cmdmsg_rl) {
+ if (maxlen >= 0) {
+ // Avoid including composing chars after the end.
+ l = utfc_ptr2len_len(s, (int)((str + maxlen) - s));
+ } else {
+ l = utfc_ptr2len(s);
+ }
+ s = screen_puts_mbyte((char_u *)s, l, attr);
+ did_last_char = true;
+ } else {
+ did_last_char = false;
+ }
+
+ if (p_more) {
+ // Store text for scrolling back.
+ store_sb_text((char_u **)&sb_str, (char_u *)s, attr, &sb_col, true);
+ }
inc_msg_scrolled();
need_wait_return = TRUE; /* may need wait_return in main() */
@@ -1707,13 +1756,15 @@ static void msg_puts_display(char_u *str, int maxlen, int attr, int recurse)
&& msg_col + t_col >= Columns - 1)
;
if (t_col > 0 && (wrap || *s == '\r' || *s == '\b'
- || *s == '\t' || *s == BELL))
- /* output any postponed text */
+ || *s == '\t' || *s == BELL)) {
+ // Output any postponed text.
t_puts(&t_col, t_s, s, attr);
+ }
- if (wrap && p_more && !recurse)
- /* store text for scrolling back */
- store_sb_text(&sb_str, s, attr, &sb_col, TRUE);
+ if (wrap && p_more && !recurse) {
+ // Store text for scrolling back.
+ store_sb_text((char_u **)&sb_str, (char_u *)s, attr, &sb_col, true);
+ }
if (*s == '\n') { /* go to next line */
msg_didout = FALSE; /* remember that line is empty */
@@ -1751,7 +1802,7 @@ static void msg_puts_display(char_u *str, int maxlen, int attr, int recurse)
// characters and draw them all at once later.
if (cmdmsg_rl || (cw > 1 && msg_col + t_col >= Columns - 1)) {
if (l > 1) {
- s = screen_puts_mbyte(s, l, attr) - 1;
+ s = screen_puts_mbyte((char_u *)s, l, attr) - 1;
} else {
msg_screen_putchar(*s, attr);
}
@@ -1766,15 +1817,29 @@ static void msg_puts_display(char_u *str, int maxlen, int attr, int recurse)
++s;
}
- /* output any postponed text */
- if (t_col > 0)
+ // Output any postponed text.
+ if (t_col > 0) {
t_puts(&t_col, t_s, s, attr);
- if (p_more && !recurse)
- store_sb_text(&sb_str, s, attr, &sb_col, FALSE);
+ }
+ if (p_more && !recurse) {
+ store_sb_text((char_u **)&sb_str, (char_u *)s, attr, &sb_col, false);
+ }
msg_check();
}
+/// Return true when ":filter pattern" was used and "msg" does not match
+/// "pattern".
+bool message_filtered(char_u *msg)
+{
+ if (cmdmod.filter_regmatch.regprog == NULL) {
+ return false;
+ }
+
+ bool match = vim_regexec(&cmdmod.filter_regmatch, msg, (colnr_T)0);
+ return cmdmod.filter_force ? match : !match;
+}
+
/*
* Scroll the screen up one line for displaying the next message line.
*/
@@ -1946,11 +2011,11 @@ static msgchunk_T *disp_sb_line(int row, msgchunk_T *smp)
/*
* Output any postponed text for msg_puts_attr_len().
*/
-static void t_puts(int *t_col, char_u *t_s, char_u *s, int attr)
+static void t_puts(int *t_col, const char_u *t_s, const char_u *s, int attr)
{
- /* output postponed text */
- msg_didout = TRUE; /* remember that line is not empty */
- screen_puts_len(t_s, (int)(s - t_s), msg_row, msg_col, attr);
+ // Output postponed text.
+ msg_didout = true; // Remember that line is not empty.
+ screen_puts_len((char_u *)t_s, (int)(s - t_s), msg_row, msg_col, attr);
msg_col += *t_col;
*t_col = 0;
/* If the string starts with a composing character don't increment the
@@ -1971,13 +2036,13 @@ int msg_use_printf(void)
}
/// Print a message when there is no valid screen.
-static void msg_puts_printf(char *str, int maxlen)
+static void msg_puts_printf(const char *str, const ptrdiff_t maxlen)
{
- char *s = str;
+ const char *s = str;
char buf[4];
char *p;
- while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen)) {
+ while ((maxlen < 0 || s - str < maxlen) && *s != NUL) {
if (!(silent_mode && p_verbose == 0)) {
// NL --> CR NL translation (for Unix, not for "--version")
p = &buf[0];
@@ -2434,24 +2499,15 @@ void msg_check(void)
* May write a string to the redirection file.
* When "maxlen" is -1 write the whole string, otherwise up to "maxlen" bytes.
*/
-static void redir_write(char_u *str, int maxlen)
+static void redir_write(const char *const str, const ptrdiff_t maxlen)
{
- char_u *s = str;
+ const char_u *s = (char_u *)str;
static int cur_col = 0;
if (maxlen == 0) {
return;
}
- // Append output for execute().
- if (capture_ga) {
- size_t len = 0;
- while (str[len] && (maxlen < 0 ? 1 : (len < (size_t)maxlen))) {
- len++;
- }
- ga_concat_len(capture_ga, (const char *)str, len);
- }
-
/* Don't do anything for displaying prompts and the like. */
if (redir_off)
return;
@@ -2464,6 +2520,9 @@ static void redir_write(char_u *str, int maxlen)
/* If the string doesn't start with CR or NL, go to msg_col */
if (*s != '\n' && *s != '\r') {
while (cur_col < msg_col) {
+ if (capture_ga) {
+ ga_concat_len(capture_ga, " ", 1);
+ }
if (redir_reg) {
write_reg_contents(redir_reg, (char_u *)" ", 1, true);
} else if (redir_vname) {
@@ -2478,28 +2537,36 @@ static void redir_write(char_u *str, int maxlen)
}
}
+ size_t len = maxlen == -1 ? STRLEN(s) : (size_t)maxlen;
+ if (capture_ga) {
+ ga_concat_len(capture_ga, (const char *)str, len);
+ }
if (redir_reg) {
- size_t len = maxlen == -1 ? STRLEN(s) : (size_t)maxlen;
write_reg_contents(redir_reg, s, len, true);
}
if (redir_vname) {
- var_redir_str(s, maxlen);
+ var_redir_str((char_u *)s, maxlen);
}
- /* Write and adjust the current column. */
- while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen)) {
- if (!redir_reg && !redir_vname)
- if (redir_fd != NULL)
+ // Write and adjust the current column.
+ while (*s != NUL
+ && (maxlen < 0 || (int)(s - (const char_u *)str) < maxlen)) {
+ if (!redir_reg && !redir_vname && !capture_ga) {
+ if (redir_fd != NULL) {
putc(*s, redir_fd);
- if (verbose_fd != NULL)
+ }
+ }
+ if (verbose_fd != NULL) {
putc(*s, verbose_fd);
- if (*s == '\r' || *s == '\n')
+ }
+ if (*s == '\r' || *s == '\n') {
cur_col = 0;
- else if (*s == '\t')
+ } else if (*s == '\t') {
cur_col += (8 - cur_col % 8);
- else
- ++cur_col;
- ++s;
+ } else {
+ cur_col++;
+ }
+ s++;
}
if (msg_silent != 0) /* should update msg_col */
@@ -2605,14 +2672,16 @@ void give_warning(char_u *message, bool hl) FUNC_ATTR_NONNULL_ARG(1)
set_vim_var_string(VV_WARNINGMSG, (char *) message, -1);
xfree(keep_msg);
keep_msg = NULL;
- if (hl)
+ if (hl) {
keep_msg_attr = hl_attr(HLF_W);
- else
+ } else {
keep_msg_attr = 0;
- if (msg_attr(message, keep_msg_attr) && msg_scrolled == 0)
+ }
+ if (msg_attr((const char *)message, keep_msg_attr) && msg_scrolled == 0) {
set_keep_msg(message, keep_msg_attr);
- msg_didout = FALSE; /* overwrite this message */
- msg_nowait = TRUE; /* don't wait for this message */
+ }
+ msg_didout = false; // Overwrite this message.
+ msg_nowait = true; // Don't wait for this message.
msg_col = 0;
--no_wait_return;
@@ -2674,9 +2743,11 @@ do_dialog (
int c;
int i;
- /* Don't output anything in silent mode ("ex -s") */
- if (silent_mode)
- return dfltbutton; /* return default option */
+ if (silent_mode // No dialogs in silent mode ("ex -s")
+ || !ui_active() // Without a UI Nvim waits for input forever.
+ ) {
+ return dfltbutton; // return default option
+ }
oldState = State;
@@ -2712,8 +2783,8 @@ do_dialog (
break;
}
- /* Make the character lowercase, as chars in "hotkeys" are. */
- c = vim_tolower(c);
+ // Make the character lowercase, as chars in "hotkeys" are.
+ c = mb_tolower(c);
retval = 1;
for (i = 0; hotkeys[i]; ++i) {
if (has_mbyte) {
@@ -2759,7 +2830,7 @@ copy_char (
if (has_mbyte) {
if (lowercase) {
- c = vim_tolower((*mb_ptr2char)(from));
+ c = mb_tolower((*mb_ptr2char)(from));
return (*mb_char2bytes)(c, to);
} else {
len = (*mb_ptr2len)(from);
@@ -2948,11 +3019,12 @@ static void copy_hotkeys_and_msg(const char_u *message, char_u *buttons,
*/
void display_confirm_msg(void)
{
- /* avoid that 'q' at the more prompt truncates the message here */
- ++confirm_msg_used;
- if (confirm_msg != NULL)
- msg_puts_attr(confirm_msg, hl_attr(HLF_M));
- --confirm_msg_used;
+ // Avoid that 'q' at the more prompt truncates the message here.
+ confirm_msg_used++;
+ if (confirm_msg != NULL) {
+ msg_puts_attr((const char *)confirm_msg, hl_attr(HLF_M));
+ }
+ confirm_msg_used--;
}
int vim_dialog_yesno(int type, char_u *title, char_u *message, int dflt)
@@ -2991,802 +3063,3 @@ int vim_dialog_yesnoallcancel(int type, char_u *title, char_u *message, int dflt
}
return VIM_CANCEL;
}
-
-
-
-static char *e_printf = N_("E766: Insufficient arguments for printf()");
-
-/*
- * Get number argument from "idxp" entry in "tvs". First entry is 1.
- */
-static long tv_nr(typval_T *tvs, int *idxp)
-{
- int idx = *idxp - 1;
- long n = 0;
- int err = FALSE;
-
- if (tvs[idx].v_type == VAR_UNKNOWN)
- EMSG(_(e_printf));
- else {
- ++*idxp;
- n = get_tv_number_chk(&tvs[idx], &err);
- if (err)
- n = 0;
- }
- return n;
-}
-
-/*
- * Get string argument from "idxp" entry in "tvs". First entry is 1.
- * Returns NULL for an error.
- */
-static char *tv_str(typval_T *tvs, int *idxp)
-{
- int idx = *idxp - 1;
- char *s = NULL;
-
- if (tvs[idx].v_type == VAR_UNKNOWN)
- EMSG(_(e_printf));
- else {
- ++*idxp;
- s = (char *)get_tv_string_chk(&tvs[idx]);
- }
- return s;
-}
-
-/*
- * Get float argument from "idxp" entry in "tvs". First entry is 1.
- */
-static double tv_float(typval_T *tvs, int *idxp)
-{
- int idx = *idxp - 1;
- double f = 0;
-
- if (tvs[idx].v_type == VAR_UNKNOWN)
- EMSG(_(e_printf));
- else {
- ++*idxp;
- if (tvs[idx].v_type == VAR_FLOAT)
- f = tvs[idx].vval.v_float;
- else if (tvs[idx].v_type == VAR_NUMBER)
- f = tvs[idx].vval.v_number;
- else
- EMSG(_("E807: Expected Float argument for printf()"));
- }
- return f;
-}
-
-/*
- * This code was included to provide a portable vsnprintf() and snprintf().
- * Some systems may provide their own, but we always use this one for
- * consistency.
- *
- * This code is based on snprintf.c - a portable implementation of snprintf
- * by Mark Martinec <mark.martinec@ijs.si>, Version 2.2, 2000-10-06.
- * Included with permission. It was heavily modified to fit in Vim.
- * The original code, including useful comments, can be found here:
- * http://www.ijs.si/software/snprintf/
- *
- * This snprintf() only supports the following conversion specifiers:
- * s, c, b, B, d, u, o, x, X, p (and synonyms: i, D, U, O - see below)
- * with flags: '-', '+', ' ', '0' and '#'.
- * An asterisk is supported for field width as well as precision.
- *
- * Limited support for floating point was added: 'f', 'e', 'E', 'g', 'G'.
- *
- * Length modifiers 'h' (short int) and 'l' (long int) are supported.
- * 'll' (long long int) is not supported.
- *
- * The locale is not used, the string is used as a byte string. This is only
- * relevant for double-byte encodings where the second byte may be '%'.
- *
- * It is permitted for "str_m" to be zero, and it is permitted to specify NULL
- * pointer for resulting string argument if "str_m" is zero (as per ISO C99).
- *
- * The return value is the number of characters which would be generated
- * for the given input, excluding the trailing NUL. If this value
- * is greater or equal to "str_m", not all characters from the result
- * have been stored in str, output bytes beyond the ("str_m"-1) -th character
- * are discarded. If "str_m" is greater than zero it is guaranteed
- * the resulting string will be NUL-terminated.
- */
-
-/*
- * When va_list is not supported we only define vim_snprintf().
- *
- * vim_vsnprintf() can be invoked with either "va_list" or a list of
- * "typval_T". When the latter is not used it must be NULL.
- */
-
-/* Like vim_vsnprintf() but append to the string. */
-int vim_snprintf_add(char *str, size_t str_m, char *fmt, ...)
-{
- va_list ap;
- int str_l;
- size_t len = STRLEN(str);
- size_t space;
-
- if (str_m <= len)
- space = 0;
- else
- space = str_m - len;
- va_start(ap, fmt);
- str_l = vim_vsnprintf(str + len, space, fmt, ap, NULL);
- va_end(ap);
- return str_l;
-}
-
-int vim_snprintf(char *str, size_t str_m, const char *fmt, ...)
-{
- va_list ap;
- int str_l;
-
- va_start(ap, fmt);
- str_l = vim_vsnprintf(str, str_m, fmt, ap, NULL);
- va_end(ap);
- return str_l;
-}
-
-int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap,
- typval_T *tvs)
-{
- size_t str_l = 0;
- bool str_avail = str_l < str_m;
- const char *p = fmt;
- int arg_idx = 1;
-
- if (!p) {
- p = "";
- }
- while (*p) {
- if (*p != '%') {
- // copy up to the next '%' or NUL without any changes
- size_t n = (size_t)(xstrchrnul(p + 1, '%') - p);
- if (str_avail) {
- size_t avail = str_m - str_l;
- memmove(str + str_l, p, MIN(n, avail));
- str_avail = n < avail;
- }
- p += n;
- assert(n <= SIZE_MAX - str_l);
- str_l += n;
- } else {
- size_t min_field_width = 0, precision = 0;
- int zero_padding = 0, precision_specified = 0, justify_left = 0;
- int alternate_form = 0, force_sign = 0;
-
- // if both ' ' and '+' flags appear, ' ' flag should be ignored
- int space_for_positive = 1;
-
- // allowed values: \0, h, l, 2 (for ll), z, L
- char length_modifier = '\0';
-
- // temporary buffer for simple numeric->string conversion
-# define TMP_LEN 350 // 1e308 seems reasonable as the maximum printable
- char tmp[TMP_LEN];
-
- // string address in case of string argument
- const char *str_arg;
-
- // natural field width of arg without padding and sign
- size_t str_arg_l;
-
- // unsigned char argument value (only defined for c conversion);
- // standard explicitly states the char argument for the c
- // conversion is unsigned
- unsigned char uchar_arg;
-
- // number of zeros to be inserted for numeric conversions as
- // required by the precision or minimal field width
- size_t number_of_zeros_to_pad = 0;
-
- // index into tmp where zero padding is to be inserted
- size_t zero_padding_insertion_ind = 0;
-
- // current conversion specifier character
- char fmt_spec = '\0';
-
- str_arg = NULL;
- p++; // skip '%'
-
- // parse flags
- while (*p == '0' || *p == '-' || *p == '+' || *p == ' '
- || *p == '#' || *p == '\'') {
- switch (*p) {
- case '0': zero_padding = 1; break;
- case '-': justify_left = 1; break;
- // if both '0' and '-' flags appear, '0' should be ignored
- case '+': force_sign = 1; space_for_positive = 0; break;
- case ' ': force_sign = 1; break;
- // if both ' ' and '+' flags appear, ' ' should be ignored
- case '#': alternate_form = 1; break;
- case '\'': break;
- }
- p++;
- }
-
- // parse field width
- if (*p == '*') {
- p++;
- int j = tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int);
- if (j >= 0) {
- min_field_width = j;
- } else {
- min_field_width = -j;
- justify_left = 1;
- }
- } else if (ascii_isdigit((int)(*p))) {
- // size_t could be wider than unsigned int; make sure we treat
- // argument like common implementations do
- unsigned int uj = *p++ - '0';
-
- while (ascii_isdigit((int)(*p))) {
- uj = 10 * uj + (unsigned int)(*p++ - '0');
- }
- min_field_width = uj;
- }
-
- // parse precision
- if (*p == '.') {
- p++;
- precision_specified = 1;
- if (*p == '*') {
- int j = tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int);
- p++;
- if (j >= 0) {
- precision = j;
- } else {
- precision_specified = 0;
- precision = 0;
- }
- } else if (ascii_isdigit((int)(*p))) {
- // size_t could be wider than unsigned int; make sure we
- // treat argument like common implementations do
- unsigned int uj = *p++ - '0';
-
- while (ascii_isdigit((int)(*p))) {
- uj = 10 * uj + (unsigned int)(*p++ - '0');
- }
- precision = uj;
- }
- }
-
- // parse 'h', 'l', 'll' and 'z' length modifiers
- if (*p == 'h' || *p == 'l' || *p == 'z') {
- length_modifier = *p;
- p++;
- if (length_modifier == 'l' && *p == 'l') { // ll, encoded as 2
- length_modifier = '2';
- p++;
- }
- }
-
- fmt_spec = *p;
-
- // common synonyms
- switch (fmt_spec) {
- case 'i': fmt_spec = 'd'; break;
- case 'D': fmt_spec = 'd'; length_modifier = 'l'; break;
- case 'U': fmt_spec = 'u'; length_modifier = 'l'; break;
- case 'O': fmt_spec = 'o'; length_modifier = 'l'; break;
- case 'F': fmt_spec = 'f'; break;
- default: break;
- }
-
- // get parameter value, do initial processing
- switch (fmt_spec) {
- // '%' and 'c' behave similar to 's' regarding flags and field widths
- case '%': case 'c': case 's': case 'S':
- str_arg_l = 1;
- switch (fmt_spec) {
- case '%':
- str_arg = p;
- break;
-
- case 'c': {
- int j = tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int);
- // standard demands unsigned char
- uchar_arg = (unsigned char)j;
- str_arg = (char *)&uchar_arg;
- break;
- }
-
- case 's':
- case 'S':
- str_arg = tvs ? tv_str(tvs, &arg_idx) : va_arg(ap, char *);
- if (!str_arg) {
- str_arg = "[NULL]";
- str_arg_l = 6;
- } else if (!precision_specified) {
- // make sure not to address string beyond the specified precision
- str_arg_l = strlen(str_arg);
- } else if (precision == 0) {
- // truncate string if necessary as requested by precision
- str_arg_l = 0;
- } else {
- // memchr on HP does not like n > 2^31
- // TODO(elmart): check if this still holds / is relevant
- str_arg_l = (size_t)((char *)xmemscan(str_arg,
- NUL,
- MIN(precision, 0x7fffffff))
- - str_arg);
- }
- if (fmt_spec == 'S') {
- if (min_field_width != 0)
- min_field_width += strlen(str_arg)
- - mb_string2cells((char_u *) str_arg);
- if (precision) {
- char_u *p1 = (char_u *)str_arg;
- for (size_t i = 0; i < precision && *p1; i++) {
- p1 += mb_ptr2len(p1);
- }
- str_arg_l = precision = p1 - (char_u *)str_arg;
- }
- }
- break;
-
- default:
- break;
- }
- break;
-
- case 'd':
- case 'u':
- case 'b': case 'B':
- case 'o':
- case 'x': case 'X':
- case 'p': {
- // u, b, B, o, x, X and p conversion specifiers imply
- // the value is unsigned; d implies a signed value
-
- // 0 if numeric argument is zero (or if pointer is NULL for 'p'),
- // +1 if greater than zero (or non NULL for 'p'),
- // -1 if negative (unsigned argument is never negative)
- int arg_sign = 0;
-
- // only defined for length modifier h, or for no length modifiers
- int int_arg = 0;
- unsigned int uint_arg = 0;
-
- // only defined for length modifier l
- long int long_arg = 0;
- unsigned long int ulong_arg = 0;
-
- // only defined for length modifier ll
- long long int long_long_arg = 0;
- unsigned long long int ulong_long_arg = 0;
-
- // only defined for length modifier z
- size_t size_t_arg = 0;
-
- // only defined for p conversion
- void *ptr_arg = NULL;
-
- if (fmt_spec == 'p') {
- length_modifier = '\0';
- ptr_arg = tvs ? (void *)tv_str(tvs, &arg_idx) : va_arg(ap, void *);
- if (ptr_arg) {
- arg_sign = 1;
- }
- } else if (fmt_spec == 'd') {
- // signed
- switch (length_modifier) {
- case '\0':
- case 'h':
- // char and short arguments are passed as int
- int_arg = tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int);
- if (int_arg > 0) {
- arg_sign = 1;
- } else if (int_arg < 0) {
- arg_sign = -1;
- }
- break;
- case 'l':
- long_arg = tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, long int);
- if (long_arg > 0) {
- arg_sign = 1;
- } else if (long_arg < 0) {
- arg_sign = -1;
- }
- break;
- case '2':
- long_long_arg = tvs ? tv_nr(tvs, &arg_idx)
- : va_arg(ap, long long int); // NOLINT (runtime/int)
- if (long_long_arg > 0) {
- arg_sign = 1;
- } else if (long_long_arg < 0) {
- arg_sign = -1;
- }
- break;
- }
- } else {
- // unsigned
- switch (length_modifier) {
- case '\0':
- case 'h':
- uint_arg = tvs ? (unsigned)tv_nr(tvs, &arg_idx)
- : va_arg(ap, unsigned int);
- if (uint_arg != 0) { arg_sign = 1; }
- break;
- case 'l':
- ulong_arg = tvs ? (unsigned long)tv_nr(tvs, &arg_idx)
- : va_arg(ap, unsigned long int);
- if (ulong_arg != 0) { arg_sign = 1; }
- break;
- case '2':
- ulong_long_arg = tvs
- ? (unsigned long long)tv_nr(tvs, &arg_idx) // NOLINT (runtime/int)
- : va_arg(ap, unsigned long long int); // NOLINT (runtime/int)
- if (ulong_long_arg) { arg_sign = 1; }
- break;
- case 'z':
- size_t_arg = tvs ? (size_t)tv_nr(tvs, &arg_idx)
- : va_arg(ap, size_t);
- if (size_t_arg) { arg_sign = 1; }
- break;
- }
- }
-
- str_arg = tmp;
- str_arg_l = 0;
-
- // For d, i, u, o, x, and X conversions, if precision is specified,
- // '0' flag should be ignored. This is so with Solaris 2.6, Digital UNIX
- // 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl.
- if (precision_specified) {
- zero_padding = 0;
- }
-
- if (fmt_spec == 'd') {
- if (force_sign && arg_sign >= 0) {
- tmp[str_arg_l++] = space_for_positive ? ' ' : '+';
- }
- // leave negative numbers for sprintf to handle, to
- // avoid handling tricky cases like (short int)-32768
- } else if (alternate_form) {
- if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X'
- || fmt_spec == 'b' || fmt_spec == 'B')) {
- tmp[str_arg_l++] = '0';
- tmp[str_arg_l++] = fmt_spec;
- }
- // alternate form should have no effect for p * conversion, but ...
- }
-
- zero_padding_insertion_ind = str_arg_l;
- if (!precision_specified) {
- precision = 1; // default precision is 1
- }
- if (precision == 0 && arg_sign == 0) {
- // when zero value is formatted with an explicit precision 0,
- // resulting formatted string is empty (d, i, u, b, B, o, x, X, p)
- } else {
- char f[5];
- int f_l = 0;
-
- // construct a simple format string for sprintf
- f[f_l++] = '%';
- if (!length_modifier) {
- } else if (length_modifier == '2') {
- f[f_l++] = 'l';
- f[f_l++] = 'l';
- } else
- f[f_l++] = length_modifier;
- f[f_l++] = fmt_spec;
- f[f_l++] = '\0';
-
- if (fmt_spec == 'p')
- str_arg_l += sprintf(tmp + str_arg_l, f, ptr_arg);
- else if (fmt_spec == 'd') {
- // signed
- switch (length_modifier) {
- case '\0':
- case 'h': str_arg_l += sprintf(tmp + str_arg_l, f, int_arg);
- break;
- case 'l': str_arg_l += sprintf(tmp + str_arg_l, f, long_arg);
- break;
- case '2': str_arg_l += sprintf(tmp + str_arg_l, f, long_long_arg);
- break;
- }
- } else if (fmt_spec == 'b' || fmt_spec == 'B') {
- // binary
- size_t bits = 0;
- switch (length_modifier) {
- case '\0':
- case 'h': for (bits = sizeof(unsigned) * 8; bits > 0; bits--) {
- if ((uint_arg >> (bits - 1)) & 0x1) { break; } }
-
- while (bits > 0) {
- tmp[str_arg_l++] =
- ((uint_arg >> --bits) & 0x1) ? '1' : '0'; }
- break;
- case 'l': for (bits = sizeof(unsigned long) * 8; bits > 0; bits--) {
- if ((ulong_arg >> (bits - 1)) & 0x1) { break; } }
-
- while (bits > 0) {
- tmp[str_arg_l++] =
- ((ulong_arg >> --bits) & 0x1) ? '1' : '0'; }
- break;
- case '2': for (bits = sizeof(unsigned long long) * 8; // NOLINT (runtime/int)
- bits > 0; bits--) {
- if ((ulong_long_arg >> (bits - 1)) & 0x1) { break; } }
-
- while (bits > 0) {
- tmp[str_arg_l++] =
- ((ulong_long_arg >> --bits) & 0x1) ? '1' : '0'; }
- break;
- case 'z': for (bits = sizeof(size_t) * 8; bits > 0; bits--) {
- if ((size_t_arg >> (bits - 1)) & 0x1) { break; } }
-
- while (bits > 0) {
- tmp[str_arg_l++] =
- ((size_t_arg >> --bits) & 0x1) ? '1' : '0'; }
- break;
- }
- } else {
- // unsigned
- switch (length_modifier) {
- case '\0':
- case 'h': str_arg_l += sprintf(tmp + str_arg_l, f, uint_arg);
- break;
- case 'l': str_arg_l += sprintf(tmp + str_arg_l, f, ulong_arg);
- break;
- case '2': str_arg_l += sprintf(tmp + str_arg_l, f, ulong_long_arg);
- break;
- case 'z': str_arg_l += sprintf(tmp + str_arg_l, f, size_t_arg);
- break;
- }
- }
-
- // include the optional minus sign and possible "0x" in the region
- // before the zero padding insertion point
- if (zero_padding_insertion_ind < str_arg_l
- && tmp[zero_padding_insertion_ind] == '-')
- zero_padding_insertion_ind++;
- if (zero_padding_insertion_ind + 1 < str_arg_l
- && tmp[zero_padding_insertion_ind] == '0'
- && (tmp[zero_padding_insertion_ind + 1] == 'x'
- || tmp[zero_padding_insertion_ind + 1] == 'X'
- || tmp[zero_padding_insertion_ind + 1] == 'b'
- || tmp[zero_padding_insertion_ind + 1] == 'B'))
- zero_padding_insertion_ind += 2;
- }
-
- {
- size_t num_of_digits = str_arg_l - zero_padding_insertion_ind;
-
- if (alternate_form && fmt_spec == 'o'
- // unless zero is already the first character
- && !(zero_padding_insertion_ind < str_arg_l
- && tmp[zero_padding_insertion_ind] == '0')) {
- // assure leading zero for alternate-form octal numbers
- if (!precision_specified
- || precision < num_of_digits + 1) {
- // precision is increased to force the first character to be zero,
- // except if a zero value is formatted with an explicit precision
- // of zero
- precision = num_of_digits + 1;
- }
- }
- // zero padding to specified precision?
- if (num_of_digits < precision)
- number_of_zeros_to_pad = precision - num_of_digits;
- }
- // zero padding to specified minimal field width?
- if (!justify_left && zero_padding) {
- int n = (int)(min_field_width - (str_arg_l
- + number_of_zeros_to_pad));
- if (n > 0)
- number_of_zeros_to_pad += n;
- }
- break;
- }
-
- case 'f':
- case 'e':
- case 'E':
- case 'g':
- case 'G':
- {
- // floating point
- char format[40];
- int l;
- int remove_trailing_zeroes = false;
-
- double f = tvs ? tv_float(tvs, &arg_idx) : va_arg(ap, double);
- double abs_f = f < 0 ? -f : f;
-
- if (fmt_spec == 'g' || fmt_spec == 'G') {
- // can't use %g directly, cause it prints "1.0" as "1"
- if ((abs_f >= 0.001 && abs_f < 10000000.0) || abs_f == 0.0)
- fmt_spec = 'f';
- else
- fmt_spec = fmt_spec == 'g' ? 'e' : 'E';
- remove_trailing_zeroes = true;
- }
-
- if (fmt_spec == 'f' && abs_f > 1.0e307) {
- // avoid a buffer overflow
- strcpy(tmp, "inf");
- str_arg_l = 3;
- } else {
- format[0] = '%';
- l = 1;
- if (precision_specified) {
- size_t max_prec = TMP_LEN - 10;
-
- // make sure we don't get more digits than we have room for
- if (fmt_spec == 'f' && abs_f > 1.0)
- max_prec -= (size_t)log10(abs_f);
- if (precision > max_prec)
- precision = max_prec;
- l += sprintf(format + 1, ".%d", (int)precision);
- }
- format[l] = fmt_spec;
- format[l + 1] = NUL;
- str_arg_l = sprintf(tmp, format, f);
-
- if (remove_trailing_zeroes) {
- int i;
- char *tp;
-
- // using %g or %G: remove superfluous zeroes
- if (fmt_spec == 'f')
- tp = tmp + str_arg_l - 1;
- else {
- tp = (char *)vim_strchr((char_u *)tmp,
- fmt_spec == 'e' ? 'e' : 'E');
- if (tp) {
- // remove superfluous '+' and leading zeroes from exponent
- if (tp[1] == '+') {
- // change "1.0e+07" to "1.0e07"
- STRMOVE(tp + 1, tp + 2);
- --str_arg_l;
- }
- i = (tp[1] == '-') ? 2 : 1;
- while (tp[i] == '0') {
- // change "1.0e07" to "1.0e7"
- STRMOVE(tp + i, tp + i + 1);
- --str_arg_l;
- }
- --tp;
- }
- }
-
- if (tp != NULL && !precision_specified)
- // remove trailing zeroes, but keep the one just after a dot
- while (tp > tmp + 2 && *tp == '0' && tp[-1] != '.') {
- STRMOVE(tp, tp + 1);
- --tp;
- --str_arg_l;
- }
- } else {
- // be consistent: some printf("%e") use 1.0e+12 and some 1.0e+012;
- // remove one zero in the last case
- char *tp = (char *)vim_strchr((char_u *)tmp,
- fmt_spec == 'e' ? 'e' : 'E');
- if (tp && (tp[1] == '+' || tp[1] == '-') && tp[2] == '0'
- && ascii_isdigit(tp[3]) && ascii_isdigit(tp[4])) {
- STRMOVE(tp + 2, tp + 3);
- --str_arg_l;
- }
- }
- }
- str_arg = tmp;
- break;
- }
-
- default:
- // unrecognized conversion specifier, keep format string as-is
- zero_padding = 0; // turn zero padding off for non-numeric conversion
- justify_left = 1;
- min_field_width = 0; // reset flags
-
- // discard the unrecognized conversion, just keep
- // the unrecognized conversion character
- str_arg = p;
- str_arg_l = 0;
- if (*p)
- str_arg_l++; // include invalid conversion specifier
- // unchanged if not at end-of-string
- break;
- }
-
- if (*p)
- p++; // step over the just processed conversion specifier
-
- // insert padding to the left as requested by min_field_width;
- // this does not include the zero padding in case of numerical conversions
- if (!justify_left) {
- assert(str_arg_l <= SIZE_MAX - number_of_zeros_to_pad);
- if (min_field_width > str_arg_l + number_of_zeros_to_pad) {
- // left padding with blank or zero
- size_t pn = min_field_width - (str_arg_l + number_of_zeros_to_pad);
- if (str_avail) {
- size_t avail = str_m - str_l;
- memset(str + str_l, zero_padding ? '0' : ' ', MIN(pn, avail));
- str_avail = pn < avail;
- }
- assert(pn <= SIZE_MAX - str_l);
- str_l += pn;
- }
- }
-
- // zero padding as requested by the precision or by the minimal
- // field width for numeric conversions required?
- if (number_of_zeros_to_pad == 0) {
- // will not copy first part of numeric right now,
- // force it to be copied later in its entirety
- zero_padding_insertion_ind = 0;
- } else {
- // insert first part of numerics (sign or '0x') before zero padding
- if (zero_padding_insertion_ind > 0) {
- size_t zn = zero_padding_insertion_ind;
- if (str_avail) {
- size_t avail = str_m - str_l;
- memmove(str + str_l, str_arg, MIN(zn, avail));
- str_avail = zn < avail;
- }
- assert(zn <= SIZE_MAX - str_l);
- str_l += zn;
- }
-
- // insert zero padding as requested by precision or min field width
- if (number_of_zeros_to_pad > 0) {
- size_t zn = number_of_zeros_to_pad;
- if (str_avail) {
- size_t avail = str_m - str_l;
- memset(str + str_l, '0', MIN(zn, avail));
- str_avail = zn < avail;
- }
- assert(zn <= SIZE_MAX - str_l);
- str_l += zn;
- }
- }
-
- // insert formatted string
- // (or as-is conversion specifier for unknown conversions)
- if (str_arg_l > zero_padding_insertion_ind) {
- size_t sn = str_arg_l - zero_padding_insertion_ind;
- if (str_avail) {
- size_t avail = str_m - str_l;
- memmove(str + str_l,
- str_arg + zero_padding_insertion_ind,
- MIN(sn, avail));
- str_avail = sn < avail;
- }
- assert(sn <= SIZE_MAX - str_l);
- str_l += sn;
- }
-
- // insert right padding
- if (justify_left) {
- assert(str_arg_l <= SIZE_MAX - number_of_zeros_to_pad);
- if (min_field_width > str_arg_l + number_of_zeros_to_pad) {
- // right blank padding to the field width
- size_t pn = min_field_width - (str_arg_l + number_of_zeros_to_pad);
- if (str_avail) {
- size_t avail = str_m - str_l;
- memset(str + str_l, ' ', MIN(pn, avail));
- str_avail = pn < avail;
- }
- assert(pn <= SIZE_MAX - str_l);
- str_l += pn;
- }
- }
- }
- }
-
- if (str_m > 0) {
- // make sure the string is nul-terminated even at the expense of
- // overwriting the last character (shouldn't happen, but just in case)
- str[str_l <= str_m - 1 ? str_l : str_m - 1] = '\0';
- }
-
- if (tvs && tvs[arg_idx - 1].v_type != VAR_UNKNOWN)
- EMSG(_("E767: Too many arguments to printf()"));
-
- // return the number of characters formatted (excluding trailing nul
- // character); that is, the number of characters that would have been
- // written to the buffer if it were large enough.
- return (int)str_l;
-}
diff --git a/src/nvim/message.h b/src/nvim/message.h
index d3a16fff93..904a9d3ca1 100644
--- a/src/nvim/message.h
+++ b/src/nvim/message.h
@@ -3,8 +3,9 @@
#include <stdbool.h>
#include <stdarg.h>
-#include "nvim/eval_defs.h" // for typval_T
-#include "nvim/ex_cmds_defs.h" // for exarg_T
+#include <stddef.h>
+
+#include "nvim/types.h"
/*
* Types of dialogs passed to do_dialog().
@@ -29,7 +30,7 @@
#define MSG(s) msg((char_u *)(s))
/// Show message highlighted according to the attr
-#define MSG_ATTR(s, attr) msg_attr((char_u *)(s), (attr))
+#define MSG_ATTR(s, attr) msg_attr((const char *)(s), (attr))
/// Display error message
///
@@ -49,13 +50,13 @@
#define EMSGU(s, n) emsgf((const char *) (s), (uint64_t)(n))
/// Display message at the recorded position
-#define MSG_PUTS(s) msg_puts((char_u *)(s))
+#define MSG_PUTS(s) msg_puts((const char *)(s))
/// Display message at the recorded position, highlighted
-#define MSG_PUTS_ATTR(s, a) msg_puts_attr((char_u *)(s), (a))
+#define MSG_PUTS_ATTR(s, a) msg_puts_attr((const char *)(s), (a))
/// Like #MSG_PUTS, but highlight like title
-#define MSG_PUTS_TITLE(s) msg_puts_title((char_u *)(s))
+#define MSG_PUTS_TITLE(s) msg_puts_title((const char *)(s))
/// Like #MSG_PUTS, but if middle part of too long messages it will be replaced
#define MSG_PUTS_LONG(s) msg_puts_long_attr((char_u *)(s), 0)
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index 71aa6e83e5..5270687a4d 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* misc1.c: functions that didn't seem to fit elsewhere
*/
@@ -51,6 +54,7 @@
#include "nvim/os/input.h"
#include "nvim/os/time.h"
#include "nvim/event/stream.h"
+#include "nvim/buffer.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "misc1.c.generated.h"
@@ -747,7 +751,7 @@ open_line (
// Skip mark_adjust when adding a line after the last one, there can't
// be marks there.
if (curwin->w_cursor.lnum + 1 < curbuf->b_ml.ml_line_count) {
- mark_adjust(curwin->w_cursor.lnum + 1, (linenr_T)MAXLNUM, 1L, 0L);
+ mark_adjust(curwin->w_cursor.lnum + 1, (linenr_T)MAXLNUM, 1L, 0L, false);
}
did_append = true;
} else {
@@ -1405,7 +1409,6 @@ void ins_char_bytes(char_u *buf, size_t charlen)
coladvance_force(getviscol());
}
- int c = buf[0];
size_t col = (size_t)curwin->w_cursor.col;
linenr_T lnum = curwin->w_cursor.lnum;
char_u *oldp = ml_get(lnum);
@@ -1498,10 +1501,7 @@ void ins_char_bytes(char_u *buf, size_t charlen)
&& msg_silent == 0
&& !ins_compl_active()
) {
- if (has_mbyte)
- showmatch(mb_ptr2char(buf));
- else
- showmatch(c);
+ showmatch(mb_ptr2char(buf));
}
if (!p_ri || (State & REPLACE_FLAG)) {
@@ -1788,7 +1788,7 @@ void changed(void)
}
changed_int();
}
- ++curbuf->b_changedtick;
+ buf_set_changedtick(curbuf, curbuf->b_changedtick + 1);
}
/*
@@ -1866,7 +1866,7 @@ void appended_lines_mark(linenr_T lnum, long count)
// Skip mark_adjust when adding a line after the last one, there can't
// be marks there.
if (lnum + count < curbuf->b_ml.ml_line_count) {
- mark_adjust(lnum + 1, (linenr_T)MAXLNUM, count, 0L);
+ mark_adjust(lnum + 1, (linenr_T)MAXLNUM, count, 0L, false);
}
changed_lines(lnum + 1, 0, lnum + 1, count);
}
@@ -1888,7 +1888,7 @@ void deleted_lines(linenr_T lnum, long count)
*/
void deleted_lines_mark(linenr_T lnum, long count)
{
- mark_adjust(lnum, (linenr_T)(lnum + count - 1), (long)MAXLNUM, -count);
+ mark_adjust(lnum, (linenr_T)(lnum + count - 1), (long)MAXLNUM, -count, false);
changed_lines(lnum, 0, lnum + count, -count);
}
@@ -2147,7 +2147,7 @@ unchanged (
redraw_tabline = TRUE;
need_maketitle = TRUE; /* set window title later */
}
- ++buf->b_changedtick;
+ buf_set_changedtick(buf, buf->b_changedtick + 1);
}
/*
@@ -2203,7 +2203,7 @@ change_warning (
set_vim_var_string(VV_WARNINGMSG, _(w_readonly), -1);
msg_clr_eos();
(void)msg_end();
- if (msg_silent == 0 && !silent_mode) {
+ if (msg_silent == 0 && !silent_mode && ui_active()) {
ui_flush();
os_delay(1000L, true); /* give the user time to think about it */
}
@@ -2214,44 +2214,47 @@ change_warning (
}
}
-/*
- * Ask for a reply from the user, a 'y' or a 'n'.
- * No other characters are accepted, the message is repeated until a valid
- * reply is entered or CTRL-C is hit.
- * If direct is TRUE, don't use vgetc() but ui_inchar(), don't get characters
- * from any buffers but directly from the user.
- *
- * return the 'y' or 'n'
- */
-int ask_yesno(char_u *str, int direct)
+/// Ask for a reply from the user, 'y' or 'n'
+///
+/// No other characters are accepted, the message is repeated until a valid
+/// reply is entered or <C-c> is hit.
+///
+/// @param[in] str Prompt: question to ask user. Is always followed by
+/// " (y/n)?".
+/// @param[in] direct Determines what function to use to get user input. If
+/// true then ui_inchar() will be used, otherwise vgetc().
+/// I.e. when direct is true then characters are obtained
+/// directly from the user without buffers involved.
+///
+/// @return 'y' or 'n'. Last is also what will be returned in case of interrupt.
+int ask_yesno(const char *const str, const bool direct)
{
- int r = ' ';
- int save_State = State;
+ const int save_State = State;
- ++no_wait_return;
- State = CONFIRM; /* mouse behaves like with :confirm */
- setmouse(); /* disables mouse for xterm */
- ++no_mapping;
- ++allow_keys; /* no mapping here, but recognize keys */
+ no_wait_return++;
+ State = CONFIRM; // Mouse behaves like with :confirm.
+ setmouse(); // Disable mouse in xterm.
+ no_mapping++;
+ int r = ' ';
while (r != 'y' && r != 'n') {
- /* same highlighting as for wait_return */
- smsg_attr(hl_attr(HLF_R),
- "%s (y/n)?", str);
- if (direct)
+ // Same highlighting as for wait_return.
+ smsg_attr(hl_attr(HLF_R), "%s (y/n)?", str);
+ if (direct) {
r = get_keystroke();
- else
+ } else {
r = plain_vgetc();
- if (r == Ctrl_C || r == ESC)
+ }
+ if (r == Ctrl_C || r == ESC) {
r = 'n';
- msg_putchar(r); /* show what you typed */
+ }
+ msg_putchar(r); // Show what you typed.
ui_flush();
}
- --no_wait_return;
+ no_wait_return--;
State = save_State;
setmouse();
- --no_mapping;
- --allow_keys;
+ no_mapping--;
return r;
}
@@ -2324,8 +2327,8 @@ int get_keystroke(void)
* terminal code to complete. */
n = os_inchar(buf + len, maxlen, len == 0 ? -1L : 100L, 0);
if (n > 0) {
- /* Replace zero and CSI by a special key code. */
- n = fix_input_buffer(buf + len, n, FALSE);
+ // Replace zero and CSI by a special key code.
+ n = fix_input_buffer(buf + len, n);
len += n;
waited = 0;
} else if (len > 0)
@@ -2401,8 +2404,7 @@ get_number (
if (msg_silent != 0)
return 0;
- ++no_mapping;
- ++allow_keys; /* no mapping here, but recognize keys */
+ no_mapping++;
for (;; ) {
ui_cursor_goto(msg_row, msg_col);
c = safe_vgetc();
@@ -2430,8 +2432,7 @@ get_number (
} else if (c == CAR || c == NL || c == Ctrl_C || c == ESC)
break;
}
- --no_mapping;
- --allow_keys;
+ no_mapping--;
return n;
}
@@ -2507,8 +2508,9 @@ void msgmore(long n)
vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
_("%" PRId64 " fewer lines"), (int64_t)pn);
}
- if (got_int)
- vim_strcat(msg_buf, (char_u *)_(" (Interrupted)"), MSG_BUF_LEN);
+ if (got_int) {
+ xstrlcat((char *)msg_buf, _(" (Interrupted)"), MSG_BUF_LEN);
+ }
if (msg(msg_buf)) {
set_keep_msg(msg_buf, 0);
keep_msg_more = TRUE;
@@ -2534,9 +2536,9 @@ void vim_beep(unsigned val)
if (emsg_silent == 0) {
if (!((bo_flags & val) || (bo_flags & BO_ALL))) {
if (p_vb) {
- ui_visual_bell();
+ ui_call_visual_bell();
} else {
- ui_putc(BELL);
+ ui_call_bell();
}
}
@@ -2544,7 +2546,7 @@ void vim_beep(unsigned val)
* function give the user a hint where the beep comes from. */
if (vim_strchr(p_debug, 'e') != NULL) {
msg_source(hl_attr(HLF_W));
- msg_attr((char_u *)_("Beep!"), hl_attr(HLF_W));
+ msg_attr(_("Beep!"), hl_attr(HLF_W));
}
}
}
@@ -2679,7 +2681,8 @@ void fast_breakcheck(void)
}
}
-// Call shell. Calls os_call_shell, with 'shellxquote' added.
+// os_call_shell wrapper. Handles 'verbose', :profile, and v:shell_error.
+// Invalidates cached tags.
int call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg)
{
int retval;
@@ -2687,9 +2690,8 @@ int call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg)
if (p_verbose > 3) {
verbose_enter();
- smsg(_("Calling shell to execute: \"%s\""),
- cmd == NULL ? p_sh : cmd);
- ui_putc('\n');
+ smsg(_("Calling shell to execute: \"%s\""), cmd == NULL ? p_sh : cmd);
+ ui_linefeed();
verbose_leave();
}
diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c
index 2ebe199f47..d908a022f1 100644
--- a/src/nvim/mouse.c
+++ b/src/nvim/mouse.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <stdbool.h>
#include "nvim/mouse.h"
@@ -456,6 +459,7 @@ void setmouse(void)
{
int checkfor;
+ ui_cursor_shape();
/* be quick when mouse is off */
if (*p_mouse == NUL)
@@ -475,9 +479,9 @@ void setmouse(void)
checkfor = MOUSE_NORMAL; /* assume normal mode */
if (mouse_has(checkfor)) {
- ui_mouse_on();
+ ui_call_mouse_on();
} else {
- ui_mouse_off();
+ ui_call_mouse_off();
}
}
diff --git a/src/nvim/move.c b/src/nvim/move.c
index bb6c032db1..4d646f5a4b 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* move.c: Functions for moving the cursor and scrolling text.
*
@@ -1760,7 +1763,7 @@ int onepage(int dir, long count)
loff.fill = 0;
if (dir == FORWARD) {
- if (firstwin == lastwin && p_window > 0 && p_window < Rows - 1) {
+ if (ONE_WINDOW && p_window > 0 && p_window < Rows - 1) {
/* Vi compatible scrolling */
if (p_window <= 2)
++curwin->w_topline;
@@ -1794,7 +1797,7 @@ int onepage(int dir, long count)
max_topfill();
continue;
}
- if (firstwin == lastwin && p_window > 0 && p_window < Rows - 1) {
+ if (ONE_WINDOW && p_window > 0 && p_window < Rows - 1) {
/* Vi compatible scrolling (sort of) */
if (p_window <= 2)
--curwin->w_topline;
@@ -1878,8 +1881,10 @@ int onepage(int dir, long count)
}
foldAdjustCursor();
cursor_correct();
- if (retval == OK)
+ check_cursor_col();
+ if (retval == OK) {
beginline(BL_SOL | BL_FIX);
+ }
curwin->w_valid &= ~(VALID_WCOL|VALID_WROW|VALID_VIRTCOL);
/*
@@ -2137,18 +2142,17 @@ void do_check_cursorbind(void)
* loop through the cursorbound windows
*/
VIsual_select = VIsual_active = 0;
- for (curwin = firstwin; curwin; curwin = curwin->w_next) {
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ curwin = wp;
curbuf = curwin->w_buffer;
/* skip original window and windows with 'noscrollbind' */
if (curwin != old_curwin && curwin->w_p_crb) {
- if (curwin->w_p_diff)
- curwin->w_cursor.lnum
- = diff_get_corresponding_line(old_curbuf,
- line,
- curbuf,
- curwin->w_cursor.lnum);
- else
+ if (curwin->w_p_diff) {
+ curwin->w_cursor.lnum =
+ diff_get_corresponding_line(old_curbuf, line);
+ } else {
curwin->w_cursor.lnum = line;
+ }
curwin->w_cursor.col = col;
curwin->w_cursor.coladd = coladd;
curwin->w_curswant = curswant;
diff --git a/src/nvim/move.h b/src/nvim/move.h
index 3f3bf70929..00fbcc580f 100644
--- a/src/nvim/move.h
+++ b/src/nvim/move.h
@@ -2,6 +2,8 @@
#define NVIM_MOVE_H
#include <stdbool.h>
+#include "nvim/buffer_defs.h"
+#include "nvim/pos.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "move.h.generated.h"
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index 98636263b9..02f3854f47 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
@@ -9,6 +12,7 @@
#include "nvim/api/vim.h"
#include "nvim/api/ui.h"
#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/msgpack_rpc/server.h"
#include "nvim/event/loop.h"
#include "nvim/event/libuv_process.h"
#include "nvim/event/rstream.h"
@@ -25,7 +29,9 @@
#include "nvim/map.h"
#include "nvim/log.h"
#include "nvim/misc1.h"
+#include "nvim/path.h"
#include "nvim/lib/kvec.h"
+#include "nvim/os/input.h"
#define CHANNEL_BUFFER_SIZE 0xffff
@@ -37,7 +43,8 @@
typedef enum {
kChannelTypeSocket,
kChannelTypeProc,
- kChannelTypeStdio
+ kChannelTypeStdio,
+ kChannelTypeInternal
} ChannelType;
typedef struct {
@@ -55,7 +62,7 @@ typedef struct {
ChannelType type;
msgpack_unpacker *unpacker;
union {
- Stream stream;
+ Stream stream; // bidirectional (socket)
Process *proc;
struct {
Stream in;
@@ -86,6 +93,7 @@ static msgpack_sbuffer out_buffer;
/// Initializes the module
void channel_init(void)
{
+ ch_before_blocking_events = multiqueue_new_child(main_loop.events);
channels = pmap_new(uint64_t)();
event_strings = pmap_new(cstr_t)();
msgpack_sbuffer_init(&out_buffer);
@@ -109,18 +117,24 @@ void channel_teardown(void)
/// Creates an API channel by starting a process and connecting to its
/// stdin/stdout. stderr is handled by the job infrastructure.
///
-/// @param argv The argument vector for the process. [consumed]
-/// @return The channel id (> 0), on success.
-/// 0, on error.
-uint64_t channel_from_process(Process *proc, uint64_t id)
+/// @param proc process object
+/// @param id (optional) channel id
+/// @param source description of source function, rplugin name, TCP addr, etc
+///
+/// @return Channel id (> 0), on success. 0, on error.
+uint64_t channel_from_process(Process *proc, uint64_t id, char *source)
{
- Channel *channel = register_channel(kChannelTypeProc, id, proc->events);
+ Channel *channel = register_channel(kChannelTypeProc, id, proc->events,
+ source);
incref(channel); // process channels are only closed by the exit_cb
channel->data.proc = proc;
wstream_init(proc->in, 0);
rstream_init(proc->out, 0);
- rstream_start(proc->out, parse_msgpack, channel);
+ rstream_start(proc->out, receive_msgpack, channel);
+
+ DLOG("ch %" PRIu64 " in-stream=%p out-stream=%p", channel->id, proc->in,
+ proc->out);
return channel->id;
}
@@ -130,14 +144,48 @@ uint64_t channel_from_process(Process *proc, uint64_t id)
/// @param watcher The SocketWatcher ready to accept the connection
void channel_from_connection(SocketWatcher *watcher)
{
- Channel *channel = register_channel(kChannelTypeSocket, 0, NULL);
+ Channel *channel = register_channel(kChannelTypeSocket, 0, NULL,
+ watcher->addr);
socket_watcher_accept(watcher, &channel->data.stream);
incref(channel); // close channel only after the stream is closed
channel->data.stream.internal_close_cb = close_cb;
channel->data.stream.internal_data = channel;
wstream_init(&channel->data.stream, 0);
rstream_init(&channel->data.stream, CHANNEL_BUFFER_SIZE);
- rstream_start(&channel->data.stream, parse_msgpack, channel);
+ rstream_start(&channel->data.stream, receive_msgpack, channel);
+
+ DLOG("ch %" PRIu64 " in/out-stream=%p", channel->id,
+ &channel->data.stream);
+}
+
+/// @param source description of source function, rplugin name, TCP addr, etc
+uint64_t channel_connect(bool tcp, const char *address, int timeout,
+ char *source, const char **error)
+{
+ if (!tcp) {
+ char *path = fix_fname(address);
+ if (server_owns_pipe_address(path)) {
+ // avoid deadlock
+ xfree(path);
+ return channel_create_internal();
+ }
+ xfree(path);
+ }
+
+ Channel *channel = register_channel(kChannelTypeSocket, 0, NULL, source);
+ if (!socket_connect(&main_loop, &channel->data.stream,
+ tcp, address, timeout, error)) {
+ decref(channel);
+ return 0;
+ }
+
+ incref(channel); // close channel only after the stream is closed
+ channel->data.stream.internal_close_cb = close_cb;
+ channel->data.stream.internal_data = channel;
+ wstream_init(&channel->data.stream, 0);
+ rstream_init(&channel->data.stream, CHANNEL_BUFFER_SIZE);
+ rstream_start(&channel->data.stream, receive_msgpack, channel);
+ return channel->id;
}
/// Sends event/arguments to channel
@@ -147,7 +195,7 @@ void channel_from_connection(SocketWatcher *watcher)
/// @param name The event name, an arbitrary string
/// @param args Array with event arguments
/// @return True if the event was sent successfully, false otherwise.
-bool channel_send_event(uint64_t id, char *name, Array args)
+bool channel_send_event(uint64_t id, const char *name, Array args)
{
Channel *channel = NULL;
@@ -160,7 +208,7 @@ bool channel_send_event(uint64_t id, char *name, Array args)
if (channel) {
if (channel->pending_requests) {
// Pending request, queue the notification for later sending.
- String method = cstr_as_string(name);
+ const String method = cstr_as_string((char *)name);
WBuffer *buffer = serialize_request(id, 0, method, args, &out_buffer, 1);
kv_push(channel->delayed_notifications, buffer);
} else {
@@ -182,14 +230,14 @@ bool channel_send_event(uint64_t id, char *name, Array args)
/// @param[out] error True if the return value is an error
/// @return Whatever the remote method returned
Object channel_send_call(uint64_t id,
- char *method_name,
+ const char *method_name,
Array args,
Error *err)
{
Channel *channel = NULL;
if (!(channel = pmap_get(uint64_t)(channels, id)) || channel->closed) {
- api_set_error(err, Exception, _("Invalid channel \"%" PRIu64 "\""), id);
+ api_set_error(err, kErrorTypeException, "Invalid channel: %" PRIu64, id);
api_free_array(args);
return NIL;
}
@@ -209,7 +257,8 @@ Object channel_send_call(uint64_t id,
if (frame.errored) {
if (frame.result.type == kObjectTypeString) {
- api_set_error(err, Exception, "%s", frame.result.data.string.data);
+ api_set_error(err, kErrorTypeException, "%s",
+ frame.result.data.string.data);
} else if (frame.result.type == kObjectTypeArray) {
// Should be an error in the form [type, message]
Array array = frame.result.data.array;
@@ -217,14 +266,13 @@ Object channel_send_call(uint64_t id,
&& (array.items[0].data.integer == kErrorTypeException
|| array.items[0].data.integer == kErrorTypeValidation)
&& array.items[1].type == kObjectTypeString) {
- err->type = (ErrorType) array.items[0].data.integer;
- xstrlcpy(err->msg, array.items[1].data.string.data, sizeof(err->msg));
- err->set = true;
+ api_set_error(err, (ErrorType)array.items[0].data.integer, "%s",
+ array.items[1].data.string.data);
} else {
- api_set_error(err, Exception, "%s", "unknown error");
+ api_set_error(err, kErrorTypeException, "%s", "unknown error");
}
} else {
- api_set_error(err, Exception, "%s", "unknown error");
+ api_set_error(err, kErrorTypeException, "%s", "unknown error");
}
api_free_object(frame.result);
@@ -292,17 +340,28 @@ bool channel_close(uint64_t id)
return true;
}
-/// Creates an API channel from stdin/stdout. This is used when embedding
-/// Neovim
+/// Creates an API channel from stdin/stdout. Used to embed Nvim.
void channel_from_stdio(void)
{
- Channel *channel = register_channel(kChannelTypeStdio, 0, NULL);
+ Channel *channel = register_channel(kChannelTypeStdio, 0, NULL, NULL);
incref(channel); // stdio channels are only closed on exit
// read stream
rstream_init_fd(&main_loop, &channel->data.std.in, 0, CHANNEL_BUFFER_SIZE);
- rstream_start(&channel->data.std.in, parse_msgpack, channel);
+ rstream_start(&channel->data.std.in, receive_msgpack, channel);
// write stream
wstream_init_fd(&main_loop, &channel->data.std.out, 1, 0);
+
+ DLOG("ch %" PRIu64 " in-stream=%p out-stream=%p", channel->id,
+ &channel->data.std.in, &channel->data.std.out);
+}
+
+/// Creates a loopback channel. This is used to avoid deadlock
+/// when an instance connects to its own named pipe.
+uint64_t channel_create_internal(void)
+{
+ Channel *channel = register_channel(kChannelTypeInternal, 0, NULL, NULL);
+ incref(channel); // internal channel lives until process exit
+ return channel->id;
}
void channel_process_exit(uint64_t id, int status)
@@ -313,28 +372,50 @@ void channel_process_exit(uint64_t id, int status)
decref(channel);
}
-static void parse_msgpack(Stream *stream, RBuffer *rbuf, size_t c, void *data,
- bool eof)
+// rstream.c:read_event() invokes this as stream->read_cb().
+static void receive_msgpack(Stream *stream, RBuffer *rbuf, size_t c,
+ void *data, bool eof)
{
Channel *channel = data;
incref(channel);
if (eof) {
close_channel(channel);
- call_set_error(channel, "Channel was closed by the client");
+ char buf[256];
+ snprintf(buf, sizeof(buf), "ch %" PRIu64 " was closed by the client",
+ channel->id);
+ call_set_error(channel, buf, WARN_LOG_LEVEL);
+ goto end;
+ }
+
+ if ((chan_wstream(channel) != NULL && chan_wstream(channel)->closed)
+ || (chan_rstream(channel) != NULL && chan_rstream(channel)->closed)) {
+ char buf[256];
+ snprintf(buf, sizeof(buf),
+ "ch %" PRIu64 ": stream closed unexpectedly. "
+ "closing channel",
+ channel->id);
+ call_set_error(channel, buf, WARN_LOG_LEVEL);
goto end;
}
size_t count = rbuffer_size(rbuf);
- DLOG("Feeding the msgpack parser with %u bytes of data from Stream(%p)",
- count,
- stream);
+ DLOG("ch %" PRIu64 ": parsing %u bytes from msgpack Stream: %p",
+ channel->id, count, stream);
// Feed the unpacker with data
msgpack_unpacker_reserve_buffer(channel->unpacker, count);
rbuffer_read(rbuf, msgpack_unpacker_buffer(channel->unpacker), count);
msgpack_unpacker_buffer_consumed(channel->unpacker, count);
+ parse_msgpack(channel);
+
+end:
+ decref(channel);
+}
+
+static void parse_msgpack(Channel *channel)
+{
msgpack_unpacked unpacked;
msgpack_unpacked_init(&unpacked);
msgpack_unpack_return result;
@@ -350,17 +431,15 @@ static void parse_msgpack(Stream *stream, RBuffer *rbuf, size_t c, void *data,
complete_call(&unpacked.data, channel);
} else {
char buf[256];
- snprintf(buf,
- sizeof(buf),
- "Channel %" PRIu64 " returned a response that doesn't have "
- "a matching request id. Ensure the client is properly "
- "synchronized",
+ snprintf(buf, sizeof(buf),
+ "ch %" PRIu64 " returned a response with an unknown request "
+ "id. Ensure the client is properly synchronized",
channel->id);
- call_set_error(channel, buf);
+ call_set_error(channel, buf, ERROR_LOG_LEVEL);
}
msgpack_unpacked_destroy(&unpacked);
// Bail out from this event loop iteration
- goto end;
+ return;
}
handle_request(channel, &unpacked.data);
@@ -378,17 +457,15 @@ static void parse_msgpack(Stream *stream, RBuffer *rbuf, size_t c, void *data,
// causes for this error(search for 'goto _failed')
//
// A not so uncommon cause for this might be deserializing objects with
- // a high nesting level: msgpack will break when it's internal parse stack
- // size exceeds MSGPACK_EMBED_STACK_SIZE(defined as 32 by default)
+ // a high nesting level: msgpack will break when its internal parse stack
+ // size exceeds MSGPACK_EMBED_STACK_SIZE (defined as 32 by default)
send_error(channel, 0, "Invalid msgpack payload. "
"This error can also happen when deserializing "
"an object with high level of nesting");
}
-
-end:
- decref(channel);
}
+
static void handle_request(Channel *channel, msgpack_object *request)
FUNC_ATTR_NONNULL_ALL
{
@@ -396,7 +473,7 @@ static void handle_request(Channel *channel, msgpack_object *request)
Error error = ERROR_INIT;
msgpack_rpc_validate(&request_id, request, &error);
- if (error.set) {
+ if (ERROR_SET(&error)) {
// Validation failed, send response with error
if (channel_write(channel,
serialize_response(channel->id,
@@ -406,13 +483,13 @@ static void handle_request(Channel *channel, msgpack_object *request)
&out_buffer))) {
char buf[256];
snprintf(buf, sizeof(buf),
- "Channel %" PRIu64 " sent an invalid message, closed.",
+ "ch %" PRIu64 " sent an invalid message, closed.",
channel->id);
- call_set_error(channel, buf);
+ call_set_error(channel, buf, ERROR_LOG_LEVEL);
}
+ api_clear_error(&error);
return;
}
-
// Retrieve the request handler
MsgpackRpcRequestHandler handler;
msgpack_object *method = msgpack_rpc_method(request);
@@ -431,16 +508,24 @@ static void handle_request(Channel *channel, msgpack_object *request)
handler.async = true;
}
- RequestEvent *event_data = xmalloc(sizeof(RequestEvent));
- event_data->channel = channel;
- event_data->handler = handler;
- event_data->args = args;
- event_data->request_id = request_id;
+ RequestEvent *evdata = xmalloc(sizeof(RequestEvent));
+ evdata->channel = channel;
+ evdata->handler = handler;
+ evdata->args = args;
+ evdata->request_id = request_id;
incref(channel);
if (handler.async) {
- on_request_event((void **)&event_data);
+ bool is_get_mode = handler.fn == handle_nvim_get_mode;
+
+ if (is_get_mode && !input_blocking()) {
+ // Defer the event to a special queue used by os/input.c. #6247
+ multiqueue_put(ch_before_blocking_events, on_request_event, 1, evdata);
+ } else {
+ // Invoke immediately.
+ on_request_event((void **)&evdata);
+ }
} else {
- multiqueue_put(channel->events, on_request_event, 1, event_data);
+ multiqueue_put(channel->events, on_request_event, 1, evdata);
}
}
@@ -468,11 +553,45 @@ static void on_request_event(void **argv)
api_free_array(args);
decref(channel);
xfree(e);
+ api_clear_error(&error);
}
+/// Returns the Stream that a Channel writes to.
+static Stream *chan_wstream(Channel *chan)
+{
+ switch (chan->type) {
+ case kChannelTypeSocket:
+ return &chan->data.stream;
+ case kChannelTypeProc:
+ return chan->data.proc->in;
+ case kChannelTypeStdio:
+ return &chan->data.std.out;
+ case kChannelTypeInternal:
+ return NULL;
+ }
+ abort();
+}
+
+/// Returns the Stream that a Channel reads from.
+static Stream *chan_rstream(Channel *chan)
+{
+ switch (chan->type) {
+ case kChannelTypeSocket:
+ return &chan->data.stream;
+ case kChannelTypeProc:
+ return chan->data.proc->out;
+ case kChannelTypeStdio:
+ return &chan->data.std.in;
+ case kChannelTypeInternal:
+ return NULL;
+ }
+ abort();
+}
+
+
static bool channel_write(Channel *channel, WBuffer *buffer)
{
- bool success;
+ bool success = false;
if (channel->closed) {
wstream_release_wbuffer(buffer);
@@ -481,16 +600,15 @@ static bool channel_write(Channel *channel, WBuffer *buffer)
switch (channel->type) {
case kChannelTypeSocket:
- success = wstream_write(&channel->data.stream, buffer);
- break;
case kChannelTypeProc:
- success = wstream_write(channel->data.proc->in, buffer);
- break;
case kChannelTypeStdio:
- success = wstream_write(&channel->data.std.out, buffer);
+ success = wstream_write(chan_wstream(channel), buffer);
+ break;
+ case kChannelTypeInternal:
+ incref(channel);
+ CREATE_EVENT(channel->events, internal_read_event, 2, channel, buffer);
+ success = true;
break;
- default:
- abort();
}
if (!success) {
@@ -498,32 +616,49 @@ static bool channel_write(Channel *channel, WBuffer *buffer)
char buf[256];
snprintf(buf,
sizeof(buf),
- "Before returning from a RPC call, channel %" PRIu64 " was "
- "closed due to a failed write",
+ "ch %" PRIu64 ": stream write failed. "
+ "RPC canceled; closing channel",
channel->id);
- call_set_error(channel, buf);
+ call_set_error(channel, buf, ERROR_LOG_LEVEL);
}
return success;
}
+static void internal_read_event(void **argv)
+{
+ Channel *channel = argv[0];
+ WBuffer *buffer = argv[1];
+
+ msgpack_unpacker_reserve_buffer(channel->unpacker, buffer->size);
+ memcpy(msgpack_unpacker_buffer(channel->unpacker),
+ buffer->data, buffer->size);
+ msgpack_unpacker_buffer_consumed(channel->unpacker, buffer->size);
+
+ parse_msgpack(channel);
+
+ decref(channel);
+ wstream_release_wbuffer(buffer);
+}
+
static void send_error(Channel *channel, uint64_t id, char *err)
{
Error e = ERROR_INIT;
- api_set_error(&e, Exception, "%s", err);
+ api_set_error(&e, kErrorTypeException, "%s", err);
channel_write(channel, serialize_response(channel->id,
id,
&e,
NIL,
&out_buffer));
+ api_clear_error(&e);
}
static void send_request(Channel *channel,
uint64_t id,
- char *name,
+ const char *name,
Array args)
{
- String method = {.size = strlen(name), .data = name};
+ const String method = cstr_as_string((char *)name);
channel_write(channel, serialize_request(channel->id,
id,
method,
@@ -533,10 +668,10 @@ static void send_request(Channel *channel,
}
static void send_event(Channel *channel,
- char *name,
+ const char *name,
Array args)
{
- String method = {.size = strlen(name), .data = name};
+ const String method = cstr_as_string((char *)name);
channel_write(channel, serialize_request(channel->id,
0,
method,
@@ -545,7 +680,7 @@ static void send_event(Channel *channel,
1));
}
-static void broadcast_event(char *name, Array args)
+static void broadcast_event(const char *name, Array args)
{
kvec_t(Channel *) subscribed = KV_INITIAL_VALUE;
Channel *channel;
@@ -561,7 +696,7 @@ static void broadcast_event(char *name, Array args)
goto end;
}
- String method = {.size = strlen(name), .data = name};
+ const String method = cstr_as_string((char *)name);
WBuffer *buffer = serialize_request(0,
0,
method,
@@ -622,8 +757,9 @@ static void close_channel(Channel *channel)
stream_close(&channel->data.std.out, NULL, NULL);
multiqueue_put(main_loop.fast_events, exit_event, 1, channel);
return;
- default:
- abort();
+ case kChannelTypeInternal:
+ // nothing to free.
+ break;
}
decref(channel);
@@ -664,9 +800,12 @@ static void close_cb(Stream *stream, void *data)
decref(data);
}
+/// @param source description of source function, rplugin name, TCP addr, etc
static Channel *register_channel(ChannelType type, uint64_t id,
- MultiQueue *events)
+ MultiQueue *events, char *source)
{
+ // Jobs and channels share the same id namespace.
+ assert(id == 0 || !pmap_get(uint64_t)(channels, id));
Channel *rv = xmalloc(sizeof(Channel));
rv->events = events ? events : multiqueue_new_child(main_loop.events);
rv->type = type;
@@ -680,6 +819,14 @@ static Channel *register_channel(ChannelType type, uint64_t id,
kv_init(rv->call_stack);
kv_init(rv->delayed_notifications);
pmap_put(uint64_t)(channels, rv->id, rv);
+
+ ILOG("new channel %" PRIu64 " (%s): %s", rv->id,
+ (type == kChannelTypeProc ? "proc"
+ : (type == kChannelTypeSocket ? "socket"
+ : (type == kChannelTypeStdio ? "stdio"
+ : (type == kChannelTypeInternal ? "internal" : "?")))),
+ (source ? source : "?"));
+
return rv;
}
@@ -714,13 +861,14 @@ static void complete_call(msgpack_object *obj, Channel *channel)
}
}
-static void call_set_error(Channel *channel, char *msg)
+static void call_set_error(Channel *channel, char *msg, int loglevel)
{
- ELOG("msgpack-rpc: %s", msg);
+ LOG(loglevel, "RPC: %s", msg);
for (size_t i = 0; i < kv_size(channel->call_stack); i++) {
ChannelCallFrame *frame = kv_A(channel->call_stack, i);
frame->returned = true;
frame->errored = true;
+ api_free_object(frame->result);
frame->result = STRING_OBJ(cstr_to_string(msg));
}
@@ -729,7 +877,7 @@ static void call_set_error(Channel *channel, char *msg)
static WBuffer *serialize_request(uint64_t channel_id,
uint64_t request_id,
- String method,
+ const String method,
Array args,
msgpack_sbuffer *sbuffer,
size_t refcount)
@@ -789,10 +937,10 @@ static void decref(Channel *channel)
}
#if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL
-#define REQ "[request] "
-#define RES "[response] "
-#define NOT "[notification] "
-#define ERR "[error] "
+#define REQ "[request] "
+#define RES "[response] "
+#define NOT "[notify] "
+#define ERR "[error] "
// Cannot define array with negative offsets, so this one is needed to be added
// to MSGPACK_UNPACK_\* values.
@@ -810,7 +958,7 @@ static void log_server_msg(uint64_t channel_id,
{
msgpack_unpacked unpacked;
msgpack_unpacked_init(&unpacked);
- DLOGN("[msgpack-rpc] nvim -> client(%" PRIu64 ") ", channel_id);
+ DLOGN("RPC ->ch %" PRIu64 ": ", channel_id);
const msgpack_unpack_return result =
msgpack_unpack_next(&unpacked, packed->data, packed->size, NULL);
switch (result) {
@@ -847,7 +995,7 @@ static void log_client_msg(uint64_t channel_id,
bool is_request,
msgpack_object msg)
{
- DLOGN("[msgpack-rpc] client(%" PRIu64 ") -> nvim ", channel_id);
+ DLOGN("RPC <-ch %" PRIu64 ": ", channel_id);
log_lock();
FILE *f = open_log_file();
fprintf(f, is_request ? REQ : RES);
diff --git a/src/nvim/msgpack_rpc/channel.h b/src/nvim/msgpack_rpc/channel.h
index 0d92976d02..f8fe6f129b 100644
--- a/src/nvim/msgpack_rpc/channel.h
+++ b/src/nvim/msgpack_rpc/channel.h
@@ -11,6 +11,11 @@
#define METHOD_MAXLEN 512
+/// HACK: os/input.c drains this queue immediately before blocking for input.
+/// Events on this queue are async-safe, but they need the resolved state
+/// of os_inchar(), so they are processed "just-in-time".
+MultiQueue *ch_before_blocking_events;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "msgpack_rpc/channel.h.generated.h"
#endif
diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c
index 5137b375f0..fecae11d45 100644
--- a/src/nvim/msgpack_rpc/helpers.c
+++ b/src/nvim/msgpack_rpc/helpers.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <stdint.h>
#include <stdbool.h>
#include <inttypes.h>
@@ -21,12 +24,12 @@ static msgpack_zone zone;
static msgpack_sbuffer sbuffer;
#define HANDLE_TYPE_CONVERSION_IMPL(t, lt) \
- bool msgpack_rpc_to_##lt(const msgpack_object *const obj, \
- Integer *const arg) \
- FUNC_ATTR_NONNULL_ALL \
+ static bool msgpack_rpc_to_##lt(const msgpack_object *const obj, \
+ Integer *const arg) \
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT \
{ \
if (obj->type != MSGPACK_OBJECT_EXT \
- || obj->via.ext.type != kObjectType##t) { \
+ || obj->via.ext.type + EXT_OBJECT_TYPE_SHIFT != kObjectType##t) { \
return false; \
} \
\
@@ -45,13 +48,14 @@ static msgpack_sbuffer sbuffer;
return true; \
} \
\
- void msgpack_rpc_from_##lt(Integer o, msgpack_packer *res) \
+ static void msgpack_rpc_from_##lt(Integer o, msgpack_packer *res) \
FUNC_ATTR_NONNULL_ARG(2) \
{ \
msgpack_packer pac; \
msgpack_packer_init(&pac, &sbuffer, msgpack_sbuffer_write); \
msgpack_pack_int64(&pac, (handle_T)o); \
- msgpack_pack_ext(res, sbuffer.size, kObjectType##t); \
+ msgpack_pack_ext(res, sbuffer.size, \
+ kObjectType##t - EXT_OBJECT_TYPE_SHIFT); \
msgpack_pack_ext_body(res, sbuffer.data, sbuffer.size); \
msgpack_sbuffer_clear(&sbuffer); \
}
@@ -73,7 +77,7 @@ typedef struct {
size_t idx;
} MPToAPIObjectStackItem;
-/// Convert type used by msgpack parser to Neovim own API type
+/// Convert type used by msgpack parser to Nvim API type.
///
/// @param[in] obj Msgpack value to convert.
/// @param[out] arg Location where result of conversion will be saved.
@@ -84,7 +88,12 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
{
bool ret = true;
kvec_t(MPToAPIObjectStackItem) stack = KV_INITIAL_VALUE;
- kv_push(stack, ((MPToAPIObjectStackItem) { obj, arg, false, 0 }));
+ kv_push(stack, ((MPToAPIObjectStackItem) {
+ .mobj = obj,
+ .aobj = arg,
+ .container = false,
+ .idx = 0,
+ }));
while (ret && kv_size(stack)) {
MPToAPIObjectStackItem cur = kv_last(stack);
if (!cur.container) {
@@ -114,10 +123,16 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
}
break;
}
- case MSGPACK_OBJECT_FLOAT: {
+#ifdef NVIM_MSGPACK_HAS_FLOAT32
+ case MSGPACK_OBJECT_FLOAT32:
+ case MSGPACK_OBJECT_FLOAT64:
+#else
+ case MSGPACK_OBJECT_FLOAT:
+#endif
+ {
STATIC_ASSERT(sizeof(Float) == sizeof(cur.mobj->via.f64),
"Msgpack floating-point size does not match API integer");
- *cur.aobj = FLOATING_OBJ(cur.mobj->via.f64);
+ *cur.aobj = FLOAT_OBJ(cur.mobj->via.f64);
break;
}
#define STR_CASE(type, attr, obj, dest, conv) \
@@ -181,7 +196,12 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
case MSGPACK_OBJECT_BOOLEAN:
case MSGPACK_OBJECT_POSITIVE_INTEGER:
case MSGPACK_OBJECT_NEGATIVE_INTEGER:
+#ifdef NVIM_MSGPACK_HAS_FLOAT32
+ case MSGPACK_OBJECT_FLOAT32:
+ case MSGPACK_OBJECT_FLOAT64:
+#else
case MSGPACK_OBJECT_FLOAT:
+#endif
case MSGPACK_OBJECT_EXT:
case MSGPACK_OBJECT_MAP:
case MSGPACK_OBJECT_ARRAY: {
@@ -211,7 +231,7 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
break;
}
case MSGPACK_OBJECT_EXT: {
- switch (cur.mobj->via.ext.type) {
+ switch ((ObjectType)(cur.mobj->via.ext.type + EXT_OBJECT_TYPE_SHIFT)) {
case kObjectTypeBuffer: {
cur.aobj->type = kObjectTypeBuffer;
ret = msgpack_rpc_to_buffer(cur.mobj, &cur.aobj->data.integer);
@@ -227,6 +247,15 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
ret = msgpack_rpc_to_tabpage(cur.mobj, &cur.aobj->data.integer);
break;
}
+ case kObjectTypeNil:
+ case kObjectTypeBoolean:
+ case kObjectTypeInteger:
+ case kObjectTypeFloat:
+ case kObjectTypeString:
+ case kObjectTypeArray:
+ case kObjectTypeDictionary: {
+ break;
+ }
}
break;
}
@@ -322,7 +351,7 @@ void msgpack_rpc_from_float(Float result, msgpack_packer *res)
msgpack_pack_double(res, result);
}
-void msgpack_rpc_from_string(String result, msgpack_packer *res)
+void msgpack_rpc_from_string(const String result, msgpack_packer *res)
FUNC_ATTR_NONNULL_ARG(2)
{
msgpack_pack_str(res, result.size);
@@ -337,7 +366,7 @@ typedef struct {
size_t idx;
} APIToMPObjectStackItem;
-/// Convert type used by Neovim API to msgpack
+/// Convert type used by Nvim API to msgpack type.
///
/// @param[in] result Object to convert.
/// @param[out] res Structure that defines where conversion results are saved.
@@ -350,6 +379,9 @@ void msgpack_rpc_from_object(const Object result, msgpack_packer *const res)
kv_push(stack, ((APIToMPObjectStackItem) { &result, false, 0 }));
while (kv_size(stack)) {
APIToMPObjectStackItem cur = kv_last(stack);
+ STATIC_ASSERT(kObjectTypeWindow == kObjectTypeBuffer + 1
+ && kObjectTypeTabpage == kObjectTypeWindow + 1,
+ "Buffer, window and tabpage enum items are in order");
switch (cur.aobj->type) {
case kObjectTypeNil: {
msgpack_pack_nil(res);
@@ -461,8 +493,7 @@ Object msgpack_rpc_handle_missing_method(uint64_t channel_id,
Array args,
Error *error)
{
- snprintf(error->msg, sizeof(error->msg), "Invalid method name");
- error->set = true;
+ api_set_error(error, kErrorTypeException, "Invalid method name");
return NIL;
}
@@ -471,14 +502,13 @@ Object msgpack_rpc_handle_invalid_arguments(uint64_t channel_id,
Array args,
Error *error)
{
- snprintf(error->msg, sizeof(error->msg), "Invalid method arguments");
- error->set = true;
+ api_set_error(error, kErrorTypeException, "Invalid method arguments");
return NIL;
}
/// Serializes a msgpack-rpc request or notification(id == 0)
void msgpack_rpc_serialize_request(uint64_t request_id,
- String method,
+ const String method,
Array args,
msgpack_packer *pac)
FUNC_ATTR_NONNULL_ARG(4)
@@ -505,7 +535,7 @@ void msgpack_rpc_serialize_response(uint64_t response_id,
msgpack_pack_int(pac, 1);
msgpack_pack_uint64(pac, response_id);
- if (err->set) {
+ if (ERROR_SET(err)) {
// error represented by a [type, message] array
msgpack_pack_array(pac, 2);
msgpack_rpc_from_integer(err->type, pac);
@@ -558,49 +588,49 @@ void msgpack_rpc_validate(uint64_t *response_id,
*response_id = NO_RESPONSE;
// Validate the basic structure of the msgpack-rpc payload
if (req->type != MSGPACK_OBJECT_ARRAY) {
- api_set_error(err, Validation, _("Message is not an array"));
+ api_set_error(err, kErrorTypeValidation, "Message is not an array");
return;
}
if (req->via.array.size == 0) {
- api_set_error(err, Validation, _("Message is empty"));
+ api_set_error(err, kErrorTypeValidation, "Message is empty");
return;
}
if (req->via.array.ptr[0].type != MSGPACK_OBJECT_POSITIVE_INTEGER) {
- api_set_error(err, Validation, _("Message type must be an integer"));
+ api_set_error(err, kErrorTypeValidation, "Message type must be an integer");
return;
}
uint64_t type = req->via.array.ptr[0].via.u64;
if (type != kMessageTypeRequest && type != kMessageTypeNotification) {
- api_set_error(err, Validation, _("Unknown message type"));
+ api_set_error(err, kErrorTypeValidation, "Unknown message type");
return;
}
if ((type == kMessageTypeRequest && req->via.array.size != 4)
|| (type == kMessageTypeNotification && req->via.array.size != 3)) {
- api_set_error(err, Validation, _("Request array size should be 4 (request) "
- "or 3 (notification)"));
+ api_set_error(err, kErrorTypeValidation,
+ "Request array size must be 4 (request) or 3 (notification)");
return;
}
if (type == kMessageTypeRequest) {
msgpack_object *id_obj = msgpack_rpc_msg_id(req);
if (!id_obj) {
- api_set_error(err, Validation, _("ID must be a positive integer"));
+ api_set_error(err, kErrorTypeValidation, "ID must be a positive integer");
return;
}
*response_id = id_obj->via.u64;
}
if (!msgpack_rpc_method(req)) {
- api_set_error(err, Validation, _("Method must be a string"));
+ api_set_error(err, kErrorTypeValidation, "Method must be a string");
return;
}
if (!msgpack_rpc_args(req)) {
- api_set_error(err, Validation, _("Parameters must be an array"));
+ api_set_error(err, kErrorTypeValidation, "Parameters must be an array");
return;
}
}
diff --git a/src/nvim/msgpack_rpc/helpers.h b/src/nvim/msgpack_rpc/helpers.h
index 7d9f114140..0e4cd1be6d 100644
--- a/src/nvim/msgpack_rpc/helpers.h
+++ b/src/nvim/msgpack_rpc/helpers.h
@@ -9,6 +9,13 @@
#include "nvim/event/wstream.h"
#include "nvim/api/private/defs.h"
+/// Value by which objects represented as EXT type are shifted
+///
+/// Subtracted when packing, added when unpacking. Used to allow moving
+/// buffer/window/tabpage block inside ObjectType enum. This block yet cannot be
+/// split or reordered.
+#define EXT_OBJECT_TYPE_SHIFT kObjectTypeBuffer
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "msgpack_rpc/helpers.h.generated.h"
#endif
diff --git a/src/nvim/msgpack_rpc/server.c b/src/nvim/msgpack_rpc/server.c
index d7c2926a0f..1e0cc27886 100644
--- a/src/nvim/msgpack_rpc/server.c
+++ b/src/nvim/msgpack_rpc/server.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <stdlib.h>
#include <string.h>
@@ -94,39 +97,61 @@ char *server_address_new(void)
#endif
}
-/// Starts listening for API calls on the TCP address or pipe path `endpoint`.
+/// Check if this instance owns a pipe address.
+/// The argument must already be resolved to an absolute path!
+bool server_owns_pipe_address(const char *path)
+{
+ for (int i = 0; i < watchers.ga_len; i++) {
+ if (!strcmp(path, ((SocketWatcher **)watchers.ga_data)[i]->addr)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/// Starts listening for API calls.
+///
/// The socket type is determined by parsing `endpoint`: If it's a valid IPv4
-/// address in 'ip[:port]' format, then it will be TCP socket. The port is
-/// optional and if omitted defaults to NVIM_DEFAULT_TCP_PORT. Otherwise it
-/// will be a unix socket or named pipe.
+/// or IPv6 address in 'ip:[port]' format, then it will be a TCP socket.
+/// Otherwise it will be a Unix socket or named pipe (Windows).
+///
+/// If no port is given, a random one will be assigned.
///
-/// @param endpoint Address of the server. Either a 'ip[:port]' string or an
-/// arbitrary identifier (trimmed to 256 bytes) for the unix socket or
-/// named pipe.
+/// @param endpoint Address of the server. Either a 'ip:[port]' string or an
+/// arbitrary identifier (trimmed to 256 bytes) for the Unix
+/// socket or named pipe.
/// @returns 0 on success, 1 on a regular error, and negative errno
-/// on failure to bind or connect.
+/// on failure to bind or listen.
int server_start(const char *endpoint)
{
- if (endpoint == NULL) {
- ELOG("Attempting to start server on NULL endpoint");
+ if (endpoint == NULL || endpoint[0] == '\0') {
+ WLOG("Empty or NULL endpoint");
return 1;
}
SocketWatcher *watcher = xmalloc(sizeof(SocketWatcher));
- socket_watcher_init(&main_loop, watcher, endpoint, NULL);
+
+ int result = socket_watcher_init(&main_loop, watcher, endpoint);
+ if (result < 0) {
+ xfree(watcher);
+ return result;
+ }
// Check if a watcher for the endpoint already exists
for (int i = 0; i < watchers.ga_len; i++) {
if (!strcmp(watcher->addr, ((SocketWatcher **)watchers.ga_data)[i]->addr)) {
ELOG("Already listening on %s", watcher->addr);
+ if (watcher->stream->type == UV_TCP) {
+ uv_freeaddrinfo(watcher->uv.tcp.addrinfo);
+ }
socket_watcher_close(watcher, free_server);
return 1;
}
}
- int result = socket_watcher_start(watcher, MAX_CONNECTIONS, connection_cb);
+ result = socket_watcher_start(watcher, MAX_CONNECTIONS, connection_cb);
if (result < 0) {
- ELOG("Failed to start server: %s", uv_strerror(result));
+ WLOG("Failed to start server: %s", uv_strerror(result));
socket_watcher_close(watcher, free_server);
return result;
}
diff --git a/src/nvim/msgpack_rpc/server.h b/src/nvim/msgpack_rpc/server.h
index f1a6703938..5446e40e0b 100644
--- a/src/nvim/msgpack_rpc/server.h
+++ b/src/nvim/msgpack_rpc/server.h
@@ -1,6 +1,8 @@
#ifndef NVIM_MSGPACK_RPC_SERVER_H
#define NVIM_MSGPACK_RPC_SERVER_H
+#include <stdio.h>
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "msgpack_rpc/server.h.generated.h"
#endif
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 227bfbe779..f9017164af 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* normal.c: Contains the main routine for processing characters in command
* mode. Communicates closely with the code in ops.c to handle
@@ -10,6 +13,7 @@
#include <stdbool.h>
#include <stdlib.h>
+#include "nvim/log.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/normal.h"
@@ -45,6 +49,7 @@
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/spell.h"
+#include "nvim/spellfile.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/tag.h"
@@ -152,196 +157,196 @@ static const struct nv_cmd {
short cmd_arg; /* value for ca.arg */
} nv_cmds[] =
{
- {NUL, nv_error, 0, 0},
- {Ctrl_A, nv_addsub, 0, 0},
- {Ctrl_B, nv_page, NV_STS, BACKWARD},
- {Ctrl_C, nv_esc, 0, true},
- {Ctrl_D, nv_halfpage, 0, 0},
- {Ctrl_E, nv_scroll_line, 0, true},
- {Ctrl_F, nv_page, NV_STS, FORWARD},
- {Ctrl_G, nv_ctrlg, 0, 0},
- {Ctrl_H, nv_ctrlh, 0, 0},
- {Ctrl_I, nv_pcmark, 0, 0},
- {NL, nv_down, 0, false},
- {Ctrl_K, nv_error, 0, 0},
- {Ctrl_L, nv_clear, 0, 0},
- {Ctrl_M, nv_down, 0, true},
- {Ctrl_N, nv_down, NV_STS, false},
- {Ctrl_O, nv_ctrlo, 0, 0},
- {Ctrl_P, nv_up, NV_STS, false},
- {Ctrl_Q, nv_visual, 0, false},
- {Ctrl_R, nv_redo, 0, 0},
- {Ctrl_S, nv_ignore, 0, 0},
- {Ctrl_T, nv_tagpop, NV_NCW, 0},
- {Ctrl_U, nv_halfpage, 0, 0},
- {Ctrl_V, nv_visual, 0, false},
- {'V', nv_visual, 0, false},
- {'v', nv_visual, 0, false},
- {Ctrl_W, nv_window, 0, 0},
- {Ctrl_X, nv_addsub, 0, 0},
- {Ctrl_Y, nv_scroll_line, 0, false},
- {Ctrl_Z, nv_suspend, 0, 0},
- {ESC, nv_esc, 0, false},
- {Ctrl_BSL, nv_normal, NV_NCH_ALW, 0},
- {Ctrl_RSB, nv_ident, NV_NCW, 0},
- {Ctrl_HAT, nv_hat, NV_NCW, 0},
- {Ctrl__, nv_error, 0, 0},
- {' ', nv_right, 0, 0},
- {'!', nv_operator, 0, 0},
- {'"', nv_regname, NV_NCH_NOP|NV_KEEPREG, 0},
- {'#', nv_ident, 0, 0},
- {'$', nv_dollar, 0, 0},
- {'%', nv_percent, 0, 0},
- {'&', nv_optrans, 0, 0},
- {'\'', nv_gomark, NV_NCH_ALW, true},
- {'(', nv_brace, 0, BACKWARD},
- {')', nv_brace, 0, FORWARD},
- {'*', nv_ident, 0, 0},
- {'+', nv_down, 0, true},
- {',', nv_csearch, 0, true},
- {'-', nv_up, 0, true},
- {'.', nv_dot, NV_KEEPREG, 0},
- {'/', nv_search, 0, false},
- {'0', nv_beginline, 0, 0},
- {'1', nv_ignore, 0, 0},
- {'2', nv_ignore, 0, 0},
- {'3', nv_ignore, 0, 0},
- {'4', nv_ignore, 0, 0},
- {'5', nv_ignore, 0, 0},
- {'6', nv_ignore, 0, 0},
- {'7', nv_ignore, 0, 0},
- {'8', nv_ignore, 0, 0},
- {'9', nv_ignore, 0, 0},
- {':', nv_colon, 0, 0},
- {';', nv_csearch, 0, false},
- {'<', nv_operator, NV_RL, 0},
- {'=', nv_operator, 0, 0},
- {'>', nv_operator, NV_RL, 0},
- {'?', nv_search, 0, false},
- {'@', nv_at, NV_NCH_NOP, false},
- {'A', nv_edit, 0, 0},
- {'B', nv_bck_word, 0, 1},
- {'C', nv_abbrev, NV_KEEPREG, 0},
- {'D', nv_abbrev, NV_KEEPREG, 0},
- {'E', nv_wordcmd, 0, true},
- {'F', nv_csearch, NV_NCH_ALW|NV_LANG, BACKWARD},
- {'G', nv_goto, 0, true},
- {'H', nv_scroll, 0, 0},
- {'I', nv_edit, 0, 0},
- {'J', nv_join, 0, 0},
- {'K', nv_ident, 0, 0},
- {'L', nv_scroll, 0, 0},
- {'M', nv_scroll, 0, 0},
- {'N', nv_next, 0, SEARCH_REV},
- {'O', nv_open, 0, 0},
- {'P', nv_put, 0, 0},
- {'Q', nv_exmode, NV_NCW, 0},
- {'R', nv_Replace, 0, false},
- {'S', nv_subst, NV_KEEPREG, 0},
- {'T', nv_csearch, NV_NCH_ALW|NV_LANG, BACKWARD},
- {'U', nv_Undo, 0, 0},
- {'W', nv_wordcmd, 0, true},
- {'X', nv_abbrev, NV_KEEPREG, 0},
- {'Y', nv_abbrev, NV_KEEPREG, 0},
- {'Z', nv_Zet, NV_NCH_NOP|NV_NCW, 0},
- {'[', nv_brackets, NV_NCH_ALW, BACKWARD},
- {'\\', nv_error, 0, 0},
- {']', nv_brackets, NV_NCH_ALW, FORWARD},
- {'^', nv_beginline, 0, BL_WHITE | BL_FIX},
- {'_', nv_lineop, 0, 0},
- {'`', nv_gomark, NV_NCH_ALW, false},
- {'a', nv_edit, NV_NCH, 0},
- {'b', nv_bck_word, 0, 0},
- {'c', nv_operator, 0, 0},
- {'d', nv_operator, 0, 0},
- {'e', nv_wordcmd, 0, false},
- {'f', nv_csearch, NV_NCH_ALW|NV_LANG, FORWARD},
- {'g', nv_g_cmd, NV_NCH_ALW, false},
- {'h', nv_left, NV_RL, 0},
- {'i', nv_edit, NV_NCH, 0},
- {'j', nv_down, 0, false},
- {'k', nv_up, 0, false},
- {'l', nv_right, NV_RL, 0},
- {'m', nv_mark, NV_NCH_NOP, 0},
- {'n', nv_next, 0, 0},
- {'o', nv_open, 0, 0},
- {'p', nv_put, 0, 0},
- {'q', nv_record, NV_NCH, 0},
- {'r', nv_replace, NV_NCH_NOP|NV_LANG, 0},
- {'s', nv_subst, NV_KEEPREG, 0},
- {'t', nv_csearch, NV_NCH_ALW|NV_LANG, FORWARD},
- {'u', nv_undo, 0, 0},
- {'w', nv_wordcmd, 0, false},
- {'x', nv_abbrev, NV_KEEPREG, 0},
- {'y', nv_operator, 0, 0},
- {'z', nv_zet, NV_NCH_ALW, 0},
- {'{', nv_findpar, 0, BACKWARD},
- {'|', nv_pipe, 0, 0},
- {'}', nv_findpar, 0, FORWARD},
- {'~', nv_tilde, 0, 0},
-
- /* pound sign */
- {POUND, nv_ident, 0, 0},
- {K_MOUSEUP, nv_mousescroll, 0, MSCR_UP},
- {K_MOUSEDOWN, nv_mousescroll, 0, MSCR_DOWN},
- {K_MOUSELEFT, nv_mousescroll, 0, MSCR_LEFT},
- {K_MOUSERIGHT, nv_mousescroll, 0, MSCR_RIGHT},
- {K_LEFTMOUSE, nv_mouse, 0, 0},
- {K_LEFTMOUSE_NM, nv_mouse, 0, 0},
- {K_LEFTDRAG, nv_mouse, 0, 0},
- {K_LEFTRELEASE, nv_mouse, 0, 0},
- {K_LEFTRELEASE_NM, nv_mouse, 0, 0},
- {K_MIDDLEMOUSE, nv_mouse, 0, 0},
- {K_MIDDLEDRAG, nv_mouse, 0, 0},
- {K_MIDDLERELEASE, nv_mouse, 0, 0},
- {K_RIGHTMOUSE, nv_mouse, 0, 0},
- {K_RIGHTDRAG, nv_mouse, 0, 0},
- {K_RIGHTRELEASE, nv_mouse, 0, 0},
- {K_X1MOUSE, nv_mouse, 0, 0},
- {K_X1DRAG, nv_mouse, 0, 0},
- {K_X1RELEASE, nv_mouse, 0, 0},
- {K_X2MOUSE, nv_mouse, 0, 0},
- {K_X2DRAG, nv_mouse, 0, 0},
- {K_X2RELEASE, nv_mouse, 0, 0},
- {K_IGNORE, nv_ignore, NV_KEEPREG, 0},
- {K_NOP, nv_nop, 0, 0},
- {K_INS, nv_edit, 0, 0},
- {K_KINS, nv_edit, 0, 0},
- {K_BS, nv_ctrlh, 0, 0},
- {K_UP, nv_up, NV_SSS|NV_STS, false},
- {K_S_UP, nv_page, NV_SS, BACKWARD},
- {K_DOWN, nv_down, NV_SSS|NV_STS, false},
- {K_S_DOWN, nv_page, NV_SS, FORWARD},
- {K_LEFT, nv_left, NV_SSS|NV_STS|NV_RL, 0},
- {K_S_LEFT, nv_bck_word, NV_SS|NV_RL, 0},
- {K_C_LEFT, nv_bck_word, NV_SSS|NV_RL|NV_STS, 1},
- {K_RIGHT, nv_right, NV_SSS|NV_STS|NV_RL, 0},
- {K_S_RIGHT, nv_wordcmd, NV_SS|NV_RL, false},
- {K_C_RIGHT, nv_wordcmd, NV_SSS|NV_RL|NV_STS, true},
- {K_PAGEUP, nv_page, NV_SSS|NV_STS, BACKWARD},
- {K_KPAGEUP, nv_page, NV_SSS|NV_STS, BACKWARD},
- {K_PAGEDOWN, nv_page, NV_SSS|NV_STS, FORWARD},
- {K_KPAGEDOWN, nv_page, NV_SSS|NV_STS, FORWARD},
- {K_END, nv_end, NV_SSS|NV_STS, false},
- {K_KEND, nv_end, NV_SSS|NV_STS, false},
- {K_S_END, nv_end, NV_SS, false},
- {K_C_END, nv_end, NV_SSS|NV_STS, true},
- {K_HOME, nv_home, NV_SSS|NV_STS, 0},
- {K_KHOME, nv_home, NV_SSS|NV_STS, 0},
- {K_S_HOME, nv_home, NV_SS, 0},
- {K_C_HOME, nv_goto, NV_SSS|NV_STS, false},
- {K_DEL, nv_abbrev, 0, 0},
- {K_KDEL, nv_abbrev, 0, 0},
- {K_UNDO, nv_kundo, 0, 0},
- {K_HELP, nv_help, NV_NCW, 0},
- {K_F1, nv_help, NV_NCW, 0},
- {K_XF1, nv_help, NV_NCW, 0},
- {K_SELECT, nv_select, 0, 0},
- {K_F8, farsi_fkey, 0, 0},
- {K_F9, farsi_fkey, 0, 0},
- {K_EVENT, nv_event, NV_KEEPREG, 0},
- {K_FOCUSGAINED, nv_focusgained, NV_KEEPREG, 0},
- {K_FOCUSLOST, nv_focuslost, NV_KEEPREG, 0},
+ { NUL, nv_error, 0, 0 },
+ { Ctrl_A, nv_addsub, 0, 0 },
+ { Ctrl_B, nv_page, NV_STS, BACKWARD },
+ { Ctrl_C, nv_esc, 0, true },
+ { Ctrl_D, nv_halfpage, 0, 0 },
+ { Ctrl_E, nv_scroll_line, 0, true },
+ { Ctrl_F, nv_page, NV_STS, FORWARD },
+ { Ctrl_G, nv_ctrlg, 0, 0 },
+ { Ctrl_H, nv_ctrlh, 0, 0 },
+ { Ctrl_I, nv_pcmark, 0, 0 },
+ { NL, nv_down, 0, false },
+ { Ctrl_K, nv_error, 0, 0 },
+ { Ctrl_L, nv_clear, 0, 0 },
+ { Ctrl_M, nv_down, 0, true },
+ { Ctrl_N, nv_down, NV_STS, false },
+ { Ctrl_O, nv_ctrlo, 0, 0 },
+ { Ctrl_P, nv_up, NV_STS, false },
+ { Ctrl_Q, nv_visual, 0, false },
+ { Ctrl_R, nv_redo, 0, 0 },
+ { Ctrl_S, nv_ignore, 0, 0 },
+ { Ctrl_T, nv_tagpop, NV_NCW, 0 },
+ { Ctrl_U, nv_halfpage, 0, 0 },
+ { Ctrl_V, nv_visual, 0, false },
+ { 'V', nv_visual, 0, false },
+ { 'v', nv_visual, 0, false },
+ { Ctrl_W, nv_window, 0, 0 },
+ { Ctrl_X, nv_addsub, 0, 0 },
+ { Ctrl_Y, nv_scroll_line, 0, false },
+ { Ctrl_Z, nv_suspend, 0, 0 },
+ { ESC, nv_esc, 0, false },
+ { Ctrl_BSL, nv_normal, NV_NCH_ALW, 0 },
+ { Ctrl_RSB, nv_ident, NV_NCW, 0 },
+ { Ctrl_HAT, nv_hat, NV_NCW, 0 },
+ { Ctrl__, nv_error, 0, 0 },
+ { ' ', nv_right, 0, 0 },
+ { '!', nv_operator, 0, 0 },
+ { '"', nv_regname, NV_NCH_NOP|NV_KEEPREG, 0 },
+ { '#', nv_ident, 0, 0 },
+ { '$', nv_dollar, 0, 0 },
+ { '%', nv_percent, 0, 0 },
+ { '&', nv_optrans, 0, 0 },
+ { '\'', nv_gomark, NV_NCH_ALW, true },
+ { '(', nv_brace, 0, BACKWARD },
+ { ')', nv_brace, 0, FORWARD },
+ { '*', nv_ident, 0, 0 },
+ { '+', nv_down, 0, true },
+ { ',', nv_csearch, 0, true },
+ { '-', nv_up, 0, true },
+ { '.', nv_dot, NV_KEEPREG, 0 },
+ { '/', nv_search, 0, false },
+ { '0', nv_beginline, 0, 0 },
+ { '1', nv_ignore, 0, 0 },
+ { '2', nv_ignore, 0, 0 },
+ { '3', nv_ignore, 0, 0 },
+ { '4', nv_ignore, 0, 0 },
+ { '5', nv_ignore, 0, 0 },
+ { '6', nv_ignore, 0, 0 },
+ { '7', nv_ignore, 0, 0 },
+ { '8', nv_ignore, 0, 0 },
+ { '9', nv_ignore, 0, 0 },
+ { ':', nv_colon, 0, 0 },
+ { ';', nv_csearch, 0, false },
+ { '<', nv_operator, NV_RL, 0 },
+ { '=', nv_operator, 0, 0 },
+ { '>', nv_operator, NV_RL, 0 },
+ { '?', nv_search, 0, false },
+ { '@', nv_at, NV_NCH_NOP, false },
+ { 'A', nv_edit, 0, 0 },
+ { 'B', nv_bck_word, 0, 1 },
+ { 'C', nv_abbrev, NV_KEEPREG, 0 },
+ { 'D', nv_abbrev, NV_KEEPREG, 0 },
+ { 'E', nv_wordcmd, 0, true },
+ { 'F', nv_csearch, NV_NCH_ALW|NV_LANG, BACKWARD },
+ { 'G', nv_goto, 0, true },
+ { 'H', nv_scroll, 0, 0 },
+ { 'I', nv_edit, 0, 0 },
+ { 'J', nv_join, 0, 0 },
+ { 'K', nv_ident, 0, 0 },
+ { 'L', nv_scroll, 0, 0 },
+ { 'M', nv_scroll, 0, 0 },
+ { 'N', nv_next, 0, SEARCH_REV },
+ { 'O', nv_open, 0, 0 },
+ { 'P', nv_put, 0, 0 },
+ { 'Q', nv_exmode, NV_NCW, 0 },
+ { 'R', nv_Replace, 0, false },
+ { 'S', nv_subst, NV_KEEPREG, 0 },
+ { 'T', nv_csearch, NV_NCH_ALW|NV_LANG, BACKWARD },
+ { 'U', nv_Undo, 0, 0 },
+ { 'W', nv_wordcmd, 0, true },
+ { 'X', nv_abbrev, NV_KEEPREG, 0 },
+ { 'Y', nv_abbrev, NV_KEEPREG, 0 },
+ { 'Z', nv_Zet, NV_NCH_NOP|NV_NCW, 0 },
+ { '[', nv_brackets, NV_NCH_ALW, BACKWARD },
+ { '\\', nv_error, 0, 0 },
+ { ']', nv_brackets, NV_NCH_ALW, FORWARD },
+ { '^', nv_beginline, 0, BL_WHITE | BL_FIX },
+ { '_', nv_lineop, 0, 0 },
+ { '`', nv_gomark, NV_NCH_ALW, false },
+ { 'a', nv_edit, NV_NCH, 0 },
+ { 'b', nv_bck_word, 0, 0 },
+ { 'c', nv_operator, 0, 0 },
+ { 'd', nv_operator, 0, 0 },
+ { 'e', nv_wordcmd, 0, false },
+ { 'f', nv_csearch, NV_NCH_ALW|NV_LANG, FORWARD },
+ { 'g', nv_g_cmd, NV_NCH_ALW, false },
+ { 'h', nv_left, NV_RL, 0 },
+ { 'i', nv_edit, NV_NCH, 0 },
+ { 'j', nv_down, 0, false },
+ { 'k', nv_up, 0, false },
+ { 'l', nv_right, NV_RL, 0 },
+ { 'm', nv_mark, NV_NCH_NOP, 0 },
+ { 'n', nv_next, 0, 0 },
+ { 'o', nv_open, 0, 0 },
+ { 'p', nv_put, 0, 0 },
+ { 'q', nv_record, NV_NCH, 0 },
+ { 'r', nv_replace, NV_NCH_NOP|NV_LANG, 0 },
+ { 's', nv_subst, NV_KEEPREG, 0 },
+ { 't', nv_csearch, NV_NCH_ALW|NV_LANG, FORWARD },
+ { 'u', nv_undo, 0, 0 },
+ { 'w', nv_wordcmd, 0, false },
+ { 'x', nv_abbrev, NV_KEEPREG, 0 },
+ { 'y', nv_operator, 0, 0 },
+ { 'z', nv_zet, NV_NCH_ALW, 0 },
+ { '{', nv_findpar, 0, BACKWARD },
+ { '|', nv_pipe, 0, 0 },
+ { '}', nv_findpar, 0, FORWARD },
+ { '~', nv_tilde, 0, 0 },
+
+ // pound sign
+ { POUND, nv_ident, 0, 0 },
+ { K_MOUSEUP, nv_mousescroll, 0, MSCR_UP },
+ { K_MOUSEDOWN, nv_mousescroll, 0, MSCR_DOWN },
+ { K_MOUSELEFT, nv_mousescroll, 0, MSCR_LEFT },
+ { K_MOUSERIGHT, nv_mousescroll, 0, MSCR_RIGHT },
+ { K_LEFTMOUSE, nv_mouse, 0, 0 },
+ { K_LEFTMOUSE_NM, nv_mouse, 0, 0 },
+ { K_LEFTDRAG, nv_mouse, 0, 0 },
+ { K_LEFTRELEASE, nv_mouse, 0, 0 },
+ { K_LEFTRELEASE_NM, nv_mouse, 0, 0 },
+ { K_MIDDLEMOUSE, nv_mouse, 0, 0 },
+ { K_MIDDLEDRAG, nv_mouse, 0, 0 },
+ { K_MIDDLERELEASE, nv_mouse, 0, 0 },
+ { K_RIGHTMOUSE, nv_mouse, 0, 0 },
+ { K_RIGHTDRAG, nv_mouse, 0, 0 },
+ { K_RIGHTRELEASE, nv_mouse, 0, 0 },
+ { K_X1MOUSE, nv_mouse, 0, 0 },
+ { K_X1DRAG, nv_mouse, 0, 0 },
+ { K_X1RELEASE, nv_mouse, 0, 0 },
+ { K_X2MOUSE, nv_mouse, 0, 0 },
+ { K_X2DRAG, nv_mouse, 0, 0 },
+ { K_X2RELEASE, nv_mouse, 0, 0 },
+ { K_IGNORE, nv_ignore, NV_KEEPREG, 0 },
+ { K_NOP, nv_nop, 0, 0 },
+ { K_INS, nv_edit, 0, 0 },
+ { K_KINS, nv_edit, 0, 0 },
+ { K_BS, nv_ctrlh, 0, 0 },
+ { K_UP, nv_up, NV_SSS|NV_STS, false },
+ { K_S_UP, nv_page, NV_SS, BACKWARD },
+ { K_DOWN, nv_down, NV_SSS|NV_STS, false },
+ { K_S_DOWN, nv_page, NV_SS, FORWARD },
+ { K_LEFT, nv_left, NV_SSS|NV_STS|NV_RL, 0 },
+ { K_S_LEFT, nv_bck_word, NV_SS|NV_RL, 0 },
+ { K_C_LEFT, nv_bck_word, NV_SSS|NV_RL|NV_STS, 1 },
+ { K_RIGHT, nv_right, NV_SSS|NV_STS|NV_RL, 0 },
+ { K_S_RIGHT, nv_wordcmd, NV_SS|NV_RL, false },
+ { K_C_RIGHT, nv_wordcmd, NV_SSS|NV_RL|NV_STS, true },
+ { K_PAGEUP, nv_page, NV_SSS|NV_STS, BACKWARD },
+ { K_KPAGEUP, nv_page, NV_SSS|NV_STS, BACKWARD },
+ { K_PAGEDOWN, nv_page, NV_SSS|NV_STS, FORWARD },
+ { K_KPAGEDOWN, nv_page, NV_SSS|NV_STS, FORWARD },
+ { K_END, nv_end, NV_SSS|NV_STS, false },
+ { K_KEND, nv_end, NV_SSS|NV_STS, false },
+ { K_S_END, nv_end, NV_SS, false },
+ { K_C_END, nv_end, NV_SSS|NV_STS, true },
+ { K_HOME, nv_home, NV_SSS|NV_STS, 0 },
+ { K_KHOME, nv_home, NV_SSS|NV_STS, 0 },
+ { K_S_HOME, nv_home, NV_SS, 0 },
+ { K_C_HOME, nv_goto, NV_SSS|NV_STS, false },
+ { K_DEL, nv_abbrev, 0, 0 },
+ { K_KDEL, nv_abbrev, 0, 0 },
+ { K_UNDO, nv_kundo, 0, 0 },
+ { K_HELP, nv_help, NV_NCW, 0 },
+ { K_F1, nv_help, NV_NCW, 0 },
+ { K_XF1, nv_help, NV_NCW, 0 },
+ { K_SELECT, nv_select, 0, 0 },
+ { K_F8, farsi_f8, 0, 0 },
+ { K_F9, farsi_f9, 0, 0 },
+ { K_EVENT, nv_event, NV_KEEPREG, 0 },
+ { K_FOCUSGAINED, nv_focusgained, NV_KEEPREG, 0 },
+ { K_FOCUSLOST, nv_focuslost, NV_KEEPREG, 0 },
};
/* Number of commands in nv_cmds[]. */
@@ -537,7 +542,7 @@ static bool normal_handle_special_visual_command(NormalState *s)
return false;
}
-static bool normal_need_aditional_char(NormalState *s)
+static bool normal_need_additional_char(NormalState *s)
{
int flags = nv_cmds[s->idx].cmd_flags;
bool pending_op = s->oa.op_type != OP_NOP;
@@ -617,7 +622,7 @@ static void normal_redraw_mode_message(NormalState *s)
update_screen(0);
// now reset it, otherwise it's put in the history again
keep_msg = kmsg;
- msg_attr(kmsg, keep_msg_attr);
+ msg_attr((const char *)kmsg, keep_msg_attr);
xfree(kmsg);
}
setcursor();
@@ -641,8 +646,7 @@ static void normal_get_additional_char(NormalState *s)
bool langmap_active = false; // using :lmap mappings
int lang; // getting a text character
- ++no_mapping;
- ++allow_keys; // no mapping for nchar, but allow key codes
+ no_mapping++;
// Don't generate a CursorHold event here, most commands can't handle
// it, e.g., nv_replace(), nv_csearch().
did_cursorhold = true;
@@ -680,8 +684,7 @@ static void normal_get_additional_char(NormalState *s)
}
if (lang && curbuf->b_p_iminsert == B_IMODE_LMAP) {
// Allow mappings defined with ":lmap".
- --no_mapping;
- --allow_keys;
+ no_mapping--;
if (repl) {
State = LREPLACE;
} else {
@@ -694,9 +697,7 @@ static void normal_get_additional_char(NormalState *s)
if (langmap_active) {
// Undo the decrement done above
- ++no_mapping;
- ++allow_keys;
- State = NORMAL_BUSY;
+ no_mapping++;
}
State = NORMAL_BUSY;
s->need_flushbuf |= add_to_showcmd(*cp);
@@ -780,8 +781,7 @@ static void normal_get_additional_char(NormalState *s)
}
no_mapping++;
}
- --no_mapping;
- --allow_keys;
+ no_mapping--;
}
static void normal_invert_horizontal(NormalState *s)
@@ -831,8 +831,7 @@ static bool normal_get_command_count(NormalState *s)
}
if (s->ctrl_w) {
- ++no_mapping;
- ++allow_keys; // no mapping for nchar, but keys
+ no_mapping++;
}
++no_zero_mapping; // don't map zero here
@@ -840,8 +839,7 @@ static bool normal_get_command_count(NormalState *s)
LANGMAP_ADJUST(s->c, true);
--no_zero_mapping;
if (s->ctrl_w) {
- --no_mapping;
- --allow_keys;
+ no_mapping--;
}
s->need_flushbuf |= add_to_showcmd(s->c);
}
@@ -851,12 +849,10 @@ static bool normal_get_command_count(NormalState *s)
s->ctrl_w = true;
s->ca.opcount = s->ca.count0; // remember first count
s->ca.count0 = 0;
- ++no_mapping;
- ++allow_keys; // no mapping for nchar, but keys
+ no_mapping++;
s->c = plain_vgetc(); // get next character
LANGMAP_ADJUST(s->c, true);
- --no_mapping;
- --allow_keys;
+ no_mapping--;
s->need_flushbuf |= add_to_showcmd(s->c);
return true;
}
@@ -924,9 +920,7 @@ normal_end:
checkpcmark(); // check if we moved since setting pcmark
xfree(s->ca.searchbuf);
- if (has_mbyte) {
- mb_adjust_cursor();
- }
+ mb_check_adjust_col(curwin); // #6203
if (curwin->w_p_scb && s->toplevel) {
validate_cursor(); // may need to update w_leftcol
@@ -1090,7 +1084,7 @@ static int normal_execute(VimState *state, int key)
}
// Get an additional character if we need one.
- if (normal_need_aditional_char(s)) {
+ if (normal_need_additional_char(s)) {
normal_get_additional_char(s);
}
@@ -1130,6 +1124,7 @@ static int normal_execute(VimState *state, int key)
start_selection();
unshift_special(&s->ca);
s->idx = find_command(s->ca.cmdchar);
+ assert(s->idx >= 0);
} else if ((nv_cmds[s->idx].cmd_flags & NV_SSS)
&& (mod_mask & MOD_MASK_SHIFT)) {
start_selection();
@@ -1163,7 +1158,7 @@ static void normal_check_stuff_buffer(NormalState *s)
if (need_start_insertmode && goto_im() && !VIsual_active) {
need_start_insertmode = false;
- stuffReadbuff((uint8_t *)"i"); // start insert mode next
+ stuffReadbuff("i"); // start insert mode next
// skip the fileinfo message now, because it would be shown
// after insert mode finishes!
need_fileinfo = false;
@@ -1275,7 +1270,7 @@ static void normal_redraw(NormalState *s)
// msg_attr_keep() will set keep_msg to NULL, must free the string here.
// Don't reset keep_msg, msg_attr_keep() uses it to check for duplicates.
char *p = (char *)keep_msg;
- msg_attr((uint8_t *)p, keep_msg_attr);
+ msg_attr(p, keep_msg_attr);
xfree(p);
}
@@ -1457,9 +1452,8 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
/* Never redo "zf" (define fold). */
if ((vim_strchr(p_cpo, CPO_YANK) != NULL || oap->op_type != OP_YANK)
&& ((!VIsual_active || oap->motion_force)
- /* Also redo Operator-pending Visual mode mappings */
- || (VIsual_active && cap->cmdchar == ':'
- && oap->op_type != OP_COLON))
+ // Also redo Operator-pending Visual mode mappings.
+ || (cap->cmdchar == ':' && oap->op_type != OP_COLON))
&& cap->cmdchar != 'D'
&& oap->op_type != OP_FOLD
&& oap->op_type != OP_FOLDOPEN
@@ -1477,8 +1471,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
* If 'cpoptions' does not contain 'r', insert the search
* pattern to really repeat the same command.
*/
- if (vim_strchr(p_cpo, CPO_REDO) == NULL)
+ if (vim_strchr(p_cpo, CPO_REDO) == NULL) {
AppendToRedobuffLit(cap->searchbuf, -1);
+ }
AppendToRedobuff(NL_STR);
} else if (cap->cmdchar == ':') {
/* do_cmdline() has stored the first typed line in
@@ -1517,10 +1512,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
coladvance(curwin->w_curswant);
}
cap->count0 = redo_VIsual_count;
- if (redo_VIsual_count != 0)
- cap->count1 = redo_VIsual_count;
- else
- cap->count1 = 1;
+ cap->count1 = (cap->count0 == 0 ? 1 : cap->count0);
} else if (VIsual_active) {
if (!gui_yank) {
/* Save the current VIsual area for '< and '> marks, and "gv" */
@@ -1597,6 +1589,8 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
oap->start = curwin->w_cursor;
}
+ // Just in case lines were deleted that make the position invalid.
+ check_pos(curwin->w_buffer, &oap->end);
oap->line_count = oap->end.lnum - oap->start.lnum + 1;
/* Set "virtual_op" before resetting VIsual_active. */
@@ -1862,10 +1856,12 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
break;
case OP_FILTER:
- if (vim_strchr(p_cpo, CPO_FILTER) != NULL)
- AppendToRedobuff((char_u *)"!\r"); /* use any last used !cmd */
- else
- bangredo = true; /* do_bang() will put cmd in redo buffer */
+ if (vim_strchr(p_cpo, CPO_FILTER) != NULL) {
+ AppendToRedobuff("!\r"); // Use any last used !cmd.
+ } else {
+ bangredo = true; // do_bang() will put cmd in redo buffer.
+ }
+ // fallthrough
case OP_INDENT:
case OP_COLON:
@@ -1900,12 +1896,13 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
break;
case OP_FORMAT:
- if (*curbuf->b_p_fex != NUL)
- op_formatexpr(oap); /* use expression */
- else if (*p_fp != NUL)
- op_colon(oap); /* use external command */
- else
- op_format(oap, false); /* use internal function */
+ if (*curbuf->b_p_fex != NUL) {
+ op_formatexpr(oap); // use expression
+ } else if (*p_fp != NUL || *curbuf->b_p_fp != NUL) {
+ op_colon(oap); // use external command
+ } else {
+ op_format(oap, false); // use internal function
+ }
break;
case OP_FORMAT2:
@@ -1913,7 +1910,10 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
break;
case OP_FUNCTION:
- op_function(oap); /* call 'operatorfunc' */
+ // Restore linebreak, so that when the user edits it looks as
+ // before.
+ curwin->w_p_lbr = lbr_saved;
+ op_function(oap); // call 'operatorfunc'
break;
case OP_INSERT:
@@ -2031,40 +2031,44 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
static void op_colon(oparg_T *oap)
{
stuffcharReadbuff(':');
- if (oap->is_VIsual)
- stuffReadbuff((char_u *)"'<,'>");
- else {
- /*
- * Make the range look nice, so it can be repeated.
- */
- if (oap->start.lnum == curwin->w_cursor.lnum)
+ if (oap->is_VIsual) {
+ stuffReadbuff("'<,'>");
+ } else {
+ // Make the range look nice, so it can be repeated.
+ if (oap->start.lnum == curwin->w_cursor.lnum) {
stuffcharReadbuff('.');
- else
+ } else {
stuffnumReadbuff((long)oap->start.lnum);
+ }
if (oap->end.lnum != oap->start.lnum) {
stuffcharReadbuff(',');
- if (oap->end.lnum == curwin->w_cursor.lnum)
+ if (oap->end.lnum == curwin->w_cursor.lnum) {
stuffcharReadbuff('.');
- else if (oap->end.lnum == curbuf->b_ml.ml_line_count)
+ } else if (oap->end.lnum == curbuf->b_ml.ml_line_count) {
stuffcharReadbuff('$');
- else if (oap->start.lnum == curwin->w_cursor.lnum) {
- stuffReadbuff((char_u *)".+");
+ } else if (oap->start.lnum == curwin->w_cursor.lnum) {
+ stuffReadbuff(".+");
stuffnumReadbuff(oap->line_count - 1);
- } else
+ } else {
stuffnumReadbuff((long)oap->end.lnum);
+ }
}
}
- if (oap->op_type != OP_COLON)
- stuffReadbuff((char_u *)"!");
+ if (oap->op_type != OP_COLON) {
+ stuffReadbuff("!");
+ }
if (oap->op_type == OP_INDENT) {
- stuffReadbuff(get_equalprg());
- stuffReadbuff((char_u *)"\n");
+ stuffReadbuff((const char *)get_equalprg());
+ stuffReadbuff("\n");
} else if (oap->op_type == OP_FORMAT) {
- if (*p_fp == NUL)
- stuffReadbuff((char_u *)"fmt");
- else
- stuffReadbuff(p_fp);
- stuffReadbuff((char_u *)"\n']");
+ if (*curbuf->b_p_fp != NUL) {
+ stuffReadbuff((const char *)curbuf->b_p_fp);
+ } else if (*p_fp != NUL) {
+ stuffReadbuff((const char *)p_fp);
+ } else {
+ stuffReadbuff("fmt");
+ }
+ stuffReadbuff("\n']");
}
/*
@@ -2077,7 +2081,6 @@ static void op_colon(oparg_T *oap)
*/
static void op_function(oparg_T *oap)
{
- char_u *(argv[1]);
int save_virtual_op = virtual_op;
if (*p_opfunc == NUL)
@@ -2091,16 +2094,16 @@ static void op_function(oparg_T *oap)
decl(&curbuf->b_op_end);
}
- if (oap->motion_type == kMTBlockWise) {
- argv[0] = (char_u *)"block";
- } else if (oap->motion_type == kMTLineWise) {
- argv[0] = (char_u *)"line";
- } else {
- argv[0] = (char_u *)"char";
- }
+ const char_u *const argv[1] = {
+ (const char_u *)(((const char *const[]) {
+ [kMTBlockWise] = "block",
+ [kMTLineWise] = "line",
+ [kMTCharWise] = "char",
+ })[oap->motion_type]),
+ };
- /* Reset virtual_op so that 'virtualedit' can be changed in the
- * function. */
+ // Reset virtual_op so that 'virtualedit' can be changed in the
+ // function.
virtual_op = MAYBE;
(void)call_func_retnr(p_opfunc, 1, argv, false);
@@ -2307,7 +2310,7 @@ do_mouse (
if (VIsual_active) {
if (VIsual_select) {
stuffcharReadbuff(Ctrl_G);
- stuffReadbuff((char_u *)"\"+p");
+ stuffReadbuff("\"+p");
} else {
stuffcharReadbuff('y');
stuffcharReadbuff(K_MIDDLEMOUSE);
@@ -2334,10 +2337,11 @@ do_mouse (
if (regname == 0 && eval_has_provider("clipboard")) {
regname = '*';
}
- if ((State & REPLACE_FLAG) && !yank_register_mline(regname))
+ if ((State & REPLACE_FLAG) && !yank_register_mline(regname)) {
insert_reg(regname, true);
- else {
- do_put(regname, NULL, BACKWARD, 1L, fixindent | PUT_CURSEND);
+ } else {
+ do_put(regname, NULL, BACKWARD, 1L,
+ (fixindent ? PUT_FIXINDENT : 0) | PUT_CURSEND);
/* Repeat it with CTRL-R CTRL-O r or CTRL-R CTRL-P r */
AppendCharToRedobuff(Ctrl_R);
@@ -2462,12 +2466,12 @@ do_mouse (
};
typval_T rettv;
int doesrange;
- (void) call_func((char_u *) tab_page_click_defs[mouse_col].func,
- (int) strlen(tab_page_click_defs[mouse_col].func),
- &rettv, ARRAY_SIZE(argv), argv,
- curwin->w_cursor.lnum, curwin->w_cursor.lnum,
- &doesrange, true, NULL, NULL);
- clear_tv(&rettv);
+ (void)call_func((char_u *)tab_page_click_defs[mouse_col].func,
+ (int)strlen(tab_page_click_defs[mouse_col].func),
+ &rettv, ARRAY_SIZE(argv), argv, NULL,
+ curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+ &doesrange, true, NULL, NULL);
+ tv_clear(&rettv);
break;
}
}
@@ -2689,7 +2693,8 @@ do_mouse (
*/
if (restart_edit != 0)
where_paste_started = curwin->w_cursor;
- do_put(regname, NULL, dir, count, fixindent | PUT_CURSEND);
+ do_put(regname, NULL, dir, count,
+ (fixindent ? PUT_FIXINDENT : 0)| PUT_CURSEND);
}
/*
* Ctrl-Mouse click or double click in a quickfix window jumps to the
@@ -2698,13 +2703,12 @@ do_mouse (
else if (((mod_mask & MOD_MASK_CTRL)
|| (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)
&& bt_quickfix(curbuf)) {
- if (State & INSERT)
- stuffcharReadbuff(Ctrl_O);
- if (curwin->w_llist_ref == NULL) /* quickfix window */
- stuffReadbuff((char_u *)":.cc\n");
- else /* location list window */
- stuffReadbuff((char_u *)":.ll\n");
- got_click = false; /* ignore drag&release now */
+ if (curwin->w_llist_ref == NULL) { // quickfix window
+ do_cmdline_cmd(".cc");
+ } else { // location list window
+ do_cmdline_cmd(".ll");
+ }
+ got_click = false; // ignore drag&release now
}
/*
* Ctrl-Mouse click (or double click in a help window) jumps to the tag
@@ -3514,7 +3518,8 @@ void check_scrollbind(linenr_T topline_diff, long leftcol_diff)
* loop through the scrollbound windows and scroll accordingly
*/
VIsual_select = VIsual_active = 0;
- for (curwin = firstwin; curwin; curwin = curwin->w_next) {
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ curwin = wp;
curbuf = curwin->w_buffer;
/* skip original window and windows with 'noscrollbind' */
if (curwin == old_curwin || !curwin->w_p_scb) {
@@ -3653,6 +3658,39 @@ nv_gd (
}
}
+// Return true if line[offset] is not inside a C-style comment or string, false
+// otherwise.
+static bool is_ident(char_u *line, int offset)
+{
+ bool incomment = false;
+ int instring = 0;
+ int prev = 0;
+
+ for (int i = 0; i < offset && line[i] != NUL; i++) {
+ if (instring != 0) {
+ if (prev != '\\' && line[i] == instring) {
+ instring = 0;
+ }
+ } else if ((line[i] == '"' || line[i] == '\'') && !incomment) {
+ instring = line[i];
+ } else {
+ if (incomment) {
+ if (prev == '*' && line[i] == '/') {
+ incomment = false;
+ }
+ } else if (prev == '/' && line[i] == '*') {
+ incomment = true;
+ } else if (prev == '/' && line[i] == '/') {
+ return false;
+ }
+ }
+
+ prev = line[i];
+ }
+
+ return incomment == false && instring == 0;
+}
+
/*
* Search for variable declaration of "ptr[len]".
* When "locally" is true in the current function ("gd"), otherwise in the
@@ -3679,6 +3717,7 @@ find_decl (
bool retval = true;
bool incll;
int searchflags = flags_arg;
+ bool valid;
pat = xmalloc(len + 7);
@@ -3713,6 +3752,7 @@ find_decl (
/* Search forward for the identifier, ignore comment lines. */
clearpos(&found_pos);
for (;; ) {
+ valid = false;
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)
@@ -3743,20 +3783,35 @@ find_decl (
curwin->w_cursor.col = 0;
continue;
}
- if (!locally) /* global search: use first match found */
+ valid = is_ident(get_cursor_line_ptr(), curwin->w_cursor.col);
+
+ // If the current position is not a valid identifier and a previous match is
+ // present, favor that one instead.
+ if (!valid && found_pos.lnum != 0) {
+ curwin->w_cursor = found_pos;
break;
- if (curwin->w_cursor.lnum >= par_pos.lnum) {
- /* If we previously found a valid position, use it. */
- if (found_pos.lnum != 0)
+ }
+ // global search: use first match found
+ if (valid && !locally) {
+ break;
+ }
+ if (valid && curwin->w_cursor.lnum >= par_pos.lnum) {
+ // If we previously found a valid position, use it.
+ if (found_pos.lnum != 0) {
curwin->w_cursor = found_pos;
+ }
break;
}
- // For finding a local variable and the match is before the "{" search
- // to find a later match. For K&R style function declarations this
- // skips the function header without types. Remove SEARCH_START from
- // flags to avoid getting stuck at one position.
- found_pos = curwin->w_cursor;
+ // For finding a local variable and the match is before the "{" or
+ // inside a comment, continue searching. For K&R style function
+ // declarations this skips the function header without types.
+ if (!valid) {
+ clearpos(&found_pos);
+ } else {
+ found_pos = curwin->w_cursor;
+ }
+ // Remove SEARCH_START from flags to avoid getting stuck at one position.
searchflags &= ~SEARCH_START;
}
@@ -4037,12 +4092,10 @@ static void nv_zet(cmdarg_T *cap)
return;
n = nchar - '0';
for (;; ) {
- ++no_mapping;
- ++allow_keys; /* no mapping for nchar, but allow key codes */
+ no_mapping++;
nchar = plain_vgetc();
LANGMAP_ADJUST(nchar, true);
- --no_mapping;
- --allow_keys;
+ no_mapping--;
(void)add_to_showcmd(nchar);
if (nchar == K_DEL || nchar == K_KDEL)
n /= 10;
@@ -4370,13 +4423,11 @@ dozet:
break;
- case 'u': /* "zug" and "zuw": undo "zg" and "zw" */
- ++no_mapping;
- ++allow_keys; /* no mapping for nchar, but allow key codes */
+ case 'u': // "zug" and "zuw": undo "zg" and "zw"
+ no_mapping++;
nchar = plain_vgetc();
LANGMAP_ADJUST(nchar, true);
- --no_mapping;
- --allow_keys;
+ no_mapping--;
(void)add_to_showcmd(nchar);
if (vim_strchr((char_u *)"gGwW", nchar) == NULL) {
clearopbeep(cap->oap);
@@ -4483,7 +4534,7 @@ static void nv_colon(cmdarg_T *cap)
/* translate "count:" into ":.,.+(count - 1)" */
stuffcharReadbuff('.');
if (cap->count0 > 1) {
- stuffReadbuff((char_u *)",.+");
+ stuffReadbuff(",.+");
stuffnumReadbuff(cap->count0 - 1L);
}
}
@@ -4674,6 +4725,7 @@ static void nv_ident(cmdarg_T *cap)
char_u *kp = *curbuf->b_p_kp == NUL ? p_kp : curbuf->b_p_kp; // 'keywordprg'
assert(*kp != NUL); // option.c:do_set() should default to ":help" if empty.
bool kp_ex = (*kp == ':'); // 'keywordprg' is an ex command
+ bool kp_help = (STRCMP(kp, ":he") == 0 || STRCMP(kp, ":help") == 0);
size_t buf_size = n * 2 + 30 + STRLEN(kp);
char *buf = xmalloc(buf_size);
buf[0] = NUL;
@@ -4696,7 +4748,9 @@ static void nv_ident(cmdarg_T *cap)
break;
case 'K':
- if (kp_ex) {
+ if (kp_help) {
+ STRCPY(buf, "he! ");
+ } else if (kp_ex) {
if (cap->count0 != 0) { // Send the count to the ex command.
snprintf(buf, buf_size, "%" PRId64, (int64_t)(cap->count0));
}
@@ -4758,13 +4812,16 @@ static void nv_ident(cmdarg_T *cap)
}
}
- /*
- * Now grab the chars in the identifier
- */
- if (cmdchar == 'K' && !kp_ex) {
- /* Escape the argument properly for a shell command */
+ // Now grab the chars in the identifier
+ if (cmdchar == 'K' && !kp_help) {
ptr = vim_strnsave(ptr, n);
- p = vim_strsave_shellescape(ptr, true, true);
+ if (kp_ex) {
+ // Escape the argument properly for an Ex command
+ p = (char_u *)vim_strsave_fnameescape((const char *)ptr, false);
+ } else {
+ // Escape the argument properly for a shell command
+ p = vim_strsave_shellescape(ptr, true, true);
+ }
xfree(ptr);
char *newbuf = xrealloc(buf, STRLEN(buf) + STRLEN(p) + 1);
buf = newbuf;
@@ -5224,6 +5281,7 @@ static void nv_dollar(cmdarg_T *cap)
static void nv_search(cmdarg_T *cap)
{
oparg_T *oap = cap->oap;
+ pos_T save_cursor = curwin->w_cursor;
if (cap->cmdchar == '?' && cap->oap->op_type == OP_ROT13) {
/* Translate "g??" to "g?g?" */
@@ -5233,6 +5291,8 @@ static void nv_search(cmdarg_T *cap)
return;
}
+ // When using 'incsearch' the cursor may be moved to set a different search
+ // start position.
cap->searchbuf = getcmdline(cap->cmdchar, cap->count1, 0);
if (cap->searchbuf == NULL) {
@@ -5241,7 +5301,8 @@ static void nv_search(cmdarg_T *cap)
}
(void)normal_search(cap, cap->cmdchar, cap->searchbuf,
- (cap->arg ? 0 : SEARCH_MARK));
+ (cap->arg || !equalpos(save_cursor, curwin->w_cursor))
+ ? 0 : SEARCH_MARK);
}
/*
@@ -6160,17 +6221,15 @@ static void nv_abbrev(cmdarg_T *cap)
*/
static void nv_optrans(cmdarg_T *cap)
{
- static char_u *(ar[8]) = {(char_u *)"dl", (char_u *)"dh",
- (char_u *)"d$", (char_u *)"c$",
- (char_u *)"cl", (char_u *)"cc",
- (char_u *)"yy", (char_u *)":s\r"};
- static char_u *str = (char_u *)"xXDCsSY&";
+ static const char *(ar[]) = { "dl", "dh", "d$", "c$", "cl", "cc", "yy",
+ ":s\r" };
+ static const char *str = "xXDCsSY&";
if (!checkclearopq(cap->oap)) {
if (cap->count0) {
stuffnumReadbuff(cap->count0);
}
- stuffReadbuff(ar[(int)(vim_strchr(str, cap->cmdchar) - str)]);
+ stuffReadbuff(ar[strchr(str, (char)cap->cmdchar) - str]);
}
cap->opcount = 0;
}
@@ -7196,8 +7255,10 @@ static void nv_wordcmd(cmdarg_T *cap)
// Another strangeness: When standing on the end of a word "ce" will
// change until the end of the next word, but "cw" will change only one
// character! This is done by setting "flag".
- cap->oap->inclusive = true;
- word_end = true;
+ if (vim_strchr(p_cpo, CPO_CHANGEW) != NULL) {
+ cap->oap->inclusive = true;
+ word_end = true;
+ }
flag = true;
}
}
@@ -7291,11 +7352,11 @@ static bool unadjust_for_sel(void)
pp = &curwin->w_cursor;
else
pp = &VIsual;
- if (pp->coladd > 0)
- --pp->coladd;
- else if (pp->col > 0) {
- --pp->col;
- mb_adjustpos(curbuf, pp);
+ if (pp->coladd > 0) {
+ pp->coladd--;
+ } else if (pp->col > 0) {
+ pp->col--;
+ mark_mb_adjustpos(curbuf, pp);
} else if (pp->lnum > 1) {
--pp->lnum;
pp->col = (colnr_T)STRLEN(ml_get(pp->lnum));
@@ -7421,27 +7482,23 @@ static void nv_esc(cmdarg_T *cap)
restart_edit = 'a';
}
-/*
- * Handle "A", "a", "I", "i" and <Insert> commands.
- */
+/// Handle "A", "a", "I", "i" and <Insert> commands.
static void nv_edit(cmdarg_T *cap)
{
- /* <Insert> is equal to "i" */
- if (cap->cmdchar == K_INS || cap->cmdchar == K_KINS)
+ // <Insert> is equal to "i"
+ if (cap->cmdchar == K_INS || cap->cmdchar == K_KINS) {
cap->cmdchar = 'i';
+ }
- /* in Visual mode "A" and "I" are an operator */
- if (VIsual_active && (cap->cmdchar == 'A' || cap->cmdchar == 'I'))
+ // in Visual mode "A" and "I" are an operator
+ if (VIsual_active && (cap->cmdchar == 'A' || cap->cmdchar == 'I')) {
v_visop(cap);
-
- /* in Visual mode and after an operator "a" and "i" are for text objects */
- else if ((cap->cmdchar == 'a' || cap->cmdchar == 'i')
- && (cap->oap->op_type != OP_NOP
- || VIsual_active
- )) {
+ // in Visual mode and after an operator "a" and "i" are for text objects
+ } else if ((cap->cmdchar == 'a' || cap->cmdchar == 'i')
+ && (cap->oap->op_type != OP_NOP || VIsual_active)) {
nv_object(cap);
- } else if (!curbuf->b_p_ma && !p_im) {
- /* Only give this error when 'insertmode' is off. */
+ } else if (!curbuf->b_p_ma && !p_im && !curbuf->terminal) {
+ // Only give this error when 'insertmode' is off.
EMSG(_(e_modifiable));
clearop(cap->oap);
} else if (!checkclearopq(cap->oap)) {
@@ -7614,11 +7671,13 @@ static void nv_record(cmdarg_T *cap)
if (cap->nchar == ':' || cap->nchar == '/' || cap->nchar == '?') {
stuffcharReadbuff(cap->nchar);
stuffcharReadbuff(K_CMDWIN);
- } else
- /* (stop) recording into a named register, unless executing a
- * register */
- if (!Exec_reg && do_record(cap->nchar) == false)
- clearopbeep(cap->oap);
+ } else {
+ // (stop) recording into a named register, unless executing a
+ // register.
+ if (!Exec_reg && do_record(cap->nchar) == FAIL) {
+ clearopbeep(cap->oap);
+ }
+ }
}
}
@@ -7727,16 +7786,22 @@ static void nv_put(cmdarg_T *cap)
savereg = copy_register(regname);
}
- /* Now delete the selected text. */
- cap->cmdchar = 'd';
- cap->nchar = NUL;
- cap->oap->regname = NUL;
- nv_operator(cap);
- do_pending_operator(cap, 0, false);
- empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
+ // To place the cursor correctly after a blockwise put, and to leave the
+ // text in the correct position when putting over a selection with
+ // 'virtualedit' and past the end of the line, we use the 'c' operator in
+ // do_put(), which requires the visual selection to still be active.
+ if (!VIsual_active || VIsual_mode == 'V' || regname != '.') {
+ // Now delete the selected text.
+ cap->cmdchar = 'd';
+ cap->nchar = NUL;
+ cap->oap->regname = NUL;
+ nv_operator(cap);
+ do_pending_operator(cap, 0, false);
+ empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
- /* delete PUT_LINE_BACKWARD; */
- cap->oap->regname = regname;
+ // delete PUT_LINE_BACKWARD;
+ cap->oap->regname = regname;
+ }
/* When deleted a linewise Visual area, put the register as
* lines to avoid it joined with the next line. When deletion was
@@ -7828,7 +7893,7 @@ static void get_op_vcol(
// prevent from moving onto a trail byte
if (has_mbyte) {
- mb_adjustpos(curwin->w_buffer, &oap->end);
+ mark_mb_adjustpos(curwin->w_buffer, &oap->end);
}
getvvcol(curwin, &(oap->start), &oap->start_vcol, NULL, &oap->end_vcol);
@@ -7893,6 +7958,7 @@ static void nv_event(cmdarg_T *cap)
may_garbage_collect = false;
multiqueue_process_events(main_loop.events);
cap->retval |= CA_COMMAND_BUSY; // don't call edit() now
+ finish_op = false;
}
/// Trigger FocusGained event.
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 907353c271..c01840cfd0 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* ops.c: implementation of various operators: op_shift, op_delete, op_tilde,
* op_change, op_yank, do_put, do_join
@@ -14,8 +17,10 @@
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/assert.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_getln.h"
@@ -41,6 +46,7 @@
#include "nvim/terminal.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
+#include "nvim/macros.h"
#include "nvim/window.h"
#include "nvim/os/input.h"
#include "nvim/os/time.h"
@@ -49,12 +55,11 @@ static yankreg_T y_regs[NUM_REGISTERS];
static yankreg_T *y_previous = NULL; /* ptr to last written yankreg */
-static bool clipboard_didwarn_unnamed = false;
-
// for behavior between start_batch_changes() and end_batch_changes())
-static bool clipboard_delay_update = false; // delay clipboard update
static int batch_change_count = 0; // inside a script
+static bool clipboard_delay_update = false; // delay clipboard update
static bool clipboard_needs_update = false; // clipboard was updated
+static bool clipboard_didwarn = false;
/*
* structure used by block_prep, op_delete and op_yank for blockwise operators
@@ -210,8 +215,6 @@ void op_shift(oparg_T *oap, int curs_top, int amount)
}
changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L);
- /* The cursor line is not in a closed fold */
- foldOpenCursor();
if (oap->motion_type == kMTBlockWise) {
curwin->w_cursor.lnum = oap->start.lnum;
@@ -222,6 +225,9 @@ void op_shift(oparg_T *oap, int curs_top, int amount)
} else
--curwin->w_cursor.lnum; /* put cursor on last line, for ":>" */
+ // The cursor line is not in a closed fold
+ foldOpenCursor();
+
if (oap->line_count > p_report) {
if (oap->op_type == OP_RSHIFT)
s = (char_u *)">";
@@ -798,7 +804,6 @@ static bool is_append_register(int regname)
/// Returns a copy of contents in register `name`
/// for use in do_put. Should be freed by caller.
yankreg_T *copy_register(int name)
- FUNC_ATTR_MALLOC
FUNC_ATTR_NONNULL_RET
{
yankreg_T *reg = get_yank_register(name, YREG_PASTE);
@@ -887,7 +892,7 @@ static void set_yreg_additional_data(yankreg_T *reg, dict_T *additional_data)
if (reg->additional_data == additional_data) {
return;
}
- dict_unref(reg->additional_data);
+ tv_dict_unref(reg->additional_data);
reg->additional_data = additional_data;
}
@@ -932,13 +937,11 @@ static int stuff_yank(int regname, char_u *p)
static int execreg_lastc = NUL;
-/*
- * execute a yank register: copy it into the stuff buffer
- *
- * return FAIL for failure, OK otherwise
- */
-int
-do_execreg (
+/// Execute a yank register: copy it into the stuff buffer
+///
+/// Return FAIL for failure, OK otherwise
+int
+do_execreg(
int regname,
int colon, /* insert ':' before each line */
int addcr, /* always add '\n' to end of line */
@@ -1105,7 +1108,6 @@ int insert_reg(
)
{
int retval = OK;
- char_u *arg;
int allocated;
/*
@@ -1121,21 +1123,24 @@ int insert_reg(
if (regname != NUL && !valid_yank_reg(regname, false))
return FAIL;
- if (regname == '.') /* insert last inserted text */
- retval = stuff_inserted(NUL, 1L, TRUE);
- else if (get_spec_reg(regname, &arg, &allocated, TRUE)) {
- if (arg == NULL)
+ char_u *arg;
+ if (regname == '.') { // Insert last inserted text.
+ retval = stuff_inserted(NUL, 1L, true);
+ } else if (get_spec_reg(regname, &arg, &allocated, true)) {
+ if (arg == NULL) {
return FAIL;
- stuffescaped(arg, literally);
- if (allocated)
+ }
+ stuffescaped((const char *)arg, literally);
+ if (allocated) {
xfree(arg);
- } else { /* name or number register */
+ }
+ } else { // Name or number register.
yankreg_T *reg = get_yank_register(regname, YREG_PASTE);
if (reg->y_array == NULL) {
retval = FAIL;
} else {
for (size_t i = 0; i < reg->y_size; i++) {
- stuffescaped(reg->y_array[i], literally);
+ stuffescaped((const char *)reg->y_array[i], literally);
// Insert a newline between lines and after last line if
// y_type is kMTLineWise.
if (reg->y_type == kMTLineWise || i < reg->y_size - 1) {
@@ -1152,29 +1157,29 @@ int insert_reg(
* Stuff a string into the typeahead buffer, such that edit() will insert it
* literally ("literally" TRUE) or interpret is as typed characters.
*/
-static void stuffescaped(char_u *arg, int literally)
+static void stuffescaped(const char *arg, int literally)
{
- int c;
- char_u *start;
-
while (*arg != NUL) {
- /* Stuff a sequence of normal ASCII characters, that's fast. Also
- * stuff K_SPECIAL to get the effect of a special key when "literally"
- * is TRUE. */
- start = arg;
- while ((*arg >= ' ' && *arg < DEL) || (*arg == K_SPECIAL && !literally))
- ++arg;
- if (arg > start)
+ // Stuff a sequence of normal ASCII characters, that's fast. Also
+ // stuff K_SPECIAL to get the effect of a special key when "literally"
+ // is TRUE.
+ const char *const start = arg;
+ while ((*arg >= ' ' && *arg < DEL) || ((uint8_t)(*arg) == K_SPECIAL
+ && !literally)) {
+ arg++;
+ }
+ if (arg > start) {
stuffReadbuffLen(start, (long)(arg - start));
+ }
/* stuff a single special character */
if (*arg != NUL) {
- if (has_mbyte)
- c = mb_cptr2char_adv(&arg);
- else
- c = *arg++;
- if (literally && ((c < ' ' && c != TAB) || c == DEL))
+ const int c = (has_mbyte
+ ? mb_cptr2char_adv((const char_u **)&arg)
+ : (uint8_t)(*arg++));
+ if (literally && ((c < ' ' && c != TAB) || c == DEL)) {
stuffcharReadbuff(Ctrl_V);
+ }
stuffcharReadbuff(c);
}
}
@@ -1260,7 +1265,7 @@ int get_spec_reg(
/// Paste a yank register into the command line.
/// Only for non-special registers.
-/// Used by CTRL-R command in command-line mode
+/// Used by CTRL-R in command-line mode.
/// insert_reg() can't be used here, because special characters from the
/// register contents will be interpreted as commands.
///
@@ -1278,9 +1283,8 @@ bool cmdline_paste_reg(int regname, bool literally, bool remcr)
for (size_t i = 0; i < reg->y_size; i++) {
cmdline_paste_str(reg->y_array[i], literally);
- // Insert ^M between lines and after last line if type is kMTLineWise.
- // Don't do this when "remcr" is true.
- if ((reg->y_type == kMTLineWise || i < reg->y_size - 1) && !remcr) {
+ // Insert ^M between lines, unless `remcr` is true.
+ if (i < reg->y_size - 1 && !remcr) {
cmdline_paste_str((char_u *)"\r", literally);
}
@@ -1403,8 +1407,11 @@ int op_delete(oparg_T *oap)
}
if (oap->regname == 0) {
+ if (reg == NULL) {
+ abort();
+ }
set_clipboard(0, reg);
- yank_do_autocmd(oap, reg);
+ do_autocmd_textyankpost(oap, reg);
}
}
@@ -1951,16 +1958,18 @@ int swapchar(int op_type, pos_T *pos)
if (enc_dbcs != 0 && c >= 0x100) /* No lower/uppercase letter */
return FALSE;
nc = c;
- if (vim_islower(c)) {
- if (op_type == OP_ROT13)
+ if (mb_islower(c)) {
+ if (op_type == OP_ROT13) {
nc = ROT13(c, 'a');
- else if (op_type != OP_LOWER)
- nc = vim_toupper(c);
- } else if (vim_isupper(c)) {
- if (op_type == OP_ROT13)
+ } else if (op_type != OP_LOWER) {
+ nc = mb_toupper(c);
+ }
+ } else if (mb_isupper(c)) {
+ if (op_type == OP_ROT13) {
nc = ROT13(c, 'A');
- else if (op_type != OP_UPPER)
- nc = vim_tolower(c);
+ } else if (op_type != OP_UPPER) {
+ nc = mb_tolower(c);
+ }
}
if (nc != c) {
if (enc_utf8 && (c >= 0x80 || nc >= 0x80)) {
@@ -2315,7 +2324,7 @@ bool op_yank(oparg_T *oap, bool message)
yankreg_T *reg = get_yank_register(oap->regname, YREG_YANK);
op_yank_reg(oap, message, reg, is_append_register(oap->regname));
set_clipboard(oap->regname, reg);
- yank_do_autocmd(oap, reg);
+ do_autocmd_textyankpost(oap, reg);
return true;
}
@@ -2538,7 +2547,7 @@ static void yank_copy_line(yankreg_T *reg, struct block_def *bd, size_t y_idx)
///
/// @param oap Operator arguments.
/// @param reg The yank register used.
-static void yank_do_autocmd(oparg_T *oap, yankreg_T *reg)
+static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
FUNC_ATTR_NONNULL_ALL
{
static bool recursive = false;
@@ -2555,33 +2564,33 @@ static void yank_do_autocmd(oparg_T *oap, yankreg_T *reg)
dict_T *dict = get_vim_var_dict(VV_EVENT);
// the yanked text
- list_T *list = list_alloc();
+ list_T *list = tv_list_alloc();
for (size_t i = 0; i < reg->y_size; i++) {
- list_append_string(list, reg->y_array[i], -1);
+ tv_list_append_string(list, (const char *)reg->y_array[i], -1);
}
list->lv_lock = VAR_FIXED;
- dict_add_list(dict, "regcontents", list);
+ tv_dict_add_list(dict, S_LEN("regcontents"), list);
// the register type
char buf[NUMBUFLEN+2];
format_reg_type(reg->y_type, reg->y_width, buf, ARRAY_SIZE(buf));
- dict_add_nr_str(dict, "regtype", 0, (char_u *)buf);
+ tv_dict_add_str(dict, S_LEN("regtype"), buf);
// name of requested register or the empty string for an unnamed operation.
buf[0] = (char)oap->regname;
buf[1] = NUL;
- dict_add_nr_str(dict, "regname", 0, (char_u *)buf);
+ tv_dict_add_str(dict, S_LEN("regname"), buf);
// kind of operation (yank/delete/change)
buf[0] = (char)get_op_char(oap->op_type);
buf[1] = NUL;
- dict_add_nr_str(dict, "operator", 0, (char_u *)buf);
+ tv_dict_add_str(dict, S_LEN("operator"), buf);
- dict_set_keys_readonly(dict);
+ tv_dict_set_keys_readonly(dict);
textlock++;
apply_autocmds(EVENT_TEXTYANKPOST, NULL, NULL, false, curbuf);
textlock--;
- dict_clear(dict);
+ tv_dict_clear(dict);
recursive = false;
}
@@ -2637,12 +2646,79 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
* special characters (newlines, etc.).
*/
if (regname == '.') {
- (void)stuff_inserted((dir == FORWARD ? (count == -1 ? 'o' : 'a') :
- (count == -1 ? 'O' : 'i')), count, FALSE);
- /* Putting the text is done later, so can't really move the cursor to
- * the next character. Use "l" to simulate it. */
- if ((flags & PUT_CURSEND) && gchar_cursor() != NUL)
- stuffcharReadbuff('l');
+ bool non_linewise_vis = (VIsual_active && VIsual_mode != 'V');
+
+ // PUT_LINE has special handling below which means we use 'i' to start.
+ char command_start_char = non_linewise_vis ? 'c' :
+ (flags & PUT_LINE ? 'i' : (dir == FORWARD ? 'a' : 'i'));
+
+ // To avoid 'autoindent' on linewise puts, create a new line with `:put _`.
+ if (flags & PUT_LINE) {
+ do_put('_', NULL, dir, 1, PUT_LINE);
+ }
+
+ // If given a count when putting linewise, we stuff the readbuf with the
+ // dot register 'count' times split by newlines.
+ if (flags & PUT_LINE) {
+ stuffcharReadbuff(command_start_char);
+ for (; count > 0; count--) {
+ (void)stuff_inserted(NUL, 1, count != 1);
+ if (count != 1) {
+ // To avoid 'autoindent' affecting the text, use Ctrl_U to remove any
+ // whitespace. Can't just insert Ctrl_U into readbuf1, this would go
+ // back to the previous line in the case of 'noautoindent' and
+ // 'backspace' includes "eol". So we insert a dummy space for Ctrl_U
+ // to consume.
+ stuffReadbuff("\n ");
+ stuffcharReadbuff(Ctrl_U);
+ }
+ }
+ } else {
+ (void)stuff_inserted(command_start_char, count, false);
+ }
+
+ // Putting the text is done later, so can't move the cursor to the next
+ // character. Simulate it with motion commands after the insert.
+ if (flags & PUT_CURSEND) {
+ if (flags & PUT_LINE) {
+ stuffReadbuff("j0");
+ } else {
+ // Avoid ringing the bell from attempting to move into the space after
+ // the current line. We can stuff the readbuffer with "l" if:
+ // 1) 'virtualedit' is "all" or "onemore"
+ // 2) We are not at the end of the line
+ // 3) We are not (one past the end of the line && on the last line)
+ // This allows a visual put over a selection one past the end of the
+ // line joining the current line with the one below.
+
+ // curwin->w_cursor.col marks the byte position of the cursor in the
+ // currunt line. It increases up to a max of
+ // STRLEN(ml_get(curwin->w_cursor.lnum)). With 'virtualedit' and the
+ // cursor past the end of the line, curwin->w_cursor.coladd is
+ // incremented instead of curwin->w_cursor.col.
+ char_u *cursor_pos = get_cursor_pos_ptr();
+ bool one_past_line = (*cursor_pos == NUL);
+ bool eol = false;
+ if (!one_past_line) {
+ eol = (*(cursor_pos + mb_ptr2len(cursor_pos)) == NUL);
+ }
+
+ bool ve_allows = (ve_flags == VE_ALL || ve_flags == VE_ONEMORE);
+ bool eof = curbuf->b_ml.ml_line_count == curwin->w_cursor.lnum
+ && one_past_line;
+ if (ve_allows || !(eol || eof)) {
+ stuffcharReadbuff('l');
+ }
+ }
+ } else if (flags & PUT_LINE) {
+ stuffReadbuff("g'[");
+ }
+
+ // So the 'u' command restores cursor position after ".p, save the cursor
+ // position now (though not saving any text).
+ if (command_start_char == 'a') {
+ u_save(curwin->w_cursor.lnum, curwin->w_cursor.lnum + 1);
+ }
return;
}
@@ -2712,7 +2788,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
}
if (curbuf->terminal) {
- for (int i = 0; i < count; i++) {
+ for (int i = 0; i < count; i++) { // -V756
// feed the lines to the terminal
for (size_t j = 0; j < y_size; j++) {
if (j) {
@@ -2831,14 +2907,12 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
else
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
- if (has_mbyte)
- /* move to start of next multi-byte character */
- curwin->w_cursor.col += (*mb_ptr2len)(get_cursor_pos_ptr());
- else if (c != TAB || ve_flags != VE_ALL)
- ++curwin->w_cursor.col;
- ++col;
- } else
+ // move to start of next multi-byte character
+ curwin->w_cursor.col += (*mb_ptr2len)(get_cursor_pos_ptr());
+ col++;
+ } else {
getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2);
+ }
col += curwin->w_cursor.coladd;
if (ve_flags == VE_ALL
@@ -2892,8 +2966,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
bd.startspaces = incr - bd.endspaces;
--bd.textcol;
delcount = 1;
- if (has_mbyte)
- bd.textcol -= (*mb_head_off)(oldp, oldp + bd.textcol);
+ bd.textcol -= (*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
@@ -2975,21 +3048,13 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
// if type is kMTCharWise, FORWARD is the same as BACKWARD on the next
// char
if (dir == FORWARD && gchar_cursor() != NUL) {
- if (has_mbyte) {
- int bytelen = (*mb_ptr2len)(get_cursor_pos_ptr());
-
- /* put it on the next of the multi-byte character. */
- col += bytelen;
- if (yanklen) {
- curwin->w_cursor.col += bytelen;
- curbuf->b_op_end.col += bytelen;
- }
- } else {
- ++col;
- if (yanklen) {
- ++curwin->w_cursor.col;
- ++curbuf->b_op_end.col;
- }
+ int bytelen = (*mb_ptr2len)(get_cursor_pos_ptr());
+
+ // put it on the next of the multi-byte character.
+ col += bytelen;
+ if (yanklen) {
+ curwin->w_cursor.col += bytelen;
+ curbuf->b_op_end.col += bytelen;
}
}
curbuf->b_op_start = curwin->w_cursor;
@@ -3027,7 +3092,9 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
}
if (VIsual_active)
lnum++;
- } while (VIsual_active && lnum <= curbuf->b_visual.vi_end.lnum);
+ } while (VIsual_active
+ && (lnum <= curbuf->b_visual.vi_end.lnum
+ || lnum <= curbuf->b_visual.vi_start.lnum));
if (VIsual_active) { /* reset lnum to the last visual line */
lnum--;
@@ -3114,7 +3181,7 @@ error:
if (curbuf->b_op_start.lnum + (y_type == kMTCharWise) - 1 + nr_lines
< curbuf->b_ml.ml_line_count) {
mark_adjust(curbuf->b_op_start.lnum + (y_type == kMTCharWise),
- (linenr_T)MAXLNUM, nr_lines, 0L);
+ (linenr_T)MAXLNUM, nr_lines, 0L, false);
}
// note changed text for displaying and folding
@@ -3264,10 +3331,11 @@ void ex_display(exarg_T *eap)
get_clipboard(name, &yb, true);
- if (name == vim_tolower(redir_reg)
- || (redir_reg == '"' && yb == y_previous))
- continue; /* do not list register being written to, the
- * pointer can be freed */
+ if (name == mb_tolower(redir_reg)
+ || (redir_reg == '"' && yb == y_previous)) {
+ continue; // do not list register being written to, the
+ // pointer can be freed
+ }
if (yb->y_array != NULL) {
msg_putchar('\n');
@@ -3380,43 +3448,47 @@ dis_msg (
os_breakcheck();
}
-/*
- * If "process" is TRUE and the line begins with a comment leader (possibly
- * after some white space), return a pointer to the text after it. Put a boolean
- * value indicating whether the line ends with an unclosed comment in
- * "is_comment".
- * line - line to be processed,
- * process - if FALSE, will only check whether the line ends with an unclosed
- * comment,
- * include_space - whether to also skip space following the comment leader,
- * is_comment - will indicate whether the current line ends with an unclosed
- * comment.
- */
-static char_u *skip_comment(char_u *line, int process, int include_space, int *is_comment)
+/// If \p "process" is true and the line begins with a comment leader (possibly
+/// after some white space), return a pointer to the text after it.
+/// Put a boolean value indicating whether the line ends with an unclosed
+/// comment in "is_comment".
+///
+/// @param line - line to be processed
+/// @param process - if false, will only check whether the line ends
+/// with an unclosed comment,
+/// @param include_space - whether to skip space following the comment leader
+/// @param[out] is_comment - whether the current line ends with an unclosed
+/// comment.
+char_u *skip_comment(
+ char_u *line, bool process, bool include_space, bool *is_comment
+)
{
char_u *comment_flags = NULL;
int lead_len;
int leader_offset = get_last_leader_offset(line, &comment_flags);
- *is_comment = FALSE;
+ *is_comment = false;
if (leader_offset != -1) {
/* Let's check whether the line ends with an unclosed comment.
* If the last comment leader has COM_END in flags, there's no comment.
*/
while (*comment_flags) {
if (*comment_flags == COM_END
- || *comment_flags == ':')
+ || *comment_flags == ':') {
break;
- ++comment_flags;
+ }
+ comment_flags++;
+ }
+ if (*comment_flags != COM_END) {
+ *is_comment = true;
}
- if (*comment_flags != COM_END)
- *is_comment = TRUE;
}
- if (process == FALSE)
+ if (process == false) {
return line;
+ }
- lead_len = get_leader_len(line, &comment_flags, FALSE, include_space);
+ lead_len = get_leader_len(line, &comment_flags, false, include_space);
if (lead_len == 0)
return line;
@@ -3438,8 +3510,9 @@ static char_u *skip_comment(char_u *line, int process, int include_space, int *i
* starting with a closing part of a three-part comment. That's good,
* because we don't want to remove those as this would be annoying.
*/
- if (*comment_flags == ':' || *comment_flags == NUL)
+ if (*comment_flags == ':' || *comment_flags == NUL) {
line += lead_len;
+ }
return line;
}
@@ -3473,7 +3546,7 @@ int do_join(size_t count,
int *comments = NULL;
int remove_comments = (use_formatoptions == TRUE)
&& has_format_option(FO_REMOVE_COMS);
- int prev_was_comment;
+ bool prev_was_comment;
if (save_undo && u_save(curwin->w_cursor.lnum - 1,
curwin->w_cursor.lnum + (linenr_T)count) == FAIL) {
@@ -3784,6 +3857,7 @@ fex_format (
int use_sandbox = was_set_insecurely((char_u *)"formatexpr",
OPT_LOCAL);
int r;
+ char_u *fex;
/*
* Set v:lnum to the first line number and v:count to the number of lines.
@@ -3793,16 +3867,22 @@ fex_format (
set_vim_var_nr(VV_COUNT, (varnumber_T)count);
set_vim_var_char(c);
- /*
- * Evaluate the function.
- */
- if (use_sandbox)
- ++sandbox;
- r = eval_to_number(curbuf->b_p_fex);
- if (use_sandbox)
- --sandbox;
+ // Make a copy, the option could be changed while calling it.
+ fex = vim_strsave(curbuf->b_p_fex);
+ if (fex == NULL) {
+ return 0;
+ }
+ // Evaluate the function.
+ if (use_sandbox) {
+ sandbox++;
+ }
+ r = (int)eval_to_number(fex);
+ if (use_sandbox) {
+ sandbox--;
+ }
set_vim_var_string(VV_CHAR, NULL, -1);
+ xfree(fex);
return r;
}
@@ -4359,8 +4439,8 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
char_u buf2[NUMBUFLEN];
int pre; // 'X' or 'x': hex; '0': octal; 'B' or 'b': bin
static bool hexupper = false; // 0xABC
- unsigned long n;
- unsigned long oldn;
+ uvarnumber_T n;
+ uvarnumber_T oldn;
char_u *ptr;
int c;
int todel;
@@ -4397,12 +4477,14 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
if (dobin) {
while (col > 0 && ascii_isbdigit(ptr[col])) {
col--;
+ col -= utf_head_off(ptr, ptr + col);
}
}
if (dohex) {
while (col > 0 && ascii_isxdigit(ptr[col])) {
col--;
+ col -= utf_head_off(ptr, ptr + col);
}
}
if (dobin
@@ -4410,6 +4492,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
&& !((col > 0
&& (ptr[col] == 'X' || ptr[col] == 'x')
&& ptr[col - 1] == '0'
+ && !utf_head_off(ptr, ptr + col - 1)
&& ascii_isxdigit(ptr[col + 1])))) {
// In case of binary/hexadecimal pattern overlap match, rescan
@@ -4417,6 +4500,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
while (col > 0 && ascii_isdigit(ptr[col])) {
col--;
+ col -= utf_head_off(ptr, ptr + col);
}
}
@@ -4424,14 +4508,17 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
&& col > 0
&& (ptr[col] == 'X' || ptr[col] == 'x')
&& ptr[col - 1] == '0'
+ && !utf_head_off(ptr, ptr + col - 1)
&& ascii_isxdigit(ptr[col + 1]))
|| (dobin
&& col > 0
&& (ptr[col] == 'B' || ptr[col] == 'b')
&& ptr[col - 1] == '0'
+ && !utf_head_off(ptr, ptr + col - 1)
&& ascii_isbdigit(ptr[col + 1]))) {
// Found hexadecimal or binary number, move to its start.
col--;
+ col -= utf_head_off(ptr, ptr + col);
} else {
// Search forward and then backward to find the start of number.
col = pos->col;
@@ -4453,15 +4540,18 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
if (visual) {
while (ptr[col] != NUL && length > 0 && !ascii_isdigit(ptr[col])
&& !(doalp && ASCII_ISALPHA(ptr[col]))) {
- col++;
- length--;
+ int mb_len = MB_PTR2LEN(ptr + col);
+
+ col += mb_len;
+ length -= mb_len;
}
if (length == 0) {
goto theend;
}
- if (col > pos->col && ptr[col - 1] == '-') {
+ if (col > pos->col && ptr[col - 1] == '-'
+ && !utf_head_off(ptr, ptr + col - 1)) {
negative = true;
was_positive = false;
}
@@ -4507,7 +4597,8 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
endpos = curwin->w_cursor;
curwin->w_cursor.col = col;
} else {
- if (col > 0 && ptr[col - 1] == '-' && !visual) {
+ if (col > 0 && ptr[col - 1] == '-'
+ && !utf_head_off(ptr, ptr + col - 1) && !visual) {
// negative number
col--;
negative = true;
@@ -4544,20 +4635,20 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
oldn = n;
- n = subtract ? n - (unsigned long) Prenum1
- : n + (unsigned long) Prenum1;
+ n = subtract ? n - (uvarnumber_T)Prenum1
+ : n + (uvarnumber_T)Prenum1;
// handle wraparound for decimal numbers
if (!pre) {
if (subtract) {
if (n > oldn) {
- n = 1 + (n ^ (unsigned long)-1);
+ n = 1 + (n ^ (uvarnumber_T)-1);
negative ^= true;
}
} else {
// add
if (n < oldn) {
- n = (n ^ (unsigned long)-1);
+ n = (n ^ (uvarnumber_T)-1);
negative ^= true;
}
}
@@ -4763,8 +4854,8 @@ static void *get_reg_wrap_one_line(char_u *s, int flags)
if (!(flags & kGRegList)) {
return s;
}
- list_T *list = list_alloc();
- list_append_string(list, NULL, -1);
+ list_T *list = tv_list_alloc();
+ tv_list_append_string(list, NULL, 0);
list->lv_first->li_tv.vval.v_string = s;
return list;
}
@@ -4814,9 +4905,9 @@ void *get_reg_contents(int regname, int flags)
return NULL;
if (flags & kGRegList) {
- list_T *list = list_alloc();
+ list_T *list = tv_list_alloc();
for (size_t i = 0; i < reg->y_size; i++) {
- list_append_string(list, reg->y_array[i], -1);
+ tv_list_append_string(list, (const char *)reg->y_array[i], -1);
}
return list;
@@ -4897,7 +4988,7 @@ void write_reg_contents(int name, const char_u *str, ssize_t len,
write_reg_contents_ex(name, str, len, must_append, kMTUnknown, 0L);
}
-void write_reg_contents_lst(int name, char_u **strings, int maxlen,
+void write_reg_contents_lst(int name, char_u **strings,
bool must_append, MotionType yank_type,
colnr_T block_len)
{
@@ -5147,11 +5238,13 @@ void clear_oparg(oparg_T *oap)
* case, eol_size will be added to the character count to account for
* the size of the EOL character.
*/
-static long line_count_info(char_u *line, long *wc, long *cc, long limit, int eol_size)
+static varnumber_T line_count_info(char_u *line, varnumber_T *wc,
+ varnumber_T *cc, varnumber_T limit,
+ int eol_size)
{
- long i;
- long words = 0;
- long chars = 0;
+ varnumber_T i;
+ varnumber_T words = 0;
+ varnumber_T chars = 0;
int is_word = 0;
for (i = 0; i < limit && line[i] != NUL; ) {
@@ -5189,15 +5282,15 @@ void cursor_pos_info(dict_T *dict)
char_u buf1[50];
char_u buf2[40];
linenr_T lnum;
- long byte_count = 0;
- long bom_count = 0;
- long byte_count_cursor = 0;
- long char_count = 0;
- long char_count_cursor = 0;
- long word_count = 0;
- long word_count_cursor = 0;
+ varnumber_T byte_count = 0;
+ varnumber_T bom_count = 0;
+ varnumber_T byte_count_cursor = 0;
+ varnumber_T char_count = 0;
+ varnumber_T char_count_cursor = 0;
+ varnumber_T word_count = 0;
+ varnumber_T word_count_cursor = 0;
int eol_size;
- long last_check = 100000L;
+ varnumber_T last_check = 100000L;
long line_count_selected = 0;
pos_T min_pos, max_pos;
oparg_T oparg;
@@ -5304,15 +5397,16 @@ void cursor_pos_info(dict_T *dict)
if (lnum == curwin->w_cursor.lnum) {
word_count_cursor += word_count;
char_count_cursor += char_count;
- byte_count_cursor = byte_count +
- line_count_info(ml_get(lnum),
- &word_count_cursor, &char_count_cursor,
- (long)(curwin->w_cursor.col + 1), eol_size);
+ byte_count_cursor = byte_count
+ + line_count_info(ml_get(lnum), &word_count_cursor,
+ &char_count_cursor,
+ (varnumber_T)(curwin->w_cursor.col + 1),
+ eol_size);
}
}
- /* Add to the running totals */
- byte_count += line_count_info(ml_get(lnum), &word_count,
- &char_count, (long)MAXCOL, eol_size);
+ // Add to the running totals
+ byte_count += line_count_info(ml_get(lnum), &word_count, &char_count,
+ (varnumber_T)MAXCOL, eol_size);
}
// Correction for when last line doesn't have an EOL.
@@ -5401,17 +5495,19 @@ void cursor_pos_info(dict_T *dict)
if (dict != NULL) {
// Don't shorten this message, the user asked for it.
- dict_add_nr_str(dict, "words", word_count, NULL);
- dict_add_nr_str(dict, "chars", char_count, NULL);
- dict_add_nr_str(dict, "bytes", byte_count + bom_count, NULL);
-
- dict_add_nr_str(dict, l_VIsual_active ? "visual_bytes" : "cursor_bytes",
- byte_count_cursor, NULL);
- dict_add_nr_str(dict, l_VIsual_active ? "visual_chars" : "cursor_chars",
- char_count_cursor, NULL);
- dict_add_nr_str(dict, l_VIsual_active ? "visual_words" : "cursor_words",
- word_count_cursor, NULL);
- }
+ tv_dict_add_nr(dict, S_LEN("words"), (varnumber_T)word_count);
+ tv_dict_add_nr(dict, S_LEN("chars"), (varnumber_T)char_count);
+ tv_dict_add_nr(dict, S_LEN("bytes"), (varnumber_T)(byte_count + bom_count));
+
+ STATIC_ASSERT(sizeof("visual") == sizeof("cursor"),
+ "key_len argument in tv_dict_add_nr is wrong");
+ tv_dict_add_nr(dict, l_VIsual_active ? "visual_bytes" : "cursor_bytes",
+ sizeof("visual_bytes") - 1, (varnumber_T)byte_count_cursor);
+ tv_dict_add_nr(dict, l_VIsual_active ? "visual_chars" : "cursor_chars",
+ sizeof("visual_chars") - 1, (varnumber_T)char_count_cursor);
+ tv_dict_add_nr(dict, l_VIsual_active ? "visual_words" : "cursor_words",
+ sizeof("visual_words") - 1, (varnumber_T)word_count_cursor);
+ }
}
/// Check if the default register (used in an unnamed paste) should be a
@@ -5427,7 +5523,7 @@ int get_default_register_name(void)
}
/// Determine if register `*name` should be used as a clipboard.
-/// In an unnammed operation, `*name` is `NUL` and will be adjusted to `'*'/'+'` if
+/// In an unnamed operation, `*name` is `NUL` and will be adjusted to */+ if
/// `clipboard=unnamed[plus]` is set.
///
/// @param name The name of register, or `NUL` if unnamed.
@@ -5438,33 +5534,41 @@ int get_default_register_name(void)
/// if the register isn't a clipboard or provider isn't available.
static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing)
{
- if (*name == '*' || *name == '+') {
- if(!eval_has_provider("clipboard")) {
- if (!quiet) {
- EMSG("clipboard: No provider. Try \":CheckHealth\" or "
- "\":h clipboard\".");
- }
- return NULL;
- }
- return &y_regs[*name == '*' ? STAR_REGISTER : PLUS_REGISTER];
- } else if ((*name == NUL) && (cb_flags & CB_UNNAMEDMASK)) {
- if(!eval_has_provider("clipboard")) {
- if (!quiet && !clipboard_didwarn_unnamed) {
- msg((char_u *)"clipboard: No provider. Try \":CheckHealth\" or "
- "\":h clipboard\".");
- clipboard_didwarn_unnamed = true;
- }
- return NULL;
+#define MSG_NO_CLIP "clipboard: No provider. " \
+ "Try \":CheckHealth\" or \":h clipboard\"."
+
+ yankreg_T *target = NULL;
+ bool explicit_cb_reg = (*name == '*' || *name == '+');
+ bool implicit_cb_reg = (*name == NUL) && (cb_flags & CB_UNNAMEDMASK);
+ if (!explicit_cb_reg && !implicit_cb_reg) {
+ goto end;
+ }
+
+ if (!eval_has_provider("clipboard")) {
+ if (batch_change_count == 1 && !quiet
+ && (!clipboard_didwarn || (explicit_cb_reg && !redirecting()))) {
+ clipboard_didwarn = true;
+ // Do NOT error (emsg()) here--if it interrupts :redir we get into
+ // a weird state, stuck in "redirect mode".
+ msg((char_u *)MSG_NO_CLIP);
}
+ // ... else, be silent (don't flood during :while, :redir, etc.).
+ goto end;
+ }
+
+ if (explicit_cb_reg) {
+ target = &y_regs[*name == '*' ? STAR_REGISTER : PLUS_REGISTER];
+ goto end;
+ } else { // unnamed register: "implicit" clipboard
if (writing && clipboard_delay_update) {
+ // For "set" (copy), defer the clipboard call.
clipboard_needs_update = true;
- return NULL;
+ goto end;
} else if (!writing && clipboard_needs_update) {
- // use the internal value
- return NULL;
+ // For "get" (paste), use the internal value.
+ goto end;
}
- yankreg_T *target;
if (cb_flags & CB_UNNAMEDPLUS) {
*name = (cb_flags & CB_UNNAMED && writing) ? '"': '+';
target = &y_regs[PLUS_REGISTER];
@@ -5472,10 +5576,11 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing)
*name = '*';
target = &y_regs[STAR_REGISTER];
}
- return target; // unnamed register
+ goto end;
}
- // don't do anything for other register names
- return NULL;
+
+end:
+ return target;
}
static bool get_clipboard(int name, yankreg_T **target, bool quiet)
@@ -5489,9 +5594,9 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
}
free_register(reg);
- list_T *args = list_alloc();
- char_u regname = (char_u)name;
- list_append_string(args, &regname, 1);
+ list_T *const args = tv_list_alloc();
+ const char regname = (char)name;
+ tv_list_append_string(args, &regname, 1);
typval_T result = eval_call_provider("clipboard", "get", args);
@@ -5503,7 +5608,8 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
goto err;
}
- list_T *res = result.vval.v_list, *lines = NULL;
+ list_T *res = result.vval.v_list;
+ list_T *lines = NULL;
if (res->lv_len == 2 && res->lv_first->li_tv.v_type == VAR_LIST) {
lines = res->lv_first->li_tv.vval.v_list;
if (res->lv_last->li_tv.v_type != VAR_STRING) {
@@ -5547,7 +5653,7 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
if (li->li_tv.v_type != VAR_STRING) {
goto err;
}
- reg->y_array[i++] = (uint8_t *)xstrdup((char *)li->li_tv.vval.v_string);
+ reg->y_array[i++] = (char_u *)xstrdupnul((char *)li->li_tv.vval.v_string);
}
if (reg->y_size > 0 && strlen((char*)reg->y_array[reg->y_size-1]) == 0) {
@@ -5605,40 +5711,44 @@ static void set_clipboard(int name, yankreg_T *reg)
return;
}
- list_T *lines = list_alloc();
+ list_T *lines = tv_list_alloc();
for (size_t i = 0; i < reg->y_size; i++) {
- list_append_string(lines, reg->y_array[i], -1);
+ tv_list_append_string(lines, (const char *)reg->y_array[i], -1);
}
- list_T *args = list_alloc();
- list_append_list(args, lines);
+ list_T *args = tv_list_alloc();
+ tv_list_append_list(args, lines);
- char_u regtype;
+ char regtype;
switch (reg->y_type) {
- case kMTLineWise:
- regtype = 'V';
- list_append_string(lines, (char_u*)"", 0);
- break;
- case kMTCharWise:
- regtype = 'v';
- break;
- case kMTBlockWise:
- regtype = 'b';
- list_append_string(lines, (char_u*)"", 0);
- break;
- case kMTUnknown:
- assert(false);
- }
- list_append_string(args, &regtype, 1);
-
- char_u regname = (char_u)name;
- list_append_string(args, &regname, 1);
+ case kMTLineWise: {
+ regtype = 'V';
+ tv_list_append_string(lines, NULL, 0);
+ break;
+ }
+ case kMTCharWise: {
+ regtype = 'v';
+ break;
+ }
+ case kMTBlockWise: {
+ regtype = 'b';
+ tv_list_append_string(lines, NULL, 0);
+ break;
+ }
+ case kMTUnknown: {
+ assert(false);
+ }
+ }
+ tv_list_append_string(args, &regtype, 1);
+
+ const char regname = (char)name;
+ tv_list_append_string(args, &regname, 1);
(void)eval_call_provider("clipboard", "set", args);
}
-/// Avoid clipboard (slow) during batch operations (i.e., a script).
+/// Avoid slow things (clipboard) during batch operations (while/for-loops).
void start_batch_changes(void)
{
if (++batch_change_count > 1) {
@@ -5648,7 +5758,7 @@ void start_batch_changes(void)
clipboard_needs_update = false;
}
-/// Update the clipboard after batch changes finished.
+/// Counterpart to start_batch_changes().
void end_batch_changes(void)
{
if (--batch_change_count > 0) {
@@ -5657,6 +5767,7 @@ void end_batch_changes(void)
}
clipboard_delay_update = false;
if (clipboard_needs_update) {
+ // unnamed ("implicit" clipboard)
set_clipboard(NUL, y_previous);
clipboard_needs_update = false;
}
@@ -5682,7 +5793,7 @@ static inline bool reg_empty(const yankreg_T *const reg)
/// @return Pointer that needs to be passed to next `op_register_iter` call or
/// NULL if iteration is over.
const void *op_register_iter(const void *const iter, char *const name,
- yankreg_T *const reg)
+ yankreg_T *const reg, bool *is_unnamed)
FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT
{
*name = NUL;
@@ -5698,6 +5809,7 @@ const void *op_register_iter(const void *const iter, char *const name,
int iter_off = (int)(iter_reg - &(y_regs[0]));
*name = (char)get_register_name(iter_off);
*reg = *iter_reg;
+ *is_unnamed = (iter_reg == y_previous);
while (++iter_reg - &(y_regs[0]) < NUM_SAVED_REGISTERS) {
if (!reg_empty(iter_reg)) {
return (void *) iter_reg;
@@ -5722,10 +5834,11 @@ size_t op_register_amount(void)
/// Set register to a given value
///
/// @param[in] name Register name.
-/// @param[in] reg Register value.
+/// @param[in] reg Register value.
+/// @param[in] is_unnamed Whether to set the unnamed regiseter to reg
///
/// @return true on success, false on failure.
-bool op_register_set(const char name, const yankreg_T reg)
+bool op_register_set(const char name, const yankreg_T reg, bool is_unnamed)
{
int i = op_reg_index(name);
if (i == -1) {
@@ -5733,6 +5846,10 @@ bool op_register_set(const char name, const yankreg_T reg)
}
free_register(&y_regs[i]);
y_regs[i] = reg;
+
+ if (is_unnamed) {
+ y_previous = &y_regs[i];
+ }
return true;
}
@@ -5749,3 +5866,20 @@ const yankreg_T *op_register_get(const char name)
}
return &y_regs[i];
}
+
+/// Set the previous yank register
+///
+/// @param[in] name Register name.
+///
+/// @return true on success, false on failure.
+bool op_register_set_previous(const char name)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ int i = op_reg_index(name);
+ if (i == -1) {
+ return false;
+ }
+
+ y_previous = &y_regs[i];
+ return true;
+}
diff --git a/src/nvim/ops.h b/src/nvim/ops.h
index 44df2e9e0c..a8867e02ea 100644
--- a/src/nvim/ops.h
+++ b/src/nvim/ops.h
@@ -6,8 +6,10 @@
#include "nvim/macros.h"
#include "nvim/ascii.h"
#include "nvim/types.h"
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
#include "nvim/os/time.h"
+#include "nvim/normal.h" // for MotionType and oparg_T
+#include "nvim/ex_cmds_defs.h" // for exarg_T
typedef int (*Indenter)(void);
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 52a8b19ca4..8ba10fd38a 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -1,24 +1,24 @@
-/*
- * Code to handle user-settable options. This is all pretty much table-
- * driven. Checklist for adding a new option:
- * - Put it in the options array below (copy an existing entry).
- * - For a global option: Add a variable for it in option_defs.h.
- * - For a buffer or window local option:
- * - Add a PV_XX entry to the enum below.
- * - Add a variable to the window or buffer struct in buffer_defs.h.
- * - For a window option, add some code to copy_winopt().
- * - For a buffer option, add some code to buf_copy_options().
- * - For a buffer string option, add code to check_buf_options().
- * - If it's a numeric option, add any necessary bounds checks to do_set().
- * - If it's a list of flags, add some code in do_set(), search for WW_ALL.
- * - When adding an option with expansion (P_EXPAND), but with a different
- * default for Vi and Vim (no P_VI_DEF), add some code at VIMEXP.
- * - Add documentation! One line in doc/help.txt, full description in
- * options.txt, and any other related places.
- * - Add an entry in runtime/optwin.vim.
- * When making changes:
- * - Adjust the help for the option in doc/option.txt.
- */
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+// User-settable options. Checklist for adding a new option:
+// - Put it in options.lua
+// - For a global option: Add a variable for it in option_defs.h.
+// - For a buffer or window local option:
+// - Add a BV_XX or WV_XX entry to option_defs.h
+// - Add a variable to the window or buffer struct in buffer_defs.h.
+// - For a window option, add some code to copy_winopt().
+// - For a window string option, add code to check_winopt()
+// and clear_winopt(). If setting the option needs parsing,
+// add some code to didset_window_options().
+// - For a buffer option, add some code to buf_copy_options().
+// - For a buffer string option, add code to check_buf_options().
+// - If it's a numeric option, add any necessary bounds checks to 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! doc/options.txt, and any other related places.
+// - Add an entry in runtime/optwin.vim.
#define IN_OPTION_C
#include <assert.h>
@@ -31,6 +31,7 @@
#include <limits.h>
#include "nvim/vim.h"
+#include "nvim/macros.h"
#include "nvim/ascii.h"
#include "nvim/edit.h"
#include "nvim/option.h"
@@ -40,6 +41,7 @@
#include "nvim/diff.h"
#include "nvim/digraph.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
@@ -65,6 +67,7 @@
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/spell.h"
+#include "nvim/spellfile.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/ui.h"
@@ -213,12 +216,12 @@ typedef struct vimoption {
#define P_VI_DEF 0x400U /* Use Vi default for Vim */
#define P_VIM 0x800U /* Vim option */
-/* when option changed, what to display: */
-#define P_RSTAT 0x1000U /* redraw status lines */
-#define P_RWIN 0x2000U /* redraw current window */
-#define P_RBUF 0x4000U /* redraw current buffer */
-#define P_RALL 0x6000U /* redraw all windows */
-#define P_RCLR 0x7000U /* clear and redraw all */
+// when option changed, what to display:
+#define P_RSTAT 0x1000U ///< redraw status lines
+#define P_RWIN 0x2000U ///< redraw current window and recompute text
+#define P_RBUF 0x4000U ///< redraw current buffer and recompute text
+#define P_RALL 0x6000U ///< redraw all windows
+#define P_RCLR 0x7000U ///< clear and redraw all
#define P_COMMA 0x8000U ///< comma separated list
#define P_ONECOMMA 0x18000U ///< P_COMMA and cannot have two consecutive
@@ -238,15 +241,18 @@ typedef struct vimoption {
///< when there is a redraw flag
#define P_NO_DEF_EXP 0x8000000U ///< Do not expand default value.
+#define P_RWINONLY 0x10000000U ///< only redraw current window
+
#define HIGHLIGHT_INIT \
"8:SpecialKey,~:EndOfBuffer,z:TermCursor,Z:TermCursorNC,@:NonText," \
"d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr," \
"N:CursorLineNr,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title," \
- "v:Visual,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn," \
+ "v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn," \
"A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal," \
"B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel," \
"x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill," \
- "!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine"
+ "!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine," \
+ "0:Whitespace,I:NormalNC"
/*
* options[] is initialized here.
@@ -335,7 +341,7 @@ static inline size_t compute_double_colon_len(const char *const val,
do {
size_t dir_len;
const char *dir;
- iter = vim_colon_env_iter(val, iter, &dir, &dir_len);
+ iter = vim_env_iter(':', val, iter, &dir, &dir_len);
if (dir != NULL && dir_len > 0) {
ret += ((dir_len + memcnt(dir, ',', dir_len) + common_suf_len
+ !after_pathsep(dir, dir + dir_len)) * 2
@@ -379,8 +385,8 @@ static inline char *add_colon_dirs(char *dest, const char *const val,
do {
size_t dir_len;
const char *dir;
- iter = (forward ? vim_colon_env_iter : vim_colon_env_iter_rev)(
- val, iter, &dir, &dir_len);
+ iter = (forward ? vim_env_iter : vim_env_iter_rev)(':', val, iter, &dir,
+ &dir_len);
if (dir != NULL && dir_len > 0) {
dest = strcpy_comma_escaped(dest, dir, dir_len);
if (!after_pathsep(dest - 1, dest)) {
@@ -607,7 +613,7 @@ void set_init_1(void)
/*
* 'maxmemtot' and 'maxmem' may have to be adjusted for available memory
*/
- opt_idx = findoption((char_u *)"maxmemtot");
+ opt_idx = findoption("maxmemtot");
if (opt_idx >= 0) {
{
/* Use half of amount of memory available to Vim. */
@@ -617,7 +623,7 @@ void set_init_1(void)
? UINTPTR_MAX
: (uintptr_t)(available_kib /2);
options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n;
- opt_idx = findoption((char_u *)"maxmem");
+ opt_idx = findoption("maxmem");
if (opt_idx >= 0) {
options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n;
}
@@ -648,7 +654,7 @@ void set_init_1(void)
}
}
buf[j] = NUL;
- opt_idx = findoption((char_u *)"cdpath");
+ opt_idx = findoption("cdpath");
if (opt_idx >= 0) {
options[opt_idx].def_val[VI_DEFAULT] = buf;
options[opt_idx].flags |= P_DEF_ALLOCED;
@@ -767,8 +773,9 @@ void set_init_1(void)
* NOTE: mlterm's author is being asked to 'set' a variable
* instead of an environment variable due to inheritance.
*/
- if (os_env_exists("MLTERM"))
- set_option_value((char_u *)"tbidi", 1L, NULL, 0);
+ if (os_env_exists("MLTERM")) {
+ set_option_value("tbidi", 1L, NULL, 0);
+ }
didset_options2();
@@ -778,7 +785,7 @@ void set_init_1(void)
char_u *p = enc_locale();
if (p == NULL) {
// use utf-8 as 'default' if locale encoding can't be detected.
- p = vim_strsave((char_u *)"utf-8");
+ p = (char_u *)xmemdupz(S_LEN("utf-8"));
}
fenc_default = p;
@@ -885,7 +892,7 @@ set_options_default (
static void set_string_default(const char *name, char *val, bool allocated)
FUNC_ATTR_NONNULL_ALL
{
- int opt_idx = findoption((char_u *)name);
+ int opt_idx = findoption(name);
if (opt_idx >= 0) {
if (options[opt_idx].flags & P_DEF_ALLOCED) {
xfree(options[opt_idx].def_val[VI_DEFAULT]);
@@ -907,9 +914,10 @@ void set_number_default(char *name, long val)
{
int opt_idx;
- opt_idx = findoption((char_u *)name);
- if (opt_idx >= 0)
+ opt_idx = findoption(name);
+ if (opt_idx >= 0) {
options[opt_idx].def_val[VI_DEFAULT] = (char_u *)val;
+ }
}
#if defined(EXITFREE)
@@ -937,11 +945,8 @@ void free_all_options(void)
#endif
-/*
- * Initialize the options, part two: After getting Rows and Columns and
- * setting 'term'.
- */
-void set_init_2(void)
+/// Initialize the options, part two: After getting Rows and Columns.
+void set_init_2(bool headless)
{
int idx;
@@ -950,20 +955,29 @@ void set_init_2(void)
* wrong when the window height changes.
*/
set_number_default("scroll", Rows / 2);
- idx = findoption((char_u *)"scroll");
- if (idx >= 0 && !(options[idx].flags & P_WAS_SET))
+ idx = findoption("scroll");
+ if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) {
set_option_default(idx, OPT_LOCAL, p_cp);
+ }
comp_col();
/*
* 'window' is only for backwards compatibility with Vi.
* Default is Rows - 1.
*/
- if (!option_was_set((char_u *)"window"))
+ if (!option_was_set("window")) {
p_window = Rows - 1;
+ }
set_number_default("window", Rows - 1);
- parse_shape_opt(SHAPE_CURSOR); /* set cursor shapes from 'guicursor' */
- (void)parse_printoptions(); /* parse 'printoptions' default value */
+#if 0
+ // This bodges around problems that should be fixed in the TUI layer.
+ if (!headless && !os_term_is_nice()) {
+ set_string_option_direct((char_u *)"guicursor", -1, (char_u *)"",
+ OPT_GLOBAL, SID_NONE);
+ }
+#endif
+ parse_shape_opt(SHAPE_CURSOR); // set cursor shapes from 'guicursor'
+ (void)parse_printoptions(); // parse 'printoptions' default value
}
/*
@@ -979,16 +993,18 @@ void set_init_3(void)
int idx_sp;
int do_sp;
- idx_srr = findoption((char_u *)"srr");
- if (idx_srr < 0)
- do_srr = FALSE;
- else
+ idx_srr = findoption("srr");
+ if (idx_srr < 0) {
+ do_srr = false;
+ } else {
do_srr = !(options[idx_srr].flags & P_WAS_SET);
- idx_sp = findoption((char_u *)"sp");
- if (idx_sp < 0)
- do_sp = FALSE;
- else
+ }
+ idx_sp = findoption("sp");
+ if (idx_sp < 0) {
+ do_sp = false;
+ } else {
do_sp = !(options[idx_sp].flags & P_WAS_SET);
+ }
size_t len = 0;
char_u *p = (char_u *)invocation_path_tail(p_sh, &len);
@@ -1032,7 +1048,7 @@ void set_init_3(void)
}
if (bufempty()) {
- int idx_ffs = findoption((char_u *)"ffs");
+ int idx_ffs = findoption_len(S_LEN("ffs"));
// Apply the first entry of 'fileformats' to the initial buffer.
if (idx_ffs >= 0 && (options[idx_ffs].flags & P_WAS_SET)) {
@@ -1049,16 +1065,20 @@ void set_init_3(void)
*/
void set_helplang_default(const char *lang)
{
- int idx;
+ if (lang == NULL) {
+ return;
+ }
- if (lang == NULL || STRLEN(lang) < 2) /* safety check */
+ const size_t lang_len = strlen(lang);
+ if (lang_len < 2) { // safety check
return;
- idx = findoption((char_u *)"hlg");
+ }
+ int idx = findoption("hlg");
if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) {
if (options[idx].flags & P_ALLOCED)
free_string_option(p_hlg);
- p_hlg = (char_u *)xstrdup(lang);
- /* zh_CN becomes "cn", zh_TW becomes "tw". */
+ p_hlg = (char_u *)xmemdupz(lang, lang_len);
+ // zh_CN becomes "cn", zh_TW becomes "tw".
if (STRNICMP(p_hlg, "zh_", 3) == 0 && STRLEN(p_hlg) >= 5) {
p_hlg[0] = (char_u)TOLOWER_ASC(p_hlg[3]);
p_hlg[1] = (char_u)TOLOWER_ASC(p_hlg[4]);
@@ -1085,12 +1105,12 @@ void set_title_defaults(void)
* icon name. Saves a bit of time, because the X11 display server does
* not need to be contacted.
*/
- idx1 = findoption((char_u *)"title");
+ idx1 = findoption("title");
if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) {
options[idx1].def_val[VI_DEFAULT] = (char_u *)(intptr_t)0;
p_title = 0;
}
- idx1 = findoption((char_u *)"icon");
+ idx1 = findoption("icon");
if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) {
options[idx1].def_val[VI_DEFAULT] = (char_u *)(intptr_t)0;
p_icon = 0;
@@ -1127,7 +1147,7 @@ do_set (
int afterchar; /* character just after option name */
int len;
int i;
- long value;
+ varnumber_T value;
int key;
uint32_t flags; /* flags for current option */
char_u *varp = NULL; /* pointer to variable for current option */
@@ -1165,10 +1185,6 @@ do_set (
showoptions(1, opt_flags);
did_show = TRUE;
}
- } else if (STRNCMP(arg, "termcap",
- 7) == 0 && !(opt_flags & OPT_MODELINE)) {
- did_show = TRUE;
- arg += 7;
} else {
prefix = 1;
if (STRNCMP(arg, "no", 2) == 0) {
@@ -1196,7 +1212,7 @@ do_set (
goto skip;
}
if (arg[1] == 't' && arg[2] == '_') { // could be term code
- opt_idx = findoption_len(arg + 1, (size_t) (len - 1));
+ opt_idx = findoption_len((const char *)arg + 1, (size_t)(len - 1));
}
len++;
if (opt_idx == -1) {
@@ -1212,7 +1228,7 @@ do_set (
len++;
}
}
- opt_idx = findoption_len(arg, (size_t) len);
+ opt_idx = findoption_len((const char *)arg, (size_t)len);
if (opt_idx == -1) {
key = find_key_option(arg);
}
@@ -1394,10 +1410,10 @@ do_set (
value = prefix;
}
- errmsg = set_bool_option(opt_idx, varp, (int)value,
- opt_flags);
- } else { /* numeric or string */
- if (vim_strchr((char_u *)"=:&<", nextchar) == NULL
+ errmsg = (char_u *)set_bool_option(opt_idx, varp, (int)value,
+ opt_flags);
+ } else { // Numeric or string.
+ if (vim_strchr((const char_u *)"=:&<", nextchar) == NULL
|| prefix != 1) {
errmsg = e_invarg;
goto skip;
@@ -1451,15 +1467,19 @@ do_set (
goto skip;
}
- if (adding)
+ if (adding) {
value = *(long *)varp + value;
- if (prepending)
+ }
+ if (prepending) {
value = *(long *)varp * value;
- if (removing)
+ }
+ if (removing) {
value = *(long *)varp - value;
- errmsg = set_num_option(opt_idx, varp, value,
- errbuf, sizeof(errbuf), opt_flags);
- } else if (opt_idx >= 0) { /* string */
+ }
+ errmsg = (char_u *)set_num_option(opt_idx, varp, (long)value,
+ errbuf, sizeof(errbuf),
+ opt_flags);
+ } else if (opt_idx >= 0) { // String.
char_u *save_arg = NULL;
char_u *s = NULL;
char_u *oldval = NULL; // previous value if *varp
@@ -1493,7 +1513,7 @@ do_set (
new_value_alloced = true;
if (newval == NULL) {
newval = empty_option;
- } else if (!(options[opt_idx].flags | P_NO_DEF_EXP)) {
+ } else if (!(options[opt_idx].flags & P_NO_DEF_EXP)) {
s = option_expand(opt_idx, newval);
if (s == NULL) {
s = newval;
@@ -1931,15 +1951,7 @@ did_set_title (
{
if (starting != NO_SCREEN) {
maketitle();
- if (icon) {
- if (!p_icon) {
- ui_set_icon(NULL);
- }
- } else {
- if (!p_title) {
- ui_set_title(NULL);
- }
- }
+ resettitle();
}
}
@@ -2111,7 +2123,7 @@ static void didset_options(void)
static void didset_options2(void)
{
// Initialize the highlight_attr[] table.
- (void)highlight_changed();
+ highlight_changed();
// Parse default for 'clipboard'.
(void)opt_strings_flags(p_cb, p_cb_values, &cb_flags, true);
@@ -2152,6 +2164,7 @@ void check_buf_options(buf_T *buf)
check_string_option(&buf->b_p_inex);
check_string_option(&buf->b_p_inde);
check_string_option(&buf->b_p_indk);
+ check_string_option(&buf->b_p_fp);
check_string_option(&buf->b_p_fex);
check_string_option(&buf->b_p_kp);
check_string_option(&buf->b_p_mps);
@@ -2223,7 +2236,7 @@ static void check_string_option(char_u **pp)
*/
int was_set_insecurely(char_u *opt, int opt_flags)
{
- int idx = findoption(opt);
+ int idx = findoption((const char *)opt);
if (idx >= 0) {
uint32_t *flagp = insecure_flag(idx, opt_flags);
@@ -2285,9 +2298,9 @@ set_string_option_direct (
int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
int idx = opt_idx;
- if (idx == -1) { /* use name */
- idx = findoption(name);
- if (idx < 0) { /* not found (should not happen) */
+ if (idx == -1) { // Use name.
+ idx = findoption((const char *)name);
+ if (idx < 0) { // Not found (should not happen).
EMSG2(_(e_intern2), "set_string_option_direct()");
EMSG2(_("For option %s"), name);
return;
@@ -2440,12 +2453,11 @@ did_set_string_option (
if ((secure || sandbox != 0)
&& (options[opt_idx].flags & P_SECURE)) {
errmsg = e_secure;
- }
- /* Check for a "normal" file name in some options. Disallow a path
- * separator (slash and/or backslash), wildcards and characters that are
- * often illegal in a file name. */
- else if ((options[opt_idx].flags & P_NFNAME)
- && vim_strpbrk(*varp, (char_u *)"/\\*?[|<>") != NULL) {
+ } else if ((options[opt_idx].flags & P_NFNAME)
+ && vim_strpbrk(*varp, (char_u *)"/\\*?[|;&<>\r\n") != NULL) {
+ // 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.
errmsg = e_invarg;
}
/* 'backupcopy' */
@@ -2524,11 +2536,11 @@ did_set_string_option (
if (s[2] == NUL)
break;
}
- }
- /* 'highlight' */
- else if (varp == &p_hl) {
- if (highlight_changed() == FAIL)
- errmsg = e_invarg; /* invalid flags */
+ } else if (varp == &p_hl) {
+ // 'highlight'
+ if (strcmp((char *)(*varp), HIGHLIGHT_INIT) != 0) {
+ errmsg = e_unsupportedoption;
+ }
}
/* 'nrformats' */
else if (gvarp == &p_nf) {
@@ -2567,12 +2579,11 @@ did_set_string_option (
init_highlight(FALSE, FALSE);
- if (dark != (*p_bg == 'd')
- && get_var_value((char_u *)"g:colors_name") != NULL) {
- /* The color scheme must have set 'background' back to another
- * value, that's not what we want here. Disable the color
- * scheme and set the colors again. */
- do_unlet((char_u *)"g:colors_name", TRUE);
+ if (dark != (*p_bg == 'd') && get_var_value("g:colors_name") != NULL) {
+ // The color scheme must have set 'background' back to another
+ // value, that's not what we want here. Disable the color
+ // scheme and set the colors again.
+ do_unlet(S_LEN("g:colors_name"), true);
free_string_option(p_bg);
p_bg = vim_strsave((char_u *)(dark ? "dark" : "light"));
check_string_option(&p_bg);
@@ -2626,7 +2637,7 @@ did_set_string_option (
if (varp == &p_enc) {
// only encoding=utf-8 allowed
if (STRCMP(p_enc, "utf-8") != 0) {
- errmsg = e_invarg;
+ errmsg = e_unsupportedoption;
}
}
}
@@ -2768,7 +2779,7 @@ did_set_string_option (
// option.
opt_idx = ((options[opt_idx].fullname[0] == 'v')
? (shada_idx == -1
- ? ((shada_idx = findoption((char_u *) "shada")))
+ ? ((shada_idx = findoption("shada")))
: shada_idx)
: opt_idx);
// Update free_oldval now that we have the opt_idx for 'shada', otherwise
@@ -2829,9 +2840,10 @@ did_set_string_option (
}
}
- /* 'guicursor' */
- else if (varp == &p_guicursor)
+ // 'guicursor'
+ else if (varp == &p_guicursor) {
errmsg = parse_shape_opt(SHAPE_CURSOR);
+ }
else if (varp == &p_popt)
errmsg = parse_printoptions();
@@ -3017,7 +3029,7 @@ did_set_string_option (
/* 'pastetoggle': translate key codes like in a mapping */
else if (varp == &p_pt) {
if (*p_pt) {
- (void)replace_termcodes(p_pt, STRLEN(p_pt), &p, true, true, false,
+ (void)replace_termcodes(p_pt, STRLEN(p_pt), &p, true, true, true,
CPO_TO_CPO_FLAGS);
if (p != NULL) {
if (new_value_alloced)
@@ -3152,6 +3164,10 @@ did_set_string_option (
if (!valid_filetype(*varp)) {
errmsg = e_invarg;
}
+ } else if (varp == &curwin->w_p_winhl) {
+ if (!parse_winhl_opt(curwin)) {
+ errmsg = e_invarg;
+ }
} else {
// Options that are a list of flags.
p = NULL;
@@ -3189,8 +3205,6 @@ did_set_string_option (
*/
if (did_chartab)
(void)init_chartab();
- if (varp == &p_hl)
- (void)highlight_changed();
} else {
/* Remember where the option was set. */
set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
@@ -3256,7 +3270,7 @@ did_set_string_option (
if (varp == &p_mouse) {
if (*p_mouse == NUL) {
- ui_mouse_off();
+ ui_call_mouse_off();
} else {
setmouse(); // in case 'mouse' changed
}
@@ -3409,15 +3423,18 @@ static char_u *set_chars_option(char_u **varp)
&& p[len] == ':'
&& p[len + 1] != NUL) {
s = p + len + 1;
- c1 = mb_ptr2char_adv(&s);
- if (mb_char2cells(c1) > 1)
+ c1 = mb_ptr2char_adv((const char_u **)&s);
+ if (mb_char2cells(c1) > 1) {
continue;
+ }
if (tab[i].cp == &lcs_tab2) {
- if (*s == NUL)
+ if (*s == NUL) {
continue;
- c2 = mb_ptr2char_adv(&s);
- if (mb_char2cells(c2) > 1)
+ }
+ c2 = mb_ptr2char_adv((const char_u **)&s);
+ if (mb_char2cells(c2) > 1) {
continue;
+ }
}
if (*s == ',' || *s == NUL) {
if (round) {
@@ -3557,6 +3574,47 @@ static char_u *compile_cap_prog(synblock_T *synblock)
return NULL;
}
+/// Handle setting `winhighlight' in window "wp"
+static bool parse_winhl_opt(win_T *wp)
+{
+ int w_hl_id_normal = 0;
+ int w_hl_ids[HLF_COUNT] = { 0 };
+ int hlf;
+
+ const char *p = (const char *)wp->w_p_winhl;
+ while (*p) {
+ char *colon = strchr(p, ':');
+ if (!colon) {
+ return false;
+ }
+ size_t nlen = (size_t)(colon-p);
+ char *hi = colon+1;
+ char *commap = xstrchrnul(hi, ',');
+ int hl_id = syn_check_group((char_u *)hi, (int)(commap-hi));
+
+ if (strncmp("Normal", p, nlen) == 0) {
+ w_hl_id_normal = hl_id;
+ } else {
+ for (hlf = 0; hlf < (int)HLF_COUNT; hlf++) {
+ if (strncmp(hlf_names[hlf], p, nlen) == 0) {
+ w_hl_ids[hlf] = hl_id;
+ break;
+ }
+ }
+ if (hlf == HLF_COUNT) {
+ return false;
+ }
+ }
+
+ p = *commap ? commap+1 : "";
+ }
+
+ wp->w_hl_id_normal = w_hl_id_normal;
+ memcpy(wp->w_hl_ids, w_hl_ids, sizeof(w_hl_ids));
+ wp->w_hl_needs_update = true;
+ return true;
+}
+
/*
* Set the scriptID for an option, taking care of setting the buffer- or
* window-local value.
@@ -3578,24 +3636,24 @@ static void set_option_scriptID_idx(int opt_idx, int opt_flags, int 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 (
- int opt_idx, /* index in options[] table */
- char_u *varp, /* pointer to the option variable */
- int value, /* new value */
- int opt_flags /* OPT_LOCAL and/or OPT_GLOBAL */
-)
+/// Set the value of a boolean option, taking care of side effects
+///
+/// @param[in] opt_idx Option index in options[] table.
+/// @param[out] varp Pointer to the option variable.
+/// @param[in] value New value.
+/// @param[in] opt_flags OPT_LOCAL and/or OPT_GLOBAL.
+///
+/// @return NULL on success, error message on error.
+static char *set_bool_option(const int opt_idx, char_u *const varp,
+ const int value,
+ const int opt_flags)
{
int old_value = *(int *)varp;
/* Disallow changing some options from secure mode */
if ((secure || sandbox != 0)
&& (options[opt_idx].flags & P_SECURE)) {
- return e_secure;
+ return (char *)e_secure;
}
*(int *)varp = value; /* set the new value */
@@ -3608,29 +3666,34 @@ set_bool_option (
*(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value;
// Ensure that options set to p_force_on cannot be disabled.
- if ((int *)varp == &p_force_on && p_force_on == FALSE) {
- p_force_on = TRUE;
- return e_unsupportedoption;
- }
+ if ((int *)varp == &p_force_on && p_force_on == false) {
+ p_force_on = true;
+ return (char *)e_unsupportedoption;
// Ensure that options set to p_force_off cannot be enabled.
- else if ((int *)varp == &p_force_off && p_force_off == TRUE) {
- p_force_off = FALSE;
- return e_unsupportedoption;
- }
- /* 'undofile' */
- else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf) {
- /* Only take action when the option was set. When reset we do not
- * delete the undo file, the option may be set again without making
- * any changes in between. */
+ } else if ((int *)varp == &p_force_off && p_force_off == true) {
+ p_force_off = false;
+ return (char *)e_unsupportedoption;
+ } else if ((int *)varp == &p_lrm) {
+ // 'langremap' -> !'langnoremap'
+ p_lnr = !p_lrm;
+ } else if ((int *)varp == &p_lnr) {
+ // 'langnoremap' -> !'langremap'
+ p_lrm = !p_lnr;
+ // 'undofile'
+ } else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf) {
+ // Only take action when the option was set. When reset we do not
+ // delete the undo file, the option may be set again without making
+ // any changes in between.
if (curbuf->b_p_udf || p_udf) {
char_u hash[UNDO_HASH_SIZE];
buf_T *save_curbuf = curbuf;
- for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next) {
- /* When 'undofile' is set globally: for every buffer, otherwise
- * only for the current buffer: Try to read in the undofile,
- * if one exists, the buffer wasn't changed and the buffer was
- * loaded */
+ FOR_ALL_BUFFERS(bp) {
+ curbuf = bp;
+ // When 'undofile' is set globally: for every buffer, otherwise
+ // only for the current buffer: Try to read in the undofile,
+ // if one exists, the buffer wasn't changed and the buffer was
+ // loaded
if ((curbuf == save_curbuf
|| (opt_flags & OPT_GLOBAL) || opt_flags == 0)
&& !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL) {
@@ -3742,8 +3805,8 @@ set_bool_option (
if (curwin->w_p_pvw) {
FOR_ALL_WINDOWS_IN_TAB(win, curtab) {
if (win->w_p_pvw && win != curwin) {
- curwin->w_p_pvw = FALSE;
- return (char_u *)N_("E590: A preview window already exists");
+ curwin->w_p_pvw = false;
+ return N_("E590: A preview window already exists");
}
}
}
@@ -3884,16 +3947,15 @@ set_bool_option (
"W17: Arabic requires UTF-8, do ':set encoding=utf-8'");
msg_source(hl_attr(HLF_W));
- MSG_ATTR(_(w_arabic), hl_attr(HLF_W));
+ msg_attr(_(w_arabic), hl_attr(HLF_W));
set_vim_var_string(VV_WARNINGMSG, _(w_arabic), -1);
}
/* set 'delcombine' */
p_deco = TRUE;
- /* Force-set the necessary keymap for arabic */
- set_option_value((char_u *)"keymap", 0L, (char_u *)"arabic",
- OPT_LOCAL);
+ // Force-set the necessary keymap for arabic.
+ set_option_value("keymap", 0L, "arabic", OPT_LOCAL);
p_altkeymap = 0;
p_hkmap = 0;
p_fkmap = 0;
@@ -3959,20 +4021,18 @@ set_bool_option (
return NULL;
}
-/*
- * Set the value of a number option, and take care of side effects.
- * Returns NULL for success, or an error message for an error.
- */
-static char_u *
-set_num_option (
- int opt_idx, /* index in options[] table */
- char_u *varp, /* pointer to the option variable */
- long value, /* new value */
- char_u *errbuf, /* buffer for error messages */
- size_t errbuflen, /* length of "errbuf" */
- int opt_flags /* OPT_LOCAL, OPT_GLOBAL and
- OPT_MODELINE */
-)
+/// Set the value of a number option, taking care of side effects
+///
+/// @param[in] opt_idx Option index in options[] table.
+/// @param[out] varp Pointer to the option variable.
+/// @param[in] value New value.
+/// @param errbuf Buffer for error messages.
+/// @param[in] errbuflen Length of `errbuf`.
+/// @param[in] opt_flags OPT_LOCAL, OPT_GLOBAL or OPT_MODELINE.
+///
+/// @return NULL on success, error message on error.
+static char *set_num_option(int opt_idx, char_u *varp, long value,
+ char_u *errbuf, size_t errbuflen, int opt_flags)
{
char_u *errmsg = NULL;
long old_value = *(long *)varp;
@@ -3983,7 +4043,7 @@ set_num_option (
/* Disallow changing some options from secure mode. */
if ((secure || sandbox != 0)
&& (options[opt_idx].flags & P_SECURE)) {
- return e_secure;
+ return (char *)e_secure;
}
*pp = value;
@@ -4013,7 +4073,7 @@ set_num_option (
}
/* Change window height NOW */
- if (lastwin != firstwin) {
+ if (!ONE_WINDOW) {
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)
@@ -4042,7 +4102,7 @@ set_num_option (
}
/* Change window width NOW */
- if (lastwin != firstwin && curwin->w_width < p_wiw)
+ if (!ONE_WINDOW && curwin->w_width < p_wiw)
win_setwidth((int)p_wiw);
}
/* 'winminwidth' */
@@ -4200,7 +4260,16 @@ set_num_option (
FOR_ALL_TAB_WINDOWS(tp, wp) {
check_colorcolumn(wp);
}
-
+ } else if (pp == &curbuf->b_p_scbk || pp == &p_scbk) {
+ // 'scrollback'
+ if (*pp < -1 || *pp > SB_MAX
+ || (*pp != -1 && opt_flags == OPT_LOCAL && !curbuf->terminal)) {
+ errmsg = e_invarg;
+ *pp = old_value;
+ } else if (curbuf->terminal) {
+ // Force the scrollback to take effect.
+ terminal_resize(curbuf->terminal, UINT16_MAX, UINT16_MAX);
+ }
}
/*
@@ -4244,8 +4313,9 @@ set_num_option (
cmdline_row = (int)(Rows - p_ch);
}
}
- if (p_window >= Rows || !option_was_set((char_u *)"window"))
+ if (p_window >= Rows || !option_was_set("window")) {
p_window = Rows - 1;
+ }
}
if (curbuf->b_p_ts <= 0) {
@@ -4320,6 +4390,11 @@ set_num_option (
if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
*(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = *pp;
+ if (pp == &curbuf->b_p_scbk && !curbuf->terminal) {
+ // Normal buffer: reset local 'scrollback' after updating the global value.
+ curbuf->b_p_scbk = -1;
+ }
+
options[opt_idx].flags |= P_WAS_SET;
if (!starting && errmsg == NULL) {
@@ -4345,7 +4420,7 @@ set_num_option (
curwin->w_set_curswant = TRUE;
check_redraw(options[opt_idx].flags);
- return errmsg;
+ return (char *)errmsg;
}
/*
@@ -4357,17 +4432,24 @@ static void check_redraw(uint32_t flags)
bool doclear = (flags & P_RCLR) == P_RCLR;
bool all = ((flags & P_RALL) == P_RALL || doclear);
- if ((flags & P_RSTAT) || all) /* mark all status lines dirty */
+ if ((flags & P_RSTAT) || all) { // mark all status lines dirty
status_redraw_all();
+ }
- if ((flags & P_RBUF) || (flags & P_RWIN) || all)
+ if ((flags & P_RBUF) || (flags & P_RWIN) || all) {
changed_window_setting();
- if (flags & P_RBUF)
+ }
+ if (flags & P_RBUF) {
redraw_curbuf_later(NOT_VALID);
- if (doclear)
+ }
+ if (flags & P_RWINONLY) {
+ redraw_later(NOT_VALID);
+ }
+ if (doclear) {
redraw_all_later(CLEAR);
- else if (all)
+ } else if (all) {
redraw_all_later(NOT_VALID);
+ }
}
/// Find index for named option
@@ -4376,39 +4458,36 @@ static void check_redraw(uint32_t flags)
/// @param[in] len Length of the option.
///
/// @return Index of the option or -1 if option was not found.
-int findoption_len(const char_u *const arg, const size_t len)
+int findoption_len(const char *const arg, const size_t len)
{
- char *s, *p;
+ const char *s;
+ const char *p;
static int quick_tab[27] = { 0, 0 }; // quick access table
- int is_term_opt;
- /*
- * For first call: Initialize the quick-access table.
- * It contains the index for the first option that starts with a certain
- * letter. There are 26 letters, plus the first "t_" option.
- */
+ // For first call: Initialize the quick-access table.
+ // It contains the index for the first option that starts with a certain
+ // letter. There are 26 letters, plus the first "t_" option.
if (quick_tab[1] == 0) {
p = options[0].fullname;
for (short int i = 1; (s = options[i].fullname) != NULL; i++) {
if (s[0] != p[0]) {
- if (s[0] == 't' && s[1] == '_')
+ if (s[0] == 't' && s[1] == '_') {
quick_tab[26] = i;
- else
+ } else {
quick_tab[CharOrdLow(s[0])] = i;
+ }
}
p = s;
}
}
- /*
- * Check for name starting with an illegal character.
- */
+ // Check for name starting with an illegal character.
if (len == 0 || arg[0] < 'a' || arg[0] > 'z') {
return -1;
}
int opt_idx;
- is_term_opt = (len > 2 && arg[0] == 't' && arg[1] == '_');
+ const bool is_term_opt = (len > 2 && arg[0] == 't' && arg[1] == '_');
if (is_term_opt) {
opt_idx = quick_tab[26];
} else {
@@ -4416,7 +4495,7 @@ int findoption_len(const char_u *const arg, const size_t len)
}
// Match full name
for (; (s = options[opt_idx].fullname) != NULL; opt_idx++) {
- if (STRNCMP(arg, s, len) == 0 && s[len] == NUL) {
+ if (strncmp(arg, s, len) == 0 && s[len] == NUL) {
break;
}
}
@@ -4425,20 +4504,22 @@ int findoption_len(const char_u *const arg, const size_t len)
// Match short name
for (; options[opt_idx].fullname != NULL; opt_idx++) {
s = options[opt_idx].shortname;
- if (s != NULL && STRNCMP(arg, s, len) == 0 && s[len] == NUL) {
+ if (s != NULL && strncmp(arg, s, len) == 0 && s[len] == NUL) {
break;
}
s = NULL;
}
}
- if (s == NULL)
+ if (s == NULL) {
opt_idx = -1;
+ }
return opt_idx;
}
-bool is_tty_option(char *name)
+bool is_tty_option(const char *name)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- return (name[0] == 't' && name[1] == '_') || !strcmp((char *)name, "term");
+ return (name[0] == 't' && name[1] == '_') || strcmp(name, "term") == 0;
}
#define TCO_BUFFER_SIZE 8
@@ -4474,7 +4555,7 @@ bool get_tty_option(char *name, char **value)
return false;
}
-bool set_tty_option(char *name, char *value)
+bool set_tty_option(const char *name, const char *value)
{
if (!strcmp(name, "t_Co")) {
int colors = atoi(value);
@@ -4485,23 +4566,24 @@ bool set_tty_option(char *name, char *value)
if (colors != t_colors) {
t_colors = colors;
// We now have a different color setup, initialize it again.
- init_highlight(TRUE, FALSE);
+ init_highlight(true, false);
}
return true;
}
- return is_tty_option(name) || !strcmp(name, "term")
- || !strcmp(name, "ttytype");
+ return (is_tty_option(name) || !strcmp(name, "term")
+ || !strcmp(name, "ttytype"));
}
-/*
- * Find index for option 'arg'.
- * Return -1 if not found.
- */
-static int findoption(char_u *arg)
+/// Find index for an option
+///
+/// @param[in] arg Option name.
+///
+/// @return Option index or -1 if option was not found.
+static int findoption(const char *const arg)
{
- return findoption_len(arg, STRLEN(arg));
+ return findoption_len(arg, strlen(arg));
}
/*
@@ -4529,9 +4611,10 @@ get_option_value (
int opt_idx;
char_u *varp;
- opt_idx = findoption(name);
- if (opt_idx < 0) /* unknown option */
+ opt_idx = findoption((const char *)name);
+ if (opt_idx < 0) { // Unknown option.
return -3;
+ }
varp = get_varp_scope(&(options[opt_idx]), opt_flags);
@@ -4554,7 +4637,7 @@ get_option_value (
if ((int *)varp == &curbuf->b_changed) {
*numval = curbufIsChanged();
} else {
- *numval = *(int *)varp;
+ *numval = (long) *(int *)varp; // NOLINT(whitespace/cast)
}
}
return 1;
@@ -4568,7 +4651,7 @@ get_option_value (
//
// Pretends that option is absent if it is not present in the requested scope
// (i.e. has no global, window-local or buffer-local value depending on
-// opt_type). Uses
+// opt_type).
//
// Returned flags:
// 0 hidden or unknown option, also option that does not have requested
@@ -4587,14 +4670,13 @@ int get_option_value_strict(char *name,
}
char_u *varp = NULL;
- vimoption_T *p;
int rv = 0;
- int opt_idx = findoption((uint8_t *)name);
+ int opt_idx = findoption(name);
if (opt_idx < 0) {
return 0;
}
- p = &(options[opt_idx]);
+ vimoption_T *p = &options[opt_idx];
// Hidden option
if (p->var == NULL) {
@@ -4610,26 +4692,25 @@ int get_option_value_strict(char *name,
}
if (p->indir == PV_NONE) {
- if (opt_type == SREQ_GLOBAL)
+ if (opt_type == SREQ_GLOBAL) {
rv |= SOPT_GLOBAL;
- else
- return 0; // Did not request global-only option
+ } else {
+ return 0; // Did not request global-only option
+ }
} else {
if (p->indir & PV_BOTH) {
rv |= SOPT_GLOBAL;
- } else if (opt_type == SREQ_GLOBAL) {
- return 0; // Requested global option
}
if (p->indir & PV_WIN) {
if (opt_type == SREQ_BUF) {
- return 0; // Did not request window-local option
+ return 0; // Requested buffer-local, not window-local option
} else {
rv |= SOPT_WIN;
}
} else if (p->indir & PV_BUF) {
if (opt_type == SREQ_WIN) {
- return 0; // Did not request buffer-local option
+ return 0; // Requested window-local, not buffer-local option
} else {
rv |= SOPT_BUF;
}
@@ -4641,7 +4722,11 @@ int get_option_value_strict(char *name,
}
if (opt_type == SREQ_GLOBAL) {
- varp = p->var;
+ if (p->var == VAR_WIN) {
+ return 0;
+ } else {
+ varp = p->var;
+ }
} else {
if (opt_type == SREQ_BUF) {
// Special case: 'modified' is b_changed, but we also want to
@@ -4683,21 +4768,19 @@ int get_option_value_strict(char *name,
return rv;
}
-/*
- * Set the value of option "name".
- * Use "string" for string options, use "number" for other options.
- *
- * Returns NULL on success or error message on error.
- */
-char_u *
-set_option_value (
- char_u *name,
- long number,
- char_u *string,
- int opt_flags /* OPT_LOCAL or 0 (both) */
-)
+/// Set the value of an option
+///
+/// @param[in] name Option name.
+/// @param[in] number New value for the number or boolean option.
+/// @param[in] string New value for string option.
+/// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both).
+///
+/// @return NULL on success, error message on error.
+char *set_option_value(const char *const name, const long number,
+ const char *const string, const int opt_flags)
+ FUNC_ATTR_NONNULL_ARG(1)
{
- if (set_tty_option((char *)name, (char *)string)) {
+ if (set_tty_option(name, string)) {
return NULL;
}
@@ -4705,9 +4788,9 @@ set_option_value (
char_u *varp;
opt_idx = findoption(name);
- if (opt_idx < 0)
+ if (opt_idx < 0) {
EMSG2(_("E355: Unknown option: %s"), name);
- else {
+ } else {
uint32_t flags = options[opt_idx].flags;
// Disallow changing some options in the sandbox
if (sandbox > 0 && (flags & P_SECURE)) {
@@ -4715,11 +4798,11 @@ set_option_value (
return NULL;
}
if (flags & P_STRING) {
- const char *s = (const char *)string;
+ const char *s = string;
if (s == NULL) {
s = "";
}
- return (char_u *)set_string_option(opt_idx, s, opt_flags);
+ return set_string_option(opt_idx, s, opt_flags);
} else {
varp = get_varp_scope(&(options[opt_idx]), opt_flags);
if (varp != NULL) { /* hidden option is not changed */
@@ -4738,28 +4821,17 @@ set_option_value (
return NULL; // do nothing as we hit an error
}
}
- if (flags & P_NUM)
- return set_num_option(opt_idx, varp, number,
- NULL, 0, opt_flags);
- else
- return set_bool_option(opt_idx, varp, (int)number,
- opt_flags);
+ if (flags & P_NUM) {
+ return set_num_option(opt_idx, varp, number, NULL, 0, opt_flags);
+ } else {
+ return set_bool_option(opt_idx, varp, (int)number, opt_flags);
+ }
}
}
}
return NULL;
}
-char_u *get_highlight_default(void)
-{
- int i;
-
- i = findoption((char_u *)"hl");
- if (i >= 0)
- return options[i].def_val[VI_DEFAULT];
- return (char_u *)NULL;
-}
-
/*
* Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number.
*/
@@ -4775,7 +4847,7 @@ int find_key_option_len(const char_u *arg, size_t len)
} else {
arg--; // put arg at the '<'
modifiers = 0;
- key = find_special_key(&arg, len + 1, &modifiers, true, true);
+ key = find_special_key(&arg, len + 1, &modifiers, true, true, false);
if (modifiers) { // can't handle modifiers here
key = 0;
}
@@ -5101,9 +5173,13 @@ static int put_setstring(FILE *fd, char *cmd, char *name, char_u **valuep, int e
* CTRL-V or backslash */
if (valuep == &p_pt) {
s = *valuep;
- while (*s != NUL)
- if (put_escstr(fd, str2special(&s, FALSE), 2) == FAIL)
+ while (*s != NUL) {
+ if (put_escstr(fd, (char_u *)str2special((const char **)&s, false,
+ false), 2)
+ == FAIL) {
return FAIL;
+ }
+ }
} else if (expand) {
buf = xmalloc(MAXPATHL);
home_replace(NULL, *valuep, buf, MAXPATHL, FALSE);
@@ -5158,7 +5234,7 @@ static int put_setbool(FILE *fd, char *cmd, char *name, int value)
void comp_col(void)
{
- int last_has_status = (p_ls == 2 || (p_ls == 1 && firstwin != lastwin));
+ int last_has_status = (p_ls == 2 || (p_ls == 1 && !ONE_WINDOW));
sc_col = 0;
ru_col = 0;
@@ -5193,7 +5269,7 @@ void unset_global_local_option(char *name, void *from)
vimoption_T *p;
buf_T *buf = (buf_T *)from;
- int opt_idx = findoption((uint8_t *)name);
+ int opt_idx = findoption(name);
if (opt_idx < 0) {
EMSG2(_("E355: Unknown option: %s"), name);
return;
@@ -5238,6 +5314,9 @@ void unset_global_local_option(char *name, void *from)
case PV_TSR:
clear_string_option(&buf->b_p_tsr);
break;
+ case PV_FP:
+ clear_string_option(&buf->b_p_fp);
+ break;
case PV_EFM:
clear_string_option(&buf->b_p_efm);
break;
@@ -5271,6 +5350,7 @@ static char_u *get_varp_scope(vimoption_T *p, int opt_flags)
}
if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH)) {
switch ((int)p->indir) {
+ case PV_FP: return (char_u *)&(curbuf->b_p_fp);
case PV_EFM: return (char_u *)&(curbuf->b_p_efm);
case PV_GP: return (char_u *)&(curbuf->b_p_gp);
case PV_MP: return (char_u *)&(curbuf->b_p_mp);
@@ -5329,6 +5409,8 @@ static char_u *get_varp(vimoption_T *p)
? (char_u *)&(curbuf->b_p_dict) : p->var;
case PV_TSR: return *curbuf->b_p_tsr != NUL
? (char_u *)&(curbuf->b_p_tsr) : p->var;
+ case PV_FP: return *curbuf->b_p_fp != NUL
+ ? (char_u *)&(curbuf->b_p_fp) : p->var;
case PV_EFM: return *curbuf->b_p_efm != NUL
? (char_u *)&(curbuf->b_p_efm) : p->var;
case PV_GP: return *curbuf->b_p_gp != NUL
@@ -5418,6 +5500,7 @@ static char_u *get_varp(vimoption_T *p)
case PV_PI: return (char_u *)&(curbuf->b_p_pi);
case PV_QE: return (char_u *)&(curbuf->b_p_qe);
case PV_RO: return (char_u *)&(curbuf->b_p_ro);
+ case PV_SCBK: return (char_u *)&(curbuf->b_p_scbk);
case PV_SI: return (char_u *)&(curbuf->b_p_si);
case PV_STS: return (char_u *)&(curbuf->b_p_sts);
case PV_SUA: return (char_u *)&(curbuf->b_p_sua);
@@ -5434,6 +5517,7 @@ static char_u *get_varp(vimoption_T *p)
case PV_WM: return (char_u *)&(curbuf->b_p_wm);
case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap);
case PV_SCL: return (char_u *)&(curwin->w_p_scl);
+ case PV_WINHL: return (char_u *)&(curwin->w_p_winhl);
default: EMSG(_("E356: get_varp ERROR"));
}
/* always return a valid pointer to avoid a crash! */
@@ -5460,7 +5544,6 @@ void win_copy_options(win_T *wp_from, win_T *wp_to)
copy_winopt(&wp_from->w_allbuf_opt, &wp_to->w_allbuf_opt);
/* Is this right? */
wp_to->w_farsi = wp_from->w_farsi;
- briopt_check(wp_to);
}
/*
@@ -5512,6 +5595,7 @@ void copy_winopt(winopt_T *from, winopt_T *to)
to->wo_fdt = vim_strsave(from->wo_fdt);
to->wo_fmr = vim_strsave(from->wo_fmr);
to->wo_scl = vim_strsave(from->wo_scl);
+ to->wo_winhl = vim_strsave(from->wo_winhl);
check_winopt(to); // don't want NULL pointers
}
@@ -5541,6 +5625,7 @@ static void check_winopt(winopt_T *wop)
check_string_option(&wop->wo_cc);
check_string_option(&wop->wo_cocu);
check_string_option(&wop->wo_briopt);
+ check_string_option(&wop->wo_winhl);
}
/*
@@ -5560,8 +5645,17 @@ void clear_winopt(winopt_T *wop)
clear_string_option(&wop->wo_cc);
clear_string_option(&wop->wo_cocu);
clear_string_option(&wop->wo_briopt);
+ clear_string_option(&wop->wo_winhl);
}
+void didset_window_options(win_T *wp)
+{
+ check_colorcolumn(wp);
+ briopt_check(wp);
+ parse_winhl_opt(wp);
+}
+
+
/*
* Copy global option values to local options for one buffer.
* Used when creating a new buffer and sometimes when entering a buffer.
@@ -5579,12 +5673,6 @@ void buf_copy_options(buf_T *buf, int flags)
int did_isk = FALSE;
/*
- * Don't do anything if the buffer is invalid.
- */
- if (buf == NULL || !buf_valid(buf))
- return;
-
- /*
* Skip this when the option defaults have not been set yet. Happens when
* main() allocates the first buffer.
*/
@@ -5625,7 +5713,22 @@ void buf_copy_options(buf_T *buf, int flags)
free_buf_options(buf, TRUE);
buf->b_p_ro = FALSE; /* don't copy readonly */
buf->b_p_fenc = vim_strsave(p_fenc);
- buf->b_p_ff = vim_strsave(p_ff);
+ switch (*p_ffs) {
+ case 'm':
+ buf->b_p_ff = vim_strsave((char_u *)FF_MAC);
+ break;
+ case 'd':
+ buf->b_p_ff = vim_strsave((char_u *)FF_DOS);
+ break;
+ case 'u':
+ buf->b_p_ff = vim_strsave((char_u *)FF_UNIX);
+ break;
+ default:
+ buf->b_p_ff = vim_strsave(p_ff);
+ }
+ if (buf->b_p_ff != NULL) {
+ buf->b_start_ffc = *buf->b_p_ff;
+ }
buf->b_p_bh = empty_option;
buf->b_p_bt = empty_option;
} else
@@ -5634,6 +5737,7 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_p_ai = p_ai;
buf->b_p_ai_nopaste = p_ai_nopaste;
buf->b_p_sw = p_sw;
+ buf->b_p_scbk = -1;
buf->b_p_tw = p_tw;
buf->b_p_tw_nopaste = p_tw_nopaste;
buf->b_p_tw_nobin = p_tw_nobin;
@@ -5681,6 +5785,7 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_s.b_p_spl = vim_strsave(p_spl);
buf->b_p_inde = vim_strsave(p_inde);
buf->b_p_indk = vim_strsave(p_indk);
+ buf->b_p_fp = empty_option;
buf->b_p_fex = vim_strsave(p_fex);
buf->b_p_sua = vim_strsave(p_sua);
buf->b_p_keymap = vim_strsave(p_keymap);
@@ -5753,11 +5858,12 @@ void reset_modifiable(void)
{
int opt_idx;
- curbuf->b_p_ma = FALSE;
- p_ma = FALSE;
- opt_idx = findoption((char_u *)"ma");
- if (opt_idx >= 0)
- options[opt_idx].def_val[VI_DEFAULT] = FALSE;
+ curbuf->b_p_ma = false;
+ p_ma = false;
+ opt_idx = findoption("ma");
+ if (opt_idx >= 0) {
+ options[opt_idx].def_val[VI_DEFAULT] = false;
+ }
}
/*
@@ -5855,15 +5961,15 @@ set_context_in_set_cmd (
expand_option_name[2] = p[-2];
expand_option_name[3] = p[-1];
} else {
- /* Allow * wildcard */
- while (ASCII_ISALNUM(*p) || *p == '_' || *p == '*')
+ // Allow * wildcard.
+ while (ASCII_ISALNUM(*p) || *p == '_' || *p == '*') {
p++;
- if (*p == NUL)
+ }
+ if (*p == NUL) {
return;
+ }
nextchar = *p;
- *p = NUL;
- opt_idx = findoption(arg);
- *p = nextchar;
+ opt_idx = findoption_len((const char *)arg, (size_t)(p - arg));
if (opt_idx == -1 || options[opt_idx].var == NULL) {
xp->xp_context = EXPAND_NOTHING;
return;
@@ -5960,8 +6066,8 @@ int ExpandSettings(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***
int count = 0;
char_u *str;
int loop;
- static char *(names[]) = {"all", "termcap"};
- int ic = regmatch->rm_ic; /* remember the ignore-case flag */
+ static char *(names[]) = { "all" };
+ int ic = regmatch->rm_ic; // remember the ignore-case flag
/* do this loop twice:
* loop == 0: count the number of matching options
@@ -6025,7 +6131,7 @@ void ExpandOldSetting(int *num_file, char_u ***file)
* For a terminal key code expand_option_idx is < 0.
*/
if (expand_option_idx < 0) {
- expand_option_idx = findoption(expand_option_name);
+ expand_option_idx = findoption((const char *)expand_option_name);
}
if (expand_option_idx >= 0) {
@@ -6084,15 +6190,16 @@ option_value2string (
}
} else { // P_STRING
varp = *(char_u **)(varp);
- if (varp == NULL) /* just in case */
+ if (varp == NULL) { // Just in case.
NameBuff[0] = NUL;
- else if (opp->flags & P_EXPAND)
- home_replace(NULL, varp, NameBuff, MAXPATHL, FALSE);
- /* Translate 'pastetoggle' into special key names */
- else if ((char_u **)opp->var == &p_pt)
- str2specialbuf(p_pt, NameBuff, MAXPATHL);
- else
+ } else if (opp->flags & P_EXPAND) {
+ home_replace(NULL, varp, NameBuff, MAXPATHL, false);
+ // Translate 'pastetoggle' into special key names.
+ } else if ((char_u **)opp->var == &p_pt) {
+ str2specialbuf((const char *)p_pt, (char *)NameBuff, MAXPATHL);
+ } else {
STRLCPY(NameBuff, varp, MAXPATHL);
+ }
}
}
@@ -6425,20 +6532,22 @@ void vimrc_found(char_u *fname, char_u *envname)
}
}
-/*
- * Return TRUE when option "name" has been set.
- * Only works correctly for global options.
- */
-int option_was_set(char_u *name)
+/// Check whether global option has been set
+///
+/// @param[in] name Option name.
+///
+/// @return True if it was set.
+static bool option_was_set(const char *name)
{
int idx;
idx = findoption(name);
- if (idx < 0) /* unknown option */
- return FALSE;
- if (options[idx].flags & P_WAS_SET)
- return TRUE;
- return FALSE;
+ if (idx < 0) { // Unknown option.
+ return false;
+ } else if (options[idx].flags & P_WAS_SET) {
+ return true;
+ }
+ return false;
}
/*
@@ -6854,8 +6963,8 @@ void set_fileformat(int eol_style, int opt_flags)
need_maketitle = true; // Set window title later.
}
-/// Skip to next part of an option argument: Skip space and comma.
-char_u *skip_to_option_part(char_u *p)
+/// Skip to next part of an option argument: skip space and comma
+char_u *skip_to_option_part(const char_u *p)
{
if (*p == ',') {
p++;
@@ -6863,7 +6972,7 @@ char_u *skip_to_option_part(char_u *p)
while (*p == ' ') {
p++;
}
- return p;
+ return (char_u *)p;
}
/// Isolate one part of a string option separated by `sep_chars`.
@@ -6923,10 +7032,11 @@ bool signcolumn_on(win_T *wp)
return wp->w_buffer->b_signlist != NULL;
}
-/// Get window or buffer local options.
-dict_T * get_winbuf_options(int bufopt)
+/// Get window or buffer local options
+dict_T *get_winbuf_options(const int bufopt)
+ FUNC_ATTR_WARN_UNUSED_RESULT
{
- dict_T *d = dict_alloc();
+ dict_T *const d = tv_dict_alloc();
for (int opt_idx = 0; options[opt_idx].fullname; opt_idx++) {
struct vimoption *opt = &options[opt_idx];
@@ -6937,9 +7047,13 @@ dict_T * get_winbuf_options(int bufopt)
if (varp != NULL) {
if (opt->flags & P_STRING) {
- dict_add_nr_str(d, opt->fullname, 0L, *(char_u **)varp);
+ tv_dict_add_str(d, opt->fullname, strlen(opt->fullname),
+ *(const char **)varp);
+ } else if (opt->flags & P_NUM) {
+ tv_dict_add_nr(d, opt->fullname, strlen(opt->fullname),
+ *(long *)varp);
} else {
- dict_add_nr_str(d, opt->fullname, *varp, NULL);
+ tv_dict_add_nr(d, opt->fullname, strlen(opt->fullname), *(int *)varp);
}
}
}
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index 32021da922..a2fe90b3c2 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -16,9 +16,9 @@
#define SOPT_UNSET 0x40 // Option does not have local value set
// Option types for various functions in option.c
-#define SREQ_GLOBAL 0 // Request global option
-#define SREQ_WIN 1 // Request window-local option
-#define SREQ_BUF 2 // Request buffer-local option
+#define SREQ_GLOBAL 0 // Request global option value
+#define SREQ_WIN 1 // Request window-local option value
+#define SREQ_BUF 2 // Request buffer-local option value
/*
* Default values for 'errorformat'.
@@ -81,57 +81,56 @@
#define DFLT_FO_VIM "tcqj"
#define FO_ALL "tcroq2vlb1mMBn,awj" /* for do_set() */
-/* characters for the p_cpo option: */
-#define CPO_ALTREAD 'a' /* ":read" sets alternate file name */
-#define CPO_ALTWRITE 'A' /* ":write" sets alternate file name */
-#define CPO_BAR 'b' /* "\|" ends a mapping */
-#define CPO_BSLASH 'B' /* backslash in mapping is not special */
+// characters for the p_cpo option:
+#define CPO_ALTREAD 'a' // ":read" sets alternate file name
+#define CPO_ALTWRITE 'A' // ":write" sets alternate file name
+#define CPO_BAR 'b' // "\|" ends a mapping
+#define CPO_BSLASH 'B' // backslash in mapping is not special
#define CPO_SEARCH 'c'
-#define CPO_CONCAT 'C' /* Don't concatenate sourced lines */
-#define CPO_DOTTAG 'd' /* "./tags" in 'tags' is in current dir */
-#define CPO_DIGRAPH 'D' /* No digraph after "r", "f", etc. */
+#define CPO_CONCAT 'C' // Don't concatenate sourced lines
+#define CPO_DOTTAG 'd' // "./tags" in 'tags' is in current dir
+#define CPO_DIGRAPH 'D' // No digraph after "r", "f", etc.
#define CPO_EXECBUF 'e'
-#define CPO_EMPTYREGION 'E' /* operating on empty region is an error */
-#define CPO_FNAMER 'f' /* set file name for ":r file" */
-#define CPO_FNAMEW 'F' /* set file name for ":w file" */
-#define CPO_INTMOD 'i' /* interrupt a read makes buffer modified */
-#define CPO_INDENT 'I' /* remove auto-indent more often */
-#define CPO_ENDOFSENT 'J' /* need two spaces to detect end of sentence */
-#define CPO_KEYCODE 'k' /* don't recognize raw key code in mappings */
-#define CPO_KOFFSET 'K' /* don't wait for key code in mappings */
-#define CPO_LITERAL 'l' /* take char after backslash in [] literal */
-#define CPO_LISTWM 'L' /* 'list' changes wrapmargin */
+#define CPO_EMPTYREGION 'E' // operating on empty region is an error
+#define CPO_FNAMER 'f' // set file name for ":r file"
+#define CPO_FNAMEW 'F' // set file name for ":w file"
+#define CPO_INTMOD 'i' // interrupt a read makes buffer modified
+#define CPO_INDENT 'I' // remove auto-indent more often
+#define CPO_ENDOFSENT 'J' // need two spaces to detect end of sentence
+#define CPO_KOFFSET 'K' // don't wait for key code in mappings
+#define CPO_LITERAL 'l' // take char after backslash in [] literal
+#define CPO_LISTWM 'L' // 'list' changes wrapmargin
#define CPO_SHOWMATCH 'm'
-#define CPO_MATCHBSL 'M' /* "%" ignores use of backslashes */
-#define CPO_NUMCOL 'n' /* 'number' column also used for text */
+#define CPO_MATCHBSL 'M' // "%" ignores use of backslashes
+#define CPO_NUMCOL 'n' // 'number' column also used for text
#define CPO_LINEOFF 'o'
-#define CPO_OVERNEW 'O' /* silently overwrite new file */
-#define CPO_LISP 'p' /* 'lisp' indenting */
-#define CPO_FNAMEAPP 'P' /* set file name for ":w >>file" */
-#define CPO_JOINCOL 'q' /* with "3J" use column after first join */
+#define CPO_OVERNEW 'O' // silently overwrite new file
+#define CPO_LISP 'p' // 'lisp' indenting
+#define CPO_FNAMEAPP 'P' // set file name for ":w >>file"
+#define CPO_JOINCOL 'q' // with "3J" use column after first join
#define CPO_REDO 'r'
-#define CPO_REMMARK 'R' /* remove marks when filtering */
+#define CPO_REMMARK 'R' // remove marks when filtering
#define CPO_BUFOPT 's'
#define CPO_BUFOPTGLOB 'S'
#define CPO_TAGPAT 't'
-#define CPO_UNDO 'u' /* "u" undoes itself */
-#define CPO_BACKSPACE 'v' /* "v" keep deleted text */
-#define CPO_FWRITE 'W' /* "w!" doesn't overwrite readonly files */
+#define CPO_UNDO 'u' // "u" undoes itself
+#define CPO_BACKSPACE 'v' // "v" keep deleted text
+#define CPO_FWRITE 'W' // "w!" doesn't overwrite readonly files
#define CPO_ESC 'x'
-#define CPO_REPLCNT 'X' /* "R" with a count only deletes chars once */
+#define CPO_REPLCNT 'X' // "R" with a count only deletes chars once
#define CPO_YANK 'y'
-#define CPO_KEEPRO 'Z' /* don't reset 'readonly' on ":w!" */
+#define CPO_KEEPRO 'Z' // don't reset 'readonly' on ":w!"
#define CPO_DOLLAR '$'
#define CPO_FILTER '!'
#define CPO_MATCH '%'
-#define CPO_PLUS '+' /* ":write file" resets 'modified' */
-#define CPO_SPECI '<' /* don't recognize <> in mappings */
-#define CPO_REGAPPEND '>' /* insert NL when appending to a register */
-#define CPO_SCOLON ';' /* using "," and ";" will skip over char if
- * cursor would not move */
-/* default values for Vim and Vi */
-#define CPO_VIM "aABceFs"
-#define CPO_VI "aAbBcCdDeEfFiIJkKlLmMnoOpPqrRsStuvWxXyZ$!%+<>;"
+#define CPO_PLUS '+' // ":write file" resets 'modified'
+#define CPO_REGAPPEND '>' // insert NL when appending to a register
+#define CPO_SCOLON ';' // using "," and ";" will skip over char if
+ // cursor would not move
+#define CPO_CHANGEW '_' // "cw" special-case
+// default values for Vim and Vi
+#define CPO_VIM "aABceFs_"
+#define CPO_VI "aAbBcCdDeEfFiIJKlLmMnoOpPqrRsStuvWxXyZ$!%+>;_"
/* characters for p_ww option: */
#define WW_ALL "bshl<>[],~"
@@ -411,7 +410,6 @@ 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'
@@ -476,8 +474,9 @@ EXTERN char_u *p_isp; // 'isprint'
EXTERN int p_js; // 'joinspaces'
EXTERN char_u *p_kp; // 'keywordprg'
EXTERN char_u *p_km; // 'keymodel'
-EXTERN char_u *p_langmap; // 'langmap'*/
-EXTERN int p_lnr; // 'langnoremap'*/
+EXTERN char_u *p_langmap; // 'langmap'
+EXTERN int p_lnr; // 'langnoremap'
+EXTERN int p_lrm; // 'langremap'
EXTERN char_u *p_lm; // 'langmenu'
EXTERN char_u *p_lispwords; // 'lispwords'
EXTERN long p_ls; // 'laststatus'
@@ -524,6 +523,7 @@ EXTERN int p_ru; // 'ruler'
EXTERN char_u *p_ruf; // 'rulerformat'
EXTERN char_u *p_pp; // 'packpath'
EXTERN char_u *p_rtp; // 'runtimepath'
+EXTERN long p_scbk; // 'scrollback'
EXTERN long p_sj; // 'scrolljump'
EXTERN long p_so; // 'scrolloff'
EXTERN char_u *p_sbo; // 'scrollopt'
@@ -602,11 +602,14 @@ EXTERN int p_tbs; ///< 'tagbsearch'
EXTERN char_u *p_tc; ///< 'tagcase'
EXTERN unsigned tc_flags; ///< flags from 'tagcase'
#ifdef IN_OPTION_C
-static char *(p_tc_values[]) = { "followic", "ignore", "match", NULL };
+static char *(p_tc_values[]) =
+ { "followic", "ignore", "match", "followscs", "smart", NULL };
#endif
#define TC_FOLLOWIC 0x01
#define TC_IGNORE 0x02
#define TC_MATCH 0x04
+#define TC_FOLLOWSCS 0x08
+#define TC_SMART 0x10
EXTERN long p_tl; ///< 'taglength'
EXTERN int p_tr; ///< 'tagrelative'
EXTERN char_u *p_tags; ///< 'tags'
@@ -710,6 +713,7 @@ enum {
, BV_EP
, BV_ET
, BV_FENC
+ , BV_FP
, BV_BEXPR
, BV_FEX
, BV_FF
@@ -737,6 +741,7 @@ enum {
, BV_PI
, BV_QE
, BV_RO
+ , BV_SCBK
, BV_SI
, BV_SMC
, BV_SYN
@@ -800,10 +805,13 @@ enum {
, WV_WFW
, WV_WRAP
, WV_SCL
+ , WV_WINHL
, WV_COUNT // must be the last one
};
/* Value for b_p_ul indicating the global value must be used. */
#define NO_LOCAL_UNDOLEVEL -123456
+#define SB_MAX 100000 // Maximum 'scrollback' value.
+
#endif // NVIM_OPTION_DEFS_H
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index 70d1f73cf4..103227f6b5 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -17,8 +17,8 @@
-- types: bool, number, string
-- lists: (nil), comma, onecomma, flags, flagscomma
-- scopes: global, buffer, window
--- redraw options: statuslines, current_window, current_buffer, all_windows,
--- everything, curswant
+-- redraw options: statuslines, current_window, curent_window_only,
+-- current_buffer, all_windows, everything, curswant
-- default: {vi=…[, vim=…]}
-- defaults: {condition=#if condition, if_true=default, if_false=default}
-- #if condition:
@@ -34,6 +34,11 @@ local macros=function(s)
return s
end
end
+local imacros=function(s)
+ return function()
+ return '(intptr_t)' .. s
+ end
+end
local N_=function(s)
return function()
return 'N_(' .. cstr(s) .. ')'
@@ -190,7 +195,7 @@ return {
type='string', list='comma', scope={'global'},
vi_def=true,
varname='p_bo',
- defaults={if_true={vi=""}}
+ defaults={if_true={vi="all"}}
},
{
full_name='binary', abbreviation='bin',
@@ -539,7 +544,7 @@ return {
full_name='cursorline', abbreviation='cul',
type='bool', scope={'window'},
vi_def=true,
- redraw={'current_window'},
+ redraw={'current_window_only'},
defaults={if_true={vi=false}}
},
{
@@ -711,13 +716,6 @@ return {
defaults={if_true={vi=macros('DFLT_EFM')}}
},
{
- full_name='esckeys', abbreviation='ek',
- type='bool', scope={'global'},
- vim=true,
- varname='p_ek',
- defaults={if_true={vi=false, vim=true}}
- },
- {
full_name='eventignore', abbreviation='ei',
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
@@ -955,7 +953,7 @@ return {
},
{
full_name='formatprg', abbreviation='fp',
- type='string', scope={'global'},
+ type='string', scope={'global', 'buffer'},
secure=true,
vi_def=true,
expand=true,
@@ -1007,7 +1005,7 @@ return {
deny_duplicates=true,
vi_def=true,
varname='p_guicursor',
- defaults={if_true={vi="n-v-c:block,o:hor50,i-ci:hor15,r-cr:hor30,sm:block"}}
+ defaults={if_true={vi="n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20"}}
},
{
full_name='guifont', abbreviation='gfn',
@@ -1033,13 +1031,6 @@ return {
enable_if=false,
},
{
- full_name='guiheadroom', abbreviation='ghr',
- type='number', scope={'global'},
- vi_def=true,
- enable_if=false,
- defaults={if_true={vi=50}}
- },
- {
full_name='guioptions', abbreviation='go',
type='string', list='flags', scope={'global'},
vi_def=true,
@@ -1354,6 +1345,12 @@ return {
defaults={if_true={vi=false, vim=true}}
},
{
+ full_name='langremap', abbreviation='lrm',
+ type='bool', scope={'global'},
+ varname='p_lrm',
+ defaults={if_true={vi=true, vim=false}}
+ },
+ {
full_name='laststatus', abbreviation='ls',
type='number', scope={'global'},
vim=true,
@@ -1572,7 +1569,7 @@ return {
full_name='mouse',
type='string', list='flags', scope={'global'},
varname='p_mouse',
- defaults={if_true={vi="", vim="a"}}
+ defaults={if_true={vi="", vim=""}}
},
{
full_name='mousefocus', abbreviation='mousef',
@@ -1890,7 +1887,7 @@ return {
vim=true,
redraw={'statuslines'},
varname='p_ru',
- defaults={if_true={vi=false}}
+ defaults={if_true={vi=true}}
},
{
full_name='rulerformat', abbreviation='ruf',
@@ -1920,6 +1917,14 @@ return {
defaults={if_true={vi=12}}
},
{
+ full_name='scrollback', abbreviation='scbk',
+ type='number', scope={'buffer'},
+ vi_def=true,
+ varname='p_scbk',
+ redraw={'current_buffer'},
+ defaults={if_true={vi=1000}}
+ },
+ {
full_name='scrollbind', abbreviation='scb',
type='bool', scope={'window'},
vi_def=true,
@@ -2051,7 +2056,11 @@ return {
secure=true,
vi_def=true,
varname='p_srr',
- defaults={if_true={vi=">"}}
+ defaults={
+ condition='WIN32',
+ if_true={vi=">%s 2>&1"},
+ if_false={vi=">"}
+ }
},
{
full_name='shellslash', abbreviation='ssl',
@@ -2118,11 +2127,7 @@ return {
type='bool', scope={'global'},
vim=true,
varname='p_sc',
- defaults={
- condition='UNIX',
- if_true={vi=false, vim=false},
- if_false={vi=false, vim=true},
- }
+ defaults={if_true={vi=false, vim=true}}
},
{
full_name='showfulltag', abbreviation='sft',
@@ -2508,14 +2513,14 @@ return {
vi_def=true,
vim=true,
varname='p_ttimeout',
- defaults={if_true={vi=false}}
+ defaults={if_true={vi=true}}
},
{
full_name='ttimeoutlen', abbreviation='ttm',
type='number', scope={'global'},
vi_def=true,
varname='p_ttm',
- defaults={if_true={vi=-1}}
+ defaults={if_true={vi=50}}
},
{
full_name='ttyfast', abbreviation='tf',
@@ -2648,7 +2653,7 @@ return {
type='number', scope={'global'},
vim=true,
varname='p_wc',
- defaults={if_true={vi=macros('Ctrl_E'), vim=macros('TAB')}}
+ defaults={if_true={vi=imacros('Ctrl_E'), vim=imacros('TAB')}}
},
{
full_name='wildcharm', abbreviation='wcm',
@@ -2702,6 +2707,14 @@ return {
defaults={if_true={vi="menu"}}
},
{
+ full_name='winhighlight', abbreviation='winhl',
+ type='string', scope={'window'},
+ vi_def=true,
+ alloced=true,
+ redraw={'current_window'},
+ defaults={if_true={vi=""}}
+ },
+ {
full_name='window', abbreviation='wi',
type='number', scope={'global'},
vi_def=true,
diff --git a/src/nvim/os/dl.c b/src/nvim/os/dl.c
index fef02cc784..267cf5ae4b 100644
--- a/src/nvim/os/dl.c
+++ b/src/nvim/os/dl.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// Functions for using external native libraries
#include <stdbool.h>
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
index 83a0262545..de0cd10d9c 100644
--- a/src/nvim/os/env.c
+++ b/src/nvim/os/env.c
@@ -1,14 +1,15 @@
-// env.c -- environment variable access
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-#include <assert.h>
+// Environment inspection
+#include <assert.h>
#include <uv.h>
-// vim.h must be included before charset.h (and possibly others) or things
-// blow up
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/charset.h"
+#include "nvim/fileio.h"
#include "nvim/os/os.h"
#include "nvim/memory.h"
#include "nvim/message.h"
@@ -18,6 +19,10 @@
#include "nvim/ex_getln.h"
#include "nvim/version.h"
+#ifdef WIN32
+#include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8
+#endif
+
#ifdef HAVE__NSGETENVIRON
#include <crt_externs.h>
#endif
@@ -45,7 +50,21 @@ bool os_env_exists(const char *name)
int os_setenv(const char *name, const char *value, int overwrite)
FUNC_ATTR_NONNULL_ALL
{
-#ifdef HAVE_SETENV
+#ifdef WIN32
+ size_t envbuflen = strlen(name) + strlen(value) + 2;
+ char *envbuf = xmalloc(envbuflen);
+ snprintf(envbuf, envbuflen, "%s=%s", name, value);
+
+ WCHAR *p;
+ utf8_to_utf16(envbuf, &p);
+ xfree(envbuf);
+ if (p == NULL) {
+ return -1;
+ }
+ _wputenv(p);
+ xfree(p); // Unlike Unix systems, we can free the string for _wputenv().
+ return 0;
+#elif defined(HAVE_SETENV)
return setenv(name, value, overwrite);
#elif defined(HAVE_PUTENV_S)
if (!overwrite && os_getenv(name) != NULL) {
@@ -99,7 +118,6 @@ char *os_getenvname_at_index(size_t index)
return name;
}
-
/// Get the process ID of the Neovim process.
///
/// @return the process ID.
@@ -112,11 +130,11 @@ int64_t os_get_pid(void)
#endif
}
-/// Get the hostname of the machine running Neovim.
+/// Gets the hostname of the current machine.
///
-/// @param hostname Buffer to store the hostname.
-/// @param len Length of `hostname`.
-void os_get_hostname(char *hostname, size_t len)
+/// @param hostname Buffer to store the hostname.
+/// @param size Size of `hostname`.
+void os_get_hostname(char *hostname, size_t size)
{
#ifdef HAVE_SYS_UTSNAME_H
struct utsname vutsname;
@@ -124,13 +142,29 @@ void os_get_hostname(char *hostname, size_t len)
if (uname(&vutsname) < 0) {
*hostname = '\0';
} else {
- strncpy(hostname, vutsname.nodename, len - 1);
- hostname[len - 1] = '\0';
+ xstrlcpy(hostname, vutsname.nodename, size);
+ }
+#elif defined(WIN32)
+ WCHAR host_utf16[MAX_COMPUTERNAME_LENGTH + 1];
+ DWORD host_wsize = sizeof(host_utf16) / sizeof(host_utf16[0]);
+ if (GetComputerNameW(host_utf16, &host_wsize) == 0) {
+ *hostname = '\0';
+ DWORD err = GetLastError();
+ EMSG2("GetComputerNameW failed: %d", err);
+ return;
+ }
+ host_utf16[host_wsize] = '\0';
+
+ char *host_utf8;
+ int conversion_result = utf16_to_utf8(host_utf16, &host_utf8);
+ if (conversion_result != 0) {
+ EMSG2("utf16_to_utf8 failed: %d", conversion_result);
+ return;
}
+ xstrlcpy(hostname, host_utf8, size);
+ xfree(host_utf8);
#else
- // TODO(unknown): Implement this for windows.
- // See the implementation used in vim:
- // https://code.google.com/p/vim/source/browse/src/os_win32.c?r=6b69d8dde19e32909f4ee3a6337e6a2ecfbb6f72#2899
+ EMSG("os_get_hostname failed: missing uname()");
*hostname = '\0';
#endif
}
@@ -146,11 +180,11 @@ static char_u *homedir = NULL;
void init_homedir(void)
{
- // In case we are called a second time (when 'encoding' changes).
+ // In case we are called a second time.
xfree(homedir);
homedir = NULL;
- char_u *var = (char_u *)os_getenv("HOME");
+ const char *var = os_getenv("HOME");
#ifdef WIN32
// Typically, $HOME is not defined on Windows, unless the user has
@@ -164,10 +198,10 @@ void init_homedir(void)
homepath = "\\";
}
if (homedrive != NULL && strlen(homedrive) + strlen(homepath) < MAXPATHL) {
- snprintf((char *)NameBuff, MAXPATHL, "%s%s", homedrive, homepath);
- if (NameBuff[0] != NUL) {
- var = NameBuff;
- vim_setenv("HOME", (char *)NameBuff);
+ snprintf(os_buf, MAXPATHL, "%s%s", homedrive, homepath);
+ if (os_buf[0] != NUL) {
+ var = os_buf;
+ vim_setenv("HOME", os_buf);
}
}
}
@@ -177,17 +211,16 @@ void init_homedir(void)
#ifdef UNIX
// Change to the directory and get the actual path. This resolves
// links. Don't do it when we can't return.
- if (os_dirname(NameBuff, MAXPATHL) == OK
- && os_chdir((char *)NameBuff) == 0) {
- if (!os_chdir((char *)var) && os_dirname(IObuff, IOSIZE) == OK) {
- var = IObuff;
+ if (os_dirname((char_u *)os_buf, MAXPATHL) == OK && os_chdir(os_buf) == 0) {
+ if (!os_chdir(var) && os_dirname(IObuff, IOSIZE) == OK) {
+ var = (char *)IObuff;
}
- if (os_chdir((char *)NameBuff) != 0) {
+ if (os_chdir(os_buf) != 0) {
EMSG(_(e_prev_dir));
}
}
#endif
- homedir = vim_strsave(var);
+ homedir = vim_strsave((char_u *)var);
}
}
@@ -226,25 +259,24 @@ char_u *expand_env_save_opt(char_u *src, bool one)
/// "~/" is also expanded, using $HOME. For Unix "~user/" is expanded.
/// Skips over "\ ", "\~" and "\$" (not for Win32 though).
/// If anything fails no expansion is done and dst equals src.
-/// @param src Input string e.g. "$HOME/vim.hlp"
-/// @param dst Where to put the result
-/// @param dstlen Maximum length of the result
+///
+/// @param src Input string e.g. "$HOME/vim.hlp"
+/// @param dst[out] Where to put the result
+/// @param dstlen Maximum length of the result
void expand_env(char_u *src, char_u *dst, int dstlen)
{
expand_env_esc(src, dst, dstlen, false, false, NULL);
}
/// Expand environment variable with path name and escaping.
-/// "~/" is also expanded, using $HOME. For Unix "~user/" is expanded.
-/// Skips over "\ ", "\~" and "\$" (not for Win32 though).
-/// If anything fails no expansion is done and dst equals src.
-/// prefix recognize the start of a new name, for '~' expansion.
-/// @param srcp Input string e.g. "$HOME/vim.hlp"
-/// @param dst Where to put the result
-/// @param dstlen Maximum length of the result
-/// @param esc Should we escape spaces in expanded variables?
-/// @param one Should we expand more than one '~'?
-/// @param prefix Common prefix for paths, can be NULL
+/// @see expand_env
+///
+/// @param srcp Input string e.g. "$HOME/vim.hlp"
+/// @param dst[out] Where to put the result
+/// @param dstlen Maximum length of the result
+/// @param esc Escape spaces in expanded variables
+/// @param one `srcp` is a single filename
+/// @param prefix Start again after this (can be NULL)
void expand_env_esc(char_u *restrict srcp,
char_u *restrict dst,
int dstlen,
@@ -489,10 +521,11 @@ static char *remove_tail(char *path, char *pend, char *dirname)
return pend;
}
-/// Iterate over colon-separated list
+/// Iterate over a delimited list.
///
/// @note Environment variables must not be modified during iteration.
///
+/// @param[in] delim Delimiter character.
/// @param[in] val Value of the environment variable to iterate over.
/// @param[in] iter Pointer used for iteration. Must be NULL on first
/// iteration.
@@ -501,18 +534,19 @@ static char *remove_tail(char *path, char *pend, char *dirname)
/// @param[out] len Location where current directory length should be saved.
///
/// @return Next iter argument value or NULL when iteration should stop.
-const void *vim_colon_env_iter(const char *const val,
- const void *const iter,
- const char **const dir,
- size_t *const len)
- FUNC_ATTR_NONNULL_ARG(1, 3, 4) FUNC_ATTR_WARN_UNUSED_RESULT
+const void *vim_env_iter(const char delim,
+ const char *const val,
+ const void *const iter,
+ const char **const dir,
+ size_t *const len)
+ FUNC_ATTR_NONNULL_ARG(2, 4, 5) FUNC_ATTR_WARN_UNUSED_RESULT
{
const char *varval = (const char *) iter;
if (varval == NULL) {
varval = val;
}
*dir = varval;
- const char *const dirend = strchr(varval, ':');
+ const char *const dirend = strchr(varval, delim);
if (dirend == NULL) {
*len = strlen(varval);
return NULL;
@@ -522,10 +556,11 @@ const void *vim_colon_env_iter(const char *const val,
}
}
-/// Iterate over colon-separated list in reverse order
+/// Iterate over a delimited list in reverse order.
///
/// @note Environment variables must not be modified during iteration.
///
+/// @param[in] delim Delimiter character.
/// @param[in] val Value of the environment variable to iterate over.
/// @param[in] iter Pointer used for iteration. Must be NULL on first
/// iteration.
@@ -534,18 +569,19 @@ const void *vim_colon_env_iter(const char *const val,
/// @param[out] len Location where current directory length should be saved.
///
/// @return Next iter argument value or NULL when iteration should stop.
-const void *vim_colon_env_iter_rev(const char *const val,
- const void *const iter,
- const char **const dir,
- size_t *const len)
- FUNC_ATTR_NONNULL_ARG(1, 3, 4) FUNC_ATTR_WARN_UNUSED_RESULT
+const void *vim_env_iter_rev(const char delim,
+ const char *const val,
+ const void *const iter,
+ const char **const dir,
+ size_t *const len)
+ FUNC_ATTR_NONNULL_ARG(2, 4, 5) FUNC_ATTR_WARN_UNUSED_RESULT
{
const char *varend = (const char *) iter;
if (varend == NULL) {
varend = val + strlen(val) - 1;
}
- const size_t varlen = (size_t) (varend - val) + 1;
- const char *const colon = xmemrchr(val, ':', varlen);
+ const size_t varlen = (size_t)(varend - val) + 1;
+ const char *const colon = xmemrchr(val, (uint8_t)delim, varlen);
if (colon == NULL) {
*len = varlen;
*dir = val;
@@ -560,10 +596,13 @@ const void *vim_colon_env_iter_rev(const char *const val,
/// Vim's version of getenv().
/// Special handling of $HOME, $VIM and $VIMRUNTIME, allowing the user to
/// override the vim runtime directory at runtime. Also does ACP to 'enc'
-/// conversion for Win32. Results must be freed by the calling function.
-/// @param name Name of environment variable to expand
+/// conversion for Win32. Result must be freed by the caller.
+/// @param name Environment variable to expand
char *vim_getenv(const char *name)
{
+ // init_path() should have been called before now.
+ assert(get_vim_var_str(VV_PROGPATH)[0] != NUL);
+
const char *kos_env_path = os_getenv(name);
if (kos_env_path != NULL) {
return xstrdup(kos_env_path);
@@ -598,6 +637,24 @@ char *vim_getenv(const char *name)
if (p_hf != NULL && vim_strchr(p_hf, '$') == NULL) {
vim_path = (char *)p_hf;
}
+
+ char exe_name[MAXPATHL];
+ // Find runtime path relative to the nvim binary: ../share/nvim/runtime
+ if (vim_path == NULL) {
+ xstrlcpy(exe_name, (char *)get_vim_var_str(VV_PROGPATH),
+ sizeof(exe_name));
+ char *path_end = (char *)path_tail_with_sep((char_u *)exe_name);
+ *path_end = '\0'; // remove the trailing "nvim.exe"
+ path_end = (char *)path_tail((char_u *)exe_name);
+ *path_end = '\0'; // remove the trailing "bin/"
+ if (append_path(
+ exe_name,
+ "share" _PATHSEPSTR "nvim" _PATHSEPSTR "runtime" _PATHSEPSTR,
+ MAXPATHL) == OK) {
+ vim_path = exe_name; // -V507
+ }
+ }
+
if (vim_path != NULL) {
// remove the file name
char *vim_path_end = (char *)path_tail((char_u *)vim_path);
@@ -627,6 +684,7 @@ char *vim_getenv(const char *name)
vim_path = NULL;
}
}
+ assert(vim_path != exe_name);
}
#ifdef HAVE_PATHDEF
@@ -668,7 +726,8 @@ char *vim_getenv(const char *name)
/// @param dstlen Maximum length of the result
/// @param one If true, only replace one file name, including spaces and commas
/// in the file name
-void home_replace(buf_T *buf, char_u *src, char_u *dst, int dstlen, bool one)
+void home_replace(const buf_T *const buf, const char_u *src,
+ char_u *dst, size_t dstlen, bool one)
{
size_t dirlen = 0, envlen = 0;
size_t len;
@@ -682,7 +741,7 @@ void home_replace(buf_T *buf, char_u *src, char_u *dst, int dstlen, bool one)
* If the file is a help file, remove the path completely.
*/
if (buf != NULL && buf->b_help) {
- STRCPY(dst, path_tail(src));
+ xstrlcpy((char *)dst, (char *)path_tail(src), dstlen);
return;
}
@@ -774,7 +833,7 @@ char_u * home_replace_save(buf_T *buf, char_u *src) FUNC_ATTR_NONNULL_RET
len += STRLEN(src);
}
char_u *dst = xmalloc(len);
- home_replace(buf, src, dst, (int)len, true);
+ home_replace(buf, src, dst, len, true);
return dst;
}
@@ -812,3 +871,86 @@ char_u *get_env_name(expand_T *xp, int idx)
return NULL;
}
+/// Appends the head of `fname` to $PATH and sets it in the environment.
+///
+/// @param fname Full path whose parent directory will be appended to $PATH.
+///
+/// @return true if `path` was appended-to
+bool os_setenv_append_path(const char *fname)
+ FUNC_ATTR_NONNULL_ALL
+{
+#ifdef WIN32
+// 8191 (plus NUL) is considered the practical maximum.
+# define MAX_ENVPATHLEN 8192
+#else
+// No prescribed maximum on unix.
+# define MAX_ENVPATHLEN INT_MAX
+#endif
+ if (!path_is_absolute_path((char_u *)fname)) {
+ EMSG2(_(e_intern2), "os_setenv_append_path()");
+ return false;
+ }
+ const char *tail = (char *)path_tail_with_sep((char_u *)fname);
+ size_t dirlen = (size_t)(tail - fname);
+ assert(tail >= fname && dirlen + 1 < sizeof(os_buf));
+ xstrlcpy(os_buf, fname, dirlen + 1);
+ const char *path = os_getenv("PATH");
+ const size_t pathlen = path ? strlen(path) : 0;
+ const size_t newlen = pathlen + dirlen + 2;
+ if (newlen < MAX_ENVPATHLEN) {
+ char *temp = xmalloc(newlen);
+ if (pathlen == 0) {
+ temp[0] = NUL;
+ } else {
+ xstrlcpy(temp, path, newlen);
+ xstrlcat(temp, ENV_SEPSTR, newlen);
+ }
+ xstrlcat(temp, os_buf, newlen);
+ os_setenv("PATH", temp, 1);
+ xfree(temp);
+ return true;
+ }
+ return false;
+}
+
+/// Returns true if the terminal can be assumed to silently ignore unknown
+/// control codes.
+bool os_term_is_nice(void)
+{
+#if defined(__APPLE__) || defined(WIN32)
+ return true;
+#else
+ const char *vte_version = os_getenv("VTE_VERSION");
+ if ((vte_version && atoi(vte_version) >= 3900)
+ || os_getenv("KONSOLE_PROFILE_NAME")
+ || os_getenv("KONSOLE_DBUS_SESSION")) {
+ return true;
+ }
+ const char *termprg = os_getenv("TERM_PROGRAM");
+ if (termprg && striequal(termprg, "iTerm.app")) {
+ return true;
+ }
+ const char *term = os_getenv("TERM");
+ if (term && strncmp(term, "rxvt", 4) == 0) {
+ return true;
+ }
+ return false;
+#endif
+}
+
+/// Returns true if `sh` looks like it resolves to "cmd.exe".
+bool os_shell_is_cmdexe(const char *sh)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (*sh == NUL) {
+ return false;
+ }
+ if (striequal(sh, "$COMSPEC")) {
+ const char *comspec = os_getenv("COMSPEC");
+ return striequal("cmd.exe", (char *)path_tail((char_u *)comspec));
+ }
+ if (striequal(sh, "cmd.exe") || striequal(sh, "cmd")) {
+ return true;
+ }
+ return striequal("cmd.exe", (char *)path_tail((char_u *)sh));
+}
diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c
index cf5bfd60ae..5d68473982 100644
--- a/src/nvim/os/fileio.c
+++ b/src/nvim/os/fileio.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// @file fileio.c
///
/// Buffered reading/writing to a file. Unlike fileio.c this is not dealing with
@@ -23,6 +26,7 @@
#include "nvim/globals.h"
#include "nvim/rbuffer.h"
#include "nvim/macros.h"
+#include "nvim/message.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/fileio.c.generated.h"
@@ -45,8 +49,8 @@ int file_open(FileDescriptor *const ret_fp, const char *const fname,
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
int os_open_flags = 0;
- int fd;
TriState wr = kNone;
+ // -V:FLAG:501
#define FLAG(flags, flag, fcntl_flags, wrval, cond) \
do { \
if (flags & flag) { \
@@ -62,19 +66,42 @@ int file_open(FileDescriptor *const ret_fp, const char *const fname,
FLAG(flags, kFileCreate, O_CREAT|O_WRONLY, kTrue, !(flags & kFileCreateOnly));
FLAG(flags, kFileTruncate, O_TRUNC|O_WRONLY, kTrue,
!(flags & kFileCreateOnly));
+ FLAG(flags, kFileAppend, O_APPEND|O_WRONLY, kTrue,
+ !(flags & kFileCreateOnly));
FLAG(flags, kFileReadOnly, O_RDONLY, kFalse, wr != kTrue);
#ifdef O_NOFOLLOW
FLAG(flags, kFileNoSymlink, O_NOFOLLOW, kNone, true);
#endif
#undef FLAG
+ // wr is used for kFileReadOnly flag, but on
+ // QB:neovim-qb-slave-ubuntu-12-04-64bit it still errors out with
+ // `error: variable ‘wr’ set but not used [-Werror=unused-but-set-variable]`
+ (void)wr;
- fd = os_open(fname, os_open_flags, mode);
+ const int fd = os_open(fname, os_open_flags, mode);
if (fd < 0) {
return fd;
}
+ return file_open_fd(ret_fp, fd, (wr == kTrue));
+}
- ret_fp->wr = (wr == kTrue);
+/// Wrap file descriptor with FileDescriptor structure
+///
+/// @warning File descriptor wrapped like this must not be accessed by other
+/// means.
+///
+/// @param[out] ret_fp Address where information needed for reading from or
+/// writing to a file is saved
+/// @param[in] fd File descriptor to wrap.
+/// @param[in] wr True if fd is opened for writing only, false if it is read
+/// only.
+///
+/// @return Error code (@see os_strerror()) or 0. Currently always returns 0.
+int file_open_fd(FileDescriptor *const ret_fp, const int fd, const bool wr)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ ret_fp->wr = wr;
ret_fp->fd = fd;
ret_fp->eof = false;
ret_fp->rv = rbuffer_new(kRWBufferSize);
@@ -98,7 +125,7 @@ int file_open(FileDescriptor *const ret_fp, const char *const fname,
/// @return [allocated] Opened file or NULL in case of error.
FileDescriptor *file_open_new(int *const error, const char *const fname,
const int flags, const int mode)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
FileDescriptor *const fp = xmalloc(sizeof(*fp));
if ((*error = file_open(fp, fname, flags, mode)) != 0) {
@@ -108,30 +135,54 @@ FileDescriptor *file_open_new(int *const error, const char *const fname,
return fp;
}
+/// Like file_open_fd(), but allocate and return ret_fp
+///
+/// @param[out] error Error code, @see os_strerror(). Is set to zero on
+/// success.
+/// @param[in] fd File descriptor to wrap.
+/// @param[in] wr True if fd is opened for writing only, false if it is read
+/// only.
+///
+/// @return [allocated] Opened file or NULL in case of error.
+FileDescriptor *file_open_fd_new(int *const error, const int fd, const bool wr)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ FileDescriptor *const fp = xmalloc(sizeof(*fp));
+ if ((*error = file_open_fd(fp, fd, wr)) != 0) {
+ xfree(fp);
+ return NULL;
+ }
+ return fp;
+}
+
/// Close file and free its buffer
///
/// @param[in,out] fp File to close.
+/// @param[in] do_fsync If true, use fsync() to write changes to disk.
///
/// @return 0 or error code.
-int file_close(FileDescriptor *const fp) FUNC_ATTR_NONNULL_ALL
+int file_close(FileDescriptor *const fp, const bool do_fsync)
+ FUNC_ATTR_NONNULL_ALL
{
- const int error = file_fsync(fp);
- const int error2 = os_close(fp->fd);
+ const int flush_error = (do_fsync ? file_fsync(fp) : file_flush(fp));
+ const int close_error = os_close(fp->fd);
rbuffer_free(fp->rv);
- if (error2 != 0) {
- return error2;
+ if (close_error != 0) {
+ return close_error;
}
- return error;
+ return flush_error;
}
/// Close and free file obtained using file_open_new()
///
/// @param[in,out] fp File to close.
+/// @param[in] do_fsync If true, use fsync() to write changes to disk.
///
/// @return 0 or error code.
-int file_free(FileDescriptor *const fp) FUNC_ATTR_NONNULL_ALL
+int file_free(FileDescriptor *const fp, const bool do_fsync)
+ FUNC_ATTR_NONNULL_ALL
{
- const int ret = file_close(fp);
+ const int ret = file_close(fp, do_fsync);
xfree(fp);
return ret;
}
@@ -141,19 +192,38 @@ int file_free(FileDescriptor *const fp) FUNC_ATTR_NONNULL_ALL
/// @param[in,out] fp File to work with.
///
/// @return 0 or error code.
-int file_fsync(FileDescriptor *const fp)
+int file_flush(FileDescriptor *const fp)
FUNC_ATTR_NONNULL_ALL
{
if (!fp->wr) {
return 0;
}
file_rb_write_full_cb(fp->rv, fp);
- if (fp->_error != 0) {
- const int error = fp->_error;
- fp->_error = 0;
- return error;
+ const int error = fp->_error;
+ fp->_error = 0;
+ return error;
+}
+
+/// Flush file modifications to disk and run fsync()
+///
+/// @param[in,out] fp File to work with.
+///
+/// @return 0 or error code.
+int file_fsync(FileDescriptor *const fp)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (!fp->wr) {
+ return 0;
+ }
+ const int flush_error = file_flush(fp);
+ if (flush_error != 0) {
+ return flush_error;
}
- return os_fsync(fp->fd);
+ const int fsync_error = os_fsync(fp->fd);
+ if (fsync_error != UV_EINVAL && fsync_error != UV_EROFS) {
+ return fsync_error;
+ }
+ return 0;
}
/// Buffer used for writing
@@ -316,3 +386,32 @@ ptrdiff_t file_skip(FileDescriptor *const fp, const size_t size)
return (ptrdiff_t)read_bytes;
}
+
+/// Msgpack callback for writing to a file
+///
+/// @param data File to write to.
+/// @param[in] buf Data to write.
+/// @param[in] len Length of the data to write.
+///
+/// @return 0 in case of success, -1 in case of error.
+int msgpack_file_write(void *data, const char *buf, size_t len)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ assert(len < PTRDIFF_MAX);
+ const ptrdiff_t written_bytes = file_write((FileDescriptor *)data, buf, len);
+ if (written_bytes < 0) {
+ return msgpack_file_write_error((int)written_bytes);
+ }
+ return 0;
+}
+
+/// Print error which occurs when failing to write msgpack data
+///
+/// @param[in] error Error code of the error to print.
+///
+/// @return -1 (error return for msgpack_packer callbacks).
+int msgpack_file_write_error(const int error)
+{
+ emsgf(_("E5420: Failed to write to file: %s"), os_strerror(error));
+ return -1;
+}
diff --git a/src/nvim/os/fileio.h b/src/nvim/os/fileio.h
index 2cffd5c851..0b55cc695f 100644
--- a/src/nvim/os/fileio.h
+++ b/src/nvim/os/fileio.h
@@ -30,6 +30,8 @@ typedef enum {
kFileTruncate = 32, ///< Truncate the file if it exists.
///< Implies kFileWriteOnly. Cannot be used with
///< kFileCreateOnly.
+ kFileAppend = 64, ///< Append to the file. Implies kFileWriteOnly. Cannot
+ ///< be used with kFileCreateOnly.
} FileOpenFlags;
static inline bool file_eof(const FileDescriptor *const fp)
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index 3c821936e9..78627f8703 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
// fs.c -- filesystem access
#include <stdbool.h>
#include <stddef.h>
@@ -58,9 +61,9 @@ void fs_init(void)
}
-/// Change to the given directory.
+/// Changes the current directory to `path`.
///
-/// @return `0` on success, a libuv error code on failure.
+/// @return 0 on success, or negative error code.
int os_chdir(const char *path)
FUNC_ATTR_NONNULL_ALL
{
@@ -91,11 +94,11 @@ int os_dirname(char_u *buf, size_t len)
/// Check if the given path is a directory and not a symlink to a directory.
/// @return `true` if `name` is a directory and NOT a symlink to a directory.
/// `false` if `name` is not a directory or if an error occurred.
-bool os_isrealdir(const char_u *name)
+bool os_isrealdir(const char *name)
FUNC_ATTR_NONNULL_ALL
{
uv_fs_t request;
- if (uv_fs_lstat(&fs_loop, &request, (char *)name, NULL) != kLibuvSuccess) {
+ if (uv_fs_lstat(&fs_loop, &request, name, NULL) != kLibuvSuccess) {
return false;
}
if (S_ISLNK(request.statbuf.st_mode)) {
@@ -111,7 +114,7 @@ bool os_isrealdir(const char_u *name)
bool os_isdir(const char_u *name)
FUNC_ATTR_NONNULL_ALL
{
- int32_t mode = os_getperm(name);
+ int32_t mode = os_getperm((const char *)name);
if (mode < 0) {
return false;
}
@@ -128,6 +131,7 @@ bool os_isdir(const char_u *name)
/// NODE_WRITABLE: writable device, socket, fifo, etc.
/// NODE_OTHER: non-writable things
int os_nodetype(const char *name)
+ FUNC_ATTR_NONNULL_ALL
{
#ifdef WIN32
// Edge case from Vim os_win32.c:
@@ -168,6 +172,10 @@ int os_nodetype(const char *name)
| O_NONBLOCK
#endif
, 0);
+ if (fd == -1) {
+ return NODE_OTHER; // open() failed.
+ }
+
switch (uv_guess_handle(fd)) {
case UV_TTY: // FILE_TYPE_CHAR
nodetype = NODE_WRITABLE;
@@ -192,6 +200,20 @@ int os_nodetype(const char *name)
return nodetype;
}
+/// Gets the absolute path of the currently running executable.
+/// May fail if procfs is missing. #6734
+/// @see path_exepath
+///
+/// @param[out] buffer Full path to the executable.
+/// @param[in] size Size of `buffer`.
+///
+/// @return 0 on success, or libuv error code.
+int os_exepath(char *buffer, size_t *size)
+ FUNC_ATTR_NONNULL_ALL
+{
+ return uv_exepath(buffer, size);
+}
+
/// Checks if the given path represents an executable file.
///
/// @param[in] name Name of the executable.
@@ -207,49 +229,87 @@ int os_nodetype(const char *name)
bool os_can_exe(const char_u *name, char_u **abspath, bool use_path)
FUNC_ATTR_NONNULL_ARG(1)
{
- // when use_path is false or if it's an absolute or relative path don't
- // need to use $PATH.
- if (!use_path || path_is_absolute_path(name)
- || (name[0] == '.'
- && (name[1] == '/'
- || (name[1] == '.' && name[2] == '/')))) {
- // There must be a path separator, files in the current directory
- // can't be executed
- if (gettail_dir(name) != name && is_executable(name)) {
+ bool no_path = !use_path || path_is_absolute_path(name);
+#ifndef WIN32
+ // If the filename is "qualified" (relative or absolute) do not check $PATH.
+ no_path |= (name[0] == '.'
+ && (name[1] == '/' || (name[1] == '.' && name[2] == '/')));
+#endif
+
+ if (no_path) {
+#ifdef WIN32
+ const char *pathext = os_getenv("PATHEXT");
+ if (!pathext) {
+ pathext = ".com;.exe;.bat;.cmd";
+ }
+ bool ok = is_executable((char *)name) || is_executable_ext((char *)name,
+ pathext);
+#else
+ // Must have path separator, cannot execute files in the current directory.
+ const bool ok = ((const char_u *)gettail_dir((const char *)name) != name
+ && is_executable((char *)name));
+#endif
+ if (ok) {
if (abspath != NULL) {
*abspath = save_absolute_path(name);
}
-
return true;
}
-
return false;
}
return is_executable_in_path(name, abspath);
}
-// Return true if "name" is an executable file, false if not or it doesn't
-// exist.
-static bool is_executable(const char_u *name)
+/// Returns true if `name` is an executable file.
+static bool is_executable(const char *name)
FUNC_ATTR_NONNULL_ALL
{
- int32_t mode = os_getperm(name);
+ int32_t mode = os_getperm((const char *)name);
if (mode < 0) {
return false;
}
-#if WIN32
+#ifdef WIN32
// Windows does not have exec bit; just check if the file exists and is not
// a directory.
return (S_ISREG(mode));
#else
return (S_ISREG(mode) && (S_IXUSR & mode));
#endif
+}
+
+#ifdef WIN32
+/// Appends file extensions from `pathext` to `name` and returns true if any
+/// such combination is executable.
+static bool is_executable_ext(char *name, const char *pathext)
+ FUNC_ATTR_NONNULL_ALL
+{
+ xstrlcpy(os_buf, name, sizeof(os_buf));
+ char *buf_end = xstrchrnul(os_buf, '\0');
+ for (const char *ext = pathext; *ext; ext++) {
+ // Skip the extension if there is no suffix after a '.'.
+ if (ext[0] == '.' && (ext[1] == '\0' || ext[1] == ENV_SEPCHAR)) {
+ ext++;
+ continue;
+ }
+
+ const char *ext_end = xstrchrnul(ext, ENV_SEPCHAR);
+ STRLCPY(buf_end, ext, ext_end - ext + 1);
+ if (is_executable(os_buf)) {
+ return true;
+ }
+
+ if (*ext_end != ENV_SEPCHAR) {
+ break;
+ }
+ ext = ext_end;
+ }
return false;
}
+#endif
/// Checks if a file is inside the `$PATH` and is executable.
///
@@ -260,89 +320,69 @@ static bool is_executable(const char_u *name)
static bool is_executable_in_path(const char_u *name, char_u **abspath)
FUNC_ATTR_NONNULL_ARG(1)
{
- const char *path = os_getenv("PATH");
- if (path == NULL) {
+ const char *path_env = os_getenv("PATH");
+ if (path_env == NULL) {
return false;
}
- size_t buf_len = STRLEN(name) + STRLEN(path) + 2;
+#ifdef WIN32
+ // Prepend ".;" to $PATH.
+ size_t pathlen = strlen(path_env);
+ char *path = memcpy(xmallocz(pathlen + 3), "." ENV_SEPSTR, 2);
+ memcpy(path + 2, path_env, pathlen);
+#else
+ char *path = xstrdup(path_env);
+#endif
+
+ size_t buf_len = STRLEN(name) + strlen(path) + 2;
#ifdef WIN32
const char *pathext = os_getenv("PATHEXT");
if (!pathext) {
pathext = ".com;.exe;.bat;.cmd";
}
-
- buf_len += STRLEN(pathext);
+ buf_len += strlen(pathext);
#endif
- char_u *buf = xmalloc(buf_len);
+ char *buf = xmalloc(buf_len);
// Walk through all entries in $PATH to check if "name" exists there and
// is an executable file.
+ char *p = path;
+ bool rv = false;
for (;; ) {
- const char *e = xstrchrnul(path, ENV_SEPCHAR);
-
- // Glue together the given directory from $PATH with name and save into
- // buf.
- STRLCPY(buf, path, e - path + 1);
- append_path((char *) buf, (const char *) name, buf_len);
-
- if (is_executable(buf)) {
- // Check if the caller asked for a copy of the path.
- if (abspath != NULL) {
- *abspath = save_absolute_path(buf);
- }
+ char *e = xstrchrnul(p, ENV_SEPCHAR);
- xfree(buf);
-
- return true;
- }
+ // Combine the $PATH segment with `name`.
+ STRLCPY(buf, p, e - p + 1);
+ append_path(buf, (char *)name, buf_len);
#ifdef WIN32
- // Try appending file extensions from $PATHEXT to the name.
- char *buf_end = xstrchrnul((char *)buf, '\0');
- for (const char *ext = pathext; *ext; ext++) {
- // Skip the extension if there is no suffix after a '.'.
- if (ext[0] == '.' && (ext[1] == '\0' || ext[1] == ';')) {
- *ext++;
-
- continue;
- }
-
- const char *ext_end = xstrchrnul(ext, ENV_SEPCHAR);
- STRLCPY(buf_end, ext, ext_end - ext + 1);
-
- if (is_executable(buf)) {
- // Check if the caller asked for a copy of the path.
- if (abspath != NULL) {
- *abspath = save_absolute_path(buf);
- }
-
- xfree(buf);
-
- return true;
+ bool ok = is_executable(buf) || is_executable_ext(buf, pathext);
+#else
+ bool ok = is_executable(buf);
+#endif
+ if (ok) {
+ if (abspath != NULL) { // Caller asked for a copy of the path.
+ *abspath = save_absolute_path((char_u *)buf);
}
- if (*ext_end != ENV_SEPCHAR) {
- break;
- }
- ext = ext_end;
+ rv = true;
+ goto end;
}
-#endif
if (*e != ENV_SEPCHAR) {
// End of $PATH without finding any executable called name.
- xfree(buf);
- return false;
+ goto end;
}
- path = e + 1;
+ p = e + 1;
}
- // We should never get to this point.
- assert(false);
- return false;
+end:
+ xfree(buf);
+ xfree(path);
+ return rv;
}
/// Opens or creates a file and returns a non-negative integer representing
@@ -362,6 +402,35 @@ int os_open(const char* path, int flags, int mode)
return r;
}
+/// Sets file descriptor `fd` to close-on-exec.
+//
+// @return -1 if failed to set, 0 otherwise.
+int os_set_cloexec(const int fd)
+{
+#ifdef HAVE_FD_CLOEXEC
+ int e;
+ int fdflags = fcntl(fd, F_GETFD);
+ if (fdflags < 0) {
+ e = errno;
+ ELOG("Failed to get flags on descriptor %d: %s", fd, strerror(e));
+ errno = e;
+ return -1;
+ }
+ if ((fdflags & FD_CLOEXEC) == 0
+ && fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC) == -1) {
+ e = errno;
+ ELOG("Failed to set CLOEXEC on descriptor %d: %s", fd, strerror(e));
+ errno = e;
+ return -1;
+ }
+ return 0;
+#endif
+
+ // No FD_CLOEXEC flag. On Windows, the file should have been opened with
+ // O_NOINHERIT anyway.
+ return -1;
+}
+
/// Close a file
///
/// @return 0 or libuv error code on failure.
@@ -395,11 +464,11 @@ ptrdiff_t os_read(const int fd, bool *ret_eof, char *const ret_buf,
size_t read_bytes = 0;
bool did_try_to_free = false;
while (read_bytes != size) {
+ assert(size >= read_bytes);
const ptrdiff_t cur_read_bytes = read(fd, ret_buf + read_bytes,
size - read_bytes);
if (cur_read_bytes > 0) {
read_bytes += (size_t)cur_read_bytes;
- assert(read_bytes <= size);
}
if (cur_read_bytes < 0) {
const int error = os_translate_sys_error(errno);
@@ -498,6 +567,7 @@ ptrdiff_t os_write(const int fd, const char *const buf, const size_t size)
}
size_t written_bytes = 0;
while (written_bytes != size) {
+ assert(size >= written_bytes);
const ptrdiff_t cur_written_bytes = write(fd, buf + written_bytes,
size - written_bytes);
if (cur_written_bytes > 0) {
@@ -535,8 +605,11 @@ int os_fsync(int fd)
///
/// @return libuv return code.
static int os_stat(const char *name, uv_stat_t *statbuf)
- FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_ARG(2)
{
+ if (!name) {
+ return UV_ENOENT;
+ }
uv_fs_t request;
int result = uv_fs_stat(&fs_loop, &request, name, NULL);
*statbuf = request.statbuf;
@@ -547,11 +620,10 @@ static int os_stat(const char *name, uv_stat_t *statbuf)
/// Get the file permissions for a given file.
///
/// @return libuv error code on error.
-int32_t os_getperm(const char_u *name)
- FUNC_ATTR_NONNULL_ALL
+int32_t os_getperm(const char *name)
{
uv_stat_t statbuf;
- int stat_result = os_stat((char *)name, &statbuf);
+ int stat_result = os_stat(name, &statbuf);
if (stat_result == kLibuvSuccess) {
return (int32_t)statbuf.st_mode;
} else {
@@ -562,11 +634,11 @@ int32_t os_getperm(const char_u *name)
/// Set the permission of a file.
///
/// @return `OK` for success, `FAIL` for failure.
-int os_setperm(const char_u *name, int perm)
+int os_setperm(const char *const name, int perm)
FUNC_ATTR_NONNULL_ALL
{
int r;
- RUN_UV_FS_FUNC(r, uv_fs_chmod, (const char *)name, perm, NULL);
+ RUN_UV_FS_FUNC(r, uv_fs_chmod, name, perm, NULL);
return (r == kLibuvSuccess ? OK : FAIL);
}
@@ -587,7 +659,6 @@ int os_fchown(int fd, uv_uid_t owner, uv_gid_t group)
///
/// @return `true` if `path` exists
bool os_path_exists(const char_u *path)
- FUNC_ATTR_NONNULL_ALL
{
uv_stat_t statbuf;
return os_stat((char *)path, &statbuf) == kLibuvSuccess;
@@ -777,7 +848,7 @@ int os_remove(const char *path)
/// @param[out] file_info Pointer to a FileInfo to put the information in.
/// @return `true` on success, `false` for failure.
bool os_fileinfo(const char *path, FileInfo *file_info)
- FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_ARG(2)
{
return os_stat(path, &(file_info->stat)) == kLibuvSuccess;
}
@@ -788,8 +859,11 @@ bool os_fileinfo(const char *path, FileInfo *file_info)
/// @param[out] file_info Pointer to a FileInfo to put the information in.
/// @return `true` on success, `false` for failure.
bool os_fileinfo_link(const char *path, FileInfo *file_info)
- FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_ARG(2)
{
+ if (path == NULL) {
+ return false;
+ }
uv_fs_t request;
int result = uv_fs_lstat(&fs_loop, &request, path, NULL);
file_info->stat = request.statbuf;
@@ -920,14 +994,13 @@ bool os_fileid_equal_fileinfo(const FileID *file_id,
/// When "fname" is the name of a shortcut (*.lnk) resolve the file it points
/// to and return that name in allocated memory.
/// Otherwise NULL is returned.
-char_u * os_resolve_shortcut(char_u *fname)
+char *os_resolve_shortcut(const char *fname)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
{
HRESULT hr;
IPersistFile *ppf = NULL;
OLECHAR wsz[MAX_PATH];
- char_u *rfname = NULL;
- int len;
- int conversion_result;
+ char *rfname = NULL;
IShellLinkW *pslw = NULL;
WIN32_FIND_DATAW ffdw;
@@ -936,7 +1009,7 @@ char_u * os_resolve_shortcut(char_u *fname)
if (fname == NULL) {
return rfname;
}
- len = (int)STRLEN(fname);
+ const size_t len = strlen(fname);
if (len <= 4 || STRNICMP(fname + len - 4, ".lnk", 4) != 0) {
return rfname;
}
@@ -948,9 +1021,9 @@ char_u * os_resolve_shortcut(char_u *fname)
&IID_IShellLinkW, (void **)&pslw);
if (hr == S_OK) {
WCHAR *p;
- int conversion_result = utf8_to_utf16((char *)fname, &p);
+ const int conversion_result = utf8_to_utf16(fname, &p);
if (conversion_result != 0) {
- EMSG2("utf8_to_utf16 failed: %s", uv_strerror(conversion_result));
+ EMSG2("utf8_to_utf16 failed: %d", conversion_result);
}
if (p != NULL) {
@@ -978,7 +1051,7 @@ char_u * os_resolve_shortcut(char_u *fname)
ZeroMemory(wsz, MAX_PATH * sizeof(WCHAR));
hr = pslw->lpVtbl->GetPath(pslw, wsz, MAX_PATH, &ffdw, 0);
if (hr == S_OK && wsz[0] != NUL) {
- int conversion_result = utf16_to_utf8(wsz, &rfname);
+ const int conversion_result = utf16_to_utf8(wsz, &rfname);
if (conversion_result != 0) {
EMSG2("utf16_to_utf8 failed: %s", uv_strerror(conversion_result));
}
@@ -1008,7 +1081,7 @@ shortcut_end:
int os_translate_sys_error(int sys_errno) {
#ifdef HAVE_UV_TRANSLATE_SYS_ERROR
return uv_translate_sys_error(sys_errno);
-#elif WIN32
+#elif defined(WIN32)
// TODO(equalsraf): libuv does not yet expose uv_translate_sys_error()
// in its public API, include a version here until it can be used.
// See https://github.com/libuv/libuv/issues/79
diff --git a/src/nvim/os/fs_defs.h b/src/nvim/os/fs_defs.h
index 0bd9c37750..2277d926b3 100644
--- a/src/nvim/os/fs_defs.h
+++ b/src/nvim/os/fs_defs.h
@@ -14,7 +14,7 @@ typedef struct {
uint64_t device_id; ///< @private The id of the device containing the file
} FileID;
-#define FILE_ID_EMPTY (FileID) {.inode = 0, .device_id = 0}
+#define FILE_ID_EMPTY (FileID) { .inode = 0, .device_id = 0 }
typedef struct {
uv_fs_t request; ///< @private The request to uv for the directory.
diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c
index b60a7eed36..31e06ce404 100644
--- a/src/nvim/os/input.c
+++ b/src/nvim/os/input.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <string.h>
#include <stdbool.h>
@@ -20,6 +23,7 @@
#include "nvim/main.h"
#include "nvim/misc1.h"
#include "nvim/state.h"
+#include "nvim/msgpack_rpc/channel.h"
#define READ_BUFFER_SIZE 0xfff
#define INPUT_BUFFER_SIZE (READ_BUFFER_SIZE * 4)
@@ -35,6 +39,7 @@ static RBuffer *input_buffer = NULL;
static bool input_eof = false;
static int global_fd = 0;
static int events_enabled = 0;
+static bool blocking = false;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/input.c.generated.h"
@@ -144,9 +149,15 @@ bool os_char_avail(void)
// Check for CTRL-C typed by reading all available characters.
void os_breakcheck(void)
{
+ int save_us = updating_screen;
+ // We do not want screen_resize() to redraw here.
+ updating_screen++;
+
if (!got_int) {
loop_poll_events(&main_loop, 0);
}
+
+ updating_screen = save_us;
}
void input_enable_events(void)
@@ -170,12 +181,14 @@ bool os_isatty(int fd)
size_t input_enqueue(String keys)
{
- char *ptr = keys.data, *end = ptr + keys.size;
+ char *ptr = keys.data;
+ char *end = ptr + keys.size;
while (rbuffer_space(input_buffer) >= 6 && ptr < end) {
uint8_t buf[6] = { 0 };
- unsigned int new_size = trans_special((const uint8_t **)&ptr, keys.size,
- buf, true);
+ unsigned int new_size
+ = trans_special((const uint8_t **)&ptr, (size_t)(end - ptr), buf, true,
+ true);
if (new_size) {
new_size = handle_mouse_event(&ptr, buf, new_size);
@@ -185,8 +198,7 @@ size_t input_enqueue(String keys)
if (*ptr == '<') {
char *old_ptr = ptr;
- // Invalid or incomplete key sequence, skip until the next '>' or until
- // *end
+ // Invalid or incomplete key sequence, skip until the next '>' or *end.
do {
ptr++;
} while (ptr < end && *ptr != '>');
@@ -317,13 +329,25 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf,
return bufsize;
}
+/// @return true if the main loop is blocked and waiting for input.
+bool input_blocking(void)
+{
+ return blocking;
+}
+
static bool input_poll(int ms)
{
if (do_profiling == PROF_YES && ms) {
prof_inchar_enter();
}
+ if ((ms == - 1 || ms > 0) && !events_enabled && !input_eof) {
+ // The pending input provoked a blocking wait. Do special events now. #6247
+ blocking = true;
+ multiqueue_process_events(ch_before_blocking_events);
+ }
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, ms, input_ready() || input_eof);
+ blocking = false;
if (do_profiling == PROF_YES && ms) {
prof_inchar_exit();
diff --git a/src/nvim/os/mem.c b/src/nvim/os/mem.c
index 871ece7a0e..eccb3c97e5 100644
--- a/src/nvim/os/mem.c
+++ b/src/nvim/os/mem.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// Functions for accessing system memory information.
#include <uv.h>
diff --git a/src/nvim/os/os_defs.h b/src/nvim/os/os_defs.h
index 5e164b54a5..923a362b41 100644
--- a/src/nvim/os/os_defs.h
+++ b/src/nvim/os/os_defs.h
@@ -13,10 +13,17 @@
# include "nvim/os/unix_defs.h"
#endif
+/// File descriptor number used for standard IO streams
+enum {
+ OS_STDIN_FILENO = STDIN_FILENO,
+ OS_STDOUT_FILENO = STDOUT_FILENO,
+ OS_STDERR_FILENO = STDERR_FILENO,
+};
+
#define BASENAMELEN (NAME_MAX - 5)
// Use the system path length if it makes sense.
-#if defined(PATH_MAX) && (PATH_MAX > 1000)
+#if defined(PATH_MAX) && (PATH_MAX > 1024)
# define MAXPATHL PATH_MAX
#else
# define MAXPATHL 1024
@@ -27,11 +34,11 @@
// Use up to 5 Mbyte for a buffer.
#ifndef DFLT_MAXMEM
-# define DFLT_MAXMEM (5*1024)
+# define DFLT_MAXMEM (5 * 1024)
#endif
// use up to 10 Mbyte for Vim.
#ifndef DFLT_MAXMEMTOT
-# define DFLT_MAXMEMTOT (10*1024)
+# define DFLT_MAXMEMTOT (10 * 1024)
#endif
// Note: Some systems need both string.h and strings.h (Savage). However,
diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c
index b57a69b82b..ee3ab96a83 100644
--- a/src/nvim/os/pty_process_unix.c
+++ b/src/nvim/os/pty_process_unix.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
// Some of the code came from pangoterm and libuv
#include <stdbool.h>
#include <stdlib.h>
@@ -9,7 +12,7 @@
#include <sys/ioctl.h>
// forkpty is not in POSIX, so headers are platform-specific
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined (__DragonFly__)
# include <libutil.h>
#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
# include <util.h>
@@ -33,7 +36,8 @@
# include "os/pty_process_unix.c.generated.h"
#endif
-bool pty_process_spawn(PtyProcess *ptyproc)
+/// @returns zero on success, or negative error code
+int pty_process_spawn(PtyProcess *ptyproc)
FUNC_ATTR_NONNULL_ALL
{
static struct termios termios;
@@ -41,6 +45,7 @@ bool pty_process_spawn(PtyProcess *ptyproc)
init_termios(&termios);
}
+ int status = 0; // zero or negative error code (libuv convention)
Process *proc = (Process *)ptyproc;
assert(!proc->err);
uv_signal_start(&proc->loop->children_watcher, chld_handler, SIGCHLD);
@@ -50,8 +55,9 @@ bool pty_process_spawn(PtyProcess *ptyproc)
int pid = forkpty(&master, NULL, &termios, &ptyproc->winsize);
if (pid < 0) {
+ status = -errno;
ELOG("forkpty failed: %s", strerror(errno));
- return false;
+ return status;
} else if (pid == 0) {
init_child(ptyproc);
abort();
@@ -60,30 +66,41 @@ bool pty_process_spawn(PtyProcess *ptyproc)
// make sure the master file descriptor is non blocking
int master_status_flags = fcntl(master, F_GETFL);
if (master_status_flags == -1) {
+ status = -errno;
ELOG("Failed to get master descriptor status flags: %s", strerror(errno));
goto error;
}
if (fcntl(master, F_SETFL, master_status_flags | O_NONBLOCK) == -1) {
+ status = -errno;
ELOG("Failed to make master descriptor non-blocking: %s", strerror(errno));
goto error;
}
- if (proc->in && !set_duplicating_descriptor(master, &proc->in->uv.pipe)) {
+ // Other jobs and providers should not get a copy of this file descriptor.
+ if (os_set_cloexec(master) == -1) {
+ status = -errno;
+ ELOG("Failed to set CLOEXEC on ptmx file descriptor");
+ goto error;
+ }
+
+ if (proc->in
+ && (status = set_duplicating_descriptor(master, &proc->in->uv.pipe))) {
goto error;
}
- if (proc->out && !set_duplicating_descriptor(master, &proc->out->uv.pipe)) {
+ if (proc->out
+ && (status = set_duplicating_descriptor(master, &proc->out->uv.pipe))) {
goto error;
}
ptyproc->tty_fd = master;
proc->pid = pid;
- return true;
+ return 0;
error:
close(master);
kill(pid, SIGKILL);
waitpid(pid, NULL, 0);
- return false;
+ return status;
}
void pty_process_resize(PtyProcess *ptyproc, uint16_t width, uint16_t height)
@@ -137,9 +154,10 @@ static void init_child(PtyProcess *ptyproc) FUNC_ATTR_NONNULL_ALL
return;
}
+ char *prog = ptyproc->process.argv[0];
setenv("TERM", ptyproc->term_name ? ptyproc->term_name : "ansi", 1);
- execvp(ptyproc->process.argv[0], ptyproc->process.argv);
- fprintf(stderr, "execvp failed: %s\n", strerror(errno));
+ execvp(prog, ptyproc->process.argv);
+ fprintf(stderr, "execvp failed: %s: %s\n", strerror(errno), prog);
}
static void init_termios(struct termios *termios) FUNC_ATTR_NONNULL_ALL
@@ -197,22 +215,34 @@ static void init_termios(struct termios *termios) FUNC_ATTR_NONNULL_ALL
termios->c_cc[VTIME] = 0;
}
-static bool set_duplicating_descriptor(int fd, uv_pipe_t *pipe)
+static int set_duplicating_descriptor(int fd, uv_pipe_t *pipe)
FUNC_ATTR_NONNULL_ALL
{
+ int status = 0; // zero or negative error code (libuv convention)
int fd_dup = dup(fd);
if (fd_dup < 0) {
+ status = -errno;
ELOG("Failed to dup descriptor %d: %s", fd, strerror(errno));
- return false;
+ return status;
}
- int uv_result = uv_pipe_open(pipe, fd_dup);
- if (uv_result) {
+
+ if (os_set_cloexec(fd_dup) == -1) {
+ status = -errno;
+ ELOG("Failed to set CLOEXEC on duplicate fd");
+ goto error;
+ }
+
+ status = uv_pipe_open(pipe, fd_dup);
+ if (status) {
ELOG("Failed to set pipe to descriptor %d: %s",
- fd_dup, uv_strerror(uv_result));
- close(fd_dup);
- return false;
+ fd_dup, uv_strerror(status));
+ goto error;
}
- return true;
+ return status;
+
+error:
+ close(fd_dup);
+ return status;
}
static void chld_handler(uv_signal_t *handle, int signum)
diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c
new file mode 100644
index 0000000000..ef8a699c56
--- /dev/null
+++ b/src/nvim/os/pty_process_win.c
@@ -0,0 +1,410 @@
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <winpty_constants.h>
+
+#include "nvim/os/os.h"
+#include "nvim/ascii.h"
+#include "nvim/memory.h"
+#include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8
+#include "nvim/os/pty_process_win.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "os/pty_process_win.c.generated.h"
+#endif
+
+static void CALLBACK pty_process_finish1(void *context, BOOLEAN unused)
+ FUNC_ATTR_NONNULL_ALL
+{
+ PtyProcess *ptyproc = (PtyProcess *)context;
+ Process *proc = (Process *)ptyproc;
+
+ uv_timer_init(&proc->loop->uv, &ptyproc->wait_eof_timer);
+ ptyproc->wait_eof_timer.data = (void *)ptyproc;
+ uv_timer_start(&ptyproc->wait_eof_timer, wait_eof_timer_cb, 200, 200);
+}
+
+/// @returns zero on success, or negative error code.
+int pty_process_spawn(PtyProcess *ptyproc)
+ FUNC_ATTR_NONNULL_ALL
+{
+ Process *proc = (Process *)ptyproc;
+ int status = 0;
+ winpty_error_ptr_t err = NULL;
+ winpty_config_t *cfg = NULL;
+ winpty_spawn_config_t *spawncfg = NULL;
+ winpty_t *winpty_object = NULL;
+ char *in_name = NULL;
+ char *out_name = NULL;
+ HANDLE process_handle = NULL;
+ uv_connect_t *in_req = NULL;
+ uv_connect_t *out_req = NULL;
+ wchar_t *cmd_line = NULL;
+ wchar_t *cwd = NULL;
+ const char *emsg = NULL;
+
+ assert(!proc->err);
+
+ cfg = winpty_config_new(WINPTY_FLAG_ALLOW_CURPROC_DESKTOP_CREATION, &err);
+ if (cfg == NULL) {
+ emsg = "Failed, winpty_config_new.";
+ goto cleanup;
+ }
+
+ winpty_config_set_initial_size(cfg, ptyproc->width, ptyproc->height);
+ winpty_object = winpty_open(cfg, &err);
+ if (winpty_object == NULL) {
+ emsg = "Failed, winpty_open.";
+ goto cleanup;
+ }
+
+ status = utf16_to_utf8(winpty_conin_name(winpty_object), &in_name);
+ if (status != 0) {
+ emsg = "Failed to convert in_name from utf16 to utf8.";
+ goto cleanup;
+ }
+
+ status = utf16_to_utf8(winpty_conout_name(winpty_object), &out_name);
+ if (status != 0) {
+ emsg = "Failed to convert out_name from utf16 to utf8.";
+ goto cleanup;
+ }
+
+ if (proc->in != NULL) {
+ in_req = xmalloc(sizeof(uv_connect_t));
+ uv_pipe_connect(
+ in_req,
+ &proc->in->uv.pipe,
+ in_name,
+ pty_process_connect_cb);
+ }
+
+ if (proc->out != NULL) {
+ out_req = xmalloc(sizeof(uv_connect_t));
+ uv_pipe_connect(
+ out_req,
+ &proc->out->uv.pipe,
+ out_name,
+ pty_process_connect_cb);
+ }
+
+ if (proc->cwd != NULL) {
+ status = utf8_to_utf16(proc->cwd, &cwd);
+ if (status != 0) {
+ emsg = "Failed to convert pwd form utf8 to utf16.";
+ goto cleanup;
+ }
+ }
+
+ status = build_cmd_line(proc->argv, &cmd_line,
+ os_shell_is_cmdexe(proc->argv[0]));
+ if (status != 0) {
+ emsg = "Failed to convert cmd line form utf8 to utf16.";
+ goto cleanup;
+ }
+
+ spawncfg = winpty_spawn_config_new(
+ WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN,
+ NULL, // Optional application name
+ cmd_line,
+ cwd,
+ NULL, // Optional environment variables
+ &err);
+ if (spawncfg == NULL) {
+ emsg = "Failed winpty_spawn_config_new.";
+ goto cleanup;
+ }
+
+ DWORD win_err = 0;
+ if (!winpty_spawn(winpty_object,
+ spawncfg,
+ &process_handle,
+ NULL, // Optional thread handle
+ &win_err,
+ &err)) {
+ if (win_err) {
+ status = (int)win_err;
+ emsg = "Failed spawn process.";
+ } else {
+ emsg = "Failed winpty_spawn.";
+ }
+ goto cleanup;
+ }
+ proc->pid = GetProcessId(process_handle);
+
+ if (!RegisterWaitForSingleObject(
+ &ptyproc->finish_wait,
+ process_handle,
+ pty_process_finish1,
+ ptyproc,
+ INFINITE,
+ WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) {
+ abort();
+ }
+
+ // Wait until pty_process_connect_cb is called.
+ while ((in_req != NULL && in_req->handle != NULL)
+ || (out_req != NULL && out_req->handle != NULL)) {
+ uv_run(&proc->loop->uv, UV_RUN_ONCE);
+ }
+
+ ptyproc->winpty_object = winpty_object;
+ ptyproc->process_handle = process_handle;
+ winpty_object = NULL;
+ process_handle = NULL;
+
+cleanup:
+ if (status) {
+ // In the case of an error of MultiByteToWideChar or CreateProcessW.
+ ELOG("%s error code: %d", emsg, status);
+ status = os_translate_sys_error(status);
+ } else if (err != NULL) {
+ status = (int)winpty_error_code(err);
+ ELOG("%s error code: %d", emsg, status);
+ status = translate_winpty_error(status);
+ }
+ winpty_error_free(err);
+ winpty_config_free(cfg);
+ winpty_spawn_config_free(spawncfg);
+ winpty_free(winpty_object);
+ xfree(in_name);
+ xfree(out_name);
+ if (process_handle != NULL) {
+ CloseHandle(process_handle);
+ }
+ xfree(in_req);
+ xfree(out_req);
+ xfree(cmd_line);
+ xfree(cwd);
+ return status;
+}
+
+void pty_process_resize(PtyProcess *ptyproc, uint16_t width,
+ uint16_t height)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (ptyproc->winpty_object != NULL) {
+ winpty_set_size(ptyproc->winpty_object, width, height, NULL);
+ }
+}
+
+void pty_process_close(PtyProcess *ptyproc)
+ FUNC_ATTR_NONNULL_ALL
+{
+ Process *proc = (Process *)ptyproc;
+
+ pty_process_close_master(ptyproc);
+
+ if (proc->internal_close_cb) {
+ proc->internal_close_cb(proc);
+ }
+}
+
+void pty_process_close_master(PtyProcess *ptyproc)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (ptyproc->winpty_object != NULL) {
+ winpty_free(ptyproc->winpty_object);
+ ptyproc->winpty_object = NULL;
+ }
+}
+
+void pty_process_teardown(Loop *loop)
+ FUNC_ATTR_NONNULL_ALL
+{
+}
+
+static void pty_process_connect_cb(uv_connect_t *req, int status)
+ FUNC_ATTR_NONNULL_ALL
+{
+ assert(status == 0);
+ req->handle = NULL;
+}
+
+static void wait_eof_timer_cb(uv_timer_t *wait_eof_timer)
+ FUNC_ATTR_NONNULL_ALL
+{
+ PtyProcess *ptyproc = wait_eof_timer->data;
+ Process *proc = (Process *)ptyproc;
+
+ if (!proc->out || !uv_is_readable(proc->out->uvstream)) {
+ uv_timer_stop(&ptyproc->wait_eof_timer);
+ pty_process_finish2(ptyproc);
+ }
+}
+
+static void pty_process_finish2(PtyProcess *ptyproc)
+ FUNC_ATTR_NONNULL_ALL
+{
+ Process *proc = (Process *)ptyproc;
+
+ UnregisterWaitEx(ptyproc->finish_wait, NULL);
+ uv_close((uv_handle_t *)&ptyproc->wait_eof_timer, NULL);
+
+ DWORD exit_code = 0;
+ GetExitCodeProcess(ptyproc->process_handle, &exit_code);
+ proc->status = (int)exit_code;
+
+ CloseHandle(ptyproc->process_handle);
+ ptyproc->process_handle = NULL;
+
+ proc->internal_exit_cb(proc);
+}
+
+/// Build the command line to pass to CreateProcessW.
+///
+/// @param[in] argv Array with string arguments.
+/// @param[out] cmd_line Location where saved builded cmd line.
+///
+/// @returns zero on success, or error code of MultiByteToWideChar function.
+///
+static int build_cmd_line(char **argv, wchar_t **cmd_line, bool is_cmdexe)
+ FUNC_ATTR_NONNULL_ALL
+{
+ size_t utf8_cmd_line_len = 0;
+ size_t argc = 0;
+ QUEUE args_q;
+
+ QUEUE_INIT(&args_q);
+ while (*argv) {
+ size_t buf_len = is_cmdexe ? (strlen(*argv) + 1) : (strlen(*argv) * 2 + 3);
+ ArgNode *arg_node = xmalloc(sizeof(*arg_node));
+ arg_node->arg = xmalloc(buf_len);
+ if (is_cmdexe) {
+ xstrlcpy(arg_node->arg, *argv, buf_len);
+ } else {
+ quote_cmd_arg(arg_node->arg, buf_len, *argv);
+ }
+ utf8_cmd_line_len += strlen(arg_node->arg);
+ QUEUE_INIT(&arg_node->node);
+ QUEUE_INSERT_TAIL(&args_q, &arg_node->node);
+ argc++;
+ argv++;
+ }
+
+ utf8_cmd_line_len += argc;
+ char *utf8_cmd_line = xmalloc(utf8_cmd_line_len);
+ *utf8_cmd_line = NUL;
+ while (1) {
+ QUEUE *head = QUEUE_HEAD(&args_q);
+ QUEUE_REMOVE(head);
+ ArgNode *arg_node = QUEUE_DATA(head, ArgNode, node);
+ xstrlcat(utf8_cmd_line, arg_node->arg, utf8_cmd_line_len);
+ xfree(arg_node->arg);
+ xfree(arg_node);
+ if (QUEUE_EMPTY(&args_q)) {
+ break;
+ } else {
+ xstrlcat(utf8_cmd_line, " ", utf8_cmd_line_len);
+ }
+ }
+
+ int result = utf8_to_utf16(utf8_cmd_line, cmd_line);
+ xfree(utf8_cmd_line);
+ return result;
+}
+
+/// Emulate quote_cmd_arg of libuv and quotes command line argument.
+/// Most of the code came from libuv.
+///
+/// @param[out] dest Location where saved quotes argument.
+/// @param dest_remaining Destination buffer size.
+/// @param[in] src Pointer to argument.
+///
+static void quote_cmd_arg(char *dest, size_t dest_remaining, const char *src)
+ FUNC_ATTR_NONNULL_ALL
+{
+ size_t src_len = strlen(src);
+ bool quote_hit = true;
+ char *start = dest;
+
+ if (src_len == 0) {
+ // Need double quotation for empty argument.
+ snprintf(dest, dest_remaining, "\"\"");
+ return;
+ }
+
+ if (NULL == strpbrk(src, " \t\"")) {
+ // No quotation needed.
+ xstrlcpy(dest, src, dest_remaining);
+ return;
+ }
+
+ if (NULL == strpbrk(src, "\"\\")) {
+ // No embedded double quotes or backlashes, so I can just wrap quote marks.
+ // around the whole thing.
+ snprintf(dest, dest_remaining, "\"%s\"", src);
+ return;
+ }
+
+ // Expected input/output:
+ // input : hello"world
+ // output: "hello\"world"
+ // input : hello""world
+ // output: "hello\"\"world"
+ // input : hello\world
+ // output: hello\world
+ // input : hello\\world
+ // output: hello\\world
+ // input : hello\"world
+ // output: "hello\\\"world"
+ // input : hello\\"world
+ // output: "hello\\\\\"world"
+ // input : hello world\
+ // output: "hello world\\"
+
+ assert(dest_remaining--);
+ *(dest++) = NUL;
+ assert(dest_remaining--);
+ *(dest++) = '"';
+ for (size_t i = src_len; i > 0; i--) {
+ assert(dest_remaining--);
+ *(dest++) = src[i - 1];
+ if (quote_hit && src[i - 1] == '\\') {
+ assert(dest_remaining--);
+ *(dest++) = '\\';
+ } else if (src[i - 1] == '"') {
+ quote_hit = true;
+ assert(dest_remaining--);
+ *(dest++) = '\\';
+ } else {
+ quote_hit = false;
+ }
+ }
+ assert(dest_remaining);
+ *dest = '"';
+
+ while (start < dest) {
+ char tmp = *start;
+ *start = *dest;
+ *dest = tmp;
+ start++;
+ dest--;
+ }
+}
+
+/// Translate winpty error code to libuv error.
+///
+/// @param[in] winpty_errno Winpty error code returned by winpty_error_code
+/// function.
+///
+/// @returns Error code of libuv error.
+int translate_winpty_error(int winpty_errno)
+{
+ if (winpty_errno <= 0) {
+ return winpty_errno; // If < 0 then it's already a libuv error.
+ }
+
+ switch (winpty_errno) {
+ case WINPTY_ERROR_OUT_OF_MEMORY: return UV_ENOMEM;
+ case WINPTY_ERROR_SPAWN_CREATE_PROCESS_FAILED: return UV_EAI_FAIL;
+ case WINPTY_ERROR_LOST_CONNECTION: return UV_ENOTCONN;
+ case WINPTY_ERROR_AGENT_EXE_MISSING: return UV_ENOENT;
+ case WINPTY_ERROR_UNSPECIFIED: return UV_UNKNOWN;
+ case WINPTY_ERROR_AGENT_DIED: return UV_ESRCH;
+ case WINPTY_ERROR_AGENT_TIMEOUT: return UV_ETIMEDOUT;
+ case WINPTY_ERROR_AGENT_CREATION_FAILED: return UV_EAI_FAIL;
+ default: return UV_UNKNOWN;
+ }
+}
diff --git a/src/nvim/os/pty_process_win.h b/src/nvim/os/pty_process_win.h
index 20cc589925..1a4019e654 100644
--- a/src/nvim/os/pty_process_win.h
+++ b/src/nvim/os/pty_process_win.h
@@ -1,19 +1,27 @@
#ifndef NVIM_OS_PTY_PROCESS_WIN_H
#define NVIM_OS_PTY_PROCESS_WIN_H
-#include "nvim/event/libuv_process.h"
+#include <uv.h>
+#include <winpty.h>
+
+#include "nvim/event/process.h"
+#include "nvim/lib/queue.h"
typedef struct pty_process {
Process process;
char *term_name;
uint16_t width, height;
+ winpty_t *winpty_object;
+ HANDLE finish_wait;
+ HANDLE process_handle;
+ uv_timer_t wait_eof_timer;
} PtyProcess;
-#define pty_process_spawn(job) libuv_process_spawn((LibuvProcess *)job)
-#define pty_process_close(job) libuv_process_close((LibuvProcess *)job)
-#define pty_process_close_master(job) libuv_process_close((LibuvProcess *)job)
-#define pty_process_resize(job, width, height)
-#define pty_process_teardown(loop)
+// Structure used by build_cmd_line()
+typedef struct arg_node {
+ char *arg; // pointer to argument.
+ QUEUE node; // QUEUE structure.
+} ArgNode;
static inline PtyProcess pty_process_init(Loop *loop, void *data)
{
@@ -22,7 +30,14 @@ static inline PtyProcess pty_process_init(Loop *loop, void *data)
rv.term_name = NULL;
rv.width = 80;
rv.height = 24;
+ rv.winpty_object = NULL;
+ rv.finish_wait = NULL;
+ rv.process_handle = NULL;
return rv;
}
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "os/pty_process_win.h.generated.h"
+#endif
+
#endif // NVIM_OS_PTY_PROCESS_WIN_H
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index 9514936ad0..32e9a70e57 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <string.h>
#include <assert.h>
#include <stdbool.h>
@@ -39,14 +42,15 @@ typedef struct {
#endif
/// Builds the argument vector for running the user-configured 'shell' (p_sh)
-/// with an optional command prefixed by 'shellcmdflag' (p_shcf).
+/// with an optional command prefixed by 'shellcmdflag' (p_shcf). E.g.:
+///
+/// ["shell", "-extra_args", "-shellcmdflag", "command with spaces"]
///
/// @param cmd Command string, or NULL to run an interactive shell.
/// @param extra_args Extra arguments to the shell, or NULL.
-/// @return A newly allocated argument vector. It must be freed with
-/// `shell_free_argv` when no longer needed.
+/// @return Newly allocated argument vector. Must be freed with shell_free_argv.
char **shell_build_argv(const char *cmd, const char *extra_args)
- FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC
+ FUNC_ATTR_NONNULL_RET
{
size_t argc = tokenize(p_sh, NULL) + (cmd ? tokenize(p_shcf, NULL) : 0);
char **rv = xmalloc((argc + 4) * sizeof(*rv));
@@ -123,15 +127,9 @@ int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_args)
}
size_t nread;
-
- int status = do_os_system(shell_build_argv((char *)cmd, (char *)extra_args),
- input.data,
- input.len,
- output_ptr,
- &nread,
- emsg_silent,
- forward_output);
-
+ int exitcode = do_os_system(shell_build_argv((char *)cmd, (char *)extra_args),
+ input.data, input.len, output_ptr, &nread,
+ emsg_silent, forward_output);
xfree(input.data);
if (output) {
@@ -139,16 +137,16 @@ int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_args)
xfree(output);
}
- if (!emsg_silent && status != 0 && !(opts & kShellOptSilent)) {
+ if (!emsg_silent && exitcode != 0 && !(opts & kShellOptSilent)) {
MSG_PUTS(_("\nshell returned "));
- msg_outnum(status);
+ msg_outnum(exitcode);
msg_putchar('\n');
}
State = current_state;
signal_accept_deadly();
- return status;
+ return exitcode;
}
/// os_system - synchronously execute a command in the shell
@@ -157,7 +155,7 @@ int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_args)
/// char *output = NULL;
/// size_t nread = 0;
/// char *argv[] = {"ls", "-la", NULL};
-/// int status = os_sytem(argv, NULL, 0, &output, &nread);
+/// int exitcode = os_sytem(argv, NULL, 0, &output, &nread);
///
/// @param argv The commandline arguments to be passed to the shell. `argv`
/// will be consumed.
@@ -218,11 +216,14 @@ static int do_os_system(char **argv,
proc->in = input != NULL ? &in : NULL;
proc->out = &out;
proc->err = &err;
- if (!process_spawn(proc)) {
+ int status = process_spawn(proc);
+ if (status) {
loop_poll_events(&main_loop, 0);
- // Failed, probably due to 'sh' not being executable
+ // Failed, probably 'shell' is not executable.
if (!silent) {
- MSG_PUTS(_("\nCannot execute "));
+ MSG_PUTS(_("\nshell failed to start: "));
+ msg_outtrans((char_u *)os_strerror(status));
+ MSG_PUTS(": ");
msg_outtrans((char_u *)prog);
msg_putchar('\n');
}
@@ -262,7 +263,7 @@ static int do_os_system(char **argv,
// busy state.
ui_busy_start();
ui_flush();
- int status = process_wait(proc, -1, NULL);
+ int exitcode = process_wait(proc, -1, NULL);
if (!got_int && out_data_decide_throttle(0)) {
// Last chunk of output was skipped; display it now.
out_data_ring(NULL, SIZE_MAX);
@@ -289,7 +290,7 @@ static int do_os_system(char **argv,
assert(multiqueue_empty(events));
multiqueue_free(events);
- return status;
+ return exitcode;
}
/// - ensures at least `desired` bytes in buffer
@@ -321,7 +322,7 @@ static void system_data_cb(Stream *stream, RBuffer *buf, size_t count,
/// Tracks output received for the current executing shell command, and displays
/// a pulsing "..." when output should be skipped. Tracking depends on the
/// synchronous/blocking nature of ":!".
-//
+///
/// Purpose:
/// 1. CTRL-C is more responsive. #1234 #5396
/// 2. Improves performance of :! (UI, esp. TUI, is the bottleneck).
@@ -446,7 +447,7 @@ static void out_data_append_to_screen(char *output, size_t remaining,
size_t off = 0;
int last_row = (int)Rows - 1;
- while (off < remaining) {
+ while (output != NULL && off < remaining) {
// Found end of line?
if (output[off] == NL) {
// Can we start a new line or do we need to continue the last one?
@@ -463,15 +464,16 @@ static void out_data_append_to_screen(char *output, size_t remaining,
continue;
}
- // Translate NUL to SOH
- if (output[off] == NUL) {
- output[off] = 1;
+ // TODO(bfredl): using msg_puts would be better until
+ // terminal emulation is implemented.
+ if (output[off] < 0x20) {
+ output[off] = ' ';
}
off++;
}
- if (remaining) {
+ if (output != NULL && remaining) {
if (last_col == 0) {
screen_del_lines(0, 0, 1, (int)Rows, NULL);
}
@@ -683,7 +685,7 @@ static void shell_write_cb(Stream *stream, void *data, int status)
uv_err_name(status));
}
if (stream->closed) { // Process may have exited before this write.
- ELOG("stream was already closed");
+ WLOG("stream was already closed");
return;
}
stream_close(stream, NULL, NULL);
diff --git a/src/nvim/os/shell.h b/src/nvim/os/shell.h
index 58960db157..48503f2601 100644
--- a/src/nvim/os/shell.h
+++ b/src/nvim/os/shell.h
@@ -1,6 +1,8 @@
#ifndef NVIM_OS_SHELL_H
#define NVIM_OS_SHELL_H
+#include <stdio.h>
+
#include "nvim/types.h"
// Flags for os_call_shell() second argument
diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c
index 1ac6d3f5e1..fd6d3b32e4 100644
--- a/src/nvim/os/signal.c
+++ b/src/nvim/os/signal.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <stdbool.h>
diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c
index afb9bdec31..a41fb7c621 100644
--- a/src/nvim/os/stdpaths.c
+++ b/src/nvim/os/stdpaths.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <stdbool.h>
#include "nvim/os/stdpaths_defs.h"
diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c
index 8ce2ecf4f4..c471352c02 100644
--- a/src/nvim/os/time.c
+++ b/src/nvim/os/time.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <stdint.h>
#include <stdbool.h>
diff --git a/src/nvim/os/unix_defs.h b/src/nvim/os/unix_defs.h
index 690a39c3cd..5c9daca476 100644
--- a/src/nvim/os/unix_defs.h
+++ b/src/nvim/os/unix_defs.h
@@ -8,7 +8,7 @@
// POSIX.1-2008 says that NAME_MAX should be in here
#include <limits.h>
-#define TEMP_DIR_NAMES {"$TMPDIR", "/tmp", ".", "~"}
+#define TEMP_DIR_NAMES { "$TMPDIR", "/tmp", ".", "~" }
#define TEMP_FILE_PATH_MAXLEN 256
#define HAVE_ACL (HAVE_POSIX_ACL || HAVE_SOLARIS_ACL)
@@ -16,7 +16,8 @@
// Special wildcards that need to be handled by the shell.
#define SPECIAL_WILDCHAR "`'{"
-// Separator character for environment variables.
+// Character that separates entries in $PATH.
#define ENV_SEPCHAR ':'
+#define ENV_SEPSTR ":"
#endif // NVIM_OS_UNIX_DEFS_H
diff --git a/src/nvim/os/users.c b/src/nvim/os/users.c
index 1c94ef0067..82bb918f70 100644
--- a/src/nvim/os/users.c
+++ b/src/nvim/os/users.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
// users.c -- operating system user information
#include <uv.h>
diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h
index 6a29f86e79..8fd2e51f8b 100644
--- a/src/nvim/os/win_defs.h
+++ b/src/nvim/os/win_defs.h
@@ -1,6 +1,10 @@
#ifndef NVIM_OS_WIN_DEFS_H
#define NVIM_OS_WIN_DEFS_H
+#ifndef WIN32
+# error Header must be included only when compiling for Windows.
+#endif
+
// winsock2.h must be first to avoid incompatibilities
// with winsock.h (included by windows.h)
#include <winsock2.h>
@@ -15,18 +19,24 @@
#define NAME_MAX _MAX_PATH
-#define TEMP_DIR_NAMES {"$TMP", "$TEMP", "$USERPROFILE", ""}
+#define TEMP_DIR_NAMES { "$TMPDIR", "$TMP", "$TEMP", "$USERPROFILE", "" }
#define TEMP_FILE_PATH_MAXLEN _MAX_PATH
#define FNAME_ILLEGAL "\"*?><|"
-// Separator character for environment variables.
+// Character that separates entries in $PATH.
#define ENV_SEPCHAR ';'
+#define ENV_SEPSTR ";"
#define USE_CRNL
-// We have our own RGB macro in macros.h.
-#undef RGB
+// Windows defines a RGB macro that produces 0x00bbggrr color values for use
+// with GDI. Our macro is different, and we don't use GDI.
+#if defined(RGB)
+# undef RGB
+ // Duplicated from macros.h to avoid include-order sensitivity.
+# define RGB(r, g, b) ((r << 16) | (g << 8) | b)
+#endif
#ifdef _MSC_VER
# ifndef inline
@@ -86,4 +96,14 @@ typedef SSIZE_T ssize_t;
# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#endif
+#ifndef STDIN_FILENO
+# define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+# define STDOUT_FILENO 1
+#endif
+#ifndef STDERR_FILENO
+# define STDERR_FILENO 2
+#endif
+
#endif // NVIM_OS_WIN_DEFS_H
diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c
index 08294fa6a0..692bcc97f4 100644
--- a/src/nvim/os_unix.c
+++ b/src/nvim/os_unix.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* os_unix.c -- code for all flavors of Unix (BSD, SYSV, SVR4, POSIX, ...)
*
@@ -62,9 +65,7 @@ static int selinux_enabled = -1;
#if defined(HAVE_SELINUX)
-/*
- * Copy security info from "from_file" to "to_file".
- */
+// Copy security info from "from_file" to "to_file".
void mch_copy_sec(char_u *from_file, char_u *to_file)
{
if (from_file == NULL)
@@ -78,11 +79,12 @@ void mch_copy_sec(char_u *from_file, char_u *to_file)
security_context_t to_context = NULL;
if (getfilecon((char *)from_file, &from_context) < 0) {
- /* If the filesystem doesn't support extended attributes,
- the original had no special security context and the
- target cannot have one either. */
- if (errno == EOPNOTSUPP)
+ // If the filesystem doesn't support extended attributes,
+ // the original had no special security context and the
+ // target cannot have one either.
+ if (errno == EOPNOTSUPP) {
return;
+ }
MSG_PUTS(_("\nCould not get security context for "));
msg_outtrans(from_file);
@@ -107,22 +109,18 @@ void mch_copy_sec(char_u *from_file, char_u *to_file)
freecon(from_context);
}
}
-#endif /* HAVE_SELINUX */
+#endif // HAVE_SELINUX
-/*
- * Return a pointer to the ACL of file "fname" in allocated memory.
- * Return NULL if the ACL is not available for whatever reason.
- */
-vim_acl_T mch_get_acl(char_u *fname)
+// Return a pointer to the ACL of file "fname" in allocated memory.
+// Return NULL if the ACL is not available for whatever reason.
+vim_acl_T mch_get_acl(const char_u *fname)
{
vim_acl_T ret = NULL;
return ret;
}
-/*
- * Set the ACL of file "fname" to "acl" (unless it's NULL).
- */
-void mch_set_acl(char_u *fname, vim_acl_T aclent)
+// Set the ACL of file "fname" to "acl" (unless it's NULL).
+void mch_set_acl(const char_u *fname, vim_acl_T aclent)
{
if (aclent == NULL)
return;
@@ -135,15 +133,17 @@ void mch_free_acl(vim_acl_T aclent)
}
#endif
-void mch_exit(int r)
+void mch_exit(int r) FUNC_ATTR_NORETURN
{
exiting = true;
ui_builtin_stop();
ui_flush();
- ml_close_all(true); /* remove all memfiles */
+ ml_close_all(true); // remove all memfiles
- event_teardown();
+ if (!event_teardown() && r == 0) {
+ r = 1; // Exit with error if main_loop did not teardown gracefully.
+ }
stream_set_blocking(input_global_fd(), true); // normalize stream (#2598)
#ifdef EXITFREE
@@ -175,7 +175,7 @@ void mch_exit(int r)
/// @returns OK for success or FAIL for error.
int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
char_u ***file, int flags) FUNC_ATTR_NONNULL_ARG(3)
- FUNC_ATTR_NONNULL_ARG(4)
+ FUNC_ATTR_NONNULL_ARG(4)
{
int i;
size_t len;
@@ -198,17 +198,22 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
int check_spaces;
static bool did_find_nul = false;
bool ampersent = false;
- /* vimglob() function to define for Posix shell */
+ // vimglob() function to define for Posix shell
static char *sh_vimglob_func =
"vimglob() { while [ $# -ge 1 ]; do echo \"$1\"; shift; done }; vimglob >";
- *num_file = 0; /* default: no files found */
+ bool is_fish_shell =
+#if defined(UNIX)
+ STRNCMP(invocation_path_tail(p_sh, NULL), "fish", 4) == 0;
+#else
+ false;
+#endif
+
+ *num_file = 0; // default: no files found
*file = NULL;
- /*
- * If there are no wildcards, just copy the names to allocated memory.
- * Saves a lot of time, because we don't have to start a new shell.
- */
+ // If there are no wildcards, just copy the names to allocated memory.
+ // Saves a lot of time, because we don't have to start a new shell.
if (!have_wildcard(num_pat, pat)) {
save_patterns(num_pat, pat, num_file, file);
return OK;
@@ -219,87 +224,99 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
return FAIL;
}
- /*
- * Don't allow the use of backticks in secure and restricted mode.
- */
- if (secure || restricted)
- for (i = 0; i < num_pat; ++i)
+ // Don't allow the use of backticks in secure and restricted mode.
+ if (secure || restricted) {
+ for (i = 0; i < num_pat; i++) {
if (vim_strchr(pat[i], '`') != NULL
- && (check_restricted() || check_secure()))
+ && (check_restricted() || check_secure())) {
return FAIL;
+ }
+ }
+ }
- /*
- * get a name for the temp file
- */
+ // get a name for the temp file
if ((tempname = vim_tempname()) == NULL) {
EMSG(_(e_notmp));
return FAIL;
}
- /*
- * Let the shell expand the patterns and write the result into the temp
- * file.
- * STYLE_BT: NL separated
- * If expanding `cmd` execute it directly.
- * STYLE_GLOB: NUL separated
- * If we use *csh, "glob" will work better than "echo".
- * STYLE_PRINT: NL or NUL separated
- * If we use *zsh, "print -N" will work better than "glob".
- * STYLE_VIMGLOB: NL separated
- * If we use *sh*, we define "vimglob()".
- * STYLE_ECHO: space separated.
- * A shell we don't know, stay safe and use "echo".
- */
+ // Let the shell expand the patterns and write the result into the temp
+ // file.
+ // STYLE_BT: NL separated
+ // If expanding `cmd` execute it directly.
+ // STYLE_GLOB: NUL separated
+ // If we use *csh, "glob" will work better than "echo".
+ // STYLE_PRINT: NL or NUL separated
+ // If we use *zsh, "print -N" will work better than "glob".
+ // STYLE_VIMGLOB: NL separated
+ // If we use *sh*, we define "vimglob()".
+ // STYLE_ECHO: space separated.
+ // A shell we don't know, stay safe and use "echo".
if (num_pat == 1 && *pat[0] == '`'
&& (len = STRLEN(pat[0])) > 2
- && *(pat[0] + len - 1) == '`')
+ && *(pat[0] + len - 1) == '`') {
shell_style = STYLE_BT;
- else if ((len = STRLEN(p_sh)) >= 3) {
- if (STRCMP(p_sh + len - 3, "csh") == 0)
+ } else if ((len = STRLEN(p_sh)) >= 3) {
+ if (STRCMP(p_sh + len - 3, "csh") == 0) {
shell_style = STYLE_GLOB;
- else if (STRCMP(p_sh + len - 3, "zsh") == 0)
+ } else if (STRCMP(p_sh + len - 3, "zsh") == 0) {
shell_style = STYLE_PRINT;
+ }
}
if (shell_style == STYLE_ECHO && strstr((char *)path_tail(p_sh),
"sh") != NULL)
shell_style = STYLE_VIMGLOB;
- /* Compute the length of the command. We need 2 extra bytes: for the
- * optional '&' and for the NUL.
- * Worst case: "unset nonomatch; print -N >" plus two is 29 */
+ // Compute the length of the command. We need 2 extra bytes: for the
+ // optional '&' and for the NUL.
+ // Worst case: "unset nonomatch; print -N >" plus two is 29
len = STRLEN(tempname) + 29;
if (shell_style == STYLE_VIMGLOB)
len += STRLEN(sh_vimglob_func);
- for (i = 0; i < num_pat; ++i) {
- /* Count the length of the patterns in the same way as they are put in
- * "command" below. */
- ++len; /* add space */
- for (j = 0; pat[i][j] != NUL; ++j) {
- if (vim_strchr(SHELL_SPECIAL, pat[i][j]) != NULL)
- ++len; /* may add a backslash */
- ++len;
+ for (i = 0; i < num_pat; i++) {
+ // Count the length of the patterns in the same way as they are put in
+ // "command" below.
+ len++; // add space
+ for (j = 0; pat[i][j] != NUL; j++) {
+ if (vim_strchr(SHELL_SPECIAL, pat[i][j]) != NULL) {
+ len++; // may add a backslash
+ }
+ len++;
}
}
+
+ if (is_fish_shell) {
+ len += sizeof("egin;"" end") - 1;
+ }
+
command = xmalloc(len);
- /*
- * Build the shell command:
- * - Set $nonomatch depending on EW_NOTFOUND (hopefully the shell
- * recognizes this).
- * - Add the shell command to print the expanded names.
- * - Add the temp file name.
- * - Add the file name patterns.
- */
+ // Build the shell command:
+ // - Set $nonomatch depending on EW_NOTFOUND (hopefully the shell
+ // recognizes this).
+ // - Add the shell command to print the expanded names.
+ // - Add the temp file name.
+ // - Add the file name patterns.
if (shell_style == STYLE_BT) {
- /* change `command; command& ` to (command; command ) */
- STRCPY(command, "(");
- STRCAT(command, pat[0] + 1); /* exclude first backtick */
+ // change `command; command& ` to (command; command )
+ if (is_fish_shell) {
+ STRCPY(command, "begin; ");
+ } else {
+ STRCPY(command, "(");
+ }
+ STRCAT(command, pat[0] + 1); // exclude first backtick
p = command + STRLEN(command) - 1;
- *p-- = ')'; /* remove last backtick */
- while (p > command && ascii_iswhite(*p))
- --p;
- if (*p == '&') { /* remove trailing '&' */
+ if (is_fish_shell) {
+ *p-- = ';';
+ STRCAT(command, " end");
+ } else {
+ *p-- = ')'; // remove last backtick
+ }
+ while (p > command && ascii_iswhite(*p)) {
+ p--;
+ }
+ if (*p == '&') { // remove trailing '&'
ampersent = true;
*p = ' ';
}
@@ -321,113 +338,109 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
STRCAT(command, tempname);
- if (shell_style != STYLE_BT)
- for (i = 0; i < num_pat; ++i) {
- /* Put a backslash before special
- * characters, except inside ``. */
+ if (shell_style != STYLE_BT) {
+ for (i = 0; i < num_pat; i++) {
+ // Put a backslash before special
+ // characters, except inside ``.
bool intick = false;
p = command + STRLEN(command);
*p++ = ' ';
- for (j = 0; pat[i][j] != NUL; ++j) {
- if (pat[i][j] == '`')
+ for (j = 0; pat[i][j] != NUL; j++) {
+ if (pat[i][j] == '`') {
intick = !intick;
- else if (pat[i][j] == '\\' && pat[i][j + 1] != NUL) {
- /* Remove a backslash, take char literally. But keep
- * backslash inside backticks, before a special character
- * and before a backtick. */
+ } else if (pat[i][j] == '\\' && pat[i][j + 1] != NUL) {
+ // Remove a backslash, take char literally. But keep
+ // backslash inside backticks, before a special character
+ // and before a backtick.
if (intick
|| vim_strchr(SHELL_SPECIAL, pat[i][j + 1]) != NULL
- || pat[i][j + 1] == '`')
+ || pat[i][j + 1] == '`') {
*p++ = '\\';
- ++j;
+ }
+ j++;
} else if (!intick
- && ((flags & EW_KEEPDOLLAR) == 0 || pat[i][j] != '$')
- && vim_strchr(SHELL_SPECIAL, pat[i][j]) != NULL)
- /* Put a backslash before a special character, but not
- * when inside ``. And not for $var when EW_KEEPDOLLAR is
- * set. */
+ && ((flags & EW_KEEPDOLLAR) == 0 || pat[i][j] != '$')
+ && vim_strchr(SHELL_SPECIAL, pat[i][j]) != NULL) {
+ // Put a backslash before a special character, but not
+ // when inside ``. And not for $var when EW_KEEPDOLLAR is
+ // set.
*p++ = '\\';
+ }
- /* Copy one character. */
+ // Copy one character.
*p++ = pat[i][j];
}
*p = NUL;
}
+ }
if (flags & EW_SILENT) {
shellopts |= kShellOptHideMess;
}
- if (ampersent)
- STRCAT(command, "&"); /* put the '&' after the redirection */
-
- /*
- * Using zsh -G: If a pattern has no matches, it is just deleted from
- * the argument list, otherwise zsh gives an error message and doesn't
- * expand any other pattern.
- */
- if (shell_style == STYLE_PRINT)
- extra_shell_arg = (char_u *)"-G"; /* Use zsh NULL_GLOB option */
-
- /*
- * If we use -f then shell variables set in .cshrc won't get expanded.
- * vi can do it, so we will too, but it is only necessary if there is a "$"
- * in one of the patterns, otherwise we can still use the fast option.
- */
- else if (shell_style == STYLE_GLOB && !have_dollars(num_pat, pat))
- extra_shell_arg = (char_u *)"-f"; /* Use csh fast option */
-
- /*
- * execute the shell command
- */
+ if (ampersent) {
+ STRCAT(command, "&"); // put the '&' after the redirection
+ }
+
+ // Using zsh -G: If a pattern has no matches, it is just deleted from
+ // the argument list, otherwise zsh gives an error message and doesn't
+ // expand any other pattern.
+ if (shell_style == STYLE_PRINT) {
+ extra_shell_arg = (char_u *)"-G"; // Use zsh NULL_GLOB option
+
+ // If we use -f then shell variables set in .cshrc won't get expanded.
+ // vi can do it, so we will too, but it is only necessary if there is a "$"
+ // in one of the patterns, otherwise we can still use the fast option.
+ } else if (shell_style == STYLE_GLOB && !have_dollars(num_pat, pat)) {
+ extra_shell_arg = (char_u *)"-f"; // Use csh fast option
+ }
+
+ // execute the shell command
i = call_shell(
command,
shellopts,
extra_shell_arg
);
- /* When running in the background, give it some time to create the temp
- * file, but don't wait for it to finish. */
- if (ampersent)
+ // When running in the background, give it some time to create the temp
+ // file, but don't wait for it to finish.
+ if (ampersent) {
os_delay(10L, true);
+ }
xfree(command);
- if (i) { /* os_call_shell() failed */
+ if (i) { // os_call_shell() failed
os_remove((char *)tempname);
xfree(tempname);
- /*
- * With interactive completion, the error message is not printed.
- */
- if (!(flags & EW_SILENT))
- {
- redraw_later_clear(); /* probably messed up screen */
- msg_putchar('\n'); /* clear bottom line quickly */
+ // With interactive completion, the error message is not printed.
+ if (!(flags & EW_SILENT)) {
+ redraw_later_clear(); // probably messed up screen
+ msg_putchar('\n'); // clear bottom line quickly
#if SIZEOF_LONG > SIZEOF_INT
assert(Rows <= (long)INT_MAX + 1);
#endif
- cmdline_row = (int)(Rows - 1); /* continue on last line */
+ cmdline_row = (int)(Rows - 1); // continue on last line
MSG(_(e_wildexpand));
- msg_start(); /* don't overwrite this message */
+ msg_start(); // don't overwrite this message
}
- /* If a `cmd` expansion failed, don't list `cmd` as a match, even when
- * EW_NOTFOUND is given */
- if (shell_style == STYLE_BT)
+ // If a `cmd` expansion failed, don't list `cmd` as a match, even when
+ // EW_NOTFOUND is given
+ if (shell_style == STYLE_BT) {
return FAIL;
+ }
goto notfound;
}
- /*
- * read the names from the file into memory
- */
+ // read the names from the file into memory
fd = fopen((char *)tempname, READBIN);
if (fd == NULL) {
- /* Something went wrong, perhaps a file name with a special char. */
+ // Something went wrong, perhaps a file name with a special char.
if (!(flags & EW_SILENT)) {
MSG(_(e_wildexpand));
- msg_start(); /* don't overwrite this message */
+ msg_start(); // don't overwrite this message
}
xfree(tempname);
goto notfound;
@@ -438,7 +451,7 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
fclose(fd);
return FAIL;
}
- long long templen = ftell(fd); /* get size of temp file */
+ int64_t templen = ftell(fd); // get size of temp file
if (templen < 0) {
xfree(tempname);
fclose(fd);
@@ -456,7 +469,7 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
fclose(fd);
os_remove((char *)tempname);
if (readlen != len) {
- /* unexpected read error */
+ // unexpected read error
EMSG2(_(e_notread), tempname);
xfree(tempname);
xfree(buffer);
@@ -464,41 +477,40 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
}
xfree(tempname);
- /* file names are separated with Space */
+ // file names are separated with Space
if (shell_style == STYLE_ECHO) {
- buffer[len] = '\n'; /* make sure the buffer ends in NL */
+ buffer[len] = '\n'; // make sure the buffer ends in NL
p = buffer;
- for (i = 0; *p != '\n'; ++i) { /* count number of entries */
- while (*p != ' ' && *p != '\n')
- ++p;
- p = skipwhite(p); /* skip to next entry */
+ for (i = 0; *p != '\n'; i++) { // count number of entries
+ while (*p != ' ' && *p != '\n') {
+ p++;
+ }
+ p = skipwhite(p); // skip to next entry
}
- }
- /* file names are separated with NL */
- else if (shell_style == STYLE_BT || shell_style == STYLE_VIMGLOB) {
- buffer[len] = NUL; /* make sure the buffer ends in NUL */
+ // file names are separated with NL
+ } else if (shell_style == STYLE_BT || shell_style == STYLE_VIMGLOB) {
+ buffer[len] = NUL; // make sure the buffer ends in NUL
p = buffer;
- for (i = 0; *p != NUL; ++i) { /* count number of entries */
- while (*p != '\n' && *p != NUL)
- ++p;
- if (*p != NUL)
- ++p;
- p = skipwhite(p); /* skip leading white space */
+ for (i = 0; *p != NUL; i++) { // count number of entries
+ while (*p != '\n' && *p != NUL) {
+ p++;
+ }
+ if (*p != NUL) {
+ p++;
+ }
+ p = skipwhite(p); // skip leading white space
}
- }
- /* file names are separated with NUL */
- else {
- /*
- * Some versions of zsh use spaces instead of NULs to separate
- * results. Only do this when there is no NUL before the end of the
- * buffer, otherwise we would never be able to use file names with
- * embedded spaces when zsh does use NULs.
- * When we found a NUL once, we know zsh is OK, set did_find_nul and
- * don't check for spaces again.
- */
+ // file names are separated with NUL
+ } else {
+ // Some versions of zsh use spaces instead of NULs to separate
+ // results. Only do this when there is no NUL before the end of the
+ // buffer, otherwise we would never be able to use file names with
+ // embedded spaces when zsh does use NULs.
+ // When we found a NUL once, we know zsh is OK, set did_find_nul and
+ // don't check for spaces again.
check_spaces = false;
if (shell_style == STYLE_PRINT && !did_find_nul) {
- /* If there is a NUL, set did_find_nul, else set check_spaces */
+ // If there is a NUL, set did_find_nul, else set check_spaces
buffer[len] = NUL;
if (len && (int)STRLEN(buffer) < (int)len)
did_find_nul = true;
@@ -506,72 +518,69 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
check_spaces = true;
}
- /*
- * Make sure the buffer ends with a NUL. For STYLE_PRINT there
- * already is one, for STYLE_GLOB it needs to be added.
- */
- if (len && buffer[len - 1] == NUL)
- --len;
- else
+ // Make sure the buffer ends with a NUL. For STYLE_PRINT there
+ // already is one, for STYLE_GLOB it needs to be added.
+ if (len && buffer[len - 1] == NUL) {
+ len--;
+ } else {
buffer[len] = NUL;
+ }
i = 0;
- for (p = buffer; p < buffer + len; ++p)
- if (*p == NUL || (*p == ' ' && check_spaces)) { /* count entry */
- ++i;
+ for (p = buffer; p < buffer + len; p++) {
+ if (*p == NUL || (*p == ' ' && check_spaces)) { // count entry
+ i++;
*p = NUL;
}
- if (len)
- ++i; /* count last entry */
+ }
+ if (len) {
+ i++; // count last entry
+ }
}
assert(buffer[len] == NUL || buffer[len] == '\n');
if (i == 0) {
- /*
- * Can happen when using /bin/sh and typing ":e $NO_SUCH_VAR^I".
- * /bin/sh will happily expand it to nothing rather than returning an
- * error; and hey, it's good to check anyway -- webb.
- */
+ // Can happen when using /bin/sh and typing ":e $NO_SUCH_VAR^I".
+ // /bin/sh will happily expand it to nothing rather than returning an
+ // error; and hey, it's good to check anyway -- webb.
xfree(buffer);
goto notfound;
}
*num_file = i;
*file = xmalloc(sizeof(char_u *) * (size_t)i);
- /*
- * Isolate the individual file names.
- */
+ // Isolate the individual file names.
p = buffer;
for (i = 0; i < *num_file; ++i) {
(*file)[i] = p;
- /* Space or NL separates */
+ // Space or NL separates
if (shell_style == STYLE_ECHO || shell_style == STYLE_BT
|| shell_style == STYLE_VIMGLOB) {
while (!(shell_style == STYLE_ECHO && *p == ' ')
- && *p != '\n' && *p != NUL)
- ++p;
- if (p == buffer + len) /* last entry */
+ && *p != '\n' && *p != NUL) {
+ p++;
+ }
+ if (p == buffer + len) { // last entry
*p = NUL;
- else {
+ } else {
*p++ = NUL;
- p = skipwhite(p); /* skip to next entry */
+ p = skipwhite(p); // skip to next entry
}
- } else { /* NUL separates */
- while (*p && p < buffer + len) /* skip entry */
- ++p;
- ++p; /* skip NUL */
+ } else { // NUL separates
+ while (*p && p < buffer + len) { // skip entry
+ p++;
+ }
+ p++; // skip NUL
}
}
- /*
- * Move the file names to allocated memory.
- */
+ // Move the file names to allocated memory.
for (j = 0, i = 0; i < *num_file; i++) {
// Require the files to exist. Helps when using /bin/sh
if (!(flags & EW_NOTFOUND) && !os_path_exists((*file)[i])) {
continue;
}
- /* check if this entry should be included */
+ // check if this entry should be included
dir = (os_isdir((*file)[i]));
if ((dir && !(flags & EW_DIR)) || (!dir && !(flags & EW_FILE)))
continue;
@@ -584,14 +593,15 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
p = xmalloc(STRLEN((*file)[i]) + 1 + dir);
STRCPY(p, (*file)[i]);
- if (dir)
- add_pathsep((char *)p); /* add '/' to a directory name */
+ if (dir) {
+ add_pathsep((char *)p); // add '/' to a directory name
+ }
(*file)[j++] = p;
}
xfree(buffer);
*num_file = j;
- if (*num_file == 0) { /* rejected all entries */
+ if (*num_file == 0) { // rejected all entries
xfree(*file);
*file = NULL;
goto notfound;
@@ -619,8 +629,8 @@ static void save_patterns(int num_pat, char_u **pat, int *num_file,
for (i = 0; i < num_pat; i++) {
s = vim_strsave(pat[i]);
- /* Be compatible with expand_filename(): halve the number of
- * backslashes. */
+ // Be compatible with expand_filename(): halve the number of
+ // backslashes.
backslash_halve(s);
(*file)[i] = s;
}
diff --git a/src/nvim/path.c b/src/nvim/path.c
index 3d1def8dd4..f2339c8046 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
@@ -84,15 +87,15 @@ FileComparison path_full_compare(char_u *s1, char_u *s2, int checkname)
///
/// @return pointer just past the last path separator (empty string, if fname
/// ends in a slash), or empty string if fname is NULL.
-char_u *path_tail(char_u *fname)
+char_u *path_tail(const char_u *fname)
FUNC_ATTR_NONNULL_RET
{
if (fname == NULL) {
return (char_u *)"";
}
- char_u *tail = get_past_head(fname);
- char_u *p = tail;
+ const char_u *tail = get_past_head(fname);
+ const char_u *p = tail;
// Find last part of path.
while (*p != NUL) {
if (vim_ispathsep_nocolon(*p)) {
@@ -100,7 +103,7 @@ char_u *path_tail(char_u *fname)
}
mb_ptr_adv(p);
}
- return tail;
+ return (char_u *)tail;
}
/// Get pointer to tail of "fname", including path separators.
@@ -159,7 +162,7 @@ const char_u *invocation_path_tail(const char_u *invocation, size_t *len)
/// @param fname A file path. (Must be != NULL.)
/// @return Pointer to first found path separator + 1.
/// An empty string, if `fname` doesn't contain a path separator,
-char_u *path_next_component(char_u *fname)
+const char *path_next_component(const char *fname)
{
assert(fname != NULL);
while (*fname != NUL && !vim_ispathsep(*fname)) {
@@ -174,9 +177,9 @@ char_u *path_next_component(char_u *fname)
/// Get a pointer to one character past the head of a path name.
/// Unix: after "/"; Win: after "c:\"
/// If there is no head, path is returned.
-char_u *get_past_head(char_u *path)
+char_u *get_past_head(const char_u *path)
{
- char_u *retval = path;
+ const char_u *retval = path;
#ifdef WIN32
// May skip "c:"
@@ -189,7 +192,7 @@ char_u *get_past_head(char_u *path)
++retval;
}
- return retval;
+ return (char_u *)retval;
}
/*
@@ -282,48 +285,63 @@ bool dir_of_file_exists(char_u *fname)
return retval;
}
-/*
- * Versions of fnamecmp() and fnamencmp() that handle '/' and '\' equally
- * and deal with 'fileignorecase'.
- */
-int vim_fnamecmp(char_u *x, char_u *y)
+/// Compare two file names
+///
+/// Handles '/' and '\\' correctly and deals with &fileignorecase option.
+///
+/// @param[in] fname1 First file name.
+/// @param[in] fname2 Second file name.
+///
+/// @return 0 if they are equal, non-zero otherwise.
+int path_fnamecmp(const char *fname1, const char *fname2)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
#ifdef BACKSLASH_IN_FILENAME
- return vim_fnamencmp(x, y, MAXPATHL);
+ const size_t len1 = strlen(fname1);
+ const size_t len2 = strlen(fname2);
+ return path_fnamencmp(fname1, fname2, MAX(len1, len2));
#else
- if (p_fic)
- return mb_stricmp(x, y);
- return STRCMP(x, y);
+ return mb_strcmp_ic((bool)p_fic, fname1, fname2);
#endif
}
-int vim_fnamencmp(char_u *x, char_u *y, size_t len)
+/// Compare two file names
+///
+/// Handles '/' and '\\' correctly and deals with &fileignorecase option.
+///
+/// @param[in] fname1 First file name.
+/// @param[in] fname2 Second file name.
+/// @param[in] len Compare at most len bytes.
+///
+/// @return 0 if they are equal, non-zero otherwise.
+int path_fnamencmp(const char *const fname1, const char *const fname2,
+ size_t len)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
#ifdef BACKSLASH_IN_FILENAME
- char_u *px = x;
- char_u *py = y;
- int cx = NUL;
- int cy = NUL;
+ int c1 = NUL;
+ int c2 = NUL;
+ const char *p1 = fname1;
+ const char *p2 = fname2;
while (len > 0) {
- cx = PTR2CHAR(px);
- cy = PTR2CHAR(py);
- if (cx == NUL || cy == NUL
- || ((p_fic ? vim_tolower(cx) != vim_tolower(cy) : cx != cy)
- && !(cx == '/' && cy == '\\')
- && !(cx == '\\' && cy == '/')))
+ c1 = PTR2CHAR((const char_u *)p1);
+ c2 = PTR2CHAR((const char_u *)p2);
+ if ((c1 == NUL || c2 == NUL
+ || (!((c1 == '/' || c1 == '\\') && (c2 == '\\' || c2 == '/'))))
+ && (p_fic ? (c1 != c2 && CH_FOLD(c1) != CH_FOLD(c2)) : c1 != c2)) {
break;
- len -= MB_PTR2LEN(px);
- px += MB_PTR2LEN(px);
- py += MB_PTR2LEN(py);
+ }
+ len -= MB_PTR2LEN((const char_u *)p1);
+ p1 += MB_PTR2LEN((const char_u *)p1);
+ p2 += MB_PTR2LEN((const char_u *)p2);
}
- if (len == 0)
- return 0;
- return cx - cy;
+ return c1 - c2;
#else
- if (p_fic)
- return mb_strnicmp(x, y, len);
- return STRNCMP(x, y, len);
+ if (p_fic) {
+ return mb_strnicmp((const char_u *)fname1, (const char_u *)fname2, len);
+ }
+ return strncmp(fname1, fname2, len);
#endif
}
@@ -391,15 +409,22 @@ char *concat_fnames_realloc(char *fname1, const char *fname2, bool sep)
fname2, len2, sep);
}
-/*
- * Add a path separator to a file name, unless it already ends in a path
- * separator.
- */
-void add_pathsep(char *p)
+/// Adds a path separator to a filename, unless it already ends in one.
+///
+/// @return `true` if the path separator was added or already existed.
+/// `false` if the filename is too long.
+bool add_pathsep(char *p)
FUNC_ATTR_NONNULL_ALL
{
- if (*p != NUL && !after_pathsep(p, p + strlen(p)))
- strcat(p, PATHSEPSTR);
+ const size_t len = strlen(p);
+ if (*p != NUL && !after_pathsep(p, p + len)) {
+ const size_t pathsep_len = sizeof(PATHSEPSTR);
+ if (len > MAXPATHL - pathsep_len) {
+ return false;
+ }
+ memcpy(p + len, PATHSEPSTR, pathsep_len);
+ }
+ return true;
}
/// Get an allocated copy of the full path to a file.
@@ -409,8 +434,8 @@ void add_pathsep(char *p)
///
/// @return [allocated] Copy of absolute path to `fname` or NULL when
/// `fname` is NULL.
-char *FullName_save(char *fname, bool force)
- FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC
+char *FullName_save(const char *fname, bool force)
+ FUNC_ATTR_MALLOC
{
if (fname == NULL) {
return NULL;
@@ -428,7 +453,7 @@ char *FullName_save(char *fname, bool force)
/// @param name An absolute or relative path.
/// @return The absolute path of `name`.
char_u *save_absolute_path(const char_u *name)
- FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
if (!path_is_absolute_path(name)) {
return (char_u *)FullName_save((char *)name, true);
@@ -579,7 +604,7 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
}
if (has_mbyte) {
len = (size_t)(*mb_ptr2len)(path_end);
- STRNCPY(p, path_end, len);
+ memcpy(p, path_end, len);
p += len;
path_end += len;
} else
@@ -797,7 +822,7 @@ static void expand_path_option(char_u *curdir, garray_T *gap)
}
STRMOVE(buf + len + 1, buf);
STRCPY(buf, curdir);
- buf[len] = PATHSEP;
+ buf[len] = (char_u)PATHSEP;
simplify_filename(buf);
}
@@ -884,9 +909,9 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
in_curdir = xcalloc((size_t)gap->ga_len, sizeof(char_u *));
for (int i = 0; i < gap->ga_len && !got_int; i++) {
- char_u *path = fnames[i];
+ char_u *path = fnames[i];
int is_in_curdir;
- char_u *dir_end = gettail_dir(path);
+ char_u *dir_end = (char_u *)gettail_dir((const char *)path);
char_u *pathsep_p;
char_u *path_cutoff;
@@ -988,20 +1013,22 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
ga_remove_duplicate_strings(gap);
}
-/*
- * Return the end of the directory name, on the first path
- * separator:
- * "/path/file", "/path/dir/", "/path//dir", "/file"
- * ^ ^ ^ ^
- */
-char_u *gettail_dir(const char_u *fname)
+/// Find end of the directory name
+///
+/// @param[in] fname File name to process.
+///
+/// @return end of the directory name, on the first path separator:
+///
+/// "/path/file", "/path/dir/", "/path//dir", "/file"
+/// ^ ^ ^ ^
+const char *gettail_dir(const char *const fname)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- const char_u *dir_end = fname;
- const char_u *next_dir_end = fname;
+ const char *dir_end = fname;
+ const char *next_dir_end = fname;
bool look_for_sep = true;
- const char_u *p;
- for (p = fname; *p != NUL; ) {
+ for (const char *p = fname; *p != NUL; ) {
if (vim_ispathsep(*p)) {
if (look_for_sep) {
next_dir_end = p;
@@ -1014,7 +1041,7 @@ char_u *gettail_dir(const char_u *fname)
}
mb_ptr_adv(p);
}
- return (char_u *)dir_end;
+ return dir_end;
}
@@ -1220,7 +1247,7 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
* "vim c:/" work. */
if (flags & EW_NOTFOUND) {
addfile(&ga, t, flags | EW_DIR | EW_FILE);
- } else if (os_path_exists(t)) {
+ } else {
addfile(&ga, t, flags);
}
xfree(t);
@@ -1309,12 +1336,12 @@ static int expand_backtick(
/// When the path looks like a URL leave it unmodified.
void slash_adjust(char_u *p)
{
- if (path_with_url(p)) {
+ if (path_with_url((const char *)p)) {
return;
}
while (*p) {
- if (*p == psepcN) {
- *p = psepc;
+ if (*p == (char_u)psepcN) {
+ *p = (char_u)psepc;
}
mb_ptr_adv(p);
}
@@ -1533,8 +1560,8 @@ void simplify_filename(char_u *filename)
p = tail; /* skip to char after ".." or "../" */
}
} else {
- ++components; /* simple path component */
- p = path_next_component(p);
+ components++; // Simple path component.
+ p = (char_u *)path_next_component((const char *)p);
}
} while (*p != NUL);
}
@@ -1688,7 +1715,7 @@ int vim_FullName(const char *fname, char *buf, size_t len, bool force)
///
/// @param fname is the filename to expand
/// @return [allocated] Full path (NULL for failure).
-char *fix_fname(char *fname)
+char *fix_fname(const char *fname)
{
#ifdef UNIX
return FullName_save(fname, true);
@@ -1829,7 +1856,7 @@ int pathcmp(const char *p, const char *q, int maxlen)
break;
}
- if ((p_fic ? vim_toupper(c1) != vim_toupper(c2) : c1 != c2)
+ if ((p_fic ? mb_toupper(c1) != mb_toupper(c2) : c1 != c2)
#ifdef BACKSLASH_IN_FILENAME
/* consider '/' and '\\' to be equal */
&& !((c1 == '/' && c2 == '\\')
@@ -1840,8 +1867,8 @@ int pathcmp(const char *p, const char *q, int maxlen)
return -1;
if (vim_ispathsep(c2))
return 1;
- return p_fic ? vim_toupper(c1) - vim_toupper(c2)
- : c1 - c2; /* no match */
+ return p_fic ? mb_toupper(c1) - mb_toupper(c2)
+ : c1 - c2; // no match
}
i += MB_PTR2LEN((char_u *)p + i);
@@ -2124,17 +2151,12 @@ int append_path(char *path, const char *to_append, size_t max_len)
size_t current_length = strlen(path);
size_t to_append_length = strlen(to_append);
- // Do not append empty strings.
- if (to_append_length == 0) {
+ // Do not append empty string or a dot.
+ if (to_append_length == 0 || strcmp(to_append, ".") == 0) {
return OK;
}
- // Do not append a dot.
- if (STRCMP(to_append, ".") == 0) {
- return OK;
- }
-
- // Glue both paths with a slash.
+ // Combine the path segments, separated by a slash.
if (current_length > 0 && !vim_ispathsep_nocolon(path[current_length-1])) {
current_length += 1; // Count the trailing slash.
@@ -2143,7 +2165,7 @@ int append_path(char *path, const char *to_append, size_t max_len)
return FAIL;
}
- STRCAT(path, PATHSEPSTR);
+ xstrlcat(path, PATHSEPSTR, max_len);
}
// +1 for the NUL at the end.
@@ -2151,7 +2173,7 @@ int append_path(char *path, const char *to_append, size_t max_len)
return FAIL;
}
- STRCAT(path, to_append);
+ xstrlcat(path, to_append, max_len);
return OK;
}
@@ -2181,7 +2203,8 @@ static int path_get_absolute_path(const char_u *fname, char_u *buf,
relative_directory[0] = '/';
relative_directory[1] = NUL;
} else {
- STRNCPY(relative_directory, fname, p-fname);
+ assert(p >= fname);
+ memcpy(relative_directory, fname, (size_t)(p - fname));
relative_directory[p-fname] = NUL;
}
end_of_path = (char *) (p + 1);
@@ -2214,3 +2237,50 @@ int path_is_absolute_path(const char_u *fname)
return *fname == '/' || *fname == '~';
#endif
}
+
+/// Builds a full path from an invocation name `argv0`, based on heuristics.
+///
+/// @param[in] argv0 Name by which Nvim was invoked.
+/// @param[out] buf Guessed full path to `argv0`.
+/// @param[in] bufsize Size of `buf`.
+///
+/// @see os_exepath
+void path_guess_exepath(const char *argv0, char *buf, size_t bufsize)
+ FUNC_ATTR_NONNULL_ALL
+{
+ char *path = getenv("PATH");
+
+ if (path == NULL || path_is_absolute_path((char_u *)argv0)) {
+ xstrlcpy(buf, argv0, bufsize);
+ } else if (argv0[0] == '.' || strchr(argv0, PATHSEP)) {
+ // Relative to CWD.
+ if (os_dirname((char_u *)buf, MAXPATHL) != OK) {
+ buf[0] = NUL;
+ }
+ xstrlcat(buf, PATHSEPSTR, bufsize);
+ xstrlcat(buf, argv0, bufsize);
+ } else {
+ // Search $PATH for plausible location.
+ const void *iter = NULL;
+ do {
+ const char *dir;
+ size_t dir_len;
+ iter = vim_env_iter(ENV_SEPCHAR, path, iter, &dir, &dir_len);
+ if (dir == NULL || dir_len == 0) {
+ break;
+ }
+ if (dir_len + 1 > sizeof(NameBuff)) {
+ continue;
+ }
+ xstrlcpy((char *)NameBuff, dir, dir_len + 1);
+ xstrlcat((char *)NameBuff, PATHSEPSTR, sizeof(NameBuff));
+ xstrlcat((char *)NameBuff, argv0, sizeof(NameBuff));
+ if (os_can_exe(NameBuff, NULL, false)) {
+ xstrlcpy(buf, (char *)NameBuff, bufsize);
+ return;
+ }
+ } while (iter != NULL);
+ // Not found in $PATH, fall back to argv0.
+ xstrlcpy(buf, argv0, bufsize);
+ }
+}
diff --git a/src/nvim/po/CMakeLists.txt b/src/nvim/po/CMakeLists.txt
index d2b62f89a0..121f22129a 100644
--- a/src/nvim/po/CMakeLists.txt
+++ b/src/nvim/po/CMakeLists.txt
@@ -32,10 +32,10 @@ if(HAVE_WORKING_LIBINTL AND GETTEXT_FOUND AND XGETTEXT_PRG AND ICONV_PRG)
zh_CN.UTF-8
zh_TW.UTF-8)
- set(NEOVIM_RELATIVE_SOURCES)
- foreach(SRC ${NEOVIM_SOURCES} ${NEOVIM_HEADERS})
+ set(NVIM_RELATIVE_SOURCES)
+ foreach(SRC ${NVIM_SOURCES} ${NVIM_HEADERS})
file(RELATIVE_PATH RELATIVE_SRC ${CMAKE_CURRENT_SOURCE_DIR} ${SRC})
- list(APPEND NEOVIM_RELATIVE_SOURCES ${RELATIVE_SRC})
+ list(APPEND NVIM_RELATIVE_SOURCES ${RELATIVE_SRC})
endforeach()
set(NVIM_POT ${CMAKE_CURRENT_BINARY_DIR}/nvim.pot)
@@ -46,9 +46,9 @@ if(HAVE_WORKING_LIBINTL AND GETTEXT_FOUND AND XGETTEXT_PRG AND ICONV_PRG)
-DXGETTEXT_PRG=${XGETTEXT_PRG}
-DPOT_FILE=${NVIM_POT}
-DSEARCH_DIR=${CMAKE_CURRENT_SOURCE_DIR}
- "\"-DSOURCES=${NEOVIM_RELATIVE_SOURCES}\""
+ "\"-DSOURCES=${NVIM_RELATIVE_SOURCES}\""
-P ${PROJECT_SOURCE_DIR}/cmake/RunXgettext.cmake
- DEPENDS ${NEOVIM_SOURCES})
+ DEPENDS ${NVIM_SOURCES})
add_custom_target(potfile DEPENDS ${NVIM_POT})
diff --git a/src/nvim/po/check.vim b/src/nvim/po/check.vim
index 1622741da6..b323174550 100644
--- a/src/nvim/po/check.vim
+++ b/src/nvim/po/check.vim
@@ -33,36 +33,66 @@ func! GetMline()
return substitute(idline, '[^%]*\(%[-+ #''.0-9*]*l\=[dsuxXpoc%]\)\=', '\1', 'g')
endfunc
-" This only works when 'wrapscan' is set.
+" This only works when 'wrapscan' is not set.
let s:save_wrapscan = &wrapscan
-set wrapscan
+set nowrapscan
" Start at the first "msgid" line.
1
-/^msgid
-let startline = line('.')
+/^msgid\>
+
+" When an error is detected this is set to the line number.
+" Note: this is used in the Makefile.
let error = 0
while 1
if getline(line('.') - 1) !~ "no-c-format"
- let fromline = GetMline()
+ " go over the "msgid" and "msgid_plural" lines
+ let prevfromline = 'foobar'
+ while 1
+ let fromline = GetMline()
+ if prevfromline != 'foobar' && prevfromline != fromline
+ echomsg 'Mismatching % in line ' . (line('.') - 1)
+ echomsg 'msgid: ' . prevfromline
+ echomsg 'msgid ' . fromline
+ if error == 0
+ let error = line('.')
+ endif
+ endif
+ if getline('.') !~ 'msgid_plural'
+ break
+ endif
+ let prevfromline = fromline
+ endwhile
+
if getline('.') !~ '^msgstr'
- echo 'Missing "msgstr" in line ' . line('.')
- let error = 1
- endif
- let toline = GetMline()
- if fromline != toline
- echo 'Mismatching % in line ' . (line('.') - 1)
- echo 'msgid: ' . fromline
- echo 'msgstr: ' . toline
- let error = 1
+ echomsg 'Missing "msgstr" in line ' . line('.')
+ if error == 0
+ let error = line('.')
+ endif
endif
+
+ " check all the 'msgstr' lines
+ while getline('.') =~ '^msgstr'
+ let toline = GetMline()
+ if fromline != toline
+ echomsg 'Mismatching % in line ' . (line('.') - 1)
+ echomsg 'msgid: ' . fromline
+ echomsg 'msgstr: ' . toline
+ if error == 0
+ let error = line('.')
+ endif
+ endif
+ if line('.') == line('$')
+ break
+ endif
+ endwhile
endif
- " Find next msgid.
- " Wrap around at the end of the file, quit when back at the first one.
- /^msgid
- if line('.') == startline
+ " Find next msgid. Quit when there is no more.
+ let lnum = line('.')
+ silent! /^msgid\>
+ if line('.') == lnum
break
endif
endwhile
@@ -77,12 +107,16 @@ endwhile
"
1
if search('msgid "\("\n"\)\?\([EW][0-9]\+:\).*\nmsgstr "\("\n"\)\?[^"]\@=\2\@!') > 0
- echo 'Mismatching error/warning code in line ' . line('.')
- let error = 1
+ echomsg 'Mismatching error/warning code in line ' . line('.')
+ if error == 0
+ let error = line('.')
+ endif
endif
if error == 0
- echo "OK"
+ echomsg "OK"
+else
+ exe error
endif
redir END
diff --git a/src/nvim/po/eo.po b/src/nvim/po/eo.po
index d0a47d6e9b..3fb300c63f 100644
--- a/src/nvim/po/eo.po
+++ b/src/nvim/po/eo.po
@@ -5,7 +5,7 @@
#
# UNUA TRADUKISTO Dominique PELLE <dominique.pelle ĉe gmail.com>
# PROVLEGANTO(J) Felipe CASTRO <fefcas ĉe gmail.com>
-# Antono MECHELYNCK <antoine.mechelynck ĉe skynet.be>
+# Antono MECHELYNCK <antoine.mechelynck ĉe gmail.com>
# Yves NEVELSTEEN
#
# Uzitaj vortaroj kaj fakvortaroj:
@@ -23,8 +23,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Vim(Esperanto)\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-03-29 23:03+0200\n"
-"PO-Revision-Date: 2016-03-29 23:05+0200\n"
+"POT-Creation-Date: 2017-01-16 00:30+0100\n"
+"PO-Revision-Date: 2017-01-16 01:14+0100\n"
"Last-Translator: Dominique PELLÉ <dominique.pelle@gmail.com>\n"
"Language-Team: \n"
"Language: eo\n"
@@ -32,203 +32,169 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "fiaskis akiri valoron de opcio"
+msgid "E831: bf_key_init() called with empty password"
+msgstr "E831: bf_key_init() alvokita kun malplena pasvorto"
-#: ../api/private/helpers.c:204
-#, fuzzy
-msgid "internal error: unknown option type"
-msgstr "interna eraro: neniu vim-a listero"
+msgid "E820: sizeof(uint32_t) != 4"
+msgstr "E820: sizeof(uint32_t) != 4"
+
+msgid "E817: Blowfish big/little endian use wrong"
+msgstr "E817: Misuzo de pezkomenca/pezfina en blowfish"
+
+msgid "E818: sha256 test failed"
+msgstr "E818: Testo de sha256 malsukcesis"
+
+msgid "E819: Blowfish test failed"
+msgstr "E819: Testo de blowfish malsukcesis"
-#: ../buffer.c:92
msgid "[Location List]"
msgstr "[Listo de lokoj]"
# DP: Ĉu vere indas traduki Quickfix?
-#: ../buffer.c:93
msgid "[Quickfix List]"
msgstr "[Listo de rapidriparoj]"
-#: ../buffer.c:94
msgid "E855: Autocommands caused command to abort"
msgstr "E855: AÅ­tokomandoj haltigis komandon"
-#: ../buffer.c:135
msgid "E82: Cannot allocate any buffer, exiting..."
msgstr "E82: Ne eblas disponigi iun ajn bufron, nun eliras..."
-#: ../buffer.c:138
msgid "E83: Cannot allocate buffer, using other one..."
msgstr "E83: Ne eblas disponigi bufron, nun uzas alian..."
-#: ../buffer.c:763
+msgid "E931: Buffer cannot be registered"
+msgstr "E931: Bufro ne povas esti registrita"
+
+msgid "E937: Attempt to delete a buffer that is in use"
+msgstr "E937: Provo de forviÅo de bufro, kiu estas uzanta"
+
msgid "E515: No buffers were unloaded"
msgstr "E515: Neniu bufro estis malÅargita"
-#: ../buffer.c:765
msgid "E516: No buffers were deleted"
msgstr "E516: Neniu bufro estis forviÅita"
-#: ../buffer.c:767
msgid "E517: No buffers were wiped out"
msgstr "E517: Neniu bufro estis detruita"
-#: ../buffer.c:772
msgid "1 buffer unloaded"
msgstr "1 bufro malÅargita"
-#: ../buffer.c:774
#, c-format
msgid "%d buffers unloaded"
msgstr "%d bufroj malÅargitaj"
-#: ../buffer.c:777
msgid "1 buffer deleted"
msgstr "1 bufro forviÅita"
-#: ../buffer.c:779
#, c-format
msgid "%d buffers deleted"
msgstr "%d bufroj forviÅitaj"
-#: ../buffer.c:782
msgid "1 buffer wiped out"
msgstr "1 bufro detruita"
-#: ../buffer.c:784
#, c-format
msgid "%d buffers wiped out"
msgstr "%d bufroj detruitaj"
-#: ../buffer.c:806
msgid "E90: Cannot unload last buffer"
msgstr "E90: Ne eblas malÅargi la lastan bufron"
-#: ../buffer.c:874
msgid "E84: No modified buffer found"
msgstr "E84: Neniu modifita bufro trovita"
#. back where we started, didn't find anything.
-#: ../buffer.c:903
msgid "E85: There is no listed buffer"
msgstr "E85: Estas neniu listigita bufro"
-#: ../buffer.c:915
msgid "E87: Cannot go beyond last buffer"
msgstr "E87: Ne eblas iri preter la lastan bufron"
-#: ../buffer.c:917
msgid "E88: Cannot go before first buffer"
msgstr "E88: Ne eblas iri antaÅ­ la unuan bufron"
-#: ../buffer.c:945
#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
msgstr ""
-"E89: Neniu skribo de post la lasta ÅanÄo de la bufro %<PRId64> (aldonu ! por "
+"E89: Neniu skribo de post la lasta ÅanÄo de la bufro %ld (aldonu ! por "
"transpasi)"
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
msgid "W14: Warning: List of file names overflow"
msgstr "W14: Averto: Listo de dosiernomoj troas"
-#: ../buffer.c:1555 ../quickfix.c:3361
#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: Bufro %<PRId64> ne trovita"
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Bufro %ld ne trovita"
-#: ../buffer.c:1798
#, c-format
msgid "E93: More than one match for %s"
msgstr "E93: Pli ol unu kongruo kun %s"
-#: ../buffer.c:1800
#, c-format
msgid "E94: No matching buffer for %s"
msgstr "E94: Neniu bufro kongruas kun %s"
-#: ../buffer.c:2161
#, c-format
-msgid "line %<PRId64>"
-msgstr "linio %<PRId64>"
+msgid "line %ld"
+msgstr "linio %ld"
-#: ../buffer.c:2233
msgid "E95: Buffer with this name already exists"
msgstr "E95: Bufro kun tiu nomo jam ekzistas"
-#: ../buffer.c:2498
msgid " [Modified]"
msgstr "[Modifita]"
-#: ../buffer.c:2501
msgid "[Not edited]"
msgstr "[Ne redaktita]"
-#: ../buffer.c:2504
msgid "[New file]"
msgstr "[Nova dosiero]"
-#: ../buffer.c:2505
msgid "[Read errors]"
msgstr "[Eraroj de legado]"
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
msgid "[RO]"
msgstr "[Nurlegebla]"
-#: ../buffer.c:2507 ../fileio.c:1807
msgid "[readonly]"
msgstr "[nurlegebla]"
-#: ../buffer.c:2524
#, c-format
msgid "1 line --%d%%--"
msgstr "1 linio --%d%%--"
-#: ../buffer.c:2526
#, c-format
-msgid "%<PRId64> lines --%d%%--"
-msgstr "%<PRId64> linioj --%d%%--"
+msgid "%ld lines --%d%%--"
+msgstr "%ld linioj --%d%%--"
-#: ../buffer.c:2530
#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "linio %<PRId64> de %<PRId64> --%d%%-- kol "
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "linio %ld de %ld --%d%%-- kol "
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
msgid "[No Name]"
msgstr "[Neniu nomo]"
#. must be a help buffer
-#: ../buffer.c:2667
msgid "help"
msgstr "helpo"
-#: ../buffer.c:3225 ../screen.c:4883
msgid "[Help]"
msgstr "[Helpo]"
-#: ../buffer.c:3254 ../screen.c:4887
msgid "[Preview]"
msgstr "[AntaÅ­vido]"
-#: ../buffer.c:3528
msgid "All"
msgstr "Ĉio"
-#: ../buffer.c:3528
msgid "Bot"
msgstr "Subo"
-#: ../buffer.c:3531
msgid "Top"
msgstr "Supro"
-#: ../buffer.c:4244
msgid ""
"\n"
"# Buffer list:\n"
@@ -236,12 +202,10 @@ msgstr ""
"\n"
"# Listo de bufroj:\n"
-#: ../buffer.c:4289
msgid "[Scratch]"
msgstr "[Malneto]"
# DP: Vidu ":help sign-support" por klarigo pri "Sign"
-#: ../buffer.c:4529
msgid ""
"\n"
"--- Signs ---"
@@ -249,200 +213,235 @@ msgstr ""
"\n"
"--- Emfazaj simbolaĵoj ---"
-#: ../buffer.c:4538
#, c-format
msgid "Signs for %s:"
msgstr "Emfazaj simbolaĵoj de %s:"
-#: ../buffer.c:4543
#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " linio=%<PRId64> id=%d nomo=%s"
+msgid " line=%ld id=%d name=%s"
+msgstr " linio=%ld id=%d nomo=%s"
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: Mankas dupunkto"
+msgid "E902: Cannot connect to port"
+msgstr "E902: Ne eblas konekti al pordo"
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: ReÄimo nepermesata"
+msgid "E901: gethostbyname() in channel_open()"
+msgstr "E901: gethostbyname() en channel_open()"
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: cifero atendata"
+msgid "E898: socket() in channel_open()"
+msgstr "E898: gethostbyname() en channel_open()"
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: Nevalida procento"
+msgid "E903: received command with non-string argument"
+msgstr "E903: ricevis komandon kun argumento, kiu ne estas ĉeno"
+
+msgid "E904: last argument for expr/call must be a number"
+msgstr "E904: lasta argumento de \"expr/call\" devas esti nombro"
+
+msgid "E904: third argument for call must be a list"
+msgstr "E904: tria argumento de \"call\" devas esti listo"
+
+#, c-format
+msgid "E905: received unknown command: %s"
+msgstr "E905: nekonata komando ricevita: %s"
+
+#, c-format
+msgid "E630: %s(): write while not connected"
+msgstr "E630: %s(): konservo dum nekonektita"
+
+#, c-format
+msgid "E631: %s(): write failed"
+msgstr "E631: %s(): Konservo malsukcesis"
+
+#, c-format
+msgid "E917: Cannot use a callback with %s()"
+msgstr "E917: Ne eblas uzi reagfunkcion kun %s()"
+
+msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel"
+msgstr "E912: ne eblas uzi ch_evalexpr()/ch_sendexpr() kun kruda aÅ­ nl kanalo"
+
+msgid "E906: not an open channel"
+msgstr "E906: ne estas malfermita kanalo"
+
+msgid "E920: _io file requires _name to be set"
+msgstr "E920: dosiero _io bezonas _name"
+
+msgid "E915: in_io buffer requires in_buf or in_name to be set"
+msgstr "E915: bufro in_io bezonas in_buf aÅ­ in_name"
+
+#, c-format
+msgid "E918: buffer must be loaded: %s"
+msgstr "E918: bufro devas esti Åargita: %s"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: Dosiero estas ĉifrita per nekonata metodo"
+
+msgid "Warning: Using a weak encryption method; see :help 'cm'"
+msgstr "Averto: uzo de malfortika ĉifrada metodo; vidu :help 'cm'"
+
+msgid "Enter encryption key: "
+msgstr "Tajpu la Ålosilon de ĉifrado: "
+
+msgid "Enter same key again: "
+msgstr "Tajpu la Ålosilon denove: "
+
+msgid "Keys don't match!"
+msgstr "Åœlosiloj ne kongruas!"
+
+msgid "[crypted]"
+msgstr "[ĉifrita]"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Mankas dupunkto en la vortaro: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Ripetita Ålosilo en la vortaro: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Mankas komo en la vortaro: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Mankas fino de vortaro '}': %s"
+
+msgid "extend() argument"
+msgstr "argumento de extend()"
-#: ../diff.c:146
#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: Ne eblas dosierdiferenci pli ol %<PRId64> bufrojn"
+msgid "E737: Key already exists: %s"
+msgstr "E737: Åœlosilo jam ekzistas: %s"
+
+#, c-format
+msgid "E96: Cannot diff more than %ld buffers"
+msgstr "E96: Ne eblas dosierdiferenci pli ol %ld bufrojn"
-#: ../diff.c:753
msgid "E810: Cannot read or write temp files"
msgstr "E810: Ne eblas legi aÅ­ skribi provizorajn dosierojn"
-#: ../diff.c:755
msgid "E97: Cannot create diffs"
msgstr "E97: Ne eblas krei dosierdiferencojn"
-#: ../diff.c:966
+msgid "Patch file"
+msgstr "Flika dosiero"
+
msgid "E816: Cannot read patch output"
msgstr "E816: Ne eblas legi eliron de flikilo \"patch\""
-#: ../diff.c:1220
msgid "E98: Cannot read diff output"
msgstr "E98: Ne eblas legi eliron de dosierdiferencilo \"diff\""
-#: ../diff.c:2081
msgid "E99: Current buffer is not in diff mode"
msgstr "E99: Aktuala bufro ne estas en dosierdiferenca reÄimo"
-#: ../diff.c:2100
msgid "E793: No other buffer in diff mode is modifiable"
msgstr "E793: Neniu alia bufro en dosierdiferenca reÄimo estas modifebla"
-#: ../diff.c:2102
msgid "E100: No other buffer in diff mode"
msgstr "E100: Neniu alia bufro en dosierdiferenca reÄimo"
-#: ../diff.c:2112
msgid "E101: More than two buffers in diff mode, don't know which one to use"
msgstr "E101: Pli ol du bufroj en dosierdiferenca reÄimo, ne scias kiun uzi"
-#: ../diff.c:2141
#, c-format
msgid "E102: Can't find buffer \"%s\""
msgstr "E102: Ne eblas trovi bufron \"%s\""
-#: ../diff.c:2152
#, c-format
msgid "E103: Buffer \"%s\" is not in diff mode"
msgstr "E103: Bufro \"%s\" ne estas en dosierdiferenca reÄimo"
-#: ../diff.c:2193
msgid "E787: Buffer changed unexpectedly"
msgstr "E787: Bufro ÅanÄiÄis neatendite"
-#: ../digraph.c:1598
msgid "E104: Escape not allowed in digraph"
msgstr "E104: Eskapsigno nepermesebla en duliteraĵo"
-#: ../digraph.c:1760
msgid "E544: Keymap file not found"
msgstr "E544: Dosiero de klavmapo ne troveblas"
-#: ../digraph.c:1785
msgid "E105: Using :loadkeymap not in a sourced file"
msgstr "E105: Uzo de \":loadkeymap\" nur eblas en vim-skripto"
-#: ../digraph.c:1821
msgid "E791: Empty keymap entry"
msgstr "E791: Malplena rikordo en klavmapo"
-#: ../edit.c:82
msgid " Keyword completion (^N^P)"
msgstr " Kompletigo de Ålosilvorto (^N^P)"
#. ctrl_x_mode == 0, ^P/^N compl.
-#: ../edit.c:83
msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
msgstr " ReÄimo ^X (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
-#: ../edit.c:85
msgid " Whole line completion (^L^N^P)"
msgstr " Kompletigo de tuta linio (^L^N^P)"
-#: ../edit.c:86
msgid " File name completion (^F^N^P)"
msgstr " Kompletigo de dosiernomo (^F^N^P)"
-#: ../edit.c:87
msgid " Tag completion (^]^N^P)"
msgstr " Kompletigo de etikedo (^]^N^P)"
-#: ../edit.c:88
msgid " Path pattern completion (^N^P)"
msgstr " Kompletigo de Åablona dosierindiko (^N^P)"
-#: ../edit.c:89
msgid " Definition completion (^D^N^P)"
msgstr " Kompletigo de difino (^D^N^P)"
-#: ../edit.c:91
msgid " Dictionary completion (^K^N^P)"
msgstr " Kompletigo de vortaro (^K^N^P)"
-#: ../edit.c:92
msgid " Thesaurus completion (^T^N^P)"
msgstr " Kompletigo de tezaÅ­ro (^T^N^P)"
-#: ../edit.c:93
msgid " Command-line completion (^V^N^P)"
msgstr " Kompletigo de komanda linio (^V^N^P)"
-#: ../edit.c:94
msgid " User defined completion (^U^N^P)"
msgstr " Kompletigo difinita de uzanto (^U^N^P)"
# DP: Ĉu eblas trovi pli bonan tradukon?
-#: ../edit.c:95
msgid " Omni completion (^O^N^P)"
msgstr " Kompletigo Omni (^O^N^P)"
-#: ../edit.c:96
msgid " Spelling suggestion (s^N^P)"
msgstr " Sugesto de literumo (s^N^P)"
-#: ../edit.c:97
msgid " Keyword Local completion (^N^P)"
msgstr " Kompletigo loka de Ålosilvorto (^N/^P)"
-#: ../edit.c:100
msgid "Hit end of paragraph"
msgstr "Atingis finon de alineo"
-#: ../edit.c:101
msgid "E839: Completion function changed window"
msgstr "E839: Kompletiga funkcio ÅanÄis la fenestron"
-#: ../edit.c:102
msgid "E840: Completion function deleted text"
msgstr "E840: Kompletiga funkcio forviÅis tekston"
-#: ../edit.c:1847
msgid "'dictionary' option is empty"
msgstr "La opcio 'dictionary' estas malplena"
-#: ../edit.c:1848
msgid "'thesaurus' option is empty"
msgstr "La opcio 'thesaurus' estas malplena"
-#: ../edit.c:2655
#, c-format
msgid "Scanning dictionary: %s"
msgstr "Analizas vortaron: %s"
-#: ../edit.c:3079
msgid " (insert) Scroll (^E/^Y)"
msgstr " (enmeto) Rulumo (^E/^Y)"
-#: ../edit.c:3081
msgid " (replace) Scroll (^E/^Y)"
msgstr " (anstataÅ­igo) Rulumo (^E/^Y)"
-#: ../edit.c:3587
#, c-format
msgid "Scanning: %s"
msgstr "Analizas: %s"
-#: ../edit.c:3614
msgid "Scanning tags."
msgstr "Analizas etikedojn."
-#: ../edit.c:4519
msgid " Adding"
msgstr " Aldonanta"
@@ -450,429 +449,159 @@ msgstr " Aldonanta"
#. * be called before line = ml_get(), or when this address is no
#. * longer needed. -- Acevedo.
#.
-#: ../edit.c:4562
msgid "-- Searching..."
msgstr "-- Serĉanta..."
-#: ../edit.c:4618
msgid "Back at original"
msgstr "Reveninta al originalo"
-#: ../edit.c:4621
msgid "Word from other line"
msgstr "Vorto el alia linio"
-#: ../edit.c:4624
msgid "The only match"
msgstr "La sola kongruo"
-#: ../edit.c:4680
#, c-format
msgid "match %d of %d"
msgstr "kongruo %d de %d"
-#: ../edit.c:4684
#, c-format
msgid "match %d"
msgstr "kongruo %d"
-#: ../eval.c:137
+#. maximum nesting of lists and dicts
msgid "E18: Unexpected characters in :let"
msgstr "E18: Neatenditaj signoj en \":let\""
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: indekso de listo ekster limoj: %<PRId64>"
-
-#: ../eval.c:139
#, c-format
msgid "E121: Undefined variable: %s"
msgstr "E121: Nedifinita variablo: %s"
-#: ../eval.c:140
msgid "E111: Missing ']'"
msgstr "E111: Mankas ']'"
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: Argumento de %s devas esti Listo"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: Argumento de %s devas esti Listo aÅ­ Vortaro"
-
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: Listo bezonata"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: Vortaro bezonata"
-
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: Tro da argumentoj por funkcio: %s"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: Åœlosilo malekzistas en Vortaro: %s"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: La funkcio %s jam ekzistas (aldonu ! por anstataÅ­igi Äin)"
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: Rikordo de vortaro jam ekzistas"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: Funcref bezonata"
-
-#: ../eval.c:153
msgid "E719: Cannot use [:] with a Dictionary"
msgstr "E719: Uzo de [:] ne eblas kun Vortaro"
-#: ../eval.c:154
#, c-format
msgid "E734: Wrong variable type for %s="
msgstr "E734: Nevalida datumtipo de variablo de %s="
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: Nekonata funkcio: %s"
-
-#: ../eval.c:156
#, c-format
msgid "E461: Illegal variable name: %s"
msgstr "E461: Nevalida nomo de variablo: %s"
-#: ../eval.c:157
msgid "E806: using Float as a String"
msgstr "E806: uzo de Glitpunktnombro kiel Ĉeno"
-#: ../eval.c:1830
msgid "E687: Less targets than List items"
msgstr "E687: Malpli da celoj ol Listeroj"
-#: ../eval.c:1834
msgid "E688: More targets than List items"
msgstr "E688: Pli da celoj ol Listeroj"
-#: ../eval.c:1906
msgid "Double ; in list of variables"
msgstr "Duobla ; en listo de variabloj"
-#: ../eval.c:2078
#, c-format
msgid "E738: Can't list variables for %s"
msgstr "E738: Ne eblas listigi variablojn de %s"
-#: ../eval.c:2391
msgid "E689: Can only index a List or Dictionary"
msgstr "E689: Nur eblas indeksi Liston aÅ­ Vortaron"
-#: ../eval.c:2396
msgid "E708: [:] must come last"
msgstr "E708: [:] devas esti laste"
-#: ../eval.c:2439
msgid "E709: [:] requires a List value"
msgstr "E709: [:] bezonas listan valoron"
-#: ../eval.c:2674
msgid "E710: List value has more items than target"
msgstr "E710: Lista valoro havas pli da eroj ol la celo"
-#: ../eval.c:2678
msgid "E711: List value has not enough items"
msgstr "E711: Lista valoro ne havas sufiĉe da eroj"
-#: ../eval.c:2867
msgid "E690: Missing \"in\" after :for"
msgstr "E690: \"in\" mankas post \":for\""
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: Mankas krampoj: %s"
-
-#: ../eval.c:3263
#, c-format
msgid "E108: No such variable: \"%s\""
msgstr "E108: Ne estas tia variablo: \"%s\""
-#: ../eval.c:3333
msgid "E743: variable nested too deep for (un)lock"
msgstr "E743: variablo ingita tro profunde por malÅlosi"
-#: ../eval.c:3630
msgid "E109: Missing ':' after '?'"
msgstr "E109: Mankas ':' post '?'"
-#: ../eval.c:3893
msgid "E691: Can only compare List with List"
msgstr "E691: Eblas nur kompari Liston kun Listo"
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
+msgid "E692: Invalid operation for List"
msgstr "E692: Nevalida operacio de Listoj"
-#: ../eval.c:3915
msgid "E735: Can only compare Dictionary with Dictionary"
msgstr "E735: Eblas nur kompari Vortaron kun Vortaro"
-#: ../eval.c:3917
msgid "E736: Invalid operation for Dictionary"
msgstr "E736: Nevalida operacio de Vortaro"
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: Eblas nur kompari Funcref kun Funcref"
-
-#: ../eval.c:3934
msgid "E694: Invalid operation for Funcrefs"
msgstr "E694: Nevalida operacio de Funcref-oj"
-#: ../eval.c:4277
msgid "E804: Cannot use '%' with Float"
msgstr "E804: Ne eblas uzi '%' kun Glitpunktnombro"
-#: ../eval.c:4478
msgid "E110: Missing ')'"
msgstr "E110: Mankas ')'"
-#: ../eval.c:4609
msgid "E695: Cannot index a Funcref"
msgstr "E695: Ne eblas indeksi Funcref"
msgid "E909: Cannot index a special variable"
msgstr "E909: Ne eblas indeksi specialan variablon"
-#: ../eval.c:4839
#, c-format
msgid "E112: Option name missing: %s"
msgstr "E112: Mankas nomo de opcio: %s"
-#: ../eval.c:4855
#, c-format
msgid "E113: Unknown option: %s"
msgstr "E113: Nekonata opcio: %s"
-#: ../eval.c:4904
#, c-format
msgid "E114: Missing quote: %s"
msgstr "E114: Mankas citilo: %s"
-#: ../eval.c:5020
#, c-format
msgid "E115: Missing quote: %s"
msgstr "E115: Mankas citilo: %s"
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: Mankas komo en Listo: %s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: Mankas fino de Listo ']': %s"
-
-#: ../eval.c:5750
msgid "Not enough memory to set references, garbage collection aborted!"
msgstr "Ne sufiĉa memoro por valorigi referencojn, senrubigado ĉesigita!"
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: Mankas dupunkto en la vortaro: %s"
-
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: Ripetita Ålosilo en la vortaro: \"%s\""
-
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: Mankas komo en la vortaro: %s"
-
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: Mankas fino de vortaro '}': %s"
-
-#: ../eval.c:6555
msgid "E724: variable nested too deep for displaying"
msgstr "E724: variablo ingita tro profunde por vidigi"
-#: ../eval.c:7188
-#, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E740: Tro da argumentoj por funkcio: %s"
-
-#: ../eval.c:7190
-#, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E116: Nevalidaj argumentoj por funkcio: %s"
-
-#: ../eval.c:7377
-#, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E117: Nekonata funkcio: %s"
-
-#: ../eval.c:7383
-#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: Ne sufiĉe da argumentoj por funkcio: %s"
-
-#: ../eval.c:7387
-#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: <SID> estas uzata ekster kunteksto de skripto: %s"
-
-#: ../eval.c:7391
-#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E725: Alvoko de funkcio dict sen Vortaro: %s"
-
-#: ../eval.c:7453
-msgid "E808: Number or Float required"
-msgstr "E808: Nombro aÅ­ Glitpunktnombro bezonata"
-
-#: ../eval.c:7503
-msgid "add() argument"
-msgstr "argumento de add()"
-
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: Tro da argumentoj"
-
-#: ../eval.c:8073
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete() uzeblas nur en Enmeta reÄimo"
-
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "&Bone"
-
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: Åœlosilo jam ekzistas: %s"
-
-#: ../eval.c:8692
-msgid "extend() argument"
-msgstr "argumento de extend()"
-
-#: ../eval.c:8915
-msgid "map() argument"
-msgstr "argumento de map()"
-
-#: ../eval.c:8916
-msgid "filter() argument"
-msgstr "argumento de filter()"
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld linioj: "
-
-#: ../eval.c:9291
-#, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E700: Nekonata funkcio: %s"
-
-#: ../eval.c:10729
-msgid "called inputrestore() more often than inputsave()"
-msgstr "alvokis inputrestore() pli ofte ol inputsave()"
-
-#: ../eval.c:10771
-msgid "insert() argument"
-msgstr "argumento de insert()"
-
-#: ../eval.c:10841
-msgid "E786: Range not allowed"
-msgstr "E786: Amplekso nepermesebla"
-
-#: ../eval.c:11140
-msgid "E701: Invalid type for len()"
-msgstr "E701: Nevalida datumtipo de len()"
-
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr "E726: PaÅo estas nul"
-
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr "E727: Komenco preter fino"
-
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr "<malplena>"
-
-#: ../eval.c:12282
-msgid "remove() argument"
-msgstr "argumento de remove()"
-
-#: ../eval.c:12466
-msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: Tro da simbolaj ligiloj (ĉu estas ciklo?)"
-
-#: ../eval.c:12593
-msgid "reverse() argument"
-msgstr "argumento de reverse()"
-
-#: ../eval.c:13721
-msgid "sort() argument"
-msgstr "argumento de sort()"
-
-#: ../eval.c:13721
-#, fuzzy
-msgid "uniq() argument"
-msgstr "argumento de add()"
-
-#: ../eval.c:13776
-msgid "E702: Sort compare function failed"
-msgstr "E702: Ordiga funkcio fiaskis"
-
-#: ../eval.c:13806
-#, fuzzy
-msgid "E882: Uniq compare function failed"
-msgstr "E702: Ordiga funkcio fiaskis"
-
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(Nevalida)"
-
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: Eraro dum skribo de provizora dosiero"
-
-#: ../eval.c:16159
msgid "E805: Using a Float as a Number"
msgstr "E805: Uzo de Glitpunktnombro kiel Nombro"
-#: ../eval.c:16162
msgid "E703: Using a Funcref as a Number"
msgstr "E703: Uzo de Funcref kiel Nombro"
-#: ../eval.c:16170
msgid "E745: Using a List as a Number"
msgstr "E745: Uzo de Listo kiel Nombro"
-#: ../eval.c:16173
msgid "E728: Using a Dictionary as a Number"
msgstr "E728: Uzo de Vortaro kiel Nombro"
+msgid "E910: Using a Job as a Number"
+msgstr "E910: Uzo de Tasko kiel Nombro"
+
+msgid "E913: Using a Channel as a Number"
+msgstr "E913: Uzo de Kanalo kiel Nombro"
+
msgid "E891: Using a Funcref as a Float"
msgstr "E891: Uzo de Funcref kiel Glitpunktnombro"
@@ -885,268 +614,280 @@ msgstr "E893: Uzo de Listo kiel Glitpunktnombro"
msgid "E894: Using a Dictionary as a Float"
msgstr "E894: Uzo de Vortaro kiel Glitpunktnombro"
-#: ../eval.c:16259
+msgid "E907: Using a special value as a Float"
+msgstr "E907: Uzo de speciala valoro kiel Glitpunktnombro"
+
+msgid "E911: Using a Job as a Float"
+msgstr "E911: Uzo de Tasko kiel Glitpunktnombro"
+
+msgid "E914: Using a Channel as a Float"
+msgstr "E914: Uzo de Kanalo kiel Glitpunktnombro"
+
msgid "E729: using Funcref as a String"
msgstr "E729: uzo de Funcref kiel Ĉeno"
-#: ../eval.c:16262
msgid "E730: using List as a String"
msgstr "E730: uzo de Listo kiel Ĉeno"
-#: ../eval.c:16265
msgid "E731: using Dictionary as a String"
msgstr "E731: uzo de Vortaro kiel Ĉeno"
msgid "E908: using an invalid value as a String"
msgstr "E908: uzo de nevalida valoro kiel Ĉeno"
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: Nekongrua datumtipo de variablo: %s"
-
-#: ../eval.c:16705
#, c-format
msgid "E795: Cannot delete variable %s"
msgstr "E795: Ne eblas forviÅi variablon %s"
-#: ../eval.c:16724
#, c-format
msgid "E704: Funcref variable name must start with a capital: %s"
msgstr "E704: Nomo de variablo Funcref devas finiÄi per majusklo: %s"
-#: ../eval.c:16732
#, c-format
msgid "E705: Variable name conflicts with existing function: %s"
msgstr "E705: Nomo de variablo konfliktas kun ekzistanta funkcio: %s"
-#: ../eval.c:16763
#, c-format
msgid "E741: Value is locked: %s"
msgstr "E741: Valoro estas Ålosita: %s"
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
msgid "Unknown"
msgstr "Nekonata"
-#: ../eval.c:16768
#, c-format
msgid "E742: Cannot change value of %s"
msgstr "E742: Ne eblas ÅanÄi valoron de %s"
-#: ../eval.c:16838
msgid "E698: variable nested too deep for making a copy"
msgstr "E698: variablo ingita tro profunde por fari kopion"
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: Nedifinita funkcio: %s"
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# mallokaj variabloj:\n"
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: Mankas '(': %s"
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tLaste Åaltita de "
-#: ../eval.c:17293
-msgid "E862: Cannot use g: here"
-msgstr "E862: Ne eblas uzi g: ĉi tie"
+msgid "map() argument"
+msgstr "argumento de map()"
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: Nevalida argumento: %s"
+msgid "filter() argument"
+msgstr "argumento de filter()"
-#: ../eval.c:17323
#, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E853: Ripetita nomo de argumento: %s"
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Argumento de %s devas esti Listo"
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: Mankas \":endfunction\""
+msgid "E928: String required"
+msgstr "E928: Ĉeno bezonata"
-#: ../eval.c:17537
-#, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E707: Nomo de funkcio konfliktas kun variablo: %s"
+msgid "E808: Number or Float required"
+msgstr "E808: Nombro aÅ­ Glitpunktnombro bezonata"
+
+msgid "add() argument"
+msgstr "argumento de add()"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() uzeblas nur en Enmeta reÄimo"
+
+#.
+#. * 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"
-#: ../eval.c:17549
#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: Ne eblas redifini funkcion %s: Estas nuntempe uzata"
+msgid "+-%s%3ld line: "
+msgid_plural "+-%s%3ld lines: "
+msgstr[0] "+-%s%3ld linio: "
+msgstr[1] "+-%s%3ld linioj: "
-#: ../eval.c:17604
#, c-format
-msgid "E746: Function name does not match script file name: %s"
-msgstr "E746: Nomo de funkcio ne kongruas kun dosiernomo de skripto: %s"
+msgid "E700: Unknown function: %s"
+msgstr "E700: Nekonata funkcio: %s"
-#: ../eval.c:17716
-msgid "E129: Function name required"
-msgstr "E129: Nomo de funkcio bezonata"
+msgid "E922: expected a dict"
+msgstr "E922: vortaro atendita"
-#: ../eval.c:17824
-#, fuzzy, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr "E128: Nomo de funkcio devas eki per majusklo aÅ­ enhavi dupunkton: %s"
+msgid "E923: Second argument of function() must be a list or a dict"
+msgstr "E923: Dua argumento de function() devas esti listo aÅ­ Vortaro"
-#: ../eval.c:17833
-#, fuzzy, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr "E128: Nomo de funkcio devas eki per majusklo aÅ­ enhavi dupunkton: %s"
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&Bone\n"
+"&Rezigni"
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: Ne eblas forviÅi funkcion %s: Estas nuntempe uzata"
+msgid "called inputrestore() more often than inputsave()"
+msgstr "alvokis inputrestore() pli ofte ol inputsave()"
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: Profundo de funkcia alvoko superas 'maxfuncdepth'"
+msgid "insert() argument"
+msgstr "argumento de insert()"
-#: ../eval.c:18568
-#, c-format
-msgid "calling %s"
-msgstr "alvokas %s"
+msgid "E786: Range not allowed"
+msgstr "E786: Amplekso nepermesebla"
-#: ../eval.c:18651
-#, c-format
-msgid "%s aborted"
-msgstr "%s ĉesigita"
+msgid "E916: not a valid job"
+msgstr "E916: nevalida tasko"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Nevalida datumtipo de len()"
-#: ../eval.c:18653
#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s liveras #%<PRId64>"
+msgid "E798: ID is reserved for \":match\": %ld"
+msgstr "E798: ID estas rezervita por \":match\": %ld"
+
+msgid "E726: Stride is zero"
+msgstr "E726: PaÅo estas nul"
+
+msgid "E727: Start past end"
+msgstr "E727: Komenco preter fino"
+
+msgid "<empty>"
+msgstr "<malplena>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Neniu konekto al Vim-servilo"
-#: ../eval.c:18670
#, c-format
-msgid "%s returning %s"
-msgstr "%s liveras %s"
+msgid "E241: Unable to send to %s"
+msgstr "E241: Ne eblas sendi al %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Ne eblas legi respondon de servilo"
+
+msgid "remove() argument"
+msgstr "argumento de remove()"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Tro da simbolaj ligiloj (ĉu estas ciklo?)"
+
+msgid "reverse() argument"
+msgstr "argumento de reverse()"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Ne eblas sendi al kliento"
-#: ../eval.c:18691 ../ex_cmds2.c:2695
#, c-format
-msgid "continuing in %s"
-msgstr "daÅ­rigas en %s"
+msgid "E927: Invalid action: '%s'"
+msgstr "E927: Nevalida ago: '%s'"
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: \":return\" ekster funkcio"
+msgid "sort() argument"
+msgstr "argumento de sort()"
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# mallokaj variabloj:\n"
+msgid "uniq() argument"
+msgstr "argumento de uniq()"
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\tLaste Åaltita de "
+msgid "E702: Sort compare function failed"
+msgstr "E702: Ordiga funkcio malsukcesis"
-#: ../eval.c:19272
-msgid "No old files"
-msgstr "Neniu malnova dosiero"
+msgid "E882: Uniq compare function failed"
+msgstr "E882: kompara funkcio de uniq() malsukcesis"
+
+msgid "(Invalid)"
+msgstr "(Nevalida)"
+
+#, c-format
+msgid "E935: invalid submatch number: %d"
+msgstr "E935: nevalida indekso de \"submatch\": %d"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Eraro dum skribo de provizora dosiero"
+
+msgid "E921: Invalid callback argument"
+msgstr "E921: Nevalida argumento de reagfunctio"
-#: ../ex_cmds.c:122
#, c-format
msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
msgstr "<%s>%s%s %d, Deksesuma %02x, Okuma %03o"
-#: ../ex_cmds.c:145
#, c-format
msgid "> %d, Hex %04x, Octal %o"
msgstr "> %d, Deksesuma %04x, Okuma %o"
-#: ../ex_cmds.c:146
#, c-format
msgid "> %d, Hex %08x, Octal %o"
msgstr "> %d, Deksesuma %08x, Okuma %o"
-#: ../ex_cmds.c:684
msgid "E134: Move lines into themselves"
msgstr "E134: Movas liniojn en ilin mem"
-#: ../ex_cmds.c:747
msgid "1 line moved"
msgstr "1 linio movita"
-#: ../ex_cmds.c:749
#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "%<PRId64> linioj movitaj"
+msgid "%ld lines moved"
+msgstr "%ld linioj movitaj"
-#: ../ex_cmds.c:1175
#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "%<PRId64> linioj filtritaj"
+msgid "%ld lines filtered"
+msgstr "%ld linioj filtritaj"
-#: ../ex_cmds.c:1194
msgid "E135: *Filter* Autocommands must not change current buffer"
msgstr "E135: *Filtraj* AÅ­tokomandoj ne rajtas ÅanÄi aktualan bufron"
-#: ../ex_cmds.c:1244
msgid "[No write since last change]\n"
msgstr "[Neniu skribo de post lasta ÅanÄo]\n"
-#: ../ex_cmds.c:1424
#, c-format
msgid "%sviminfo: %s in line: "
msgstr "%sviminfo: %s en linio: "
-#: ../ex_cmds.c:1431
msgid "E136: viminfo: Too many errors, skipping rest of file"
msgstr "E136: viminfo: Tro da eraroj, nun ignoras la reston de la dosiero"
-#: ../ex_cmds.c:1458
#, c-format
msgid "Reading viminfo file \"%s\"%s%s%s"
msgstr "Legado de dosiero viminfo \"%s\"%s%s%s"
-#: ../ex_cmds.c:1460
msgid " info"
msgstr " informo"
-#: ../ex_cmds.c:1461
msgid " marks"
msgstr " markoj"
-#: ../ex_cmds.c:1462
msgid " oldfiles"
msgstr " malnovaj dosieroj"
-#: ../ex_cmds.c:1463
msgid " FAILED"
-msgstr " FIASKIS"
+msgstr " MALSUKCESIS"
#. avoid a wait_return for this message, it's annoying
-#: ../ex_cmds.c:1541
#, c-format
msgid "E137: Viminfo file is not writable: %s"
msgstr "E137: Dosiero viminfo ne skribeblas: %s"
-#: ../ex_cmds.c:1626
+#, c-format
+msgid "E929: Too many viminfo temp files, like %s!"
+msgstr "E929: Tro da provizoraj dosieroj viminfo, kiel %s!"
+
#, c-format
msgid "E138: Can't write viminfo file %s!"
msgstr "E138: Ne eblas skribi dosieron viminfo %s!"
-#: ../ex_cmds.c:1635
#, c-format
msgid "Writing viminfo file \"%s\""
msgstr "Skribas dosieron viminfo \"%s\""
+#, c-format
+msgid "E886: Can't rename viminfo file to %s!"
+msgstr "E886: Ne eblas renomi dosieron viminfo al %s!"
+
#. Write the info:
-#: ../ex_cmds.c:1720
#, c-format
msgid "# This viminfo file was generated by Vim %s.\n"
msgstr "# Tiu dosiero viminfo estis kreita de Vim %s.\n"
-#: ../ex_cmds.c:1722
msgid ""
"# You may edit it if you're careful!\n"
"\n"
@@ -1154,47 +895,47 @@ msgstr ""
"# Vi povas redakti Äin se vi estas singarda.\n"
"\n"
-#: ../ex_cmds.c:1723
msgid "# Value of 'encoding' when this file was written\n"
msgstr "# Valoro de 'encoding' kiam tiu dosiero estis kreita\n"
-#: ../ex_cmds.c:1800
msgid "Illegal starting char"
msgstr "Nevalida eka signo"
-#: ../ex_cmds.c:2162
+msgid ""
+"\n"
+"# Bar lines, copied verbatim:\n"
+msgstr ""
+"\n"
+"# Linioj komencantaj per |, kopiitaj sen ÅanÄo:\n"
+
+msgid "Save As"
+msgstr "Konservi kiel"
+
msgid "Write partial file?"
msgstr "Ĉu skribi partan dosieron?"
-#: ../ex_cmds.c:2166
msgid "E140: Use ! to write partial buffer"
msgstr "E140: Uzu ! por skribi partan bufron"
-#: ../ex_cmds.c:2281
#, c-format
msgid "Overwrite existing file \"%s\"?"
msgstr "Ĉu anstataŭigi ekzistantan dosieron \"%s\"?"
-#: ../ex_cmds.c:2317
#, c-format
msgid "Swap file \"%s\" exists, overwrite anyway?"
msgstr "Permutodosiero .swp \"%s\" ekzistas, ĉu tamen anstataÅ­igi Äin?"
-#: ../ex_cmds.c:2326
#, c-format
msgid "E768: Swap file exists: %s (:silent! overrides)"
msgstr "E768: Permutodosiero .swp ekzistas: %s (:silent! por transpasi)"
-#: ../ex_cmds.c:2381
#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: Neniu dosiernomo de bufro %<PRId64>"
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Neniu dosiernomo de bufro %ld"
-#: ../ex_cmds.c:2412
msgid "E142: File not written: Writing is disabled by 'write' option"
msgstr "E142: Dosiero ne skribita: Skribo malÅaltita per la opcio 'write'"
-#: ../ex_cmds.c:2434
#, c-format
msgid ""
"'readonly' option is set for \"%s\".\n"
@@ -1203,7 +944,6 @@ msgstr ""
"La opcio 'readonly' estas Åaltita por \"%s\".\n"
"Ĉu vi tamen volas skribi?"
-#: ../ex_cmds.c:2439
#, c-format
msgid ""
"File permissions of \"%s\" are read-only.\n"
@@ -1214,84 +954,69 @@ msgstr ""
"BonÅance Äi eble skribeblus.\n"
"Ĉu vi volas provi?"
-#: ../ex_cmds.c:2451
#, c-format
msgid "E505: \"%s\" is read-only (add ! to override)"
msgstr "E505: \"%s\" estas nurlegebla (aldonu ! por transpasi)"
-#: ../ex_cmds.c:3120
+msgid "Edit File"
+msgstr "Redakti dosieron"
+
#, c-format
msgid "E143: Autocommands unexpectedly deleted new buffer %s"
msgstr "E143: AÅ­tokomandoj neatendite forviÅis novan bufron %s"
-#: ../ex_cmds.c:3313
msgid "E144: non-numeric argument to :z"
msgstr "E144: nenumera argumento de :z"
-#: ../ex_cmds.c:3404
msgid "E145: Shell commands not allowed in rvim"
msgstr "E145: Åœelkomandoj nepermeseblaj en rvim"
-#: ../ex_cmds.c:3498
msgid "E146: Regular expressions can't be delimited by letters"
msgstr "E146: Ne eblas limigi regulesprimon per literoj"
-#: ../ex_cmds.c:3964
#, c-format
msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
msgstr "ĉu anstataŭigi per %s (y/n/a/q/l/^E/^Y)?"
-#: ../ex_cmds.c:4379
msgid "(Interrupted) "
msgstr "(Interrompita) "
-#: ../ex_cmds.c:4384
msgid "1 match"
msgstr "1 kongruo"
-#: ../ex_cmds.c:4384
msgid "1 substitution"
msgstr "1 anstataÅ­igo"
-#: ../ex_cmds.c:4387
#, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> kongruoj"
+msgid "%ld matches"
+msgstr "%ld kongruoj"
-#: ../ex_cmds.c:4388
#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> anstataÅ­igoj"
+msgid "%ld substitutions"
+msgstr "%ld anstataÅ­igoj"
-#: ../ex_cmds.c:4392
msgid " on 1 line"
msgstr " en 1 linio"
-#: ../ex_cmds.c:4395
#, c-format
-msgid " on %<PRId64> lines"
-msgstr " en %<PRId64> linioj"
+msgid " on %ld lines"
+msgstr " en %ld linioj"
-#: ../ex_cmds.c:4438
msgid "E147: Cannot do :global recursive"
msgstr "E147: Ne eblas fari \":global\" rekursie"
# DP: global estas por ":global" do mi ne tradukis Äin
-#: ../ex_cmds.c:4467
msgid "E148: Regular expression missing from global"
msgstr "E148: Regulesprimo mankas el global"
-#: ../ex_cmds.c:4508
#, c-format
msgid "Pattern found in every line: %s"
msgstr "Ŝablono trovita en ĉiuj linioj: %s"
-#: ../ex_cmds.c:4510
#, c-format
msgid "Pattern not found: %s"
msgstr "Åœablono ne trovita: %s"
-#: ../ex_cmds.c:4587
msgid ""
"\n"
"# Last Substitute String:\n"
@@ -1302,104 +1027,100 @@ msgstr ""
"$"
# This message should *so* be E42!
-#: ../ex_cmds.c:4679
msgid "E478: Don't panic!"
msgstr "E478: Ne paniku!"
-#: ../ex_cmds.c:4717
#, c-format
msgid "E661: Sorry, no '%s' help for %s"
msgstr "E661: BedaÅ­rinde estas neniu helpo '%s' por %s"
-#: ../ex_cmds.c:4719
#, c-format
msgid "E149: Sorry, no help for %s"
msgstr "E149: BedaÅ­rinde estas neniu helpo por %s"
-#: ../ex_cmds.c:4751
#, c-format
msgid "Sorry, help file \"%s\" not found"
msgstr "BedaÅ­rinde, la helpdosiero \"%s\" ne troveblas"
-#: ../ex_cmds.c:5323
#, c-format
-msgid "E150: Not a directory: %s"
-msgstr "E150: Ne estas dosierujo: %s"
+msgid "E151: No match: %s"
+msgstr "E151: Neniu kongruo: %s"
-#: ../ex_cmds.c:5446
#, c-format
msgid "E152: Cannot open %s for writing"
msgstr "E152: Ne eblas malfermi %s en skribreÄimo"
-#: ../ex_cmds.c:5471
#, c-format
msgid "E153: Unable to open %s for reading"
msgstr "E153: Ne eblas malfermi %s en legreÄimo"
-#: ../ex_cmds.c:5500
#, c-format
msgid "E670: Mix of help file encodings within a language: %s"
msgstr "E670: Miksaĵo de kodoprezento de helpa dosiero en lingvo: %s"
-#: ../ex_cmds.c:5565
#, c-format
msgid "E154: Duplicate tag \"%s\" in file %s/%s"
msgstr "E154: Ripetita etikedo \"%s\" en dosiero %s/%s"
#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Ne estas dosierujo: %s"
+
+#, c-format
msgid "E160: Unknown sign command: %s"
msgstr "E160: Nekonata simbola komando: %s"
-#: ../ex_cmds.c:5704
msgid "E156: Missing sign name"
msgstr "E156: Mankas nomo de simbolo"
-#: ../ex_cmds.c:5746
msgid "E612: Too many signs defined"
msgstr "E612: Tro da simboloj estas difinitaj"
-#: ../ex_cmds.c:5813
#, c-format
msgid "E239: Invalid sign text: %s"
msgstr "E239: Nevalida teksto de simbolo: %s"
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
#, c-format
msgid "E155: Unknown sign: %s"
msgstr "E155: Nekonata simbolo: %s"
-#: ../ex_cmds.c:5877
msgid "E159: Missing sign number"
msgstr "E159: Mankas numero de simbolo"
-#: ../ex_cmds.c:5971
#, c-format
msgid "E158: Invalid buffer name: %s"
msgstr "E158: Nevalida nomo de bufro: %s"
-#: ../ex_cmds.c:6008
+msgid "E934: Cannot jump to a buffer that does not have a name"
+msgstr "E934: Ne eblas salti al sennoma bufro"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Nevalida identigilo de simbolo: %ld"
+
#, c-format
-msgid "E157: Invalid sign ID: %<PRId64>"
-msgstr "E157: Nevalida identigilo de simbolo: %<PRId64>"
+msgid "E885: Not possible to change sign %s"
+msgstr "E885: Ne eblas ÅanÄi simbolon %s"
+
+msgid " (NOT FOUND)"
+msgstr " (NETROVITA)"
-#: ../ex_cmds.c:6066
msgid " (not supported)"
msgstr " (nesubtenata)"
-#: ../ex_cmds.c:6169
msgid "[Deleted]"
msgstr "[ForviÅita]"
-#: ../ex_cmds2.c:139
+msgid "No old files"
+msgstr "Neniu malnova dosiero"
+
msgid "Entering Debug mode. Type \"cont\" to continue."
msgstr "Eniras sencimigan reÄimon. Tajpu \"cont\" por daÅ­rigi."
-#: ../ex_cmds2.c:143 ../ex_docmd.c:759
#, c-format
-msgid "line %<PRId64>: %s"
-msgstr "linio %<PRId64>: %s"
+msgid "line %ld: %s"
+msgstr "linio %ld: %s"
-#: ../ex_cmds2.c:145
#, c-format
msgid "cmd: %s"
msgstr "kmd: %s"
@@ -1411,231 +1132,183 @@ msgstr "kadro estas nul"
msgid "frame at highest level: %d"
msgstr "kadro je la plej alta nivelo: %d"
-#: ../ex_cmds2.c:322
#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "Kontrolpunkto en \"%s%s\" linio %<PRId64>"
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Kontrolpunkto en \"%s%s\" linio %ld"
-#: ../ex_cmds2.c:581
#, c-format
msgid "E161: Breakpoint not found: %s"
msgstr "E161: Kontrolpunkto ne trovita: %s"
-#: ../ex_cmds2.c:611
msgid "No breakpoints defined"
msgstr "Neniu kontrolpunkto estas difinita"
-#: ../ex_cmds2.c:617
#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s linio %<PRId64>"
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s linio %ld"
-#: ../ex_cmds2.c:942
msgid "E750: First use \":profile start {fname}\""
msgstr "E750: Uzu unue \":profile start {dosiernomo}\""
-#: ../ex_cmds2.c:1269
#, c-format
msgid "Save changes to \"%s\"?"
msgstr "Ĉu konservi ÅanÄojn al \"%s\"?"
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
msgid "Untitled"
msgstr "Sen titolo"
-#: ../ex_cmds2.c:1421
#, c-format
msgid "E162: No write since last change for buffer \"%s\""
msgstr "E162: Neniu skribo de post la lasta ÅanÄo por bufro \"%s\""
-#: ../ex_cmds2.c:1480
msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
msgstr "Averto: Eniris neatendite alian bufron (kontrolu aÅ­tokomandojn)"
-#: ../ex_cmds2.c:1826
msgid "E163: There is only one file to edit"
msgstr "E163: Estas nur unu redaktenda dosiero"
-#: ../ex_cmds2.c:1828
msgid "E164: Cannot go before first file"
msgstr "E164: Ne eblas iri antaÅ­ ol la unuan dosieron"
-#: ../ex_cmds2.c:1830
msgid "E165: Cannot go beyond last file"
msgstr "E165: Ne eblas iri preter la lastan dosieron"
-#: ../ex_cmds2.c:2175
#, c-format
msgid "E666: compiler not supported: %s"
msgstr "E666: kompililo nesubtenata: %s"
-#: ../ex_cmds2.c:2257
#, c-format
msgid "Searching for \"%s\" in \"%s\""
msgstr "Serĉado de \"%s\" en \"%s\""
-#: ../ex_cmds2.c:2284
#, c-format
msgid "Searching for \"%s\""
msgstr "Serĉado de \"%s\""
-#: ../ex_cmds2.c:2307
#, c-format
msgid "not found in '%s': \"%s\""
msgstr "ne trovita en '%s: \"%s\""
-#: ../ex_cmds2.c:2472
+msgid "Source Vim script"
+msgstr "Ruli Vim-skripton"
+
#, c-format
msgid "Cannot source a directory: \"%s\""
msgstr "Ne eblas ruli dosierujon: \"%s\""
-#: ../ex_cmds2.c:2518
#, c-format
msgid "could not source \"%s\""
msgstr "ne eblis ruli \"%s\""
-#: ../ex_cmds2.c:2520
#, c-format
-msgid "line %<PRId64>: could not source \"%s\""
-msgstr "linio %<PRId64>: ne eblis ruli \"%s\""
+msgid "line %ld: could not source \"%s\""
+msgstr "linio %ld: ne eblis ruli \"%s\""
-#: ../ex_cmds2.c:2535
#, c-format
msgid "sourcing \"%s\""
msgstr "rulas \"%s\""
-#: ../ex_cmds2.c:2537
#, c-format
-msgid "line %<PRId64>: sourcing \"%s\""
-msgstr "linio %<PRId64>: rulas \"%s\""
+msgid "line %ld: sourcing \"%s\""
+msgstr "linio %ld: rulas \"%s\""
-#: ../ex_cmds2.c:2693
#, c-format
msgid "finished sourcing %s"
msgstr "finis ruli %s"
-#: ../ex_cmds2.c:2765
+#, c-format
+msgid "continuing in %s"
+msgstr "daÅ­rigas en %s"
+
msgid "modeline"
msgstr "reÄimlinio"
-#: ../ex_cmds2.c:2767
msgid "--cmd argument"
msgstr "--cmd argumento"
-#: ../ex_cmds2.c:2769
msgid "-c argument"
msgstr "-c argumento"
-#: ../ex_cmds2.c:2771
msgid "environment variable"
msgstr "medivariablo"
-#: ../ex_cmds2.c:2773
msgid "error handler"
msgstr "erartraktilo"
-#: ../ex_cmds2.c:3020
msgid "W15: Warning: Wrong line separator, ^M may be missing"
msgstr "W15: Averto: NeÄusta disigilo de linio, ^M eble mankas"
-#: ../ex_cmds2.c:3139
msgid "E167: :scriptencoding used outside of a sourced file"
msgstr "E167: \":scriptencoding\" uzita ekster rulita dosiero"
-#: ../ex_cmds2.c:3166
msgid "E168: :finish used outside of a sourced file"
msgstr "E168: \":finish\" uzita ekster rulita dosiero"
-#: ../ex_cmds2.c:3389
#, c-format
msgid "Current %slanguage: \"%s\""
msgstr "Aktuala %slingvo: \"%s\""
-#: ../ex_cmds2.c:3404
#, c-format
msgid "E197: Cannot set language to \"%s\""
msgstr "E197: Ne eblas ÅanÄi la lingvon al \"%s\""
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
msgstr "Eniras reÄimon Ex. Tajpu \"visual\" por iri al reÄimo Normala."
-#: ../ex_docmd.c:428
msgid "E501: At end-of-file"
msgstr "E501: Ĉe fino-de-dosiero"
-#: ../ex_docmd.c:513
msgid "E169: Command too recursive"
msgstr "E169: Komando tro rekursia"
-#: ../ex_docmd.c:1006
#, c-format
msgid "E605: Exception not caught: %s"
msgstr "E605: Escepto nekaptita: %s"
-#: ../ex_docmd.c:1085
msgid "End of sourced file"
msgstr "Fino de rulita dosiero"
-#: ../ex_docmd.c:1086
msgid "End of function"
msgstr "Fino de funkcio"
-#: ../ex_docmd.c:1628
msgid "E464: Ambiguous use of user-defined command"
msgstr "E464: Ambigua uzo de komando difinita de uzanto"
-#: ../ex_docmd.c:1638
msgid "E492: Not an editor command"
msgstr "E492: Ne estas redaktila komando"
-#: ../ex_docmd.c:1729
msgid "E493: Backwards range given"
msgstr "E493: Inversa amplekso donita"
-#: ../ex_docmd.c:1733
msgid "Backwards range given, OK to swap"
msgstr "Inversa amplekso donita, permuteblas"
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
msgid "E494: Use w or w>>"
msgstr "E494: Uzu w aÅ­ w>>"
-#: ../ex_docmd.c:3454
-msgid "E319: The command is not available in this version"
+msgid "E319: Sorry, the command is not available in this version"
msgstr "E319: BedaÅ­rinde, tiu komando ne haveblas en tiu versio"
-#: ../ex_docmd.c:3752
msgid "E172: Only one file name allowed"
msgstr "E172: Nur unu dosiernomo permesebla"
-#: ../ex_docmd.c:4238
msgid "1 more file to edit. Quit anyway?"
msgstr "1 plia redaktenda dosiero. Ĉu tamen eliri?"
-#: ../ex_docmd.c:4242
#, c-format
msgid "%d more files to edit. Quit anyway?"
msgstr "%d pliaj redaktendaj dosieroj. Ĉu tamen eliri?"
-#: ../ex_docmd.c:4248
msgid "E173: 1 more file to edit"
msgstr "E173: 1 plia redaktenda dosiero"
-#: ../ex_docmd.c:4250
#, c-format
-msgid "E173: %<PRId64> more files to edit"
-msgstr "E173: %<PRId64> pliaj redaktendaj dosieroj"
+msgid "E173: %ld more files to edit"
+msgstr "E173: %ld pliaj redaktendaj dosieroj"
-#: ../ex_docmd.c:4320
msgid "E174: Command already exists: add ! to replace it"
msgstr "E174: La komando jam ekzistas: aldonu ! por anstataÅ­igi Äin"
-#: ../ex_docmd.c:4432
msgid ""
"\n"
" Name Args Address Complete Definition"
@@ -1643,352 +1316,308 @@ msgstr ""
"\n"
" Nomo Argumentoj Adreso Kompleto Difino"
-#: ../ex_docmd.c:4516
msgid "No user-defined commands found"
msgstr "Neniu komando difinita de uzanto trovita"
-#: ../ex_docmd.c:4538
msgid "E175: No attribute specified"
msgstr "E175: Neniu atributo specifita"
-#: ../ex_docmd.c:4583
msgid "E176: Invalid number of arguments"
msgstr "E176: Nevalida nombro de argumentoj"
-#: ../ex_docmd.c:4594
msgid "E177: Count cannot be specified twice"
msgstr "E177: Kvantoro ne povas aperi dufoje"
-#: ../ex_docmd.c:4603
msgid "E178: Invalid default value for count"
msgstr "E178: Nevalida defaÅ­lta valoro de kvantoro"
-#: ../ex_docmd.c:4625
msgid "E179: argument required for -complete"
msgstr "E179: argumento bezonata por -complete"
-#: ../ex_docmd.c:4933
msgid "E179: argument required for -addr"
msgstr "E179: argumento bezonata por -addr"
-#: ../ex_docmd.c:4635
#, c-format
msgid "E181: Invalid attribute: %s"
msgstr "E181: Nevalida atributo: %s"
-#: ../ex_docmd.c:4678
msgid "E182: Invalid command name"
msgstr "E182: Nevalida komanda nomo"
-#: ../ex_docmd.c:4691
msgid "E183: User defined commands must start with an uppercase letter"
msgstr "E183: Komandoj difinataj de uzanto devas eki per majusklo"
-#: ../ex_docmd.c:4696
msgid "E841: Reserved name, cannot be used for user defined command"
msgstr "E841: Rezervita nomo, neuzebla por komando difinita de uzanto"
-#: ../ex_docmd.c:4751
#, c-format
msgid "E184: No such user-defined command: %s"
msgstr "E184: Neniu komando-difinita-de-uzanto kiel: %s"
-#: ../ex_docmd.c:5516
#, c-format
msgid "E180: Invalid address type value: %s"
msgstr "E180: Nevalida valoro de tipo de adreso: %s"
-#: ../ex_docmd.c:5219
#, c-format
msgid "E180: Invalid complete value: %s"
msgstr "E180: Nevalida valoro de kompletigo: %s"
-#: ../ex_docmd.c:5225
msgid "E468: Completion argument only allowed for custom completion"
msgstr ""
"E468: Argumento de kompletigo nur permesebla por kompletigo difinita de "
"uzanto"
-#: ../ex_docmd.c:5231
msgid "E467: Custom completion requires a function argument"
msgstr "E467: Uzula kompletigo bezonas funkcian argumenton"
-#: ../ex_docmd.c:5257
+msgid "unknown"
+msgstr "nekonata"
+
#, c-format
msgid "E185: Cannot find color scheme '%s'"
msgstr "E185: Ne eblas trovi agordaron de koloroj '%s'"
-#: ../ex_docmd.c:5263
msgid "Greetings, Vim user!"
msgstr "Bonvenon, uzanto de Vim!"
-#: ../ex_docmd.c:5431
msgid "E784: Cannot close last tab page"
msgstr "E784: Ne eblas fermi lastan langeton"
-#: ../ex_docmd.c:5462
msgid "Already only one tab page"
msgstr "Jam nur unu langeto"
-#: ../ex_docmd.c:6004
+msgid "Edit File in new window"
+msgstr "Redakti Dosieron en nova fenestro"
+
#, c-format
msgid "Tab page %d"
msgstr "Langeto %d"
-#: ../ex_docmd.c:6295
msgid "No swap file"
msgstr "Neniu permutodosiero .swp"
-#: ../ex_docmd.c:6478
+msgid "Append File"
+msgstr "Postaldoni dosieron"
+
msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
msgstr ""
"E747: Ne eblas ÅanÄi dosierujon, bufro estas ÅanÄita (aldonu ! por transpasi)"
-#: ../ex_docmd.c:6485
msgid "E186: No previous directory"
msgstr "E186: Neniu antaÅ­a dosierujo"
-#: ../ex_docmd.c:6530
msgid "E187: Unknown"
msgstr "E187: Nekonata"
-#: ../ex_docmd.c:6610
msgid "E465: :winsize requires two number arguments"
msgstr "E465: \":winsize\" bezonas du numerajn argumentojn"
-#: ../ex_docmd.c:6655
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Pozicio de fenestro: X %d, Y %d"
+
msgid "E188: Obtaining window position not implemented for this platform"
msgstr ""
"E188: Akiro de pozicio de fenestro ne estas realigita por tiu platformo"
-#: ../ex_docmd.c:6662
msgid "E466: :winpos requires two number arguments"
msgstr "E466: \":winpos\" bezonas du numerajn argumentojn"
-#: ../ex_docmd.c:7241
+msgid "E930: Cannot use :redir inside execute()"
+msgstr "E930: Ne eblas uzi :redir en execute()"
+
+msgid "Save Redirection"
+msgstr "Konservi alidirekton"
+
+# DP: mi ne certas pri superflugo
+msgid "Save View"
+msgstr "Konservi superflugon"
+
+msgid "Save Session"
+msgstr "Konservi seancon"
+
+msgid "Save Setup"
+msgstr "Konservi agordaron"
+
#, c-format
msgid "E739: Cannot create directory: %s"
msgstr "E739: Ne eblas krei dosierujon %s"
-#: ../ex_docmd.c:7268
#, c-format
msgid "E189: \"%s\" exists (add ! to override)"
msgstr "E189: \"%s\" ekzistas (aldonu ! por transpasi)"
-#: ../ex_docmd.c:7273
#, c-format
msgid "E190: Cannot open \"%s\" for writing"
msgstr "E190: Ne eblas malfermi \"%s\" por skribi"
#. set mark
-#: ../ex_docmd.c:7294
msgid "E191: Argument must be a letter or forward/backward quote"
msgstr "E191: Argumento devas esti litero, citilo aÅ­ retrocitilo"
-#: ../ex_docmd.c:7333
msgid "E192: Recursive use of :normal too deep"
msgstr "E192: Tro profunda rekursia alvoko de \":normal\""
-#: ../ex_docmd.c:7807
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< ne haveblas sen la eblo +eval"
+
msgid "E194: No alternate file name to substitute for '#'"
msgstr "E194: Neniu alterna dosiernomo por anstataÅ­igi al '#'"
-#: ../ex_docmd.c:7841
msgid "E495: no autocommand file name to substitute for \"<afile>\""
msgstr "E495: neniu dosiernomo de aÅ­tokomando por anstataÅ­igi al \"<afile>\""
-#: ../ex_docmd.c:7850
msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
msgstr ""
"E496: neniu numero de bufro de aÅ­tokomando por anstataÅ­igi al \"<abuf>\""
# DP: ĉu match estas verbo aŭ nomo en la angla version?
# AM: ĉi tie, nomo, Åajnas al mi
-#: ../ex_docmd.c:7861
msgid "E497: no autocommand match name to substitute for \"<amatch>\""
msgstr ""
"E497: neniu nomo de kongruo de aÅ­tokomando por anstataÅ­igi al \"<amatch>\""
-#: ../ex_docmd.c:7870
msgid "E498: no :source file name to substitute for \"<sfile>\""
msgstr "E498: neniu dosiernomo \":source\" por anstataÅ­igi al \"<sfile>\""
-#: ../ex_docmd.c:7876
msgid "E842: no line number to use for \"<slnum>\""
msgstr "E842: neniu uzebla numero de linio por \"<slnum>\""
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
+#, no-c-format
msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
msgstr "E499: Malplena dosiernomo por '%' aÅ­ '#', nur funkcias kun \":p:h\""
-#: ../ex_docmd.c:7905
msgid "E500: Evaluates to an empty string"
msgstr "E500: Liveras malplenan ĉenon"
-#: ../ex_docmd.c:8838
msgid "E195: Cannot open viminfo file for reading"
msgstr "E195: Ne eblas malfermi dosieron viminfo en lega reÄimo"
-#: ../ex_eval.c:464
+msgid "E196: No digraphs in this version"
+msgstr "E196: Neniu duliteraĵo en tiu versio"
+
msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
msgstr "E608: Ne eblas lanĉi (:throw) escepton kun prefikso 'Vim'"
#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
#, c-format
msgid "Exception thrown: %s"
msgstr "Escepto lanĉita: %s"
-#: ../ex_eval.c:545
#, c-format
msgid "Exception finished: %s"
msgstr "Escepto finiÄis: %s"
-#: ../ex_eval.c:546
#, c-format
msgid "Exception discarded: %s"
msgstr "Escepto ne konservita: %s"
-#: ../ex_eval.c:588 ../ex_eval.c:634
#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, linio %<PRId64>"
+msgid "%s, line %ld"
+msgstr "%s, linio %ld"
#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
#, c-format
msgid "Exception caught: %s"
msgstr "Kaptis escepton: %s"
-#: ../ex_eval.c:676
#, c-format
msgid "%s made pending"
msgstr "%s iÄis atendanta(j)"
-#: ../ex_eval.c:679
#, c-format
msgid "%s resumed"
msgstr "%s daÅ­rigita(j)"
-#: ../ex_eval.c:683
#, c-format
msgid "%s discarded"
msgstr "%s ne konservita(j)"
-#: ../ex_eval.c:708
msgid "Exception"
msgstr "Escepto"
-#: ../ex_eval.c:713
msgid "Error and interrupt"
msgstr "Eraro kaj interrompo"
-#: ../ex_eval.c:715
msgid "Error"
msgstr "Eraro"
#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
msgid "Interrupt"
msgstr "Interrompo"
-#: ../ex_eval.c:795
msgid "E579: :if nesting too deep"
msgstr "E579: \":if\" tro profunde ingita"
-#: ../ex_eval.c:830
msgid "E580: :endif without :if"
msgstr "E580: \":endif\" sen \":if\""
-#: ../ex_eval.c:873
msgid "E581: :else without :if"
msgstr "E581: \":else\" sen \":if\""
-#: ../ex_eval.c:876
msgid "E582: :elseif without :if"
msgstr "E582: \":elseif\" sen \":if\""
-#: ../ex_eval.c:880
msgid "E583: multiple :else"
msgstr "E583: pluraj \":else\""
-#: ../ex_eval.c:883
msgid "E584: :elseif after :else"
msgstr "E584: \":elseif\" post \":else\""
-#: ../ex_eval.c:941
msgid "E585: :while/:for nesting too deep"
msgstr "E585: \":while/:for\" ingita tro profunde"
-#: ../ex_eval.c:1028
msgid "E586: :continue without :while or :for"
msgstr "E586: \":continue\" sen \":while\" aÅ­ \":for\""
-#: ../ex_eval.c:1061
msgid "E587: :break without :while or :for"
msgstr "E587: \":break\" sen \":while\" aÅ­ \":for\""
-#: ../ex_eval.c:1102
msgid "E732: Using :endfor with :while"
msgstr "E732: Uzo de \":endfor\" kun \":while\""
-#: ../ex_eval.c:1104
msgid "E733: Using :endwhile with :for"
msgstr "E733: Uzo de \":endwhile\" kun \":for\""
-#: ../ex_eval.c:1247
msgid "E601: :try nesting too deep"
msgstr "E601: \":try\" ingita tro profunde"
-#: ../ex_eval.c:1317
msgid "E603: :catch without :try"
msgstr "E603: \":catch\" sen \":try\""
#. Give up for a ":catch" after ":finally" and ignore it.
#. * Just parse.
-#: ../ex_eval.c:1332
msgid "E604: :catch after :finally"
msgstr "E604: \":catch\" post \":finally\""
-#: ../ex_eval.c:1451
msgid "E606: :finally without :try"
msgstr "E606: \":finally\" sen \":try\""
#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
msgid "E607: multiple :finally"
msgstr "E607: pluraj \":finally\""
-#: ../ex_eval.c:1571
msgid "E602: :endtry without :try"
msgstr "E602: \":endtry\" sen \":try\""
-#: ../ex_eval.c:2026
msgid "E193: :endfunction not inside a function"
msgstr "E193: \":endfunction\" ekster funkcio"
-#: ../ex_getln.c:1643
msgid "E788: Not allowed to edit another buffer now"
msgstr "E788: Ne eblas redakti alian bufron nun"
-#: ../ex_getln.c:1656
msgid "E811: Not allowed to change buffer information now"
msgstr "E811: Ne eblas ÅanÄi informon de bufro nun"
-#: ../ex_getln.c:3178
msgid "tagname"
msgstr "nomo de etikedo"
-#: ../ex_getln.c:3181
msgid " kind file\n"
msgstr " tipo de dosiero\n"
-#: ../ex_getln.c:4799
msgid "'history' option is zero"
msgstr "opcio 'history' estas nul"
-#: ../ex_getln.c:5046
#, c-format
msgid ""
"\n"
@@ -1997,303 +1626,224 @@ msgstr ""
"\n"
"# Historio %s (de plej nova al plej malnova):\n"
-#: ../ex_getln.c:5047
msgid "Command Line"
msgstr "Komanda linio"
-#: ../ex_getln.c:5048
msgid "Search String"
msgstr "Serĉa ĉeno"
-#: ../ex_getln.c:5049
msgid "Expression"
msgstr "Esprimo"
-#: ../ex_getln.c:5050
msgid "Input Line"
msgstr "Eniga linio"
-#: ../ex_getln.c:5117
+msgid "Debug Line"
+msgstr "Sencimiga linio"
+
msgid "E198: cmd_pchar beyond the command length"
msgstr "E198: cmd_pchar preter la longo de komando"
-#: ../ex_getln.c:5279
msgid "E199: Active window or buffer deleted"
msgstr "E199: Aktiva fenestro aÅ­ bufro forviÅita"
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr "E854: tro longa vojo por kompletigo"
-
-#: ../file_search.c:446
-#, c-format
-msgid ""
-"E343: Invalid path: '**[number]' must be at the end of the path or be "
-"followed by '%s'."
-msgstr ""
-"E343: Nevalida vojo: '**[nombro]' devas esti ĉe la fino de la vojo aŭ "
-"sekvita de '%s'."
-
-#: ../file_search.c:1505
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: Ne eblas trovi dosierujon \"%s\" en cdpath"
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: Ne eblas trovi dosieron \"%s\" en serĉvojo"
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: Ne plu trovis dosierujon \"%s\" en cdpath"
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: Ne plu trovis dosieron \"%s\" en serĉvojo"
-
-#: ../fileio.c:137
msgid "E812: Autocommands changed buffer or buffer name"
msgstr "E812: AÅ­tokomandoj ÅanÄis bufron aÅ­ nomon de bufro"
-#: ../fileio.c:368
msgid "Illegal file name"
msgstr "Nevalida dosiernomo"
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
msgid "is a directory"
msgstr "estas dosierujo"
-#: ../fileio.c:397
msgid "is not a file"
msgstr "ne estas dosiero"
-#: ../fileio.c:508 ../fileio.c:3522
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "estas aparatdosiero (malÅaltita per la opcio 'opendevice')"
+
msgid "[New File]"
msgstr "[Nova dosiero]"
-#: ../fileio.c:511
msgid "[New DIRECTORY]"
msgstr "[Nova DOSIERUJO]"
-#: ../fileio.c:529 ../fileio.c:532
msgid "[File too big]"
msgstr "[Dosiero tro granda]"
-#: ../fileio.c:534
msgid "[Permission Denied]"
msgstr "[Permeso rifuzita]"
-#: ../fileio.c:653
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr "E200: La aÅ­tokomandoj *ReadPre igis la dosieron nelegebla"
-#: ../fileio.c:655
msgid "E201: *ReadPre autocommands must not change current buffer"
msgstr "E201: La aÅ­tokomandoj *ReadPre ne rajtas ÅanÄi la aktualan bufron"
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
+msgid "Vim: Reading from stdin...\n"
msgstr "Vim: Legado el stdin...\n"
+msgid "Reading from stdin..."
+msgstr "Legado el stdin..."
+
#. Re-opening the original file failed!
-#: ../fileio.c:909
msgid "E202: Conversion made file unreadable!"
msgstr "E202: Konverto igis la dosieron nelegebla!"
-#. fifo or socket
-#: ../fileio.c:1782
msgid "[fifo/socket]"
msgstr "[rektvica memoro/kontaktoskatolo]"
-#. fifo
-#: ../fileio.c:1788
msgid "[fifo]"
msgstr "[rektvica memoro]"
-#. or socket
-#: ../fileio.c:1794
msgid "[socket]"
msgstr "[kontaktoskatolo]"
-#. or character special
-#: ../fileio.c:1801
msgid "[character special]"
msgstr "[speciala signo]"
-#: ../fileio.c:1815
msgid "[CR missing]"
msgstr "[CR mankas]"
-#: ../fileio.c:1819
msgid "[long lines split]"
msgstr "[divido de longaj linioj]"
-#: ../fileio.c:1823 ../fileio.c:3512
msgid "[NOT converted]"
msgstr "[NE konvertita]"
-#: ../fileio.c:1826 ../fileio.c:3515
msgid "[converted]"
msgstr "[konvertita]"
-#: ../fileio.c:1831
#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[ERARO DE KONVERTO en linio %<PRId64>]"
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[ERARO DE KONVERTO en linio %ld]"
-#: ../fileio.c:1835
#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[NEVALIDA BAJTO en linio %<PRId64>]"
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[NEVALIDA BAJTO en linio %ld]"
-#: ../fileio.c:1838
msgid "[READ ERRORS]"
msgstr "[ERAROJ DE LEGADO]"
-#: ../fileio.c:2104
msgid "Can't find temp file for conversion"
msgstr "Ne eblas trovi provizoran dosieron por konverti"
-#: ../fileio.c:2110
msgid "Conversion with 'charconvert' failed"
-msgstr "Konverto kun 'charconvert' fiaskis"
+msgstr "Konverto kun 'charconvert' malsukcesis"
-#: ../fileio.c:2113
msgid "can't read output of 'charconvert'"
msgstr "ne eblas legi la eligon de 'charconvert'"
-#: ../fileio.c:2437
msgid "E676: No matching autocommands for acwrite buffer"
msgstr "E676: Neniu kongrua aÅ­tokomando por la bufro acwrite"
-#: ../fileio.c:2466
msgid "E203: Autocommands deleted or unloaded buffer to be written"
msgstr "E203: AÅ­tokomandoj forviÅis aÅ­ malÅargis la skribendan bufron"
-#: ../fileio.c:2486
msgid "E204: Autocommand changed number of lines in unexpected way"
msgstr "E204: AÅ­tokomando ÅanÄis la nombron de linioj neatendite"
-#: ../fileio.c:2548 ../fileio.c:2565
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans malpermesas skribojn de neÅanÄitaj bufroj"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Partaj skriboj malpermesitaj ĉe bufroj NetBeans"
+
msgid "is not a file or writable device"
msgstr "ne estas dosiero aÅ­ skribebla aparatdosiero"
-#: ../fileio.c:2601
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "skribo al aparatdosiero malÅaltita per la opcio 'opendevice'"
+
msgid "is read-only (add ! to override)"
msgstr "estas nurlegebla (aldonu ! por transpasi)"
-#: ../fileio.c:2886
msgid "E506: Can't write to backup file (add ! to override)"
msgstr "E506: Ne eblas skribi restaÅ­rkopion (aldonu ! por transpasi)"
-#: ../fileio.c:2898
msgid "E507: Close error for backup file (add ! to override)"
msgstr "E507: Eraro dum fermo de restaÅ­rkopio (aldonu ! transpasi)"
-#: ../fileio.c:2901
msgid "E508: Can't read file for backup (add ! to override)"
msgstr "E508: Ne eblas legi restaÅ­rkopion (aldonu ! por transpasi)"
-#: ../fileio.c:2923
msgid "E509: Cannot create backup file (add ! to override)"
msgstr "E509: Ne eblas krei restaÅ­rkopion (aldonu ! por transpasi)"
-#: ../fileio.c:3008
msgid "E510: Can't make backup file (add ! to override)"
msgstr "E510: Ne eblas krei restaÅ­rkopion (aldonu ! por transpasi)"
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: La rimeda forko estus perdita (aldonu ! por transpasi)"
+
msgid "E214: Can't find temp file for writing"
msgstr "E214: Ne eblas trovi provizoran dosieron por skribi"
-#: ../fileio.c:3134
msgid "E213: Cannot convert (add ! to write without conversion)"
msgstr "E213: Ne eblas konverti (aldonu ! por skribi sen konverto)"
-#: ../fileio.c:3169
msgid "E166: Can't open linked file for writing"
msgstr "E166: Ne eblas malfermi ligitan dosieron por skribi"
-#: ../fileio.c:3173
msgid "E212: Can't open file for writing"
msgstr "E212: Ne eblas malfermi la dosieron por skribi"
# AM: fsync: ne traduku (nomo de C-komando)
-#: ../fileio.c:3363
msgid "E667: Fsync failed"
-msgstr "E667: Fsync fiaskis"
+msgstr "E667: Fsync malsukcesis"
-#: ../fileio.c:3398
msgid "E512: Close failed"
-msgstr "E512: Fermo fiaskis"
+msgstr "E512: Fermo malsukcesis"
-#: ../fileio.c:3436
msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
-msgstr "E513: skriberaro, konverto fiaskis (igu 'fenc' malplena por transpasi)"
+msgstr ""
+"E513: skriberaro, konverto malsukcesis (igu 'fenc' malplena por transpasi)"
-#: ../fileio.c:3441
#, c-format
msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
"override)"
msgstr ""
-"E513: skriberaro, konverto fiaskis en linio %<PRId64> (igu 'fenc' malplena "
+"E513: skriberaro, konverto malsukcesis en linio %ld (igu 'fenc' malplena "
"por transpasi)"
-#: ../fileio.c:3448
msgid "E514: write error (file system full?)"
msgstr "E514: skriberaro (ĉu plena dosiersistemo?)"
-#: ../fileio.c:3506
msgid " CONVERSION ERROR"
msgstr " ERARO DE KONVERTO"
-#: ../fileio.c:3509
#, c-format
-msgid " in line %<PRId64>;"
-msgstr " en linio %<PRId64>;"
+msgid " in line %ld;"
+msgstr " en linio %ld;"
-#: ../fileio.c:3519
msgid "[Device]"
msgstr "[Aparatdosiero]"
-#: ../fileio.c:3522
msgid "[New]"
msgstr "[Nova]"
-#: ../fileio.c:3535
msgid " [a]"
msgstr " [a]"
-#: ../fileio.c:3535
msgid " appended"
msgstr " postaldonita(j)"
-#: ../fileio.c:3537
msgid " [w]"
msgstr " [s]"
-#: ../fileio.c:3537
msgid " written"
msgstr " skribita(j)"
-#: ../fileio.c:3579
msgid "E205: Patchmode: can't save original file"
msgstr "E205: Patchmode: ne eblas konservi originalan dosieron"
-#: ../fileio.c:3602
msgid "E206: patchmode: can't touch empty original file"
msgstr "E206: patchmode: ne eblas tuÅi malplenan originalan dosieron"
-#: ../fileio.c:3616
msgid "E207: Can't delete backup file"
msgstr "E207: Ne eblas forviÅi restaÅ­rkopion"
-#: ../fileio.c:3672
msgid ""
"\n"
"WARNING: Original file may be lost or damaged\n"
@@ -2301,96 +1851,75 @@ msgstr ""
"\n"
"AVERTO: Originala dosiero estas eble perdita aÅ­ difekta\n"
-#: ../fileio.c:3675
msgid "don't quit the editor until the file is successfully written!"
msgstr "ne eliru el la redaktilo Äis kiam la dosiero estas sukcese konservita!"
-#: ../fileio.c:3795
msgid "[dos]"
msgstr "[dos]"
-#: ../fileio.c:3795
msgid "[dos format]"
msgstr "[formato dos]"
-#: ../fileio.c:3801
msgid "[mac]"
msgstr "[mac]"
-#: ../fileio.c:3801
msgid "[mac format]"
msgstr "[formato mac]"
-#: ../fileio.c:3807
msgid "[unix]"
msgstr "[unikso]"
-#: ../fileio.c:3807
msgid "[unix format]"
msgstr "[formato unikso]"
-#: ../fileio.c:3831
msgid "1 line, "
msgstr "1 linio, "
-#: ../fileio.c:3833
#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> linioj, "
+msgid "%ld lines, "
+msgstr "%ld linioj, "
-#: ../fileio.c:3836
msgid "1 character"
msgstr "1 signo"
-#: ../fileio.c:3838
#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> signoj"
+msgid "%lld characters"
+msgstr "%lld signoj"
-#: ../fileio.c:3849
msgid "[noeol]"
msgstr "[sen EOL]"
-#: ../fileio.c:3849
msgid "[Incomplete last line]"
msgstr "[Nekompleta lasta linio]"
#. don't overwrite messages here
#. must give this prompt
#. don't use emsg() here, don't want to flush the buffers
-#: ../fileio.c:3865
msgid "WARNING: The file has been changed since reading it!!!"
msgstr "AVERTO: La dosiero estas ÅanÄita de post kiam Äi estis legita!!!"
-#: ../fileio.c:3867
msgid "Do you really want to write to it"
msgstr "Ĉu vi vere volas skribi al Äi"
-#: ../fileio.c:4648
#, c-format
msgid "E208: Error writing to \"%s\""
msgstr "E208: Eraro dum skribo de \"%s\""
-#: ../fileio.c:4655
#, c-format
msgid "E209: Error closing \"%s\""
msgstr "E209: Eraro dum fermo de \"%s\""
-#: ../fileio.c:4657
#, c-format
msgid "E210: Error reading \"%s\""
msgstr "E210: Eraro dum lego de \"%s\""
-#: ../fileio.c:4883
msgid "E246: FileChangedShell autocommand deleted buffer"
msgstr "E246: AÅ­tokomando FileChangedShell forviÅis bufron"
-#: ../fileio.c:4894
#, c-format
msgid "E211: File \"%s\" no longer available"
msgstr "E211: Dosiero \"%s\" ne plu haveblas"
-#: ../fileio.c:4906
#, c-format
msgid ""
"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
@@ -2398,38 +1927,30 @@ msgid ""
msgstr ""
"W12: Averto: Dosiero \"%s\" ÅanÄiÄis kaj la bufro estis ÅanÄita ankaÅ­ en Vim"
-#: ../fileio.c:4907
msgid "See \":help W12\" for more info."
msgstr "Vidu \":help W12\" por pliaj informoj."
-#: ../fileio.c:4910
#, c-format
msgid "W11: Warning: File \"%s\" has changed since editing started"
msgstr "W11: Averto: La dosiero \"%s\" ÅanÄiÄis ekde redakti Äin"
-#: ../fileio.c:4911
msgid "See \":help W11\" for more info."
msgstr "Vidu \":help W11\" por pliaj informoj."
-#: ../fileio.c:4914
#, c-format
msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
msgstr "W16: Averto: Permeso de dosiero \"%s\" ÅanÄiÄis ekde redakti Äin"
-#: ../fileio.c:4915
msgid "See \":help W16\" for more info."
msgstr "Vidu \":help W16\" por pliaj informoj."
-#: ../fileio.c:4927
#, c-format
msgid "W13: Warning: File \"%s\" has been created after editing started"
msgstr "W13: Averto: Dosiero \"%s\" kreiÄis post la komenco de redaktado"
-#: ../fileio.c:4947
msgid "Warning"
msgstr "Averto"
-#: ../fileio.c:4948
msgid ""
"&OK\n"
"&Load File"
@@ -2437,48 +1958,45 @@ msgstr ""
"&Bone\n"
"Ŝ&argi Dosieron"
-#: ../fileio.c:5065
#, c-format
msgid "E462: Could not prepare for reloading \"%s\""
msgstr "E462: Ne eblis prepari por reÅargi \"%s\""
-#: ../fileio.c:5078
#, c-format
msgid "E321: Could not reload \"%s\""
msgstr "E321: Ne eblis reÅargi \"%s\""
-#: ../fileio.c:5601
msgid "--Deleted--"
msgstr "--ForviÅita--"
-#: ../fileio.c:5732
#, c-format
msgid "auto-removing autocommand: %s <buffer=%d>"
msgstr "aÅ­to-forviÅas aÅ­tokomandon: %s <bufro=%d>"
#. the group doesn't exist
-#: ../fileio.c:5772
#, c-format
msgid "E367: No such group: \"%s\""
msgstr "E367: Ne ekzistas tia grupo: \"%s\""
-#: ../fileio.c:5897
+msgid "E936: Cannot delete the current group"
+msgstr "E936: Ne eblas forviÅi la aktualan grupon"
+
+msgid "W19: Deleting augroup that is still in use"
+msgstr "W19: ForviÅo de augroup kiu estas ankoraÅ­ uzata"
+
#, c-format
msgid "E215: Illegal character after *: %s"
msgstr "E215: Nevalida signo post *: %s"
-#: ../fileio.c:5905
#, c-format
msgid "E216: No such event: %s"
msgstr "E216: Ne estas tia evento: %s"
-#: ../fileio.c:5907
#, c-format
msgid "E216: No such group or event: %s"
msgstr "E216: Ne ekzistas tia grupo aÅ­ evento: %s"
#. Highlight title
-#: ../fileio.c:6090
msgid ""
"\n"
"--- Auto-Commands ---"
@@ -2486,767 +2004,561 @@ msgstr ""
"\n"
"--- AÅ­to-Komandoj ---"
-#: ../fileio.c:6293
#, c-format
msgid "E680: <buffer=%d>: invalid buffer number "
msgstr "E680: <bufro=%d>: nevalida numero de bufro "
-#: ../fileio.c:6370
msgid "E217: Can't execute autocommands for ALL events"
msgstr "E217: Ne eblas plenumi aŭtokomandojn por ĈIUJ eventoj"
-#: ../fileio.c:6393
msgid "No matching autocommands"
msgstr "Neniu kongrua aÅ­tokomando"
-#: ../fileio.c:6831
msgid "E218: autocommand nesting too deep"
msgstr "E218: aÅ­tokomando tro ingita"
-#: ../fileio.c:7143
#, c-format
msgid "%s Auto commands for \"%s\""
msgstr "%s AÅ­tokomandoj por \"%s\""
-#: ../fileio.c:7149
#, c-format
msgid "Executing %s"
msgstr "Plenumado de %s"
-#: ../fileio.c:7211
#, c-format
msgid "autocommand %s"
msgstr "aÅ­tokomando %s"
-#: ../fileio.c:7795
msgid "E219: Missing {."
msgstr "E219: Mankas {."
-#: ../fileio.c:7797
msgid "E220: Missing }."
msgstr "E220: Mankas }."
-#: ../fold.c:93
msgid "E490: No fold found"
msgstr "E490: Neniu faldo trovita"
-#: ../fold.c:544
msgid "E350: Cannot create fold with current 'foldmethod'"
msgstr "E350: Ne eblas krei faldon per la aktuala 'foldmethod'"
-#: ../fold.c:546
msgid "E351: Cannot delete fold with current 'foldmethod'"
msgstr "E351: Ne eblas forviÅi faldon per la aktuala 'foldmethod'"
-#: ../fold.c:1784
#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld linioj falditaj "
+msgid "+--%3ld line folded "
+msgid_plural "+--%3ld lines folded "
+msgstr[0] "+--%3ld linio faldita "
+msgstr[1] "+--%3ld linioj falditaj "
-#. buffer has already been read
-#: ../getchar.c:273
msgid "E222: Add to read buffer"
msgstr "E222: Aldoni al lega bufro"
-#: ../getchar.c:2040
msgid "E223: recursive mapping"
msgstr "E223: rekursia mapo"
-#: ../getchar.c:2849
#, c-format
msgid "E224: global abbreviation already exists for %s"
msgstr "E224: malloka mallongigo jam ekzistas por %s"
-#: ../getchar.c:2852
#, c-format
msgid "E225: global mapping already exists for %s"
msgstr "E225: malloka mapo jam ekzistas por %s"
-#: ../getchar.c:2952
#, c-format
msgid "E226: abbreviation already exists for %s"
msgstr "E226: mallongigo jam ekzistas por %s"
-#: ../getchar.c:2955
#, c-format
msgid "E227: mapping already exists for %s"
msgstr "E227: mapo jam ekzistas por %s"
-#: ../getchar.c:3008
msgid "No abbreviation found"
msgstr "Neniu mallongigo trovita"
-#: ../getchar.c:3010
msgid "No mapping found"
msgstr "Neniu mapo trovita"
-#: ../getchar.c:3974
msgid "E228: makemap: Illegal mode"
msgstr "E228: makemap: Nevalida reÄimo"
-#. key value of 'cedit' option
-#. type of cmdline window or 0
-#. result of cmdline window or 0
-#: ../globals.h:924
-msgid "--No lines in buffer--"
-msgstr "--Neniu linio en bufro--"
-
-#.
-#. * The error messages that can be shared are included here.
-#. * Excluded are errors that are only used once and debugging messages.
-#.
-#: ../globals.h:996
-msgid "E470: Command aborted"
-msgstr "E470: komando ĉesigita"
+msgid "E851: Failed to create a new process for the GUI"
+msgstr "E851: Malsukcesis krei novan procezon por la grafika interfaco"
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: Argumento bezonata"
+msgid "E852: The child process failed to start the GUI"
+msgstr "E852: La ida procezo malsukcesis startigi la grafikan interfacon"
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: \\ devus esti sekvita de /, ? aÅ­ &"
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Ne eblas lanĉi la grafikan interfacon"
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr ""
-"E11: Nevalida en fenestro de komanda linio; <CR> plenumas, CTRL-C eliras"
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Ne eblas legi el \"%s\""
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgid "E665: Cannot start GUI, no valid font found"
msgstr ""
-"E12: Nepermesebla komando el exrc/vimrc en aktuala dosierujo aŭ etikeda serĉo"
+"E665: Ne eblas startigi grafikan interfacon, neniu valida tiparo trovita"
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: Mankas \":endif\""
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' nevalida"
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: Mankas \":endtry\""
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Valoro de 'imactivatekey' estas nevalida"
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: Mankas \":endwhile\""
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Ne eblas disponigi koloron %s"
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: Mankas \":endfor\""
+msgid "No match at cursor, finding next"
+msgstr "Neniu kongruo ĉe kursorpozicio, trovas sekvan"
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: \":endwhile\" sen \":while\""
+msgid "<cannot open> "
+msgstr "<ne eblas malfermi> "
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: \":endfor\" sen \":for\""
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: ne eblas akiri tiparon %s"
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: Dosiero ekzistas (aldonu ! por transpasi)"
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: ne eblas reveni al la aktuala dosierujo"
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: La komando fiaskis"
+msgid "Pathname:"
+msgstr "Serĉvojo:"
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: Interna eraro"
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: ne eblas akiri aktualan dosierujon"
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "Interrompita"
+msgid "OK"
+msgstr "Bone"
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: Nevalida adreso"
+msgid "Cancel"
+msgstr "Rezigni"
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: Nevalida argumento"
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr ""
+"Fenestraĵo de rulumskalo: Ne eblis akiri geometrion de reduktita rastrumbildo"
-#: ../globals.h:1015
-#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: Nevalida argumento: %s"
+msgid "Vim dialog"
+msgstr "Vim dialogo"
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: Nevalida esprimo: %s"
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: Ne eblas krei BalloonEval kun ambaÅ­ mesaÄo kaj reagfunkcio"
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: Nevalida amplekso"
+msgid "_Cancel"
+msgstr "_Rezigni"
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: Nevalida komando"
+msgid "_Save"
+msgstr "_Konservi"
-#: ../globals.h:1019
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: \"%s\" estas dosierujo"
+msgid "_Open"
+msgstr "_Malfermi"
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: Nevalida grando de rulumo"
+msgid "_OK"
+msgstr "_Bone"
-#: ../globals.h:1021
-msgid "E901: Job table is full"
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
msgstr ""
+"&Jes\n"
+"&Ne\n"
+"&Rezigni"
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: Alvoko al biblioteko fiaskis por \"%s()\""
+msgid "Yes"
+msgstr "Jes"
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: Marko havas nevalidan numeron de linio"
+msgid "No"
+msgstr "Ne"
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: Marko ne estas agordita"
+# todo '_' is for hotkey, i guess?
+msgid "Input _Methods"
+msgstr "Enigaj _metodoj"
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: Ne eblas fari ÅanÄojn, 'modifiable' estas malÅaltita"
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Serĉi kaj anstataŭigi..."
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: Tro profunde ingitaj skriptoj"
+msgid "VIM - Search..."
+msgstr "VIM- Serĉi..."
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: Neniu alterna dosiero"
+msgid "Find what:"
+msgstr "Serĉi kion:"
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: Ne estas tia mallongigo"
+msgid "Replace with:"
+msgstr "AnstataÅ­igi per:"
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: Neniu ! permesebla"
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Kongrui kun nur plena vorto"
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: Grafika interfaco ne uzeblas: MalÅaltita dum kompilado"
+#. match case button
+msgid "Match case"
+msgstr "Uskleca kongruo"
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: Neniu grupo de emfazo kiel: %s"
+msgid "Direction"
+msgstr "Direkto"
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: AnkoraÅ­ neniu enmetita teksto"
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Supren"
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: Neniu antaÅ­a komanda linio"
+msgid "Down"
+msgstr "Suben"
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: Neniu tiel mapo"
+msgid "Find Next"
+msgstr "Trovi sekvantan"
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: Neniu kongruo"
+msgid "Replace"
+msgstr "AnstataÅ­igi"
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: Neniu kongruo: %s"
+msgid "Replace All"
+msgstr "Anstataŭigi ĉiujn"
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: Neniu dosiernomo"
+msgid "_Close"
+msgstr "_Fermi"
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: Neniu antaÅ­a regulesprimo de anstataÅ­igo"
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: Ricevis peton \"die\" (morti) el la seanca administrilo\n"
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: Neniu antaÅ­a komando"
+msgid "Close tab"
+msgstr "Fermi langeton"
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: Neniu antaÅ­a regulesprimo"
+msgid "New tab"
+msgstr "Nova langeto"
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: Amplekso nepermesebla"
+msgid "Open Tab..."
+msgstr "Malfermi langeton..."
-#: ../globals.h:1048
-msgid "E36: Not enough room"
-msgstr "E36: Ne sufiĉe da spaco"
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Ĉefa fenestro neatendite detruiÄis\n"
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: Ne eblas krei dosieron %s"
+msgid "&Filter"
+msgstr "&Filtri"
-#: ../globals.h:1050
-msgid "E483: Can't get temp file name"
-msgstr "E483: Ne eblas akiri provizoran dosiernomon"
+msgid "&Cancel"
+msgstr "&Rezigni"
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: Ne eblas malfermi dosieron %s"
+msgid "Directories"
+msgstr "Dosierujoj"
-#: ../globals.h:1052
-#, c-format
-msgid "E485: Can't read file %s"
-msgstr "E485: Ne eblas legi dosieron %s"
+msgid "Filter"
+msgstr "Filtri"
-#: ../globals.h:1054
-msgid "E37: No write since last change (add ! to override)"
-msgstr "E37: Neniu skribo de post lasta ÅanÄo (aldonu ! por transpasi)"
+msgid "&Help"
+msgstr "&Helpo"
-#: ../globals.h:1055
-#, fuzzy
-msgid "E37: No write since last change"
-msgstr "[Neniu skribo de post lasta ÅanÄo]\n"
+msgid "Files"
+msgstr "Dosieroj"
-#: ../globals.h:1056
-msgid "E38: Null argument"
-msgstr "E38: Nula argumento"
+msgid "&OK"
+msgstr "&Bone"
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: Nombro atendita"
+msgid "Selection"
+msgstr "Apartigo"
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: Ne eblas malfermi eraran dosieron %s"
+msgid "Find &Next"
+msgstr "Trovi &Sekvanta"
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: Ne plu restas memoro!"
+msgid "&Replace"
+msgstr "&AnstataÅ­igi"
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "Åœablono ne trovita"
+msgid "Replace &All"
+msgstr "Anstataŭigi ĉi&on"
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: Åœablono ne trovita: %s"
-
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: La argumento devas esti pozitiva"
+msgid "&Undo"
+msgstr "&Malfari"
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: Ne eblas reiri al antaÅ­a dosierujo"
-
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: Neniu eraro"
+msgid "Open tab..."
+msgstr "Malfermi langeton..."
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: Neniu listo de loko"
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Trovi ĉenon (uzu '\\\\' por trovi '\\')"
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: Difekta kongruenda ĉeno"
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Trovi kaj anstataÅ­igi (uzu '\\\\' por trovi '\\')"
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: Difekta programo de regulesprimo"
+#. 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"
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: La opcio 'readonly' estas Åaltita '(aldonu ! por transpasi)"
+msgid "Directory\t*.nothing\n"
+msgstr "Dosierujo\t*.nenio\n"
-#: ../globals.h:1073
#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: Ne eblas ÅanÄi nurlegeblan variablon \"%s\""
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Ne eblas trovi titolon de fenestro \"%s\""
-#: ../globals.h:1075
#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E794: Ne eblas agordi variablon en la sabloludejo: \"%s\""
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Ne subtenata argumento: \"-%s\"; Uzu la version OLE."
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Ne eblas uzi malplenan Ålosilon de Vortaro"
-
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: Eraro dum legado de erardosiero"
-
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: Nepermesebla en sabloludejo"
-
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: Nepermesebla tie"
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Ne eblas malfermi fenestron interne de aplikaĵo MDI"
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: ReÄimo de ekrano ne subtenata"
-
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: Nevalida grando de rulumo"
-
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: La opcio 'shell' estas malplena"
-
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: Ne eblis legi datumojn de simboloj!"
-
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: Eraro dum malfermo de permutodosiero .swp"
-
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: malplena stako de etikedo"
-
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: Komando tro kompleksa"
-
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: Nomo tro longa"
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: Ne eblas disponigi rikordon de kolormapo, iuj koloroj estas eble "
+"neÄustaj"
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: Tro da ["
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Tiparoj de tiuj signaroj mankas en aro de tiparo %s:"
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: Tro da dosiernomoj"
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Nomo de tiparo: %s"
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: Vostaj signoj"
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Tiparo '%s' ne estas egallarÄa"
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: Nekonata marko"
+#, c-format
+msgid "E253: Fontset name: %s"
+msgstr "E253: Nomo de tiparo: %s"
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: Ne eblas malvolvi ĵokerojn"
+#, c-format
+msgid "Font0: %s"
+msgstr "Font0: %s"
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: 'winheight' ne rajtas esti malpli ol 'winminheight'"
+#, c-format
+msgid "Font1: %s"
+msgstr "Font1: %s"
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: 'winwidth' ne rajtas esti malpli ol 'winminwidth'"
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "Font%ld ne estas duoble pli larÄa ol font0"
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: Eraro dum skribado"
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "LarÄo de font0: %ld"
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "Nul kvantoro"
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "LarÄo de Font1: %ld"
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: Uzo de <SID> ekster kunteksto de skripto"
+msgid "Invalid font specification"
+msgstr "Nevalida tiparo specifita"
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: Interna eraro: %s"
+msgid "&Dismiss"
+msgstr "&Forlasi"
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: Åablono uzas pli da memoro ol 'maxmempattern'"
+msgid "no specific match"
+msgstr "Neniu specifa kongruo"
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: malplena bufro"
+msgid "Vim - Font Selector"
+msgstr "Vim - Elektilo de tiparo"
-#: ../globals.h:1226
-#, c-format
-msgid "E86: Buffer %<PRId64> does not exist"
-msgstr "E86: La bufro %<PRId64> ne ekzistas"
+msgid "Name:"
+msgstr "Nomo:"
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: Nevalida serĉa Åablono aÅ­ disigilo"
+#. create toggle button
+msgid "Show size in Points"
+msgstr "Montri grandon en punktoj"
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: Dosiero estas Åargita en alia bufro"
+msgid "Encoding:"
+msgstr "Kodoprezento:"
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: La opcio '%s' ne estas Åaltita"
+msgid "Font:"
+msgstr "Tiparo:"
-#: ../globals.h:1111
-msgid "E850: Invalid register name"
-msgstr "E850: Nevalida nomo de reÄistro"
+msgid "Style:"
+msgstr "Stilo:"
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "serĉo atingis SUPRON, daŭrigonte al SUBO"
+msgid "Size:"
+msgstr "Grando:"
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "serĉo atingis SUBON, daŭrigonte al SUPRO"
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: ERARO en aÅ­tomato de korea alfabeto"
-#: ../hardcopy.c:240
msgid "E550: Missing colon"
msgstr "E550: Mankas dupunkto"
-#: ../hardcopy.c:252
msgid "E551: Illegal component"
msgstr "E551: Nevalida komponento"
-#: ../hardcopy.c:259
msgid "E552: digit expected"
msgstr "E552: cifero atendita"
-#: ../hardcopy.c:473
#, c-format
msgid "Page %d"
msgstr "PaÄo %d"
-#: ../hardcopy.c:597
msgid "No text to be printed"
msgstr "Neniu presenda teksto"
-#: ../hardcopy.c:668
#, c-format
msgid "Printing page %d (%d%%)"
msgstr "Presas paÄon %d (%d%%)"
-#: ../hardcopy.c:680
#, c-format
msgid " Copy %d of %d"
msgstr " Kopio %d de %d"
-#: ../hardcopy.c:733
#, c-format
msgid "Printed: %s"
msgstr "Presis: %s"
-#: ../hardcopy.c:740
msgid "Printing aborted"
msgstr "Presado ĉesigita"
-#: ../hardcopy.c:1365
msgid "E455: Error writing to PostScript output file"
msgstr "E455: Eraro dum skribo de PostSkripta eliga dosiero"
-#: ../hardcopy.c:1747
#, c-format
msgid "E624: Can't open file \"%s\""
msgstr "E624: Ne eblas malfermi dosieron \"%s\""
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
#, c-format
msgid "E457: Can't read PostScript resource file \"%s\""
msgstr "E457: Ne eblas legi dosieron de PostSkripta rimedo \"%s\""
-#: ../hardcopy.c:1772
#, c-format
msgid "E618: file \"%s\" is not a PostScript resource file"
msgstr "E618: \"%s\" ne estas dosiero de PostSkripta rimedo"
-#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844
#, c-format
msgid "E619: file \"%s\" is not a supported PostScript resource file"
msgstr "E619: \"%s\" ne estas subtenata dosiero de PostSkripta rimedo"
-#: ../hardcopy.c:1856
#, c-format
msgid "E621: \"%s\" resource file has wrong version"
msgstr "E621: \"%s\" dosiero de rimedo havas neÄustan version"
-#: ../hardcopy.c:2225
msgid "E673: Incompatible multi-byte encoding and character set."
msgstr "E673: Nekongrua plurbajta kodoprezento kaj signaro."
-#: ../hardcopy.c:2238
msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
msgstr ""
"E674: printmbcharset ne rajtas esti malplena kun plurbajta kodoprezento."
-#: ../hardcopy.c:2254
msgid "E675: No default font specified for multi-byte printing."
msgstr "E675: Neniu defaÅ­lta tiparo specifita por plurbajta presado."
-#: ../hardcopy.c:2426
msgid "E324: Can't open PostScript output file"
msgstr "E324: Ne eblas malfermi eligan PostSkriptan dosieron"
-#: ../hardcopy.c:2458
#, c-format
msgid "E456: Can't open file \"%s\""
msgstr "E456: Ne eblas malfermi dosieron \"%s\""
-#: ../hardcopy.c:2583
msgid "E456: Can't find PostScript resource file \"prolog.ps\""
msgstr "E456: Dosiero de PostSkripta rimedo \"prolog.ps\" ne troveblas"
-#: ../hardcopy.c:2593
msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
msgstr "E456: Dosiero de PostSkripta rimedo \"cidfont.ps\" ne troveblas"
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
#, c-format
msgid "E456: Can't find PostScript resource file \"%s.ps\""
msgstr "E456: Dosiero de PostSkripta rimedo \"%s.ps\" ne troveblas"
-#: ../hardcopy.c:2654
#, c-format
msgid "E620: Unable to convert to print encoding \"%s\""
msgstr "E620: Ne eblas konverti al la presa kodoprezento \"%s\""
-#: ../hardcopy.c:2877
msgid "Sending to printer..."
msgstr "Sendas al presilo..."
-#: ../hardcopy.c:2881
msgid "E365: Failed to print PostScript file"
-msgstr "E365: Presado de PostSkripta dosiero fiaskis"
+msgstr "E365: Presado de PostSkripta dosiero malsukcesis"
-#: ../hardcopy.c:2883
msgid "Print job sent."
msgstr "Laboro de presado sendita."
-#: ../if_cscope.c:85
msgid "Add a new database"
msgstr "Aldoni novan datumbazon"
-#: ../if_cscope.c:87
msgid "Query for a pattern"
msgstr "Serĉi Åablonon"
-#: ../if_cscope.c:89
msgid "Show this message"
msgstr "Montri tiun mesaÄon"
-#: ../if_cscope.c:91
msgid "Kill a connection"
msgstr "Ĉesigi konekton"
-#: ../if_cscope.c:93
msgid "Reinit all connections"
msgstr "Repravalorizi ĉiujn konektojn"
-#: ../if_cscope.c:95
msgid "Show connections"
msgstr "Montri konektojn"
-#: ../if_cscope.c:101
#, c-format
msgid "E560: Usage: cs[cope] %s"
msgstr "E560: Uzo: cs[cope] %s"
-#: ../if_cscope.c:225
msgid "This cscope command does not support splitting the window.\n"
msgstr "Tiu ĉi komando de cscope ne subtenas dividon de fenestro.\n"
-#: ../if_cscope.c:266
msgid "E562: Usage: cstag <ident>"
msgstr "E562: Uzo: cstag <ident>"
-#: ../if_cscope.c:313
msgid "E257: cstag: tag not found"
msgstr "E257: cstag: etikedo netrovita"
-#: ../if_cscope.c:461
#, c-format
msgid "E563: stat(%s) error: %d"
msgstr "E563: Eraro de stat(%s): %d"
-#: ../if_cscope.c:551
+msgid "E563: stat error"
+msgstr "E563: Eraro de stat"
+
#, c-format
msgid "E564: %s is not a directory or a valid cscope database"
msgstr "E564: %s ne estas dosierujo aÅ­ valida datumbazo de cscope"
-#: ../if_cscope.c:566
#, c-format
msgid "Added cscope database %s"
msgstr "Aldonis datumbazon de cscope %s"
-#: ../if_cscope.c:616
#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: eraro dum legado de konekto de cscope %<PRId64>"
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: eraro dum legado de konekto de cscope %ld"
-#: ../if_cscope.c:711
msgid "E561: unknown cscope search type"
msgstr "E561: nekonata tipo de serĉo de cscope"
-#: ../if_cscope.c:752 ../if_cscope.c:789
msgid "E566: Could not create cscope pipes"
msgstr "E566: Ne eblis krei duktojn de cscope"
-#: ../if_cscope.c:767
msgid "E622: Could not fork for cscope"
msgstr "E622: Ne eblis forki cscope"
-#: ../if_cscope.c:849
-#, fuzzy
msgid "cs_create_connection setpgid failed"
-msgstr "plenumo de cs_create_connection fiaskis"
+msgstr "plenumo de cs_create_connection-setgpid malsukcesis"
-#: ../if_cscope.c:853 ../if_cscope.c:889
msgid "cs_create_connection exec failed"
-msgstr "plenumo de cs_create_connection fiaskis"
+msgstr "plenumo de cs_create_connection malsukcesis"
-#: ../if_cscope.c:863 ../if_cscope.c:902
msgid "cs_create_connection: fdopen for to_fp failed"
-msgstr "cs_create_connection: fdopen de to_fp fiaskis"
+msgstr "cs_create_connection: fdopen de to_fp malsukcesis"
-#: ../if_cscope.c:865 ../if_cscope.c:906
msgid "cs_create_connection: fdopen for fr_fp failed"
-msgstr "cs_create_connection: fdopen de fr_fp fiaskis"
+msgstr "cs_create_connection: fdopen de fr_fp malsukcesis"
-#: ../if_cscope.c:890
msgid "E623: Could not spawn cscope process"
msgstr "E623: Ne eblis naskigi procezon cscope"
-#: ../if_cscope.c:932
msgid "E567: no cscope connections"
msgstr "E567: neniu konekto al cscope"
-#: ../if_cscope.c:1009
#, c-format
msgid "E469: invalid cscopequickfix flag %c for %c"
msgstr "E469: nevalida flago cscopequickfix %c de %c"
-#: ../if_cscope.c:1058
#, c-format
msgid "E259: no matches found for cscope query %s of %s"
msgstr "E259: neniu kongruo trovita por serĉo per cscope %s de %s"
-#: ../if_cscope.c:1142
msgid "cscope commands:\n"
msgstr "komandoj de cscope:\n"
-#: ../if_cscope.c:1150
#, c-format
msgid "%-5s: %s%*s (Usage: %s)"
msgstr "%-5s: %s%*s (Uzo: %s)"
-#: ../if_cscope.c:1155
msgid ""
"\n"
+" a: Find assignments to this symbol\n"
" c: Find functions calling this function\n"
" d: Find functions called by this function\n"
" e: Find this egrep pattern\n"
@@ -3257,6 +2569,7 @@ msgid ""
" t: Find this text string\n"
msgstr ""
"\n"
+" a: Trovi valirizojn al tiu simbolo\n"
" c: Trovi funkciojn, kiuj alvokas tiun funkcion\n"
" d: Trovi funkciojn alvokataj de tiu funkcio\n"
" e: Trovi tiun egrep-Åablonon\n"
@@ -3266,31 +2579,32 @@ msgstr ""
" s: Trovi tiun C-simbolon\n"
" t: Trovi tiun ĉenon\n"
-#: ../if_cscope.c:1226
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: ne eblas malfermi datumbazon de cscope: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: ne eblas akiri informojn pri la datumbazo de cscope"
+
msgid "E568: duplicate cscope database not added"
msgstr "E568: ripetita datumbazo de cscope ne aldonita"
-#: ../if_cscope.c:1335
#, c-format
msgid "E261: cscope connection %s not found"
msgstr "E261: konekto cscope %s netrovita"
-#: ../if_cscope.c:1364
#, c-format
msgid "cscope connection %s closed"
msgstr "konekto cscope %s fermita"
#. should not reach here
-#: ../if_cscope.c:1486
msgid "E570: fatal error in cs_manage_matches"
msgstr "E570: neriparebla eraro en cs_manage_matches"
-#: ../if_cscope.c:1693
#, c-format
msgid "Cscope tag: %s"
msgstr "Etikedo de cscope: %s"
-#: ../if_cscope.c:1711
msgid ""
"\n"
" # line"
@@ -3298,87 +2612,306 @@ msgstr ""
"\n"
" nro linio"
-#: ../if_cscope.c:1713
msgid "filename / context / line\n"
msgstr "dosiernomo / kunteksto / linio\n"
-#: ../if_cscope.c:1809
#, c-format
msgid "E609: Cscope error: %s"
msgstr "E609: Eraro de cscope: %s"
-#: ../if_cscope.c:2053
msgid "All cscope databases reset"
msgstr "ReÅargo de ĉiuj datumbazoj de cscope"
-#: ../if_cscope.c:2123
msgid "no cscope connections\n"
msgstr "neniu konekto de cscope\n"
-#: ../if_cscope.c:2126
msgid " # pid database name prepend path\n"
msgstr " # pid nomo de datumbazo prefiksa vojo\n"
-#: ../main.c:144
+msgid "Lua library cannot be loaded."
+msgstr "La biblioteko Lua no Åargeblis."
+
+msgid "cannot save undo information"
+msgstr "ne eblas konservi informojn de malfaro"
+
+msgid ""
+"E815: Sorry, this command is disabled, the MzScheme libraries could not be "
+"loaded."
+msgstr ""
+"E815: BedaÅ­rinde, tiu komando estas malÅaltita, ne eblis Åargi la "
+"bibliotekojn."
+
+msgid ""
+"E895: Sorry, this command is disabled, the MzScheme's racket/base module "
+"could not be loaded."
+msgstr ""
+"E895: BedaÅ­rinde, tiu komando estas malÅaltita, ne eblis Åargi la modulon de "
+"MzScheme racket/base."
+
+msgid "invalid expression"
+msgstr "nevalida esprimo"
+
+msgid "expressions disabled at compile time"
+msgstr "esprimoj malÅaltitaj dum kompilado"
+
+msgid "hidden option"
+msgstr "kaÅita opcio"
+
+msgid "unknown option"
+msgstr "nekonata opcio"
+
+msgid "window index is out of range"
+msgstr "indekso de fenestro estas ekster limoj"
+
+msgid "couldn't open buffer"
+msgstr "ne eblis malfermi bufron"
+
+msgid "cannot delete line"
+msgstr "ne eblas forviÅi linion"
+
+msgid "cannot replace line"
+msgstr "ne eblas anstataÅ­igi linion"
+
+msgid "cannot insert line"
+msgstr "ne eblas enmeti linion"
+
+msgid "string cannot contain newlines"
+msgstr "ĉeno ne rajtas enhavi liniavancojn"
+
+msgid "error converting Scheme values to Vim"
+msgstr "eraro dum konverto de Scheme-valoro al Vim"
+
+msgid "Vim error: ~a"
+msgstr "Eraro de Vim: ~a"
+
+msgid "Vim error"
+msgstr "Eraro de Vim"
+
+msgid "buffer is invalid"
+msgstr "bufro estas nevalida"
+
+msgid "window is invalid"
+msgstr "fenestro estas nevalida"
+
+msgid "linenr out of range"
+msgstr "numero de linio ekster limoj"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "nepermesebla en sabloludejo de Vim"
+
+msgid "E836: This Vim cannot execute :python after using :py3"
+msgstr "E836: Vim ne povas plenumi :python post uzo de :py3"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: BedaÅ­rinde tiu komando estas malÅaltita: la biblioteko de Pitono ne "
+"Åargeblis."
+
+msgid ""
+"E887: Sorry, this command is disabled, the Python's site module could not be "
+"loaded."
+msgstr ""
+"E887` BedaÅ­rinde tiu komando estas malÅaltita: la biblioteko de Pitono ne "
+"Åargeblis."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Ne eblas alvoki Pitonon rekursie"
+
+msgid "E837: This Vim cannot execute :py3 after using :python"
+msgstr "E837: Vim ne povas plenumi :py3 post uzo de :python"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: $_ devas esti apero de Ĉeno"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: BedaÅ­rinde tiu komando estas malÅaltita, la biblioteko Ruby ne "
+"Åargeblis."
+
+msgid "E267: unexpected return"
+msgstr "E267: \"return\" neatendita"
+
+msgid "E268: unexpected next"
+msgstr "E268: \"next\" neatendita"
+
+msgid "E269: unexpected break"
+msgstr "E269: \"break\" neatendita"
+
+msgid "E270: unexpected redo"
+msgstr "E270: \"redo\" neatendita"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: \"retry\" ekster klaÅ­zo \"rescue\""
+
+msgid "E272: unhandled exception"
+msgstr "E272: netraktita escepto"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: nekonata stato de longjmp: %d"
+
+msgid "invalid buffer number"
+msgstr "nevalida numero de bufro"
+
+msgid "not implemented yet"
+msgstr "ankoraÅ­ ne realigita"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "ne eblas meti la linio(j)n"
+
+msgid "invalid mark name"
+msgstr "nevalida nomo de marko"
+
+msgid "mark not set"
+msgstr "marko ne estas metita"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "linio %d kolumno %d"
+
+msgid "cannot insert/append line"
+msgstr "ne eblas enmeti/postaldoni linion"
+
+msgid "line number out of range"
+msgstr "numero de linio ekster limoj"
+
+msgid "unknown flag: "
+msgstr "nekonata flago: "
+
+# DP: ĉu traduki vimOption
+msgid "unknown vimOption"
+msgstr "nekonata vimOption"
+
+msgid "keyboard interrupt"
+msgstr "klavara interrompo"
+
+msgid "vim error"
+msgstr "eraro de Vim"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "ne eblas krei komandon de bufro/fenestro: objekto estas forviÅiÄanta"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"ne eblas registri postalvokan komandon: bufro/fenestro estas jam forviÅiÄanta"
+
+#. 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 malsukcesis"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: Nevalida identigilo de servilo uzita: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr ""
+"E251: Ecoj de registro de apero de VIM estas nevalide formata. ForviÅita!"
+
+#, c-format
+msgid "E938: Duplicate key in JSON: \"%s\""
+msgstr "E938: Ripetita Ålosilo en JSON: \"%s\""
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Mankas komo en Listo: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Mankas fino de Listo ']': %s"
+
msgid "Unknown option argument"
msgstr "Nekonata argumento de opcio"
-#: ../main.c:146
msgid "Too many edit arguments"
msgstr "Tro da argumentoj de redakto"
-#: ../main.c:148
msgid "Argument missing after"
msgstr "Argumento mankas post"
-#: ../main.c:150
msgid "Garbage after option argument"
msgstr "Forĵetindaĵo post argumento de opcio"
-#: ../main.c:152
msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
msgstr "Tro da argumentoj \"+komando\", \"-c komando\" aÅ­ \"--cmd komando\""
-#: ../main.c:154
msgid "Invalid argument for"
msgstr "Nevalida argumento por"
-#: ../main.c:294
#, c-format
msgid "%d files to edit\n"
msgstr "%d redaktendaj dosieroj\n"
-#: ../main.c:1342
+msgid "netbeans is not supported with this GUI\n"
+msgstr "netbeans ne estas subtenata kun tiu grafika interfaco\n"
+
+msgid "'-nb' cannot be used: not enabled at compile time\n"
+msgstr "'-nb' ne uzeblas: malÅaltita dum kompilado\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Tiu Vim ne estis kompilita kun la kompara eblo."
+
msgid "Attempt to open script file again: \""
msgstr "Provas malfermi skriptan dosieron denove: \""
-#: ../main.c:1350
msgid "Cannot open for reading: \""
msgstr "Ne eblas malfermi en lega reÄimo: \""
-#: ../main.c:1393
msgid "Cannot open for script output: \""
msgstr "Ne eblas malfermi por eligo de skripto: \""
-#: ../main.c:1622
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Eraro: malsukcesis lanĉi gvim el NetBeans\n"
+
+msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n"
+msgstr "Vim: Eraro: Tiu versio de Vim ne ruliÄas en terminalo Cygwin\n"
+
msgid "Vim: Warning: Output is not to a terminal\n"
msgstr "Vim: Averto: Eligo ne estas al terminalo\n"
-#: ../main.c:1624
msgid "Vim: Warning: Input is not from a terminal\n"
msgstr "Vim: Averto: Enigo ne estas el terminalo\n"
#. just in case..
-#: ../main.c:1891
msgid "pre-vimrc command line"
msgstr "komanda linio pre-vimrc"
-#: ../main.c:1964
#, c-format
msgid "E282: Cannot read from \"%s\""
msgstr "E282: Ne eblas legi el \"%s\""
-#: ../main.c:2149
msgid ""
"\n"
"More info with: \"vim -h\"\n"
@@ -3387,23 +2920,18 @@ msgstr ""
"Pliaj informoj per: \"vim -h\"\n"
# DP: tajpu "vim --help" por testi tiujn mesaÄojn
-#: ../main.c:2178
msgid "[file ..] edit specified file(s)"
msgstr "[dosiero...] redakti specifita(j)n dosiero(j)n"
-#: ../main.c:2179
msgid "- read text from stdin"
msgstr "- legi tekston el stdin"
-#: ../main.c:2180
msgid "-t tag edit file where tag is defined"
msgstr "-t etikedo redakti dosieron kie etikedo estas difinata"
-#: ../main.c:2181
msgid "-q [errorfile] edit file with first error"
msgstr "-q [erardosiero] redakti dosieron kun unua eraro"
-#: ../main.c:2187
msgid ""
"\n"
"\n"
@@ -3413,11 +2941,9 @@ msgstr ""
"\n"
" uzo:"
-#: ../main.c:2189
msgid " vim [arguments] "
msgstr " vim [argumentoj] "
-#: ../main.c:2193
msgid ""
"\n"
" or:"
@@ -3425,7 +2951,13 @@ msgstr ""
"\n"
" aÅ­:"
-#: ../main.c:2196
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"Kie uskleco estas ignorita antaÅ­aldonu / por igi flagon majuskla"
+
msgid ""
"\n"
"\n"
@@ -3435,197 +2967,336 @@ msgstr ""
"\n"
"Argumentoj:\n"
-#: ../main.c:2197
msgid "--\t\t\tOnly file names after this"
msgstr "--\t\t\tNur dosiernomoj post tio"
-#: ../main.c:2199
msgid "--literal\t\tDon't expand wildcards"
msgstr "--literal\t\tNe malvolvi ĵokerojn"
-#: ../main.c:2201
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tRegistri tiun gvim al OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tMalregistri gvim de OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tRuli per grafika interfaco (kiel \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f aŭ --nofork\tMalfono: ne forki kiam lanĉas grafikan interfacon"
+
msgid "-v\t\t\tVi mode (like \"vi\")"
msgstr "-v\t\t\tReÄimo Vi (kiel \"vi\")"
-#: ../main.c:2202
msgid "-e\t\t\tEx mode (like \"ex\")"
msgstr "-e\t\t\tReÄimo Ex (kiel \"ex\")"
-#: ../main.c:2203
msgid "-E\t\t\tImproved Ex mode"
msgstr "-E\t\t\tPlibonigita Ex-reÄimo"
-#: ../main.c:2204
msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
msgstr "-s\t\t\tSilenta (stapla) reÄimo (nur por \"ex\")"
-#: ../main.c:2205
msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
msgstr "-d\t\t\tKompara reÄimo (kiel \"vimdiff\")"
-#: ../main.c:2206
msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
msgstr "-y\t\t\tFacila reÄimo (kiel \"evim\", senreÄima)"
-#: ../main.c:2207
msgid "-R\t\t\tReadonly mode (like \"view\")"
msgstr "-R\t\t\tNurlegebla reÄimo (kiel \"view\")"
-#: ../main.c:2208
msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
msgstr "-Z\t\t\tLimigita reÄimo (kiel \"rvim\")"
-#: ../main.c:2209
msgid "-m\t\t\tModifications (writing files) not allowed"
msgstr "-m\t\t\tÅœanÄoj (skribo al dosieroj) nepermeseblaj"
-#: ../main.c:2210
msgid "-M\t\t\tModifications in text not allowed"
msgstr "-M\t\t\tÅœanÄoj al teksto nepermeseblaj"
-#: ../main.c:2211
msgid "-b\t\t\tBinary mode"
msgstr "-b\t\t\tDuuma reÄimo"
-#: ../main.c:2212
msgid "-l\t\t\tLisp mode"
msgstr "-l\t\t\tReÄimo Lisp"
-#: ../main.c:2213
msgid "-C\t\t\tCompatible with Vi: 'compatible'"
msgstr "-C\t\t\tKongrua kun Vi: 'compatible'"
-#: ../main.c:2214
msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
msgstr "-N\t\t\tNe tute kongrua kun Vi: 'nocompatible'"
-#: ../main.c:2215
msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
msgstr ""
"-V[N][dosiernomo]\tEsti babilema [nivelo N] [konservi mesaÄojn al dosiernomo]"
-#: ../main.c:2216
msgid "-D\t\t\tDebugging mode"
msgstr "-D\t\t\tSencimiga reÄimo"
-#: ../main.c:2217
msgid "-n\t\t\tNo swap file, use memory only"
msgstr "-n\t\t\tNeniu permutodosiero .swp, uzas nur memoron"
-#: ../main.c:2218
msgid "-r\t\t\tList swap files and exit"
msgstr "-r\t\t\tListigi permutodosierojn .swp kaj eliri"
-#: ../main.c:2219
msgid "-r (with file name)\tRecover crashed session"
msgstr "-r (kun dosiernomo)\tRestaÅ­ri kolapsintan seancon"
-#: ../main.c:2220
msgid "-L\t\t\tSame as -r"
msgstr "-L\t\t\tKiel -r"
-#: ../main.c:2221
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tNe uzi newcli por malfermi fenestrojn"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <aparatdosiero>\t\tUzi <aparatdosiero>-n por eneligo"
+
msgid "-A\t\t\tstart in Arabic mode"
msgstr "-A\t\t\tKomenci en araba reÄimo"
-#: ../main.c:2222
msgid "-H\t\t\tStart in Hebrew mode"
msgstr "-H\t\t\tKomenci en hebrea reÄimo"
-#: ../main.c:2223
msgid "-F\t\t\tStart in Farsi mode"
msgstr "-F\t\t\tKomenci en persa reÄimo"
-#: ../main.c:2224
msgid "-T <terminal>\tSet terminal type to <terminal>"
msgstr "-T <terminalo>\tAgordi terminalon al <terminalo>"
-#: ../main.c:2225
+msgid "--not-a-term\t\tSkip warning for input/output not being a terminal"
+msgstr ""
+"--not-a-term\t\tPreterpasi averton por enigo/eligo, kiu ne estas terminalo"
+
+msgid "--ttyfail\t\tExit if input or output is not a terminal"
+msgstr ""
+"--ttyfail\t\tEliri se le eniro aÅ­ eliro ne estas terminalo"
+
msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
msgstr "-u <vimrc>\t\tUzi <vimrc> anstataÅ­ iun ajn .vimrc"
-#: ../main.c:2226
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tUzi <gvimrc> anstataÅ­ iun ajn .gvimrc"
+
msgid "--noplugin\t\tDon't load plugin scripts"
msgstr "--noplugin\t\tNe Åargi kromaĵajn skriptojn"
-#: ../main.c:2227
msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
msgstr "-p[N]\t\tMalfermi N langetojn (defaŭlto: po unu por ĉiu dosiero)"
-#: ../main.c:2228
msgid "-o[N]\t\tOpen N windows (default: one for each file)"
msgstr "-o[N]\t\tMalfermi N fenestrojn (defaŭlto: po unu por ĉiu dosiero)"
-#: ../main.c:2229
msgid "-O[N]\t\tLike -o but split vertically"
msgstr "-O[N]\t\tKiel -o sed dividi vertikale"
-#: ../main.c:2230
msgid "+\t\t\tStart at end of file"
msgstr "+\t\t\tKomenci ĉe la fino de la dosiero"
-#: ../main.c:2231
msgid "+<lnum>\t\tStart at line <lnum>"
msgstr "+<numL>\t\tKomenci ĉe linio <numL>"
-#: ../main.c:2232
msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
msgstr ""
"--cmd <komando>\tPlenumi <komando>-n antaÅ­ ol Åargi iun ajn dosieron vimrc"
-#: ../main.c:2233
msgid "-c <command>\t\tExecute <command> after loading the first file"
msgstr "-c <komando>\t\tPlenumi <komando>-n post kiam la unua dosiero ÅargiÄis"
-#: ../main.c:2235
msgid "-S <session>\t\tSource file <session> after loading the first file"
msgstr ""
"-S <seanco>\t\tRuli dosieron <seanco>-n post kiam la unua dosiero ÅargiÄis"
-#: ../main.c:2236
msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
msgstr "-s <skripto>\t\tLegi komandojn en Normala reÄimo el dosiero <skripto>"
-#: ../main.c:2237
msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
msgstr ""
"-w <eligaskripto>\tPostaldoni ĉiujn tajpitajn komandojn al dosiero "
"<eligaskripto>"
-#: ../main.c:2238
msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
msgstr ""
"-W <eligaskripto>\tSkribi ĉiujn tajpitajn komandojn al dosiero <eligaskripto>"
-#: ../main.c:2240
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tRedakti ĉifradan dosieron"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <ekrano>\tKonekti Vim al tiu X-servilo"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tNe konekti al X-servilo"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <dosieroj>\tRedakti <dosieroj>-n en Vim-servilo se eblas"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-silent <dosieroj> Same, sed ne plendi se ne estas servilo"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr ""
+"--remote-wait <dosieroj> Kiel --remote sed atendi Äis dosieroj estas "
+"redaktitaj"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-wait-silent <dosieroj> Same, sed ne plendi se ne estas servilo"
+
+msgid ""
+"--remote-tab[-wait][-silent] <files> As --remote but use tab page per file"
+msgstr ""
+"--remote-tab[-wait][-silent] <dosieroj> Kiel --remote sed uzi langeton por "
+"ĉiu dosiero"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <klavoj> Sendi <klavoj>-n al Vim-servilo kaj eliri"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr "--remote-expr <espr>\tKomputi <espr> en Vim-servilo kaj afiÅi rezulton"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tListigi haveblajn nomojn de Vim-serviloj kaj eliri"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <nomo>\tSendu al/iÄi la Vim-servilo <nomo>"
+
msgid "--startuptime <file>\tWrite startup timing messages to <file>"
msgstr ""
"--startuptime <dosiero> Skribi mesaÄojn de komenca tempomezurado al "
"<dosiero>"
-#: ../main.c:2242
msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
msgstr "-i <viminfo>\t\tUzi <viminfo> anstataÅ­ .viminfo"
-#: ../main.c:2243
msgid "-h or --help\tPrint Help (this message) and exit"
msgstr "-h aÅ­ --help\tAfiÅi Helpon (tiun mesaÄon) kaj eliri"
-#: ../main.c:2244
msgid "--version\t\tPrint version information and exit"
msgstr "--version\t\tAfiÅi informon de versio kaj eliri"
-#: ../mark.c:676
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Argumentoj agnoskitaj de gvim (versio Motif):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Argumentoj agnoskitaj de gvim (versio neXtaw):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Argumentoj agnoskitaj de gvim (versio Athena):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <ekrano>\tLanĉi vim sur <ekrano>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tLanĉi vim piktograme"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <koloro>\tUzi <koloro>-n por la fona koloro (ankaÅ­: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr ""
+"-foreground <koloro>\tUzi <koloro>-n por la malfona koloro (ankaÅ­: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <tiparo>\tUzi <tiparo>-n por normala teksto (ankaÅ­: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <tiparo>\tUzi <tiparo>-n por grasa teksto"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <tiparo>\tUzi <tiparo>-n por kursiva teksto"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <geom>\tUzi <geom> kiel komenca geometrio (ankaÅ­: -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <larÄo>\tUzi <larÄo>-n kiel larÄo de bordero (ankaÅ­: -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <larÄo> Uzi <larÄo>-n kiel larÄo de rulumskalo (ankaÅ­: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr ""
+"-menuheight <alto>\tUzi <alto>-n kiel alto de menuzona alto (ankaÅ­: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tUzi inversan videon (ankaÅ­: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tNe uzi inversan videon (ankaÅ­: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <rimedo>\tAgordi la specifitan <rimedo>-n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Argumentoj agnoskitaj de gvim (versio GTK+):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <ekrano>\tLanĉi Vim sur tiu <ekrano> (ankaŭ: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "--role <rolo>\tDoni unikan rolon por identigi la ĉefan fenestron"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tMalfermi Vim en alia GTK fenestraĵo"
+
+msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
+msgstr "--echo-wid\t\tIgas gvim afiÅi la identigilon de vindozo sur stdout"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <gepatra titolo>\tMalfermi Vim en gepatra aplikaĵo"
+
+msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
+msgstr "--windowid <HWND>\tMalfermi Vim en alia win32 fenestraĵo"
+
+msgid "No display"
+msgstr "Neniu ekrano"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Sendo malsukcesis.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Sendo malsukcesis. Provo de loka plenumo\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d de %d redaktita(j)"
+
+msgid "No display: Send expression failed.\n"
+msgstr "Neniu ekrano: Sendado de esprimo malsukcesis.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Sendado de esprimo malsukcesis.\n"
+
msgid "No marks set"
msgstr "Neniu marko"
-#: ../mark.c:678
#, c-format
msgid "E283: No marks matching \"%s\""
msgstr "E283: Neniu marko kongruas kun \"%s\""
#. Highlight title
-#: ../mark.c:687
msgid ""
"\n"
"mark line col file/text"
@@ -3634,7 +3305,6 @@ msgstr ""
"mark linio kol dosiero/teksto"
#. Highlight title
-#: ../mark.c:789
msgid ""
"\n"
" jump line col file/text"
@@ -3643,7 +3313,6 @@ msgstr ""
" salt linio kol dosiero/teksto"
#. Highlight title
-#: ../mark.c:831
msgid ""
"\n"
"change line col text"
@@ -3651,7 +3320,6 @@ msgstr ""
"\n"
"ÅanÄo linio kol teksto"
-#: ../mark.c:1238
msgid ""
"\n"
"# File marks:\n"
@@ -3660,7 +3328,6 @@ msgstr ""
"# Markoj de dosiero:\n"
#. Write the jumplist with -'
-#: ../mark.c:1271
msgid ""
"\n"
"# Jumplist (newest first):\n"
@@ -3668,7 +3335,6 @@ msgstr ""
"\n"
"# Saltlisto (plej novaj unue):\n"
-#: ../mark.c:1352
msgid ""
"\n"
"# History of marks within files (newest to oldest):\n"
@@ -3676,85 +3342,90 @@ msgstr ""
"\n"
"# Historio de markoj en dosieroj (de plej nova al plej malnova):\n"
-#: ../mark.c:1431
msgid "Missing '>'"
msgstr "Mankas '>'"
-#: ../memfile.c:426
+msgid "E543: Not a valid codepage"
+msgstr "E543: Nevalida kodpaÄo"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Ne eblas agordi valorojn de IC"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Kreado de eniga kunteksto malsukcesis"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Malfermo de eniga metodo malsukcesis"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: Averto: Ne eblis agordi detruan reagfunkcion al IM"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: eniga metodo subtenas neniun stilon"
+
+# DP: mi ne scias, kio estas "preedit"
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: eniga metodo ne subtenas mian antaÅ­redaktan tipon"
+
msgid "E293: block was not locked"
msgstr "E293: bloko ne estis Ålosita"
-#: ../memfile.c:799
msgid "E294: Seek error in swap file read"
msgstr "E294: Eraro de enpoziciigo dum lego de permutodosiero .swp"
-#: ../memfile.c:803
msgid "E295: Read error in swap file"
msgstr "E295: Eraro de lego en permutodosiero .swp"
-#: ../memfile.c:849
msgid "E296: Seek error in swap file write"
msgstr "E296: Eraro de enpoziciigo dum skribo de permutodosiero .swp"
-#: ../memfile.c:865
msgid "E297: Write error in swap file"
msgstr "E297: Skriberaro en permutodosiero .swp"
-#: ../memfile.c:1036
msgid "E300: Swap file already exists (symlink attack?)"
msgstr "E300: Permutodosiero .swp jam ekzistas (ĉu atako per simbola ligilo?)"
-#: ../memline.c:318
msgid "E298: Didn't get block nr 0?"
msgstr "E298: Ĉu ne akiris blokon n-ro 0?"
-#: ../memline.c:361
msgid "E298: Didn't get block nr 1?"
msgstr "E298: Ĉu ne akiris blokon n-ro 1?"
-#: ../memline.c:377
msgid "E298: Didn't get block nr 2?"
msgstr "E298: Ĉu ne akiris blokon n-ro 2?"
+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????
-#: ../memline.c:465
msgid "E301: Oops, lost the swap file!!!"
msgstr "E301: Ve, perdis la permutodosieron .swp!!!"
-#: ../memline.c:477
msgid "E302: Could not rename swap file"
msgstr "E302: Ne eblis renomi la permutodosieron .swp"
-#: ../memline.c:554
#, c-format
msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
msgstr ""
"E303: Ne eblas malfermi permutodosieron .swp de \"%s\", restaÅ­ro neeblas"
-#: ../memline.c:666
msgid "E304: ml_upd_block0(): Didn't get block 0??"
msgstr "E304: ml_upd_block0(): Ne akiris blokon 0??"
-#. no swap files found
-#: ../memline.c:830
#, c-format
msgid "E305: No swap file found for %s"
msgstr "E305: Neniu permutodosiero .swp trovita por %s"
-#: ../memline.c:839
msgid "Enter number of swap file to use (0 to quit): "
msgstr "Entajpu la uzendan numeron de permutodosiero .swp (0 por eliri): "
-#: ../memline.c:879
#, c-format
msgid "E306: Cannot open %s"
msgstr "E306: Ne eblas malfermi %s"
-#: ../memline.c:897
msgid "Unable to read block 0 from "
msgstr "Ne eblas legi blokon 0 de "
-#: ../memline.c:900
msgid ""
"\n"
"Maybe no changes were made or Vim did not update the swap file."
@@ -3762,28 +3433,22 @@ msgstr ""
"\n"
"Eble neniu ÅanÄo estis farita aÅ­ Vim ne Äisdatigis la permutodosieron .swp."
-#: ../memline.c:909
msgid " cannot be used with this version of Vim.\n"
msgstr " ne uzeblas per tiu versio de vim.\n"
-#: ../memline.c:911
msgid "Use Vim version 3.0.\n"
msgstr "Uzu version 3.0 de Vim\n"
-#: ../memline.c:916
#, c-format
msgid "E307: %s does not look like a Vim swap file"
msgstr "E307: %s ne aspektas kiel permutodosiero .swp de Vim"
-#: ../memline.c:922
msgid " cannot be used on this computer.\n"
msgstr " ne uzeblas per tiu komputilo.\n"
-#: ../memline.c:924
msgid "The file was created on "
msgstr "La dosiero estas kreita je "
-#: ../memline.c:928
msgid ""
",\n"
"or the file has been damaged."
@@ -3791,85 +3456,104 @@ msgstr ""
",\n"
"aÅ­ la dosiero estas difekta."
-#: ../memline.c:945
+#, c-format
+msgid ""
+"E833: %s is encrypted and this version of Vim does not support encryption"
+msgstr "E833: %s estas ĉ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"
-#: ../memline.c:974
#, c-format
msgid "Using swap file \"%s\""
msgstr "Uzado de permutodosiero .swp \"%s\""
-#: ../memline.c:980
#, c-format
msgid "Original file \"%s\""
msgstr "Originala dosiero \"%s\""
-#: ../memline.c:995
msgid "E308: Warning: Original file may have been changed"
msgstr "E308: Averto: Originala dosiero eble ÅanÄiÄis"
-#: ../memline.c:1061
+#, c-format
+msgid "Swap file is encrypted: \"%s\""
+msgstr "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"
-#: ../memline.c:1065
msgid "???MANY LINES MISSING"
msgstr "???MULTAJ LINIOJ MANKAS"
-#: ../memline.c:1076
msgid "???LINE COUNT WRONG"
msgstr "???NOMBRO DE LINIOJ NE ÄœUSTAS"
-#: ../memline.c:1082
msgid "???EMPTY BLOCK"
msgstr "???MALPLENA BLOKO"
-#: ../memline.c:1103
msgid "???LINES MISSING"
msgstr "???LINIOJ MANKANTAJ"
-#: ../memline.c:1128
#, c-format
msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
msgstr ""
"E310: Nevalida identigilo de bloko 1 (ĉu %s ne estas permutodosiero .swp?)"
-#: ../memline.c:1133
msgid "???BLOCK MISSING"
msgstr "???MANKAS BLOKO"
-#: ../memline.c:1147
msgid "??? from here until ???END lines may be messed up"
msgstr "??? ekde tie Äis ???FINO linioj estas eble difektaj"
-#: ../memline.c:1164
msgid "??? from here until ???END lines may have been inserted/deleted"
msgstr "??? ekde tie Äis ???FINO linioj estas eble enmetitaj/forviÅitaj"
-#: ../memline.c:1181
msgid "???END"
msgstr "???FINO"
-#: ../memline.c:1238
msgid "E311: Recovery Interrupted"
msgstr "E311: RestaÅ­ro interrompita"
-#: ../memline.c:1243
msgid ""
"E312: Errors detected while recovering; look for lines starting with ???"
msgstr "E312: Eraroj dum restaÅ­ro; rigardu liniojn komencantajn per ???"
-#: ../memline.c:1245
msgid "See \":help E312\" for more information."
msgstr "Vidu \":help E312\" por pliaj informoj."
-#: ../memline.c:1249
msgid "Recovery completed. You should check if everything is OK."
msgstr "RestaÅ­ro finiÄis. Indus kontroli ĉu ĉio estas en ordo."
-#: ../memline.c:1251
msgid ""
"\n"
"(You might want to write out this file under another name\n"
@@ -3877,16 +3561,13 @@ msgstr ""
"\n"
"(Indas konservi tiun dosieron per alia nomo\n"
-#: ../memline.c:1252
msgid "and run diff with the original file to check for changes)"
msgstr "kaj lanĉi diff kun la originala dosiero por kontroli la ÅanÄojn)"
-#: ../memline.c:1254
msgid "Recovery completed. Buffer contents equals file contents."
msgstr ""
"RestaÅ­ro finiÄis. La enhavo de la bufro samas kun la enhavo de la dosiero."
-#: ../memline.c:1255
msgid ""
"\n"
"You may want to delete the .swp file now.\n"
@@ -3896,52 +3577,44 @@ msgstr ""
"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
-#: ../memline.c:1327
msgid "Swap files found:"
msgstr "Permutodosiero .swp trovita:"
-#: ../memline.c:1446
msgid " In current directory:\n"
msgstr " En la aktuala dosierujo:\n"
-#: ../memline.c:1448
msgid " Using specified name:\n"
msgstr " Uzado de specifita nomo:\n"
-#: ../memline.c:1450
msgid " In directory "
msgstr " En dosierujo "
-#: ../memline.c:1465
msgid " -- none --\n"
msgstr " -- nenio --\n"
-#: ../memline.c:1527
msgid " owned by: "
msgstr " posedata de: "
-#: ../memline.c:1529
msgid " dated: "
msgstr " dato: "
-#: ../memline.c:1532 ../memline.c:3231
msgid " dated: "
msgstr " dato: "
-#: ../memline.c:1548
msgid " [from Vim version 3.0]"
msgstr " [de Vim versio 3.0]"
-#: ../memline.c:1550
msgid " [does not look like a Vim swap file]"
msgstr " [ne aspektas kiel permutodosiero .swp de Vim]"
-#: ../memline.c:1552
msgid " file name: "
msgstr " dosiernomo: "
-#: ../memline.c:1558
msgid ""
"\n"
" modified: "
@@ -3949,15 +3622,12 @@ msgstr ""
"\n"
" modifita: "
-#: ../memline.c:1559
msgid "YES"
msgstr "JES"
-#: ../memline.c:1559
msgid "no"
msgstr "ne"
-#: ../memline.c:1562
msgid ""
"\n"
" user name: "
@@ -3965,11 +3635,9 @@ msgstr ""
"\n"
" uzantonomo: "
-#: ../memline.c:1568
msgid " host name: "
msgstr " komputila nomo: "
-#: ../memline.c:1570
msgid ""
"\n"
" host name: "
@@ -3977,7 +3645,6 @@ msgstr ""
"\n"
" komputila nomo: "
-#: ../memline.c:1575
msgid ""
"\n"
" process ID: "
@@ -3985,11 +3652,16 @@ msgstr ""
"\n"
" proceza ID: "
-#: ../memline.c:1579
msgid " (still running)"
msgstr " (ankoraÅ­ ruliÄas)"
-#: ../memline.c:1586
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [ne uzebla per tiu versio de Vim]"
+
msgid ""
"\n"
" [not usable on this computer]"
@@ -3997,97 +3669,75 @@ msgstr ""
"\n"
" [neuzebla per tiu komputilo]"
-#: ../memline.c:1590
msgid " [cannot be read]"
msgstr " [nelegebla]"
-#: ../memline.c:1593
msgid " [cannot be opened]"
msgstr " [nemalfermebla]"
-#: ../memline.c:1698
msgid "E313: Cannot preserve, there is no swap file"
msgstr "E313: Ne eblas konservi, ne estas permutodosiero .swp"
-#: ../memline.c:1747
msgid "File preserved"
msgstr "Dosiero konservita"
-#: ../memline.c:1749
msgid "E314: Preserve failed"
-msgstr "E314: Konservo fiaskis"
+msgstr "E314: Konservo malsukcesis"
-#: ../memline.c:1819
#, c-format
-msgid "E315: ml_get: invalid lnum: %<PRId64>"
-msgstr "E315: ml_get: nevalida lnum: %<PRId64>"
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: nevalida lnum: %ld"
-#: ../memline.c:1851
#, c-format
-msgid "E316: ml_get: cannot find line %<PRId64>"
-msgstr "E316: ml_get: ne eblas trovi linion %<PRId64>"
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: ne eblas trovi linion %ld"
-#: ../memline.c:2236
msgid "E317: pointer block id wrong 3"
msgstr "E317: nevalida referenco de bloko id 3"
-#: ../memline.c:2311
msgid "stack_idx should be 0"
msgstr "stack_idx devus esti 0"
-#: ../memline.c:2369
msgid "E318: Updated too many blocks?"
msgstr "E318: Ĉu Äisdatigis tro da blokoj?"
-#: ../memline.c:2511
msgid "E317: pointer block id wrong 4"
msgstr "E317: nevalida referenco de bloko id 4"
-#: ../memline.c:2536
msgid "deleted block 1?"
msgstr "ĉu forviÅita bloko 1?"
-#: ../memline.c:2707
#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: Ne eblas trovi linion %<PRId64>"
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Ne eblas trovi linion %ld"
-#: ../memline.c:2916
msgid "E317: pointer block id wrong"
msgstr "E317: nevalida referenco de bloko id"
-#: ../memline.c:2930
msgid "pe_line_count is zero"
msgstr "pe_line_count estas nul"
-#: ../memline.c:2955
#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: numero de linio ekster limoj: %<PRId64> preter la fino"
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: numero de linio ekster limoj: %ld preter la fino"
-#: ../memline.c:2959
#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: nevalida nombro de linioj en bloko %<PRId64>"
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: nevalida nombro de linioj en bloko %ld"
-#: ../memline.c:2999
msgid "Stack size increases"
msgstr "Stako pligrandiÄas"
-#: ../memline.c:3038
msgid "E317: pointer block id wrong 2"
msgstr "E317: nevalida referenco de bloko id 2"
-#: ../memline.c:3070
#, c-format
msgid "E773: Symlink loop for \"%s\""
msgstr "E773: Buklo de simbolaj ligiloj por \"%s\""
-#: ../memline.c:3221
msgid "E325: ATTENTION"
msgstr "E325: ATENTO"
-#: ../memline.c:3222
msgid ""
"\n"
"Found a swap file by the name \""
@@ -4095,15 +3745,14 @@ msgstr ""
"\n"
"Trovis permutodosieron .swp kun la nomo \""
-#: ../memline.c:3226
msgid "While opening file \""
msgstr "Dum malfermo de dosiero \""
-#: ../memline.c:3239
msgid " NEWER than swap file!\n"
msgstr " PLI NOVA ol permutodosiero .swp!\n"
-#: ../memline.c:3244
+#. 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"
@@ -4115,19 +3764,12 @@ msgstr ""
" por ne havi du malsamajn aperojn de la sama dosiero, kiam vi faros\n"
" ÅanÄojn. Eliru aÅ­ daÅ­rigu singarde.\n"
-#: ../memline.c:3245
-msgid " Quit, or continue with caution.\n"
-msgstr " Eliru, aÅ­ daÅ­rigu singarde.\n"
-
-#: ../memline.c:3246
msgid "(2) An edit session for this file crashed.\n"
msgstr "(2) Redakta seanco de tiu dosiero kolapsis.\n"
-#: ../memline.c:3247
msgid " If this is the case, use \":recover\" or \"vim -r "
msgstr " Se veras, uzu \":recover\" aÅ­ \"vim -r "
-#: ../memline.c:3249
msgid ""
"\"\n"
" to recover the changes (see \":help recovery\").\n"
@@ -4135,11 +3777,9 @@ msgstr ""
"\"\n"
" por restaÅ­ri la ÅanÄojn (vidu \":help recovery\").\n"
-#: ../memline.c:3250
msgid " If you did this already, delete the swap file \""
msgstr " Se vi jam faris Äin, forviÅu la permutodosieron .swp \""
-#: ../memline.c:3252
msgid ""
"\"\n"
" to avoid this message.\n"
@@ -4147,25 +3787,20 @@ msgstr ""
"\"\n"
" por eviti tiun mesaÄon.\n"
-#: ../memline.c:3450 ../memline.c:3452
msgid "Swap file \""
msgstr "Permutodosiero .swp \""
-#: ../memline.c:3451 ../memline.c:3455
msgid "\" already exists!"
msgstr "\" jam ekzistas!"
-#: ../memline.c:3457
msgid "VIM - ATTENTION"
msgstr "VIM - ATENTO"
-#: ../memline.c:3459
msgid "Swap file already exists!"
msgstr "Permutodosiero .swp jam ekzistas!"
# AM: ĉu Vim konvertos la unuliterajn respondojn de la uzulo?
# DP: jes, la '&' respondoj bone funkcias (mi kontrolis)
-#: ../memline.c:3464
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4179,7 +3814,6 @@ msgstr ""
"&Eliri\n"
"Ĉe&sigi"
-#: ../memline.c:3467
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4195,56 +3829,34 @@ msgstr ""
"&Eliri\n"
"Ĉe&sigi"
-#.
-#. * Change the ".swp" extension to find another file that can be used.
-#. * First decrement the last char: ".swo", ".swn", etc.
-#. * If that still isn't enough decrement the last but one char: ".svz"
-#. * Can happen when editing many "No Name" buffers.
-#.
-#. ".s?a"
-#. ".saa": tried enough, give up
-#: ../memline.c:3528
msgid "E326: Too many swap files found"
msgstr "E326: Tro da dosieroj trovitaj"
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: Ne plu restas memoro! (disponigo de %<PRIu64> bajtoj)"
-
-#: ../menu.c:62
msgid "E327: Part of menu-item path is not sub-menu"
msgstr "E327: Parto de vojo de menuero ne estas sub-menuo"
-#: ../menu.c:63
msgid "E328: Menu only exists in another mode"
msgstr "E328: Menuo nur ekzistas en alia reÄimo"
-#: ../menu.c:64
#, c-format
msgid "E329: No menu \"%s\""
msgstr "E329: Neniu menuo \"%s\""
#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
msgid "E792: Empty menu name"
msgstr "E792: Malplena nomo de menuo"
-#: ../menu.c:340
msgid "E330: Menu path must not lead to a sub-menu"
msgstr "E330: Vojo de menuo ne rajtas konduki al sub-menuo"
-#: ../menu.c:365
msgid "E331: Must not add menu items directly to menu bar"
msgstr "E331: Aldono de menueroj direkte al menuzono estas malpermesita"
-#: ../menu.c:370
msgid "E332: Separator cannot be part of a menu path"
msgstr "E332: Disigilo ne rajtas esti ero de vojo de menuo"
#. Now we have found the matching menu, and we list the mappings
#. Highlight title
-#: ../menu.c:762
msgid ""
"\n"
"--- Menus ---"
@@ -4252,69 +3864,60 @@ msgstr ""
"\n"
"--- Menuoj ---"
-#: ../menu.c:1313
+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"
-#: ../menu.c:1330
#, c-format
msgid "E334: Menu not found: %s"
msgstr "E334: Menuo netrovita: %s"
-#: ../menu.c:1396
#, c-format
msgid "E335: Menu not defined for %s mode"
msgstr "E335: Menuo ne estas difinita por reÄimo %s"
-#: ../menu.c:1426
msgid "E336: Menu path must lead to a sub-menu"
msgstr "E336: Vojo de menuo devas konduki al sub-menuo"
-#: ../menu.c:1447
msgid "E337: Menu not found - check menu names"
msgstr "E337: Menuo ne trovita - kontrolu nomojn de menuoj"
-#: ../message.c:423
#, c-format
msgid "Error detected while processing %s:"
msgstr "Eraro okazis dum traktado de %s:"
-#: ../message.c:445
#, c-format
msgid "line %4ld:"
msgstr "linio %4ld:"
-#: ../message.c:617
#, c-format
msgid "E354: Invalid register name: '%s'"
msgstr "E354: Nevalida nomo de reÄistro: '%s'"
-#: ../message.c:986
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Flegado de mesaÄoj: Dominique PELLÉ <dominique.pelle@gmail.com>"
+
msgid "Interrupt: "
msgstr "Interrompo: "
-#: ../message.c:988
msgid "Press ENTER or type command to continue"
msgstr "Premu ENEN-KLAVON aÅ­ tajpu komandon por daÅ­rigi"
-#: ../message.c:1843
#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s linio %<PRId64>"
+msgid "%s line %ld"
+msgstr "%s linio %ld"
-#: ../message.c:2392
msgid "-- More --"
msgstr "-- Pli --"
-#: ../message.c:2398
msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
msgstr " SPACETO/d/j: ekrano/paÄo/sub linio, b/u/k: supre, q: eliri "
-#: ../message.c:3021 ../message.c:3031
msgid "Question"
msgstr "Demando"
-#: ../message.c:3023
msgid ""
"&Yes\n"
"&No"
@@ -4322,19 +3925,8 @@ msgstr ""
"&Jes\n"
"&Ne"
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"&Jes\n"
-"&Ne\n"
-"&Rezigni"
-
# AM: ĉu Vim konvertos unuliterajn respondojn?
# DP: jes, '&' bone funkcias (mi kontrolis)
-#: ../message.c:3045
msgid ""
"&Yes\n"
"&No\n"
@@ -4348,175 +3940,249 @@ msgstr ""
"&Forlasi Ĉion\n"
"&Rezigni"
-#: ../message.c:3058
+msgid "Select Directory dialog"
+msgstr "Dialogujo de dosiera elekto"
+
+msgid "Save File dialog"
+msgstr "Dialogujo de dosiera konservo"
+
+msgid "Open File dialog"
+msgstr "Dialogujo de dosiera malfermo"
+
+#. 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()"
-#: ../message.c:3119
msgid "E807: Expected Float argument for printf()"
-msgstr "E807: Atendis Glitpunktnombron kiel argumento de printf()"
+msgstr "E807: Atendis Glitpunktnombron kiel argumenton de printf()"
-#: ../message.c:3873
msgid "E767: Too many arguments to printf()"
msgstr "E767: Tro da argumentoj al printf()"
-#: ../misc1.c:2256
msgid "W10: Warning: Changing a readonly file"
msgstr "W10: Averto: ÅœanÄo de nurlegebla dosiero"
-#: ../misc1.c:2537
msgid "Type number and <Enter> or click with mouse (empty cancels): "
msgstr ""
"Tajpu nombron kaj <Enenklavon> aÅ­ alklaku per la muso (malpleno rezignas): "
-#: ../misc1.c:2539
msgid "Type number and <Enter> (empty cancels): "
msgstr "Tajpu nombron kaj <Enenklavon> (malpleno rezignas): "
-#: ../misc1.c:2585
msgid "1 more line"
msgstr "1 plia linio"
-#: ../misc1.c:2588
msgid "1 line less"
msgstr "1 malplia linio"
-#: ../misc1.c:2593
#, c-format
-msgid "%<PRId64> more lines"
-msgstr "%<PRId64> pliaj linioj"
+msgid "%ld more lines"
+msgstr "%ld pliaj linioj"
-#: ../misc1.c:2596
#, c-format
-msgid "%<PRId64> fewer lines"
-msgstr "%<PRId64> malpliaj linioj"
+msgid "%ld fewer lines"
+msgstr "%ld malpliaj linioj"
-#: ../misc1.c:2599
msgid " (Interrupted)"
msgstr " (Interrompita)"
-#: ../misc1.c:2635
msgid "Beep!"
msgstr "Bip!"
-#: ../misc2.c:738
+msgid "ERROR: "
+msgstr "ERARO: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[bajtoj] totalaj disponigitaj/maldisponigitaj %lu-%lu, nun uzataj %lu, "
+"kulmina uzo %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[alvokoj] totalaj re/malloc() %lu, totalaj free() %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Linio iÄas tro longa"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Interna eraro: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Ne plu restas memoro! (disponigo de %lu bajtoj)"
+
#, c-format
msgid "Calling shell to execute: \"%s\""
msgstr "Alvokas Åelon por plenumi: \"%s\""
-#: ../normal.c:183
+msgid "E545: Missing colon"
+msgstr "E545: Mankas dupunkto"
+
+msgid "E546: Illegal mode"
+msgstr "E546: ReÄimo nepermesata"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Nevalida formo de muskursoro"
+
+msgid "E548: digit expected"
+msgstr "E548: cifero atendata"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Nevalida procento"
+
+msgid "E854: path too long for completion"
+msgstr "E854: tro longa vojo por kompletigo"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: Nevalida vojo: '**[nombro]' devas esti ĉe la fino de la vojo aŭ "
+"sekvita de '%s'."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Ne eblas trovi dosierujon \"%s\" en cdpath"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Ne eblas trovi dosieron \"%s\" en serĉvojo"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Ne plu trovis dosierujon \"%s\" en cdpath"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Ne plu trovis dosieron \"%s\" en serĉvojo"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: Nevalida permeso de dosiero de informo de konekto NetBeans: \"%s\""
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Konekto de NetBeans perdita por bufro %ld"
+
+msgid "E838: netbeans is not supported with this GUI"
+msgstr "E838: netbeans ne estas subtenata kun tiu grafika interfaco"
+
+msgid "E511: netbeans already connected"
+msgstr "E511: nebeans jam konektata"
+
+#, c-format
+msgid "E505: %s is read-only (add ! to override)"
+msgstr "E505: %s estas nurlegebla (aldonu ! por transpasi)"
+
msgid "E349: No identifier under cursor"
msgstr "E349: Neniu identigilo sub la kursoro"
-#: ../normal.c:1866
msgid "E774: 'operatorfunc' is empty"
msgstr "E774: 'operatorfunc' estas malplena"
-#: ../normal.c:2637
+# DP: ĉu Eval devas esti tradukita?
+msgid "E775: Eval feature not available"
+msgstr "E775: Eval eblo ne disponeblas"
+
msgid "Warning: terminal cannot highlight"
msgstr "Averto: terminalo ne povas emfazi"
-#: ../normal.c:2807
msgid "E348: No string under cursor"
msgstr "E348: Neniu ĉeno sub la kursoro"
-#: ../normal.c:3937
msgid "E352: Cannot erase folds with current 'foldmethod'"
msgstr "E352: Ne eblas forviÅi faldon per aktuala 'foldmethod'"
-#: ../normal.c:5897
msgid "E664: changelist is empty"
msgstr "E664: Listo de ÅanÄoj estas malplena"
-#: ../normal.c:5899
msgid "E662: At start of changelist"
msgstr "E662: Ĉe komenco de ÅanÄlisto"
-#: ../normal.c:5901
msgid "E663: At end of changelist"
msgstr "E663: Ĉe fino de ÅanÄlisto"
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
+msgid "Type :quit<Enter> to exit Vim"
msgstr "Tajpu \":quit<Enenklavo>\" por eliri el Vim"
-#: ../ops.c:248
#, c-format
msgid "1 line %sed 1 time"
msgstr "1 linio %sita 1 foje"
-#: ../ops.c:250
#, c-format
msgid "1 line %sed %d times"
msgstr "1 linio %sita %d foje"
-#: ../ops.c:253
#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> linio %sita 1 foje"
+msgid "%ld lines %sed 1 time"
+msgstr "%ld linio %sita 1 foje"
-#: ../ops.c:256
#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> linioj %sitaj %d foje"
+msgid "%ld lines %sed %d times"
+msgstr "%ld linioj %sitaj %d foje"
-#: ../ops.c:592
#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "%<PRId64> krommarÄenendaj linioj... "
+msgid "%ld lines to indent... "
+msgstr "%ld krommarÄenendaj linioj... "
-#: ../ops.c:634
msgid "1 line indented "
msgstr "1 linio krommarÄenita "
-#: ../ops.c:636
#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "%<PRId64> linioj krommarÄenitaj "
+msgid "%ld lines indented "
+msgstr "%ld linioj krommarÄenitaj "
-#: ../ops.c:938
msgid "E748: No previously used register"
msgstr "E748: Neniu reÄistro antaÅ­e uzata"
#. must display the prompt
-#: ../ops.c:1433
msgid "cannot yank; delete anyway"
-msgstr "ne eblas kopii; forviÅi tamene"
+msgstr "ne eblas kopii; tamen forviÅi"
-#: ../ops.c:1929
msgid "1 line changed"
msgstr "1 linio ÅanÄita"
-#: ../ops.c:1931
#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "%<PRId64> linioj ÅanÄitaj"
+msgid "%ld lines changed"
+msgstr "%ld linioj ÅanÄitaj"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "malokupas %ld liniojn"
-#: ../ops.c:2521
msgid "block of 1 line yanked"
msgstr "bloko de 1 linio kopiita"
-#: ../ops.c:2523
msgid "1 line yanked"
msgstr "1 linio kopiita"
-#: ../ops.c:2525
#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "bloko de %<PRId64> linioj kopiita"
+msgid "block of %ld lines yanked"
+msgstr "bloko de %ld linioj kopiita"
-#: ../ops.c:2528
#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "%<PRId64> linioj kopiitaj"
+msgid "%ld lines yanked"
+msgstr "%ld linioj kopiitaj"
-#: ../ops.c:2710
#, c-format
msgid "E353: Nothing in register %s"
msgstr "E353: Nenio en reÄistro %s"
#. Highlight title
-#: ../ops.c:3185
msgid ""
"\n"
"--- Registers ---"
@@ -4524,11 +4190,9 @@ msgstr ""
"\n"
"--- ReÄistroj ---"
-#: ../ops.c:4455
msgid "Illegal register name"
msgstr "Nevalida nomo de reÄistro"
-#: ../ops.c:4533
msgid ""
"\n"
"# Registers:\n"
@@ -4536,186 +4200,173 @@ msgstr ""
"\n"
"# ReÄistroj:\n"
-#: ../ops.c:4575
#, c-format
msgid "E574: Unknown register type %d"
msgstr "E574: Nekonata tipo de reÄistro %d"
-#: ../ops.c:5089
+msgid ""
+"E883: search pattern and expression register may not contain two or more "
+"lines"
+msgstr ""
+"E883: serĉa Åablono kaj esprima reÄistro ne povas enhavi du aÅ­ pliajn liniojn"
+
#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> Kolumnoj; "
+msgid "%ld Cols; "
+msgstr "%ld Kolumnoj; "
-#: ../ops.c:5097
#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
+msgid "Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes"
msgstr ""
-"Apartigis %s%<PRId64> de %<PRId64> Linioj; %<PRId64> de %<PRId64> Vortoj; "
-"%<PRId64> de %<PRId64> Bajtoj"
+"Apartigis %s%ld de %ld Linioj; %lld de %lld Vortoj; %lld de %lld Bajtoj"
-#: ../ops.c:5105
#, c-format
msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
+"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of "
+"%lld Bytes"
msgstr ""
-"Apartigis %s%<PRId64> de %<PRId64> Linioj; %<PRId64> de %<PRId64> Vortoj; "
-"%<PRId64> de %<PRId64> Signoj; %<PRId64> de %<PRId64> Bajtoj"
+"Apartigis %s%ld de %ld Linioj; %lld de %lld Vortoj; %lld de %lld Signoj; "
+"%lld de %lld Bajtoj"
-#: ../ops.c:5123
#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
-msgstr ""
-"Kol %s de %s; Linio %<PRId64> de %<PRId64>; Vorto %<PRId64> de %<PRId64>; "
-"Bajto %<PRId64> de %<PRId64>"
+msgid "Col %s of %s; Line %ld of %ld; Word %lld of %lld; Byte %lld of %lld"
+msgstr "Kol %s de %s; Linio %ld de %ld; Vorto %lld de %lld; Bajto %lld de %lld"
-#: ../ops.c:5133
#, c-format
msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
+"Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte "
+"%lld of %lld"
msgstr ""
-"Kol %s de %s; Linio %<PRId64> de %<PRId64>; Vorto %<PRId64> de %<PRId64>; "
-"Signo %<PRId64> de %<PRId64>; Bajto %<PRId64> de %<PRId64>"
+"Kol %s de %s; Linio %ld de %ld; Vorto %lld de %lld; Signo %lld de %lld; "
+"Bajto %lld de %lld"
-#: ../ops.c:5146
#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> por BOM)"
+msgid "(+%ld for BOM)"
+msgstr "(+%ld por BOM)"
-#: ../option.c:1238
msgid "%<%f%h%m%=Page %N"
msgstr "%<%f%h%m%=Folio %N"
-#: ../option.c:1574
msgid "Thanks for flying Vim"
msgstr "Dankon pro flugi per Vim"
-#. found a mismatch: skip
-#: ../option.c:2698
msgid "E518: Unknown option"
msgstr "E518: Nekonata opcio"
-#: ../option.c:2709
msgid "E519: Option not supported"
msgstr "E519: Opcio ne subtenata"
-#: ../option.c:2740
msgid "E520: Not allowed in a modeline"
msgstr "E520: Nepermesebla en reÄimlinio"
-#: ../option.c:2815
msgid "E846: Key code not set"
msgstr "E846: Klavkodo ne agordita"
-#: ../option.c:2924
msgid "E521: Number required after ="
msgstr "E521: Nombro bezonata post ="
-#: ../option.c:3226 ../option.c:3864
msgid "E522: Not found in termcap"
msgstr "E522: Netrovita en termcap"
-#: ../option.c:3335
#, c-format
msgid "E539: Illegal character <%s>"
msgstr "E539: Nevalida signo <%s>"
-#: ../option.c:2253
#, c-format
msgid "For option %s"
msgstr "Por opcio %s"
-#: ../option.c:3862
msgid "E529: Cannot set 'term' to empty string"
msgstr "E529: Ne eblas agordi 'term' al malplena ĉeno"
-#: ../option.c:3885
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: term ne ÅanÄeblas en grafika interfaco"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Uzu \":gui\" por lanĉi la grafikan interfacon"
+
msgid "E589: 'backupext' and 'patchmode' are equal"
msgstr "E589: 'backupext' kaj 'patchmode' estas egalaj"
-#: ../option.c:3964
msgid "E834: Conflicts with value of 'listchars'"
msgstr "E834: Konfliktoj kun la valoro de 'listchars'"
-#: ../option.c:3966
msgid "E835: Conflicts with value of 'fillchars'"
msgstr "E835: Konfliktoj kun la valoro de 'fillchars'"
-#: ../option.c:4163
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Ne ÅanÄeblas en la grafika interfaco GTK+ 2"
+
msgid "E524: Missing colon"
msgstr "E524: Mankas dupunkto"
-#: ../option.c:4165
msgid "E525: Zero length string"
msgstr "E525: Ĉeno de nula longo"
-#: ../option.c:4220
#, c-format
msgid "E526: Missing number after <%s>"
msgstr "E526: Mankas nombro post <%s>"
-#: ../option.c:4232
msgid "E527: Missing comma"
msgstr "E527: Mankas komo"
-#: ../option.c:4239
msgid "E528: Must specify a ' value"
msgstr "E528: Devas specifi ' valoron"
-#: ../option.c:4271
msgid "E595: contains unprintable or wide character"
msgstr "E595: enhavas nepreseblan aÅ­ plurĉellarÄan signon"
-#: ../option.c:4469
+msgid "E596: Invalid font(s)"
+msgstr "E596: Nevalida(j) tiparo(j)"
+
+msgid "E597: can't select fontset"
+msgstr "E597: ne eblas elekti tiparon"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Nevalida tiparo"
+
+msgid "E533: can't select wide font"
+msgstr "E533: ne eblas elekti larÄan tiparon"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Nevalida larÄa tiparo"
+
#, c-format
msgid "E535: Illegal character after <%c>"
msgstr "E535: Nevalida signo post <%c>"
-#: ../option.c:4534
msgid "E536: comma required"
msgstr "E536: komo bezonata"
-#: ../option.c:4543
#, c-format
msgid "E537: 'commentstring' must be empty or contain %s"
msgstr "E537: 'commentstring' devas esti malplena aÅ­ enhavi %s"
-#: ../option.c:4928
+msgid "E538: No mouse support"
+msgstr "E538: Neniu muso subtenata"
+
msgid "E540: Unclosed expression sequence"
msgstr "E540: '}' mankas"
-#: ../option.c:4932
msgid "E541: too many items"
msgstr "E541: tro da elementoj"
-#: ../option.c:4934
msgid "E542: unbalanced groups"
-msgstr "E542: misekvilibritaj grupoj"
+msgstr "E542: misekvilibraj grupoj"
-#: ../option.c:5148
msgid "E590: A preview window already exists"
msgstr "E590: AntaÅ­vida fenestro jam ekzistas"
-#: ../option.c:5311
msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
msgstr "W17: La araba bezonas UTF-8, tajpu \":set encoding=utf-8\""
-#: ../option.c:5623
#, c-format
msgid "E593: Need at least %d lines"
msgstr "E593: Bezonas almenaÅ­ %d liniojn"
-#: ../option.c:5631
#, c-format
msgid "E594: Need at least %d columns"
msgstr "E594: Bezonas almenaÅ­ %d kolumnojn"
-#: ../option.c:6011
#, c-format
msgid "E355: Unknown option: %s"
msgstr "E355: Nekonata opcio: %s"
@@ -4723,12 +4374,10 @@ msgstr "E355: Nekonata opcio: %s"
#. There's another character after zeros or the string
#. * is empty. In both cases, we are trying to set a
#. * num option using a string.
-#: ../option.c:6037
#, c-format
msgid "E521: Number required: &%s = '%s'"
msgstr "E521: Nombro bezonata: &%s = '%s'"
-#: ../option.c:6149
msgid ""
"\n"
"--- Terminal codes ---"
@@ -4736,7 +4385,6 @@ msgstr ""
"\n"
"--- Kodoj de terminalo ---"
-#: ../option.c:6151
msgid ""
"\n"
"--- Global option values ---"
@@ -4744,7 +4392,6 @@ msgstr ""
"\n"
"--- Mallokaj opcioj ---"
-#: ../option.c:6153
msgid ""
"\n"
"--- Local option values ---"
@@ -4752,7 +4399,6 @@ msgstr ""
"\n"
"--- Valoroj de lokaj opcioj ---"
-#: ../option.c:6155
msgid ""
"\n"
"--- Options ---"
@@ -4760,37 +4406,116 @@ msgstr ""
"\n"
"--- Opcioj ---"
-#: ../option.c:6816
msgid "E356: get_varp ERROR"
msgstr "E356: ERARO get_varp"
-#: ../option.c:7696
#, c-format
msgid "E357: 'langmap': Matching character missing for %s"
msgstr "E357: 'langmap': Kongrua signo mankas por %s"
-#: ../option.c:7715
#, c-format
msgid "E358: 'langmap': Extra characters after semicolon: %s"
msgstr "E358: 'langmap': Ekstraj signoj post punktokomo: %s"
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"Ne eblas plenumi Åelon "
+msgid "cannot open "
+msgstr "ne eblas malfermi "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Ne eblas malfermi fenestron!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Bezonas version 2.04 de Amigados aÅ­ pli novan\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Bezonas %s-on versio %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Ne eblas malfermi NIL:\n"
+
+msgid "Cannot create "
+msgstr "Ne eblas krei "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim eliras kun %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "ne eblas ÅanÄi reÄimon de konzolo?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: ne estas konzolo??\n"
+
+#. 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 "E237: Printer selection failed"
+msgstr "E237: Elekto de presilo malsukcesis"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "al %s de %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Nekonata tiparo de presilo: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Eraro de presado: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Presas '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Nevalida nomo de signaro \"%s\" en nomo de tiparo \"%s\""
+
+#, c-format
+msgid "E244: Illegal quality name \"%s\" in font name \"%s\""
+msgstr "E244: Nevalida nomo de kvalito \"%s\" en nomo de tiparo \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Nevalida signo '%c' en nomo de tiparo \"%s\""
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Malfermo de vidigo X daÅ­ris %ld msek"
-#: ../os/shell.c:439
msgid ""
"\n"
-"shell returned "
+"Vim: Got X error\n"
msgstr ""
"\n"
-"Åelo liveris "
+"Vim: Alvenis X eraro\n"
+
+msgid "Testing the X display failed"
+msgstr "Testo de la vidigo X malsukcesis"
+
+msgid "Opening the X display timed out"
+msgstr "Tempolimo okazis dum malfermo de vidigo X"
-#: ../os_unix.c:465 ../os_unix.c:471
msgid ""
"\n"
"Could not get security context for "
@@ -4798,7 +4523,6 @@ msgstr ""
"\n"
"Ne povis akiri kuntekston de sekureco por "
-#: ../os_unix.c:479
msgid ""
"\n"
"Could not set security context for "
@@ -4815,219 +4539,293 @@ msgid "Could not get security context %s for %s. Removing it!"
msgstr ""
"Ne povis akiri kuntekston de sekureco %s por %s. Gi nun estas forigata!"
-#: ../os_unix.c:1558 ../os_unix.c:1647
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Ne eblas plenumi Åelon sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"Åelo liveris "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Ne eblas krei duktojn\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"Ne eblas forki\n"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Ne eblas plenumi Åelon "
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Komando terminigita\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP perdis la konekton ICE"
+
#, c-format
msgid "dlerror = \"%s\""
msgstr "dlerror = \"%s\""
-#: ../path.c:1449
+msgid "Opening the X display failed"
+msgstr "Malfermo de vidigo X malsukcesis"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP: traktado de peto konservi-mem"
+
+msgid "XSMP opening connection"
+msgstr "XSMP: malfermo de konekto"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP: kontrolo de konekto ICE malsukcesis"
+
#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: Ne eblas trovi dosieron \"%s\" en serĉvojo"
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP: SmcOpenConnection malsukcesis: %s"
+
+msgid "At line"
+msgstr "Ĉe linio"
+
+msgid "Could not load vim32.dll!"
+msgstr "Ne eblis Åargi vim32.dll!"
+
+msgid "VIM Error"
+msgstr "Eraro de VIM"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Ne eblis ripari referencojn de funkcioj al la DLL!"
+
+# DP: la eventoj estas tiuj, kiuj estas en la sekvantaj ĉenoj
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Kaptis eventon %s\n"
+
+msgid "close"
+msgstr "fermo"
+
+msgid "logoff"
+msgstr "elsaluto"
+
+msgid "shutdown"
+msgstr "sistemfermo"
+
+msgid "E371: Command not found"
+msgstr "E371: Netrovebla komando"
+
+msgid ""
+"VIMRUN.EXE not found in your $PATH.\n"
+"External commands will not pause after completion.\n"
+"See :help win32-vimrun for more information."
+msgstr ""
+"VIMRUN.EXE ne troveblas en via $PATH.\n"
+"Eksteraj komandoj ne paÅ­zos post kompletigo.\n"
+"Vidu :help win32-vimrun por pliaj informoj."
+
+msgid "Vim Warning"
+msgstr "Averto de Vim"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "la Åelo liveris %d"
-#: ../quickfix.c:359
#, c-format
msgid "E372: Too many %%%c in format string"
msgstr "E372: Tro da %%%c en formata ĉeno"
-#: ../quickfix.c:371
#, c-format
msgid "E373: Unexpected %%%c in format string"
msgstr "E373: Neatendita %%%c en formata ĉeno"
-#: ../quickfix.c:420
msgid "E374: Missing ] in format string"
msgstr "E374: Mankas ] en formata ĉeno"
-#: ../quickfix.c:431
#, c-format
msgid "E375: Unsupported %%%c in format string"
msgstr "E375: Nesubtenata %%%c en formata ĉeno"
-#: ../quickfix.c:448
#, c-format
msgid "E376: Invalid %%%c in format string prefix"
msgstr "E376: Nevalida %%%c en prefikso de formata ĉeno"
-#: ../quickfix.c:454
#, c-format
msgid "E377: Invalid %%%c in format string"
msgstr "E377: Nevalida %%%c en formata ĉeno"
#. nothing found
-#: ../quickfix.c:477
msgid "E378: 'errorformat' contains no pattern"
msgstr "E378: 'errorformat' enhavas neniun Åablonon"
-#: ../quickfix.c:695
msgid "E379: Missing or empty directory name"
msgstr "E379: Nomo de dosierujo mankas aÅ­ estas malplena"
-#: ../quickfix.c:1305
msgid "E553: No more items"
msgstr "E553: Ne plu estas eroj"
-#: ../quickfix.c:1674
+msgid "E924: Current window was closed"
+msgstr "E924: Aktuala vindozo fermiÄis"
+
+msgid "E925: Current quickfix was changed"
+msgstr "E925: Aktuala rapidriparo ÅanÄiÄis"
+
+msgid "E926: Current location list was changed"
+msgstr "E926: Aktuala listo de lokoj ÅanÄiÄis"
+
#, c-format
msgid "(%d of %d)%s%s: "
msgstr "(%d de %d)%s%s: "
-#: ../quickfix.c:1676
msgid " (line deleted)"
msgstr " (forviÅita linio)"
-#: ../quickfix.c:1863
+#, c-format
+msgid "%serror list %d of %d; %d errors "
+msgstr "%slisto de eraroj %d de %d; %d eraroj"
+
msgid "E380: At bottom of quickfix stack"
msgstr "E380: Ĉe la subo de stako de rapidriparo"
-#: ../quickfix.c:1869
msgid "E381: At top of quickfix stack"
msgstr "E381: Ĉe la supro de stako de rapidriparo"
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "listo de eraroj %d de %d; %d eraroj"
+msgid "No entries"
+msgstr "Neniu ano"
-#: ../quickfix.c:2427
msgid "E382: Cannot write, 'buftype' option is set"
msgstr "E382: Ne eblas skribi, opcio 'buftype' estas Åaltita"
-#: ../quickfix.c:2812
+msgid "Error file"
+msgstr "Erara Dosiero"
+
msgid "E683: File name missing or invalid pattern"
msgstr "E683: Dosiernomo mankas aÅ­ nevalida Åablono"
-#: ../quickfix.c:2911
#, c-format
msgid "Cannot open file \"%s\""
msgstr "Ne eblas malfermi dosieron \"%s\""
-#: ../quickfix.c:3429
msgid "E681: Buffer is not loaded"
msgstr "E681: Bufro ne estas Åargita"
-#: ../quickfix.c:3487
msgid "E777: String or List expected"
msgstr "E777: Ĉeno aŭ Listo atendita"
-#: ../regexp.c:359
#, c-format
msgid "E369: invalid item in %s%%[]"
msgstr "E369: nevalida ano en %s%%[]"
-#: ../regexp.c:374
#, c-format
msgid "E769: Missing ] after %s["
msgstr "E769: Mankas ] post %s["
-#: ../regexp.c:375
#, c-format
msgid "E53: Unmatched %s%%("
msgstr "E53: Neekvilibra %s%%("
-#: ../regexp.c:376
#, c-format
msgid "E54: Unmatched %s("
msgstr "E54: Neekvilibra %s("
-#: ../regexp.c:377
#, c-format
msgid "E55: Unmatched %s)"
msgstr "E55: Neekvilibra %s"
-#: ../regexp.c:378
msgid "E66: \\z( not allowed here"
-msgstr "E66: \\z( estas permesebla tie"
+msgstr "E66: \\z( estas nepermesebla tie"
# DP: vidu http://www.thefreedictionary.com/et+al.
-#: ../regexp.c:379
msgid "E67: \\z1 et al. not allowed here"
msgstr "E67: \\z1 kaj aliaj estas nepermeseblaj tie"
-#: ../regexp.c:380
#, c-format
msgid "E69: Missing ] after %s%%["
msgstr "E69: Mankas ] post %s%%["
-#: ../regexp.c:381
#, c-format
msgid "E70: Empty %s%%[]"
msgstr "E70: Malplena %s%%[]"
-#: ../regexp.c:1209 ../regexp.c:1224
msgid "E339: Pattern too long"
msgstr "E339: Åœablono tro longa"
-#: ../regexp.c:1371
msgid "E50: Too many \\z("
msgstr "E50: Tro da \\z("
-#: ../regexp.c:1378
#, c-format
msgid "E51: Too many %s("
msgstr "E51: Tro da %s("
-#: ../regexp.c:1427
msgid "E52: Unmatched \\z("
msgstr "E52: Neekvilibra \\z("
-#: ../regexp.c:1637
#, c-format
msgid "E59: invalid character after %s@"
msgstr "E59: nevalida signo post %s@"
-#: ../regexp.c:1672
#, c-format
msgid "E60: Too many complex %s{...}s"
msgstr "E60: Tro da kompleksaj %s{...}-oj"
-#: ../regexp.c:1687
#, c-format
msgid "E61: Nested %s*"
msgstr "E61: Ingita %s*"
-#: ../regexp.c:1690
#, c-format
msgid "E62: Nested %s%c"
msgstr "E62: Ingita %s%c"
-#: ../regexp.c:1800
msgid "E63: invalid use of \\_"
msgstr "E63: nevalida uzo de \\_"
-#: ../regexp.c:1850
#, c-format
msgid "E64: %s%c follows nothing"
msgstr "E64: %s%c sekvas nenion"
-#: ../regexp.c:1902
msgid "E65: Illegal back reference"
msgstr "E65: Nevalida retro-referenco"
-#: ../regexp.c:1943
msgid "E68: Invalid character after \\z"
msgstr "E68: Nevalida signo post \\z"
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
#, c-format
msgid "E678: Invalid character after %s%%[dxouU]"
msgstr "E678: Nevalida signo post %s%%[dxouU]"
-#: ../regexp.c:2107
#, c-format
msgid "E71: Invalid character after %s%%"
msgstr "E71: Nevalida signo post %s%%"
-#: ../regexp.c:3017
#, c-format
msgid "E554: Syntax error in %s{...}"
msgstr "E554: Sintaksa eraro en %s{...}"
-#: ../regexp.c:3805
msgid "External submatches:\n"
msgstr "Eksteraj subkongruoj:\n"
-#: ../regexp.c:7022
+#, c-format
+msgid "E888: (NFA regexp) cannot repeat %s"
+msgstr "E888: (NFA-regulesprimo) ne eblas ripeti %s"
+
msgid ""
"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
"used "
@@ -5035,65 +4833,58 @@ msgstr ""
"E864: \\%#= povas nur esti sekvita de 0, 1, aÅ­ 2. La aÅ­tomata motoro de "
"regulesprimo estos uzata "
-#: ../regexp_nfa.c:239
+msgid "Switching to backtracking RE engine for pattern: "
+msgstr "Åœangota al malavanca motoro de regulesprimo por Åablono: "
+
msgid "E865: (NFA) Regexp end encountered prematurely"
msgstr "E865: (NFA) Trovis finon de regulesprimo tro frue"
-#: ../regexp_nfa.c:240
#, c-format
msgid "E866: (NFA regexp) Misplaced %c"
msgstr "E866: (NFA-regulesprimo) Mispoziciigita %c"
-#: ../regexp_nfa.c:242
-#, fuzzy, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr "E877: (NFA-regulesprimo) Nevalida klaso de signo "
+#, c-format
+msgid "E877: (NFA regexp) Invalid character class: %ld"
+msgstr "E877: (NFA-regulesprimo) Nevalida klaso de signo: %ld"
-#: ../regexp_nfa.c:1261
#, c-format
msgid "E867: (NFA) Unknown operator '\\z%c'"
msgstr "E867: (NFA) Nekonata operatoro '\\z%c'"
-#: ../regexp_nfa.c:1387
-#, fuzzy, c-format
+#, c-format
msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr "E867: (NFA) Nekonata operatoro '\\z%c'"
+msgstr "E867: (NFA) Nekonata operatoro '\\%%%c'"
+
+#. should never happen
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: Eraro dum prekomputado de NFA kun ekvivalentoklaso!"
-#: ../regexp_nfa.c:1802
#, c-format
msgid "E869: (NFA) Unknown operator '\\@%c'"
msgstr "E869: (NFA) Nekonata operatoro '\\@%c'"
-#: ../regexp_nfa.c:1831
msgid "E870: (NFA regexp) Error reading repetition limits"
msgstr "E870: (NFS-regulesprimo) Eraro dum legado de limoj de ripeto"
#. Can't have a multi follow a multi.
-#: ../regexp_nfa.c:1895
msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
msgstr ""
"E871: (NFA-regulesprimo) Ne povas havi mult-selekton tuj post alia mult-"
"selekto!"
#. Too many `('
-#: ../regexp_nfa.c:2037
msgid "E872: (NFA regexp) Too many '('"
msgstr "E872: (NFA-regulesprimo) tro da '('"
-#: ../regexp_nfa.c:2042
-#, fuzzy
msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E872: (NFA-regulesprimo) tro da '('"
+msgstr "E879: (NFA-regulesprimo) tro da \\z("
-#: ../regexp_nfa.c:2066
msgid "E873: (NFA regexp) proper termination error"
msgstr "E873: (NFA-regulesprimo) propra end-eraro"
-#: ../regexp_nfa.c:2599
msgid "E874: (NFA) Could not pop the stack !"
msgstr "E874: (NFA) Ne povis elpreni de la staplo!"
-#: ../regexp_nfa.c:3298
msgid ""
"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
"left on stack"
@@ -5101,177 +4892,136 @@ msgstr ""
"E875: (NFA-regulesprimo) (dum konverto de postmeto al NFA), restas tro da "
"statoj en la staplo"
-#: ../regexp_nfa.c:3302
msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
msgstr "E876: (NFA-regulesprimo) ne sufiĉa spaco por enmomorigi la tutan NFA "
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
+msgid "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, displaying on stderr ... "
msgstr ""
"Ne povis malfermi provizoran protokolan dosieron por skribi, nun montras sur "
"stderr ..."
-#: ../regexp_nfa.c:4840
#, c-format
msgid "(NFA) COULD NOT OPEN %s !"
msgstr "(NFA) NE POVIS MALFERMI %s!"
-#: ../regexp_nfa.c:6049
msgid "Could not open temporary log file for writing "
msgstr "Ne povis malfermi la provizoran protokolan dosieron por skribi "
-#: ../screen.c:7435
msgid " VREPLACE"
msgstr " V-ANSTATAŬIGO"
-#: ../screen.c:7437
msgid " REPLACE"
msgstr " ANSTATAŬIGO"
-#: ../screen.c:7440
msgid " REVERSE"
msgstr " INVERSI"
-#: ../screen.c:7441
msgid " INSERT"
msgstr " ENMETO"
-#: ../screen.c:7443
msgid " (insert)"
msgstr " (enmeto)"
-#: ../screen.c:7445
msgid " (replace)"
msgstr " (anstataÅ­igo)"
-#: ../screen.c:7447
msgid " (vreplace)"
msgstr " (v-anstataÅ­igo)"
-#: ../screen.c:7449
msgid " Hebrew"
msgstr " hebrea"
-#: ../screen.c:7454
msgid " Arabic"
msgstr " araba"
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (lingvo)"
-
-#: ../screen.c:7459
msgid " (paste)"
msgstr " (algluo)"
-#: ../screen.c:7469
msgid " VISUAL"
msgstr " VIDUMA"
-#: ../screen.c:7470
msgid " VISUAL LINE"
msgstr " VIDUMA LINIO"
-#: ../screen.c:7471
msgid " VISUAL BLOCK"
msgstr " VIDUMA BLOKO"
-#: ../screen.c:7472
msgid " SELECT"
msgstr " APARTIGO"
-#: ../screen.c:7473
msgid " SELECT LINE"
msgstr " APARTIGITA LINIO"
-#: ../screen.c:7474
msgid " SELECT BLOCK"
msgstr " APARTIGITA BLOKO"
-#: ../screen.c:7486 ../screen.c:7541
msgid "recording"
msgstr "registrado"
-#: ../search.c:487
#, c-format
msgid "E383: Invalid search string: %s"
msgstr "E383: Nevalida serĉenda ĉeno: %s"
-#: ../search.c:832
#, c-format
msgid "E384: search hit TOP without match for: %s"
msgstr "E384: serĉo atingis SUPRON sen trovi: %s"
-#: ../search.c:835
#, c-format
msgid "E385: search hit BOTTOM without match for: %s"
msgstr "E385: serĉo atingis SUBON sen trovi: %s"
-#: ../search.c:1200
msgid "E386: Expected '?' or '/' after ';'"
msgstr "E386: Atendis '?' aÅ­ '/' post ';'"
-#: ../search.c:4085
msgid " (includes previously listed match)"
msgstr " (enhavas antaÅ­e listigitajn kongruojn)"
#. cursor at status line
-#: ../search.c:4104
msgid "--- Included files "
msgstr "--- Inkluzivitaj dosieroj "
-#: ../search.c:4106
msgid "not found "
msgstr "netrovitaj "
-#: ../search.c:4107
msgid "in path ---\n"
msgstr "en serĉvojo ---\n"
-#: ../search.c:4168
msgid " (Already listed)"
msgstr " (Jam listigita)"
-#: ../search.c:4170
msgid " NOT FOUND"
msgstr " NETROVITA"
-#: ../search.c:4211
#, c-format
msgid "Scanning included file: %s"
msgstr "Skanado de inkluzivitaj dosieroj: %s"
-#: ../search.c:4216
#, c-format
msgid "Searching included file %s"
msgstr "Serĉado de inkluzivitaj dosieroj %s"
-#: ../search.c:4405
msgid "E387: Match is on current line"
msgstr "E387: Kongruo estas ĉe aktuala linio"
-#: ../search.c:4517
msgid "All included files were found"
msgstr "Ĉiuj inkluzivitaj dosieroj estis trovitaj"
-#: ../search.c:4519
msgid "No included files"
msgstr "Neniu inkluzivita dosiero"
-#: ../search.c:4527
msgid "E388: Couldn't find definition"
msgstr "E388: Ne eblis trovi difinon"
-#: ../search.c:4529
msgid "E389: Couldn't find pattern"
msgstr "E389: Ne eblis trovi Åablonon"
-#: ../search.c:4668
msgid "Substitute "
msgstr "AnstataÅ­igi "
-#: ../search.c:4681
#, c-format
msgid ""
"\n"
@@ -5282,97 +5032,128 @@ msgstr ""
"# Lasta serĉa Åablono %s:\n"
"~"
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: Eraro de formato en literuma dosiero"
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Literumilo ne estas Åaltita"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
+msgstr "Averto: Ne eblas trovi vortliston \"%s_%s.spl\" aÅ­ \"%s_ascii.spl\""
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr "Averto: Ne eblas trovi vortliston \"%s.%s.spl\" aÅ­ \"%s.ascii.spl\""
+
+msgid "E797: SpellFileMissing autocommand deleted buffer"
+msgstr "E797: AÅ­tokomando SpellFileMissing forviÅis bufron"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Averto: regiono %s ne subtenata"
+
+msgid "Sorry, no suggestions"
+msgstr "BedaÅ­rinde ne estas sugestoj"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "BedaÅ­rinde estas nur %ld sugestoj"
+
+#. 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"
-#: ../spell.c:952
msgid "E758: Truncated spell file"
msgstr "E758: Trunkita literuma dosiero"
-#: ../spell.c:953
#, c-format
msgid "Trailing text in %s line %d: %s"
msgstr "Vosta teksto en %s linio %d: %s"
-#: ../spell.c:954
#, c-format
msgid "Affix name too long in %s line %d: %s"
msgstr "Nomo de afikso tro longa en %s linio %d: %s"
-#: ../spell.c:955
msgid "E761: Format error in affix file FOL, LOW or UPP"
msgstr "E761: Eraro de formato en afiksa dosiero FOL, LOW aÅ­ UPP"
-#: ../spell.c:957
msgid "E762: Character in FOL, LOW or UPP is out of range"
msgstr "E762: Signo en FOL, LOW aÅ­ UPP estas ekster limoj"
-#: ../spell.c:958
msgid "Compressing word tree..."
msgstr "Densigas arbon de vortoj..."
-#: ../spell.c:1951
-msgid "E756: Spell checking is not enabled"
-msgstr "E756: Literumilo ne estas Åaltita"
-
-#: ../spell.c:2249
-#, c-format
-msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
-msgstr "Averto: Ne eblas trovi vortliston \"%s.%s.spl\" aÅ­ \"%s.ascii.spl\""
-
-#: ../spell.c:2473
#, c-format
msgid "Reading spell file \"%s\""
msgstr "Legado de literuma dosiero \"%s\""
-#: ../spell.c:2496
msgid "E757: This does not look like a spell file"
msgstr "E757: Tio ne Åajnas esti literuma dosiero"
-#: ../spell.c:2501
msgid "E771: Old spell file, needs to be updated"
msgstr "E771: Malnova literuma dosiero, Äisdatigo bezonata"
-#: ../spell.c:2504
msgid "E772: Spell file is for newer version of Vim"
msgstr "E772: Literuma dosiero estas por pli nova versio de Vim"
-#: ../spell.c:2602
msgid "E770: Unsupported section in spell file"
msgstr "E770: Nesubtenata sekcio en literuma dosiero"
-#: ../spell.c:3762
#, c-format
-msgid "Warning: region %s not supported"
-msgstr "Averto: regiono %s ne subtenata"
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Tio ne Åajnas esti dosiero .sug: %s"
+
+#, 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"
-#: ../spell.c:4550
#, c-format
msgid "Reading affix file %s ..."
msgstr "Legado de afiksa dosiero %s ..."
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
msgid "Conversion failure for word in %s line %d: %s"
msgstr "Malsukceso dum konverto de vorto en %s linio %d: %s"
-#: ../spell.c:4630 ../spell.c:6170
#, c-format
msgid "Conversion in %s not supported: from %s to %s"
msgstr "Konverto en %s nesubtenata: de %s al %s"
-#: ../spell.c:4642
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Konverto en %s nesubtenata"
+
#, c-format
msgid "Invalid value for FLAG in %s line %d: %s"
msgstr "Nevalida valoro de FLAG en %s linio %d: %s"
-#: ../spell.c:4655
#, c-format
msgid "FLAG after using flags in %s line %d: %s"
msgstr "FLAG post flagoj en %s linio %d: %s"
-#: ../spell.c:4723
#, c-format
msgid ""
"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
@@ -5381,7 +5162,6 @@ msgstr ""
"Difino de COMPOUNDFORBIDFLAG post ano PFX povas doni neÄustajn rezultojn en "
"%s linio %d"
-#: ../spell.c:4731
#, c-format
msgid ""
"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
@@ -5390,42 +5170,34 @@ msgstr ""
"Difino de COMPOUNDPERMITFLAG post ano PFX povas doni neÄustajn rezultojn en "
"%s linio %d"
-#: ../spell.c:4747
#, c-format
msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
msgstr "Nevalida valoro de COMPOUNDRULES en %s linio %d: %s"
-#: ../spell.c:4771
#, c-format
msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
msgstr "Nevalida valoro de COMPOUNDWORDMAX en %s linio %d: %s"
-#: ../spell.c:4777
#, c-format
msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
msgstr "Nevalida valoro de COMPOUNDMIN en %s linio %d: %s"
-#: ../spell.c:4783
#, c-format
msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
msgstr "Nevalida valoro de COMPOUNDSYLMAX en %s linio %d: %s"
-#: ../spell.c:4795
#, c-format
msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
msgstr "Nevalida valoro de CHECKCOMPOUNDPATTERN en %s linio %d: %s"
-#: ../spell.c:4847
#, c-format
msgid "Different combining flag in continued affix block in %s line %d: %s"
msgstr "Malsama flago de kombino en daÅ­ra bloko de afikso en %s linio %d: %s"
-#: ../spell.c:4850
#, c-format
msgid "Duplicate affix in %s line %d: %s"
msgstr "Ripetita afikso en %s linio %d: %s"
-#: ../spell.c:4871
#, c-format
msgid ""
"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
@@ -5434,308 +5206,206 @@ msgstr ""
"Afikso ankaÅ­ uzata por BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST en "
"%s linio %d: %s"
-#: ../spell.c:4893
#, c-format
msgid "Expected Y or N in %s line %d: %s"
msgstr "Y aÅ­ N atendita en %s linio %d: %s"
-#: ../spell.c:4968
#, c-format
msgid "Broken condition in %s line %d: %s"
msgstr "Nevalida kondiĉo en %s linio %d: %s"
-#: ../spell.c:5091
#, c-format
msgid "Expected REP(SAL) count in %s line %d"
msgstr "Neatendita nombro REP(SAL) en %s linio %d"
-#: ../spell.c:5120
#, c-format
msgid "Expected MAP count in %s line %d"
msgstr "Neatendita nombro de MAPen %s linio %d"
-#: ../spell.c:5132
#, c-format
msgid "Duplicate character in MAP in %s line %d"
msgstr "Ripetita signo en MAP en %s linio %d"
-#: ../spell.c:5176
#, c-format
msgid "Unrecognized or duplicate item in %s line %d: %s"
msgstr "Neagnoskita aÅ­ ripetita ano en %s linio %d: %s"
-#: ../spell.c:5197
#, c-format
msgid "Missing FOL/LOW/UPP line in %s"
msgstr "Mankas linio FOL/LOW/UPP en %s"
-#: ../spell.c:5220
msgid "COMPOUNDSYLMAX used without SYLLABLE"
msgstr "COMPOUNDSYLMAX uzita sen SYLLABLE"
-#: ../spell.c:5236
msgid "Too many postponed prefixes"
msgstr "Tro da prokrastitaj prefiksoj"
-#: ../spell.c:5238
msgid "Too many compound flags"
msgstr "Tro da kunmetitaj flagoj"
-#: ../spell.c:5240
msgid "Too many postponed prefixes and/or compound flags"
msgstr "Tro da prokrastitaj prefiksoj kaj/aÅ­ kunmetitaj flagoj"
-#: ../spell.c:5250
#, c-format
msgid "Missing SOFO%s line in %s"
msgstr "Mankas SOFO%s-aj linioj en %s"
-#: ../spell.c:5253
#, c-format
msgid "Both SAL and SOFO lines in %s"
msgstr "AmbaÅ­ SAL kaj SOFO linioj en %s"
-#: ../spell.c:5331
#, c-format
msgid "Flag is not a number in %s line %d: %s"
msgstr "Flago ne estas nombro en %s linio %d: %s"
-#: ../spell.c:5334
#, c-format
msgid "Illegal flag in %s line %d: %s"
msgstr "Nevalida flago en %s linio %d: %s"
-#: ../spell.c:5493 ../spell.c:5501
#, c-format
msgid "%s value differs from what is used in another .aff file"
msgstr "Valoro de %s malsamas ol tiu en alia dosiero .aff"
-#: ../spell.c:5602
#, c-format
msgid "Reading dictionary file %s ..."
msgstr "Legado de vortardosiero %s ..."
-#: ../spell.c:5611
#, c-format
msgid "E760: No word count in %s"
msgstr "E760: Ne estas nombro de vortoj en %s"
-#: ../spell.c:5669
#, c-format
msgid "line %6d, word %6d - %s"
msgstr "linio %6d, vorto %6d - %s"
-#: ../spell.c:5691
#, c-format
msgid "Duplicate word in %s line %d: %s"
msgstr "Ripetita vorto en %s linio %d: %s"
-#: ../spell.c:5694
#, c-format
msgid "First duplicate word in %s line %d: %s"
msgstr "Unua ripetita vorto en %s linio %d: %s"
-#: ../spell.c:5746
#, c-format
msgid "%d duplicate word(s) in %s"
msgstr "%d ripetita(j) vorto(j) en %s"
-#: ../spell.c:5748
#, c-format
msgid "Ignored %d word(s) with non-ASCII characters in %s"
msgstr "%d ignorita(j) vorto(j) kun neaskiaj signoj en %s"
-#: ../spell.c:6115
#, c-format
msgid "Reading word file %s ..."
msgstr "Legado de dosiero de vortoj %s ..."
-#: ../spell.c:6155
#, c-format
msgid "Duplicate /encoding= line ignored in %s line %d: %s"
msgstr "Ripetita linio /encoding= ignorita en %s linio %d: %s"
-#: ../spell.c:6159
#, c-format
msgid "/encoding= line after word ignored in %s line %d: %s"
msgstr "Linio /encoding= post vorto ignorita en %s linio %d: %s"
-#: ../spell.c:6180
#, c-format
msgid "Duplicate /regions= line ignored in %s line %d: %s"
msgstr "Ripetita linio /regions= ignorita en %s linio %d: %s"
-#: ../spell.c:6185
#, c-format
msgid "Too many regions in %s line %d: %s"
msgstr "Tro da regionoj en %s linio %d: %s"
-#: ../spell.c:6198
#, c-format
msgid "/ line ignored in %s line %d: %s"
msgstr "Linio / ignorita en %s linio %d: %s"
-#: ../spell.c:6224
#, c-format
msgid "Invalid region nr in %s line %d: %s"
msgstr "Nevalida regiono nr en %s linio %d: %s"
-#: ../spell.c:6230
#, c-format
msgid "Unrecognized flags in %s line %d: %s"
msgstr "Nekonata flago en %s linio %d: %s"
-#: ../spell.c:6257
#, c-format
msgid "Ignored %d words with non-ASCII characters"
msgstr "Ignoris %d vorto(j)n kun neaskiaj signoj"
-#: ../spell.c:6656
+msgid "E845: Insufficient memory, word list will be incomplete"
+msgstr "E845: Ne sufiĉe da memoro, vortlisto estos nekompleta."
+
#, c-format
msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
msgstr "Densigis %d de %d nodoj; %d (%d%%) restantaj"
-#: ../spell.c:7340
msgid "Reading back spell file..."
msgstr "Relegas la dosieron de literumo..."
-#. Go through the trie of good words, soundfold each word and add it to
-#. the soundfold trie.
-#: ../spell.c:7357
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
msgid "Performing soundfolding..."
msgstr "Fonetika analizado..."
-#: ../spell.c:7368
#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "Nombro de vortoj post fonetika analizado: %<PRId64>"
+msgid "Number of words after soundfolding: %ld"
+msgstr "Nombro de vortoj post fonetika analizado: %ld"
-#: ../spell.c:7476
#, c-format
msgid "Total number of words: %d"
msgstr "Totala nombro de vortoj: %d"
-#: ../spell.c:7655
#, c-format
msgid "Writing suggestion file %s ..."
msgstr "Skribado de dosiero de sugesto %s ..."
-#: ../spell.c:7707 ../spell.c:7927
#, c-format
msgid "Estimated runtime memory use: %d bytes"
msgstr "Evaluo de memoro uzata: %d bajtoj"
-#: ../spell.c:7820
msgid "E751: Output file name must not have region name"
msgstr "E751: Nomo de eliga dosiero ne devas havi nomon de regiono"
-#: ../spell.c:7822
msgid "E754: Only up to 8 regions supported"
msgstr "E754: Nur 8 regionoj subtenataj"
-#: ../spell.c:7846
#, c-format
msgid "E755: Invalid region in %s"
msgstr "E755: Nevalida regiono en %s"
-#: ../spell.c:7907
msgid "Warning: both compounding and NOBREAK specified"
msgstr "Averto: ambaÅ­ NOBREAK kaj NOBREAK specifitaj"
-#: ../spell.c:7920
#, c-format
msgid "Writing spell file %s ..."
msgstr "Skribado de literuma dosiero %s ..."
-#: ../spell.c:7925
msgid "Done!"
msgstr "Farita!"
-#: ../spell.c:8034
#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: 'spellfile' ne havas %<PRId64> rikordojn"
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' ne havas %ld rikordojn"
-#: ../spell.c:8074
-#, fuzzy, c-format
+#, c-format
msgid "Word '%.*s' removed from %s"
-msgstr "Vorto fortirita el %s"
+msgstr "Vorto '%.*s' fortirita el %s"
-#: ../spell.c:8117
-#, fuzzy, c-format
+#, c-format
msgid "Word '%.*s' added to %s"
-msgstr "Vorto aldonita al %s"
+msgstr "Vorto '%.*s' aldonita al %s"
-#: ../spell.c:8381
msgid "E763: Word characters differ between spell files"
msgstr "E763: Signoj de vorto malsamas tra literumaj dosieroj"
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "BedaÅ­rinde ne estas sugestoj"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "BedaÅ­rinde estas nur %<PRId64> sugestoj"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "AnstataÅ­igi \"%.*s\" per:"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < \"%.*s\""
-
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: Neniu antaÅ­a literuma anstataÅ­igo"
-
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: Netrovita: %s"
-
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: Tio ne Åajnas esti dosiero .sug: %s"
-
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: Malnova dosiero .sug, bezonas Äisdatigon: %s"
-
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: Dosiero .sug estas por pli nova versio de Vim: %s"
-
-#: ../spell.c:9295
-#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr "E781: Dosiero .sug ne kongruas kun dosiero .spl: %s"
-
-#: ../spell.c:9305
-#, 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.
-#: ../spell.c:11575
+#. * file.
msgid "E783: duplicate char in MAP entry"
msgstr "E783: ripetita signo en rikordo MAP"
-#: ../syntax.c:266
msgid "No Syntax items defined for this buffer"
msgstr "Neniu sintaksa elemento difinita por tiu bufro"
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
#, c-format
msgid "E390: Illegal argument: %s"
msgstr "E390: Nevalida argumento: %s"
@@ -5743,28 +5413,22 @@ msgstr "E390: Nevalida argumento: %s"
msgid "syntax iskeyword "
msgstr "sintakso iskeyword "
-#: ../syntax.c:3299
#, c-format
msgid "E391: No such syntax cluster: %s"
msgstr "E391: Nenia sintaksa fasko: %s"
-#: ../syntax.c:3433
msgid "syncing on C-style comments"
msgstr "sinkronigo per C-stilaj komentoj"
-#: ../syntax.c:3439
msgid "no syncing"
msgstr "neniu sinkronigo"
-#: ../syntax.c:3441
msgid "syncing starts "
msgstr "sinkronigo ekas "
-#: ../syntax.c:3443 ../syntax.c:3506
msgid " lines before top line"
msgstr " linioj antaÅ­ supra linio"
-#: ../syntax.c:3448
msgid ""
"\n"
"--- Syntax sync items ---"
@@ -5772,7 +5436,6 @@ msgstr ""
"\n"
"--- Eroj de sintaksa sinkronigo ---"
-#: ../syntax.c:3452
msgid ""
"\n"
"syncing on items"
@@ -5780,7 +5443,6 @@ msgstr ""
"\n"
"sinkronigo per eroj"
-#: ../syntax.c:3457
msgid ""
"\n"
"--- Syntax items ---"
@@ -5788,53 +5450,41 @@ msgstr ""
"\n"
"--- Sintakseroj ---"
-#: ../syntax.c:3475
#, c-format
msgid "E392: No such syntax cluster: %s"
msgstr "E392: Nenia sintaksa fasko: %s"
-#: ../syntax.c:3497
msgid "minimal "
msgstr "minimuma "
-#: ../syntax.c:3503
msgid "maximal "
msgstr "maksimuma "
-#: ../syntax.c:3513
msgid "; match "
msgstr "; kongruo "
-#: ../syntax.c:3515
msgid " line breaks"
msgstr " liniavancoj"
-#: ../syntax.c:4076
msgid "E395: contains argument not accepted here"
msgstr "E395: La argumento \"contains\" ne akcepteblas tie"
-#: ../syntax.c:4096
msgid "E844: invalid cchar value"
msgstr "E844: nevalida valoro de cchar"
-#: ../syntax.c:4107
msgid "E393: group[t]here not accepted here"
msgstr "E393: La argumento \"group[t]here\" ne akcepteblas tie"
-#: ../syntax.c:4126
#, c-format
msgid "E394: Didn't find region item for %s"
msgstr "E394: Ne trovis regionan elementon por %s"
-#: ../syntax.c:4188
msgid "E397: Filename required"
msgstr "E397: Dosiernomo bezonata"
-#: ../syntax.c:4221
msgid "E847: Too many syntax includes"
msgstr "E847: Tro da sintaksaj inkluzivoj"
-#: ../syntax.c:4303
#, c-format
msgid "E789: Missing ']': %s"
msgstr "E789: Mankas ']': %s"
@@ -5843,221 +5493,174 @@ msgstr "E789: Mankas ']': %s"
msgid "E890: trailing char after ']': %s]%s"
msgstr "E890: vosta signo post ']': %s]%s"
-#: ../syntax.c:4531
#, c-format
msgid "E398: Missing '=': %s"
msgstr "E398: Mankas '=': %s"
-#: ../syntax.c:4666
#, c-format
msgid "E399: Not enough arguments: syntax region %s"
msgstr "E399: Ne sufiĉaj argumentoj: sintaksa regiono %s"
-#: ../syntax.c:4870
msgid "E848: Too many syntax clusters"
msgstr "E848: Tro da sintaksaj grupoj"
-#: ../syntax.c:4954
msgid "E400: No cluster specified"
msgstr "E400: Neniu fasko specifita"
-#. end delimiter not found
-#: ../syntax.c:4986
#, c-format
msgid "E401: Pattern delimiter not found: %s"
msgstr "E401: Disigilo de Åablono netrovita: %s"
-#: ../syntax.c:5049
#, c-format
msgid "E402: Garbage after pattern: %s"
msgstr "E402: Forĵetindaĵo post Åablono: %s"
-#: ../syntax.c:5120
msgid "E403: syntax sync: line continuations pattern specified twice"
msgstr "E403: sintaksa sinkronigo: Åablono de linia daÅ­rigo specifita dufoje"
-#: ../syntax.c:5169
#, c-format
msgid "E404: Illegal arguments: %s"
msgstr "E404: Nevalidaj argumentoj: %s"
-#: ../syntax.c:5217
#, c-format
msgid "E405: Missing equal sign: %s"
msgstr "E405: Mankas egalsigno: %s"
-#: ../syntax.c:5222
#, c-format
msgid "E406: Empty argument: %s"
msgstr "E406: Malplena argumento: %s"
-#: ../syntax.c:5240
#, c-format
msgid "E407: %s not allowed here"
msgstr "E407: %s ne estas permesebla tie"
-#: ../syntax.c:5246
#, c-format
msgid "E408: %s must be first in contains list"
msgstr "E408: %s devas esti la unua ano de la listo \"contains\""
-#: ../syntax.c:5304
#, c-format
msgid "E409: Unknown group name: %s"
msgstr "E409: Nekonata nomo de grupo: %s"
-#: ../syntax.c:5512
#, c-format
msgid "E410: Invalid :syntax subcommand: %s"
msgstr "E410: Nevalida \":syntax\" subkomando: %s"
-#: ../syntax.c:5854
msgid ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
msgstr ""
+" TOTALO NOMBRO KONGRUO PLEJ MALRAPID MEZA NOMO ÅœABLONO"
-#: ../syntax.c:6146
msgid "E679: recursive loop loading syncolor.vim"
msgstr "E679: rekursia buklo dum Åargo de syncolor.vim"
-#: ../syntax.c:6256
#, c-format
msgid "E411: highlight group not found: %s"
msgstr "E411: emfaza grupo netrovita: %s"
-#: ../syntax.c:6278
#, c-format
msgid "E412: Not enough arguments: \":highlight link %s\""
msgstr "E412: Ne sufiĉaj argumentoj: \":highlight link %s\""
-#: ../syntax.c:6284
#, c-format
msgid "E413: Too many arguments: \":highlight link %s\""
-msgstr "E413: Tro argumentoj: \":highlight link %s\""
+msgstr "E413: Tro da argumentoj: \":highlight link %s\""
-#: ../syntax.c:6302
msgid "E414: group has settings, highlight link ignored"
msgstr "E414: grupo havas agordojn, ligilo de emfazo ignorita"
-#: ../syntax.c:6367
#, c-format
msgid "E415: unexpected equal sign: %s"
msgstr "E415: neatendita egalsigno: %s"
-#: ../syntax.c:6395
#, c-format
msgid "E416: missing equal sign: %s"
msgstr "E416: mankas egalsigno: %s"
-#: ../syntax.c:6418
#, c-format
msgid "E417: missing argument: %s"
msgstr "E417: mankas argumento: %s"
-#: ../syntax.c:6446
#, c-format
msgid "E418: Illegal value: %s"
msgstr "E418: Nevalida valoro: %s"
-#: ../syntax.c:6496
msgid "E419: FG color unknown"
msgstr "E419: Nekonata malfona koloro"
-#: ../syntax.c:6504
msgid "E420: BG color unknown"
msgstr "E420: Nekonata fona koloro"
-#: ../syntax.c:6564
#, c-format
msgid "E421: Color name or number not recognized: %s"
msgstr "E421: Kolora nomo aÅ­ nombro nerekonita: %s"
-#: ../syntax.c:6714
#, c-format
msgid "E422: terminal code too long: %s"
msgstr "E422: kodo de terminalo estas tro longa: %s"
-#: ../syntax.c:6753
#, c-format
msgid "E423: Illegal argument: %s"
msgstr "E423: Nevalida argumento: %s"
-#: ../syntax.c:6925
msgid "E424: Too many different highlighting attributes in use"
msgstr "E424: Tro da malsamaj atributoj de emfazo uzataj"
-#: ../syntax.c:7427
msgid "E669: Unprintable character in group name"
msgstr "E669: Nepresebla signo en nomo de grupo"
-#: ../syntax.c:7434
msgid "W18: Invalid character in group name"
msgstr "W18: Nevalida signo en nomo de grupo"
-#: ../syntax.c:7448
msgid "E849: Too many highlight and syntax groups"
msgstr "E849: Tro da emfazaj kaj sintaksaj grupoj"
-#: ../tag.c:104
msgid "E555: at bottom of tag stack"
msgstr "E555: ĉe subo de stako de etikedoj"
-#: ../tag.c:105
msgid "E556: at top of tag stack"
msgstr "E556: ĉe supro de stako de etikedoj"
-#: ../tag.c:380
msgid "E425: Cannot go before first matching tag"
msgstr "E425: Ne eblas iri antaÅ­ la unuan kongruan etikedon"
-#: ../tag.c:504
#, c-format
msgid "E426: tag not found: %s"
msgstr "E426: etikedo netrovita: %s"
# DP: "pri" estas "priority"
-#: ../tag.c:528
msgid " # pri kind tag"
msgstr "nro pri tipo etikedo"
-#: ../tag.c:531
msgid "file\n"
msgstr "dosiero\n"
-#: ../tag.c:829
msgid "E427: There is only one matching tag"
msgstr "E427: Estas nur unu kongrua etikedo"
-#: ../tag.c:831
msgid "E428: Cannot go beyond last matching tag"
msgstr "E428: Ne eblas iri preter lastan kongruan etikedon"
-#: ../tag.c:850
#, c-format
msgid "File \"%s\" does not exist"
msgstr "La dosiero \"%s\" ne ekzistas"
#. Give an indication of the number of matching tags
-#: ../tag.c:859
#, c-format
msgid "tag %d of %d%s"
msgstr "etikedo %d de %d%s"
-#: ../tag.c:862
msgid " or more"
msgstr " aÅ­ pli"
-#: ../tag.c:864
msgid " Using tag with different case!"
msgstr " Uzo de etikedo kun malsama uskleco!"
-#: ../tag.c:909
#, c-format
msgid "E429: File \"%s\" does not exist"
msgstr "E429: Dosiero \"%s\" ne ekzistas"
#. Highlight title
-#: ../tag.c:960
msgid ""
"\n"
" # TO tag FROM line in file/text"
@@ -6065,79 +5668,66 @@ msgstr ""
"\n"
"nro AL etikedo DE linio en dosiero/teksto"
-#: ../tag.c:1303
#, c-format
msgid "Searching tags file %s"
msgstr "Serĉado de dosiero de etikedoj %s"
-#: ../tag.c:1545
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Vojo de etikeda dosiero trunkita por %s\n"
+
msgid "Ignoring long line in tags file"
msgstr "Ignoro de longa linio en etikeda dosiero"
-#: ../tag.c:1915
#, c-format
msgid "E431: Format error in tags file \"%s\""
msgstr "E431: Eraro de formato en etikeda dosiero \"%s\""
-#: ../tag.c:1917
#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "AntaÅ­ bajto %<PRId64>"
+msgid "Before byte %ld"
+msgstr "AntaÅ­ bajto %ld"
-#: ../tag.c:1929
#, c-format
msgid "E432: Tags file not sorted: %s"
msgstr "E432: Etikeda dosiero ne estas ordigita: %s"
#. never opened any tags file
-#: ../tag.c:1960
msgid "E433: No tags file"
msgstr "E433: Neniu etikeda dosiero"
-#: ../tag.c:2536
msgid "E434: Can't find tag pattern"
msgstr "E434: Ne eblas trovi Åablonon de etikedo"
-#: ../tag.c:2544
msgid "E435: Couldn't find tag, just guessing!"
msgstr "E435: Ne eblis trovi etikedon, nur divenas!"
-#: ../tag.c:2797
#, c-format
msgid "Duplicate field name: %s"
msgstr "Ripetita kamponomo: %s"
-#: ../term.c:1442
msgid "' not known. Available builtin terminals are:"
msgstr "' nekonata. Haveblaj terminaloj estas:"
-#: ../term.c:1463
msgid "defaulting to '"
msgstr "defaÅ­lto al '"
-#: ../term.c:1731
msgid "E557: Cannot open termcap file"
msgstr "E557: Ne eblas malfermi la dosieron termcap"
-#: ../term.c:1735
msgid "E558: Terminal entry not found in terminfo"
msgstr "E558: Ne trovis rikordon de terminalo terminfo"
-#: ../term.c:1737
msgid "E559: Terminal entry not found in termcap"
msgstr "E559: Ne trovis rikordon de terminalo en termcap"
-#: ../term.c:1878
#, c-format
msgid "E436: No \"%s\" entry in termcap"
msgstr "E436: Neniu rikordo \"%s\" en termcap"
-#: ../term.c:2249
msgid "E437: terminal capability \"cm\" required"
msgstr "E437: kapablo de terminalo \"cm\" bezonata"
#. Highlight title
-#: ../term.c:4376
msgid ""
"\n"
"--- Terminal keys ---"
@@ -6145,169 +5735,339 @@ msgstr ""
"\n"
"--- Klavoj de terminalo ---"
-#: ../ui.c:481
+msgid "Cannot open $VIMRUNTIME/rgb.txt"
+msgstr "Ne povas malfermi $VIMRUNTIME/rgb.txt"
+
+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.
-#: ../undo.c:379
-#, fuzzy
msgid "E881: Line count changed unexpectedly"
-msgstr "E834: Nombro de linioj ÅanÄiÄis neatendite"
+msgstr "E881: Nombro de linioj ÅanÄiÄis neatendite"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Malfaro neebla; tamen daÅ­rigi"
-#: ../undo.c:627
#, c-format
msgid "E828: Cannot open undo file for writing: %s"
msgstr "E828: Ne eblas malfermi la malfaran dosieron por skribi: %s"
-#: ../undo.c:717
#, c-format
msgid "E825: Corrupted undo file (%s): %s"
msgstr "E825: Difektita malfara dosiero (%s): %s"
-#: ../undo.c:1039
msgid "Cannot write undo file in any directory in 'undodir'"
msgstr "Ne eblis skribi malfaran dosieron en iu dosiero ajn de 'undodir'"
-#: ../undo.c:1074
#, c-format
msgid "Will not overwrite with undo file, cannot read: %s"
msgstr "Ne superskribos malfaran dosieron, ne eblis legi: %s"
-#: ../undo.c:1092
#, c-format
msgid "Will not overwrite, this is not an undo file: %s"
msgstr "Ne superskribos, tio ne estas malfara dosiero: %s"
-#: ../undo.c:1108
msgid "Skipping undo file write, nothing to undo"
msgstr "Preterpasas skribon de malfara dosiero, nenio por malfari"
-#: ../undo.c:1121
#, c-format
msgid "Writing undo file: %s"
msgstr "Skribas malfaran dosieron: %s"
-#: ../undo.c:1213
#, c-format
msgid "E829: write error in undo file: %s"
msgstr "E829: Skriberaro en malfara dosiero: %s"
-#: ../undo.c:1280
#, c-format
msgid "Not reading undo file, owner differs: %s"
msgstr "Ne legas malfaran dosieron, posedanto malsamas: %s"
-#: ../undo.c:1292
#, c-format
msgid "Reading undo file: %s"
msgstr "Legado de malfara dosiero: %s"
-#: ../undo.c:1299
#, c-format
msgid "E822: Cannot open undo file for reading: %s"
msgstr "E822: Ne eblas malfermi malfaran dosieron por legi: %s"
-#: ../undo.c:1308
#, c-format
msgid "E823: Not an undo file: %s"
msgstr "E823: Ne estas malfara dosiero: %s"
-#: ../undo.c:1313
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: Ne ĉifrata dosiero havas ĉifratan malfaran dosieron: %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: Malĉifrado de malfara dosiero malsukcesis: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: Malfara dosiero estas ĉifrata: %s"
+
#, c-format
msgid "E824: Incompatible undo file: %s"
msgstr "E824: Malkongrua malfara dosiero: %s"
-#: ../undo.c:1328
msgid "File contents changed, cannot use undo info"
msgstr "Enhavo de dosiero ÅanÄiÄis, ne eblas uzi malfarajn informojn"
-#: ../undo.c:1497
#, c-format
msgid "Finished reading undo file %s"
msgstr "Finis legi malfaran dosieron %s"
-#: ../undo.c:1586 ../undo.c:1812
msgid "Already at oldest change"
msgstr "Jam al la plej malnova ÅanÄo"
-#: ../undo.c:1597 ../undo.c:1814
msgid "Already at newest change"
msgstr "Jam al la plej nova ÅanÄo"
-#: ../undo.c:1806
#, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E830: Malfara numero %<PRId64> netrovita"
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Malfara numero %ld netrovita"
-#: ../undo.c:1979
msgid "E438: u_undo: line numbers wrong"
msgstr "E438: u_undo: nevalidaj numeroj de linioj"
-#: ../undo.c:2183
msgid "more line"
msgstr "plia linio"
-#: ../undo.c:2185
msgid "more lines"
msgstr "pliaj linioj"
-#: ../undo.c:2187
msgid "line less"
msgstr "malpli linio"
-#: ../undo.c:2189
msgid "fewer lines"
msgstr "malpli linioj"
-#: ../undo.c:2193
msgid "change"
msgstr "ÅanÄo"
-#: ../undo.c:2195
msgid "changes"
msgstr "ÅanÄoj"
-#: ../undo.c:2225
#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s; %s #%<PRId64> %s"
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
-#: ../undo.c:2228
msgid "before"
msgstr "antaÅ­"
-#: ../undo.c:2228
msgid "after"
msgstr "post"
-#: ../undo.c:2325
msgid "Nothing to undo"
msgstr "Nenio por malfari"
-#: ../undo.c:2330
msgid "number changes when saved"
msgstr "numero ÅanÄoj tempo konservita"
-#: ../undo.c:2360
#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "antaÅ­ %<PRId64> sekundoj"
+msgid "%ld seconds ago"
+msgstr "antaÅ­ %ld sekundoj"
-#: ../undo.c:2372
msgid "E790: undojoin is not allowed after undo"
msgstr "E790: undojoin estas nepermesebla post malfaro"
-#: ../undo.c:2466
msgid "E439: undo list corrupt"
msgstr "E439: listo de malfaro estas difekta"
-#: ../undo.c:2495
msgid "E440: undo line missing"
msgstr "E440: linio de malfaro mankas"
-#: ../version.c:600
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: La funkcio %s jam ekzistas (aldonu ! por anstataÅ­igi Äin)"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Rikordo de vortaro jam ekzistas"
+
+msgid "E718: Funcref required"
+msgstr "E718: Funcref bezonata"
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Nekonata funkcio: %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Nevalida argumento: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Ripetita nomo de argumento: %s"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: Tro da argumentoj por funkcio: %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Nevalidaj argumentoj por funkcio: %s"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Profundo de funkcia alvoko superas 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "alvokas %s"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s ĉesigita"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s liveras #%ld"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s liveras %s"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Tro da argumentoj"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Nekonata funkcio: %s"
+
+#, c-format
+msgid "E933: Function was deleted: %s"
+msgstr "E933: funkcio estis forviÅita: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Ne sufiĉe da argumentoj por funkcio: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: <SID> estas uzata ekster kunteksto de skripto: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Alvoko de funkcio dict sen Vortaro: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Nomo de funkcio bezonata"
+
+#, c-format
+msgid "E128: Function name must start with a capital or \"s:\": %s"
+msgstr "E128: Nomo de funkcio devas eki per majusklo aÅ­ per \"s:\": %s"
+
+#, c-format
+msgid "E884: Function name cannot contain a colon: %s"
+msgstr "E884: Nomo de funkcio ne povas enhavi dupunkton: %s"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Nedifinita funkcio: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Mankas '(': %s"
+
+msgid "E862: Cannot use g: here"
+msgstr "E862: Ne eblas uzi g: ĉi tie"
+
+#, c-format
+msgid "E932: Closure function should not be at top level: %s"
+msgstr "E932: Fermo-funkcio devus esti je la plej alta nivelo: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Mankas \":endfunction\""
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: Nomo de funkcio konfliktas kun variablo: %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: Ne eblas redifini funkcion %s: Estas nuntempe uzata"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Nomo de funkcio ne kongruas kun dosiernomo de skripto: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Ne eblas forviÅi funkcion %s: Estas nuntempe uzata"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: \":return\" ekster funkcio"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Mankas krampoj: %s"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"Grafika versio MS-Vindozo 64-bitoj"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"Grafika versio MS-Vindozo 32-bitoj"
+
+msgid " with OLE support"
+msgstr " kun subteno de OLE"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit console version"
+msgstr ""
+"\n"
+"Versio konzola MS-Vindozo 64-bitoj"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"Versio konzola MS-Vindozo 32-bitoj"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"Versio Mak OS X (unikso)"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"Versio Mak OS X"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"Versio Mak OS"
+
+msgid ""
+"\n"
+"OpenVMS version"
+msgstr ""
+"\n"
+"Versio OpenVMS"
+
msgid ""
"\n"
"Included patches: "
@@ -6315,7 +6075,6 @@ msgstr ""
"\n"
"Flikaĵoj inkluzivitaj: "
-#: ../version.c:627
msgid ""
"\n"
"Extra patches: "
@@ -6323,11 +6082,9 @@ msgstr ""
"\n"
"Ekstraj flikaĵoj: "
-#: ../version.c:639 ../version.c:864
msgid "Modified by "
msgstr "Modifita de "
-#: ../version.c:646
msgid ""
"\n"
"Compiled "
@@ -6335,11 +6092,9 @@ msgstr ""
"\n"
"Kompilita "
-#: ../version.c:649
msgid "by "
msgstr "de "
-#: ../version.c:660
msgid ""
"\n"
"Huge version "
@@ -6347,1903 +6102,936 @@ msgstr ""
"\n"
"Grandega versio "
-#: ../version.c:661
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Granda versio "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Normala versio "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Malgranda versio "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Malgrandega versio "
+
msgid "without GUI."
msgstr "sen grafika interfaco."
-#: ../version.c:662
+msgid "with GTK3 GUI."
+msgstr "kun grafika interfaco GTK3."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "kun grafika interfaco GTK2-GNOME."
+
+msgid "with GTK2 GUI."
+msgstr "kun grafika interfaco GTK2."
+
+msgid "with X11-Motif GUI."
+msgstr "kun grafika interfaco X11-Motif."
+
+msgid "with X11-neXtaw GUI."
+msgstr "kun grafika interfaco X11-neXtaw."
+
+msgid "with X11-Athena GUI."
+msgstr "kun grafika interfaco X11-Athena."
+
+msgid "with Photon GUI."
+msgstr "kun grafika interfaco Photon."
+
+msgid "with GUI."
+msgstr "sen grafika interfaco."
+
+msgid "with Carbon GUI."
+msgstr "kun grafika interfaco Carbon."
+
+msgid "with Cocoa GUI."
+msgstr "kun grafika interfaco Cocoa."
+
+msgid "with (classic) GUI."
+msgstr "kun (klasika) grafika interfaco."
+
msgid " Features included (+) or not (-):\n"
msgstr " Ebloj inkluzivitaj (+) aÅ­ ne (-):\n"
-#: ../version.c:667
msgid " system vimrc file: \""
msgstr " sistema dosiero vimrc: \""
-#: ../version.c:672
msgid " user vimrc file: \""
msgstr " dosiero vimrc de uzanto: \""
-#: ../version.c:677
msgid " 2nd user vimrc file: \""
msgstr " 2-a dosiero vimrc de uzanto: \""
-#: ../version.c:682
msgid " 3rd user vimrc file: \""
msgstr " 3-a dosiero vimrc de uzanto: \""
-#: ../version.c:687
msgid " user exrc file: \""
msgstr " dosiero exrc de uzanto: \""
-#: ../version.c:692
msgid " 2nd user exrc file: \""
msgstr " 2-a dosiero exrc de uzanto: \""
-#: ../version.c:699
+msgid " system gvimrc file: \""
+msgstr " sistema dosiero gvimrc: \""
+
+msgid " user gvimrc file: \""
+msgstr " dosiero gvimrc de uzanto: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr " 2-a dosiero gvimrc de uzanto: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr " 3-a dosiero gvimrc de uzanto: \""
+
+msgid " defaults file: \""
+msgstr " dosiero de defaÅ­ltoj: \""
+
+msgid " system menu file: \""
+msgstr " dosiero de sistema menuo: \""
+
msgid " fall-back for $VIM: \""
msgstr " defaÅ­lto de $VIM: \""
-#: ../version.c:705
msgid " f-b for $VIMRUNTIME: \""
msgstr " defaÅ­lto de VIMRUNTIME: \""
-#: ../version.c:709
msgid "Compilation: "
msgstr "Kompilado: "
-#: ../version.c:712
+msgid "Compiler: "
+msgstr "Kompililo: "
+
msgid "Linking: "
msgstr "Ligado: "
-#: ../version.c:717
msgid " DEBUG BUILD"
msgstr " SENCIMIGA MUNTO"
-#: ../version.c:767
msgid "VIM - Vi IMproved"
msgstr "VIM - Vi plibonigita"
-#: ../version.c:769
msgid "version "
msgstr "versio "
# DP: vidu http://www.thefreedictionary.com/et+al.
-#: ../version.c:770
msgid "by Bram Moolenaar et al."
msgstr "de Bram Moolenaar kaj aliuloj"
-#: ../version.c:774
msgid "Vim is open source and freely distributable"
msgstr "Vim estas libera programo kaj disdoneblas libere"
-#: ../version.c:776
msgid "Help poor children in Uganda!"
msgstr "Helpu malriĉajn infanojn en Ugando!"
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:777
msgid "type :help iccf<Enter> for information "
msgstr "tajpu :help iccf<Enenklavo> por pliaj informoj "
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:779
msgid "type :q<Enter> to exit "
msgstr "tajpu :q<Enenklavo> por eliri "
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:780
msgid "type :help<Enter> or <F1> for on-line help"
msgstr "tajpu :help<Enenklavo> aÅ­ <F1> por aliri la helpon "
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:781
-msgid "type :help version7<Enter> for version info"
-msgstr "tajpu :help version7<Enenklavo> por informo de versio"
+msgid "type :help version8<Enter> for version info"
+msgstr "tajpu :help version8<Enenklavo> por informo de versio"
-#: ../version.c:784
msgid "Running in Vi compatible mode"
msgstr "RuliÄas en reÄimo kongrua kun Vi"
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:785
msgid "type :set nocp<Enter> for Vim defaults"
msgstr "tajpu :set nocp<Enenklavo> por Vim defaÅ­ltoj "
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:786
msgid "type :help cp-default<Enter> for info on this"
msgstr "tajpu :help cp-default<Enenklavo> por pliaj informoj "
-#: ../version.c:827
+# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
+msgid "menu Help->Orphans for information "
+msgstr "menuo Help->Orfinoj por pliaj informoj "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "RuliÄas senreÄime, tajpita teksto estas enmetita"
+
+# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "menuo Redakti->Mallokaj Agordoj->Baskuligi Enmetan ReÄimon"
+
+# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
+msgid " for two modes "
+msgstr " por du reÄimoj "
+
+# DP: tiu ĉeno pli longas (mi ne volas igi ĉiujn aliajn ĉenojn
+# pli longajn)
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "menuo Redakti->Mallokaj Agordoj->Baskuligi ReÄimon Kongruan kun Vi"
+
+# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
+msgid " for Vim defaults "
+msgstr " por defaÅ­ltoj de Vim "
+
msgid "Sponsor Vim development!"
msgstr "Subtenu la programadon de Vim!"
-#: ../version.c:828
msgid "Become a registered Vim user!"
msgstr "IÄu registrita uzanto de Vim!"
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:831
msgid "type :help sponsor<Enter> for information "
msgstr "tajpu :help sponsor<Enenklavo> por pliaj informoj "
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:832
msgid "type :help register<Enter> for information "
msgstr "tajpu :help register<Enenklavo> por pliaj informoj "
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:834
msgid "menu Help->Sponsor/Register for information "
msgstr "menuo Helpo->Subteni/Registri por pliaj informoj "
-#: ../window.c:119
msgid "Already only one window"
msgstr "Jam nur unu fenestro"
-#: ../window.c:224
msgid "E441: There is no preview window"
msgstr "E441: Ne estas antaÅ­vida fenestro"
-#: ../window.c:559
msgid "E442: Can't split topleft and botright at the same time"
msgstr "E442: Ne eblas dividi supralivan kaj subdekstran samtempe"
-#: ../window.c:1228
msgid "E443: Cannot rotate when another window is split"
msgstr "E443: Ne eblas rotacii kiam alia fenestro estas dividita"
-#: ../window.c:1803
msgid "E444: Cannot close last window"
msgstr "E444: Ne eblas fermi la lastan fenestron"
-#: ../window.c:1810
msgid "E813: Cannot close autocmd window"
msgstr "E813: Ne eblas fermi la fenestron de aÅ­tokomandoj"
-#: ../window.c:1814
msgid "E814: Cannot close window, only autocmd window would remain"
msgstr "E814: Ne eblas fermi fenestron, nur la fenestro de aÅ­tokomandoj restus"
-#: ../window.c:2717
msgid "E445: Other window contains changes"
msgstr "E445: La alia fenestro enhavas ÅanÄojn"
-#: ../window.c:4805
msgid "E446: No file name under cursor"
msgstr "E446: Neniu dosiernomo sub la kursoro"
-#~ msgid "E831: bf_key_init() called with empty password"
-#~ msgstr "E831: bf_key_init() alvokita kun malplena pasvorto"
-
-#~ msgid "E820: sizeof(uint32_t) != 4"
-#~ msgstr "E820: sizeof(uint32_t) != 4"
-
-#~ msgid "E817: Blowfish big/little endian use wrong"
-#~ msgstr "E817: Misuzo de pezkomenca/pezfina en blowfish"
-
-#~ msgid "E818: sha256 test failed"
-#~ msgstr "E818: Testo de sha256 fiaskis"
-
-#~ msgid "E819: Blowfish test failed"
-#~ msgstr "E819: Testo de blowfish fiaskis"
-
-#~ msgid "Patch file"
-#~ msgstr "Flika dosiero"
-
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "&Bone\n"
-#~ "&Rezigni"
-
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Neniu konekto al Vim-servilo"
-
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: Ne eblas sendi al %s"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: Ne eblas legi respondon de servilo"
-
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: Ne eblas sendi al kliento"
-
-#~ msgid "Save As"
-#~ msgstr "Konservi kiel"
-
-#~ msgid "Edit File"
-#~ msgstr "Redakti dosieron"
-
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (NETROVITA)"
-
-#~ msgid "Source Vim script"
-#~ msgstr "Ruli Vim-skripton"
-
-#~ msgid "unknown"
-#~ msgstr "nekonata"
-
-#~ msgid "Edit File in new window"
-#~ msgstr "Redakti Dosieron en nova fenestro"
-
-#~ msgid "Append File"
-#~ msgstr "Postaldoni dosieron"
-
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "Pozicio de fenestro: X %d, Y %d"
-
-#~ msgid "Save Redirection"
-#~ msgstr "Konservi alidirekton"
-
-# DP: mi ne certas pri superflugo
-#~ msgid "Save View"
-#~ msgstr "Konservi superflugon"
-
-#~ msgid "Save Session"
-#~ msgstr "Konservi seancon"
-
-#~ msgid "Save Setup"
-#~ msgstr "Konservi agordaron"
-
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: #< ne haveblas sen la eblo +eval"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: Neniu duliteraĵo en tiu versio"
-
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr "estas aparatdosiero (malÅaltita per la opcio 'opendevice')"
-
-#~ msgid "Reading from stdin..."
-#~ msgstr "Legado el stdin..."
-
-#~ msgid "[crypted]"
-#~ msgstr "[ĉifrita]"
-
-#~ msgid "E821: File is encrypted with unknown method"
-#~ msgstr "E821: Dosiero estas ĉifrata per nekonata metodo"
-
-#~ msgid "Warning: Using a weak encryption method; see :help 'cm'"
-#~ msgstr "Averto: uzo de malfortika ĉifrada metodo; vidu :help 'cm'"
-
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans malpermesas skribojn de neÅanÄitaj bufroj"
-
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "Partaj skriboj malpermesitaj ĉe bufroj NetBeans"
-
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "skribo al aparatdosiero malÅaltita per la opcio 'opendevice'"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: La rimeda forko estus perdita (aldonu ! por transpasi)"
-
-#~ msgid "E851: Failed to create a new process for the GUI"
-#~ msgstr "E851: Ne sukcesis krei novan procezon por la grafika interfaco"
-
-#~ msgid "E852: The child process failed to start the GUI"
-#~ msgstr "E852: La ida procezo ne sukcesis startigi la grafikan interfacon"
-
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: Ne eblas lanĉi la grafikan interfacon"
-
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: Ne eblas legi el \"%s\""
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr ""
-#~ "E665: Ne eblas startigi grafikan interfacon, neniu valida tiparo trovita"
-
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: 'guifontwide' nevalida"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: Valoro de 'imactivatekey' estas nevalida"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: Ne eblas disponigi koloron %s"
-
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "Neniu kongruo ĉe kursorpozicio, trovas sekvan"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<ne eblas malfermi> "
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: ne eblas akiri tiparon %s"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: ne eblas reveni al la aktuala dosierujo"
-
-#~ msgid "Pathname:"
-#~ msgstr "Serĉvojo:"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: ne eblas akiri aktualan dosierujon"
-
-#~ msgid "OK"
-#~ msgstr "Bone"
-
-#~ msgid "Cancel"
-#~ msgstr "Rezigni"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr ""
-#~ "Fenestraĵo de rulumskalo: Ne eblis akiri geometrion de reduktita "
-#~ "rastrumbildo"
-
-#~ msgid "Vim dialog"
-#~ msgstr "Vim dialogo"
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: Ne eblas krei BalloonEval kun ambaÅ­ mesaÄo kaj reagfunkcio"
-
-msgid "Yes"
-msgstr "Jes"
-
-msgid "No"
-msgstr "Ne"
-
-# todo '_' is for hotkey, i guess?
-#~ msgid "Input _Methods"
-#~ msgstr "Enigaj _metodoj"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - Serĉi kaj anstataŭigi..."
-
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM- Serĉi..."
-
-#~ msgid "Find what:"
-#~ msgstr "Serĉi kion:"
-
-#~ msgid "Replace with:"
-#~ msgstr "AnstataÅ­igi per:"
-
-#~ msgid "Match whole word only"
-#~ msgstr "Kongrui kun nur plena vorto"
-
-#~ msgid "Match case"
-#~ msgstr "Uskleca kongruo"
-
-#~ msgid "Direction"
-#~ msgstr "Direkto"
-
-#~ msgid "Up"
-#~ msgstr "Supren"
-
-#~ msgid "Down"
-#~ msgstr "Suben"
-
-#~ msgid "Find Next"
-#~ msgstr "Trovi sekvantan"
-
-#~ msgid "Replace"
-#~ msgstr "AnstataÅ­igi"
-
-#~ msgid "Replace All"
-#~ msgstr "Anstataŭigi ĉiujn"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: Ricevis peton \"die\" (morti) el la seanca administrilo\n"
-
-#~ msgid "Close tab"
-#~ msgstr "Fermi langeton"
-
-#~ msgid "New tab"
-#~ msgstr "Nova langeto"
-
-#~ msgid "Open Tab..."
-#~ msgstr "Malfermi langeton..."
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: Ĉefa fenestro neatendite detruiÄis\n"
-
-#~ msgid "&Filter"
-#~ msgstr "&Filtri"
-
-#~ msgid "&Cancel"
-#~ msgstr "&Rezigni"
-
-#~ msgid "Directories"
-#~ msgstr "Dosierujoj"
-
-#~ msgid "Filter"
-#~ msgstr "Filtri"
-
-#~ msgid "&Help"
-#~ msgstr "&Helpo"
-
-#~ msgid "Files"
-#~ msgstr "Dosieroj"
-
-#~ msgid "&OK"
-#~ msgstr "&Bone"
-
-#~ msgid "Selection"
-#~ msgstr "Apartigo"
-
-#~ msgid "Find &Next"
-#~ msgstr "Trovi &Sekvanta"
-
-#~ msgid "&Replace"
-#~ msgstr "&AnstataÅ­igi"
-
-#~ msgid "Replace &All"
-#~ msgstr "Anstataŭigi ĉi&on"
-
-#~ msgid "&Undo"
-#~ msgstr "&Malfari"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: Ne eblas trovi titolon de fenestro \"%s\""
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: Ne subtenata argumento: \"-%s\"; Uzu la version OLE."
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: Ne eblas malfermi fenestron interne de aplikaĵo MDI"
-
-#~ msgid "Open tab..."
-#~ msgstr "Malfermi langeton..."
-
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "Trovi ĉenon (uzu '\\\\' por trovi '\\')"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "Trovi kaj anstataÅ­igi (uzu '\\\\' por trovi '\\')"
-
-#~ msgid "Not Used"
-#~ msgstr "Ne uzata"
-
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "Dosierujo\t*.nenio\n"
-
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr ""
-#~ "Vim E458: Ne eblas disponigi rikordon de kolormapo, iuj koloroj estas "
-#~ "eble neÄustaj"
-
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr "E250: Tiparoj de tiuj signaroj mankas en aro de tiparo %s:"
-
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: Nomo de tiparo: %s"
-
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "Tiparo '%s' ne estas egallarÄa"
-
-#~ msgid "E253: Fontset name: %s\n"
-#~ msgstr "E253: Nomo de tiparo: %s\n"
-
-#~ msgid "Font0: %s\n"
-#~ msgstr "Font0: %s\n"
-
-#~ msgid "Font1: %s\n"
-#~ msgstr "Font1: %s\n"
-
-#~ msgid "Font%<PRId64> width is not twice that of font0\n"
-#~ msgstr "Font%<PRId64> ne estas duoble pli larÄa ol font0\n"
-
-#~ msgid "Font0 width: %<PRId64>\n"
-#~ msgstr "LarÄo de font0: %<PRId64>\n"
-
-#~ msgid ""
-#~ "Font1 width: %<PRId64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "LarÄo de Font1: %<PRId64>\n"
-#~ "\n"
-
-#~ msgid "Invalid font specification"
-#~ msgstr "Nevalida tiparo specifita"
-
-#~ msgid "&Dismiss"
-#~ msgstr "&Forlasi"
-
-#~ msgid "no specific match"
-#~ msgstr "Neniu specifa kongruo"
-
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - Elektilo de tiparo"
-
-#~ msgid "Name:"
-#~ msgstr "Nomo:"
-
-#~ msgid "Show size in Points"
-#~ msgstr "Montri grandon en punktoj"
-
-#~ msgid "Encoding:"
-#~ msgstr "Kodoprezento:"
-
-#~ msgid "Font:"
-#~ msgstr "Tiparo:"
-
-#~ msgid "Style:"
-#~ msgstr "Stilo:"
-
-#~ msgid "Size:"
-#~ msgstr "Grando:"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: ERARO en aÅ­tomato de korea alfabeto"
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: Eraro de stat"
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: ne eblas malfermi datumbazon de cscope: %s"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: ne eblas akiri informojn pri la datumbazo de cscope"
-
-#~ msgid "Lua library cannot be loaded."
-#~ msgstr "La biblioteko Lua no Åargeblis."
-
-#~ msgid "cannot save undo information"
-#~ msgstr "ne eblas konservi informojn de malfaro"
-
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr ""
-#~ "E815: BedaÅ­rinde, tiu komando estas malÅaltita, ne eblis Åargi la "
-#~ "bibliotekojn."
-
-#~ msgid "invalid expression"
-#~ msgstr "nevalida esprimo"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "esprimoj malÅaltitaj dum kompilado"
-
-#~ msgid "hidden option"
-#~ msgstr "kaÅita opcio"
-
-#~ msgid "unknown option"
-#~ msgstr "nekonata opcio"
-
-#~ msgid "window index is out of range"
-#~ msgstr "indekso de fenestro estas ekster limoj"
-
-#~ msgid "couldn't open buffer"
-#~ msgstr "ne eblis malfermi bufron"
-
-#~ msgid "cannot delete line"
-#~ msgstr "ne eblas forviÅi linion"
-
-#~ msgid "cannot replace line"
-#~ msgstr "ne eblas anstataÅ­igi linion"
-
-#~ msgid "cannot insert line"
-#~ msgstr "ne eblas enmeti linion"
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "ĉeno ne rajtas enhavi liniavancojn"
-
-#~ msgid "error converting Scheme values to Vim"
-#~ msgstr "eraro dum konverto de Scheme-valoro al Vim"
-
-#~ msgid "Vim error: ~a"
-#~ msgstr "Eraro de Vim: ~a"
-
-#~ msgid "Vim error"
-#~ msgstr "Eraro de Vim"
-
-#~ msgid "buffer is invalid"
-#~ msgstr "bufro estas nevalida"
-
-#~ msgid "window is invalid"
-#~ msgstr "fenestro estas nevalida"
-
-#~ msgid "linenr out of range"
-#~ msgstr "numero de linio ekster limoj"
-
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "nepermesebla en sabloludejo de Vim"
-
-#~ msgid "E836: This Vim cannot execute :python after using :py3"
-#~ msgstr "E836: Vim ne povas plenumi :python post uzo de :py3"
-
-#~ msgid "only string keys are allowed"
-#~ msgstr "nur ĉenaj Ålosiloj estas permeseblaj"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E263: BedaÅ­rinde tiu komando estas malÅaltita: la biblioteko de Pitono ne "
-#~ "Åargeblis."
-
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Ne eblas alvoki Pitonon rekursie"
-
-#~ msgid "E837: This Vim cannot execute :py3 after using :python"
-#~ msgstr "E837: Vim ne povas plenumi :py3 post uzo de :python"
-
-#~ msgid "index must be int or slice"
-#~ msgstr "indekso devas esti 'int' aÅ­ 'slice'"
-
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: $_ devas esti apero de Ĉeno"
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E266: BedaÅ­rinde tiu komando estas malÅaltita, la biblioteko Ruby ne "
-#~ "Åargeblis."
-
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: \"return\" neatendita"
-
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: \"next\" neatendita"
-
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: \"break\" neatendita"
-
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: \"redo\" neatendita"
-
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: \"retry\" ekster klaÅ­zo \"rescue\""
-
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: netraktita escepto"
-
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: nekonata stato de longjmp: %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "Baskuligi realigon/difinon"
-
-#~ msgid "Show base class of"
-#~ msgstr "Vidigi bazan klason de"
-
-#~ msgid "Show overridden member function"
-#~ msgstr "Montri anajn homonimigajn funkciojn"
-
-#~ msgid "Retrieve from file"
-#~ msgstr "Rekuperi el dosiero"
-
-#~ msgid "Retrieve from project"
-#~ msgstr "Rekuperi el projekto"
-
-#~ msgid "Retrieve from all projects"
-#~ msgstr "Rekuperi de ĉiuj projektoj"
-
-#~ msgid "Retrieve"
-#~ msgstr "Rekuperi"
-
-#~ msgid "Show source of"
-#~ msgstr "Vidigi fonton de"
-
-#~ msgid "Find symbol"
-#~ msgstr "Trovi simbolon"
-
-#~ msgid "Browse class"
-#~ msgstr "Foliumi klasojn"
-
-#~ msgid "Show class in hierarchy"
-#~ msgstr "Montri klason en hierarkio"
-
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "Montri klason en hierarkio restriktita"
-
-# todo
-#~ msgid "Xref refers to"
-#~ msgstr "Xref ligas al"
-
-#~ msgid "Xref referred by"
-#~ msgstr "Xref ligiÄas de"
-
-#~ msgid "Xref has a"
-#~ msgstr "Xref havas"
-
-#~ msgid "Xref used by"
-#~ msgstr "Xref uzita de"
-
-# DP: mi ne certas pri kio temas
-#~ msgid "Show docu of"
-#~ msgstr "Vidigi dokumentaron de"
-
-#~ msgid "Generate docu for"
-#~ msgstr "Krei dokumentaron de"
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "Konekto al SNiFF+ neeblas. Kontrolu medion (sniffemacs trovendas en "
-#~ "$PATH).\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: Eraro dum lego. Malkonektita"
-
-# DP: Tiuj 3 mesaÄoj estas kune
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "SNiFF+ estas aktuale "
-
-#~ msgid "not "
-#~ msgstr "ne "
-
-#~ msgid "connected"
-#~ msgstr "konektita"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: Nekonata peto de SNiFF+: %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: Eraro dum konekto al SNiFF+"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SNiFF+ ne estas konektita"
-
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: Ne estas bufro SNiFF+"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: Eraro dum skribo. Malkonektita"
-
-#~ msgid "invalid buffer number"
-#~ msgstr "nevalida numero de bufro"
-
-#~ msgid "not implemented yet"
-#~ msgstr "ankoraÅ­ ne realigita"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "ne eblas meti la linio(j)n"
-
-#~ msgid "invalid mark name"
-#~ msgstr "nevalida nomo de marko"
-
-#~ msgid "mark not set"
-#~ msgstr "marko ne estas metita"
-
-#~ msgid "row %d column %d"
-#~ msgstr "linio %d kolumno %d"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "ne eblas enmeti/postaldoni linion"
-
-#~ msgid "line number out of range"
-#~ msgstr "numero de linio ekster limoj"
-
-#~ msgid "unknown flag: "
-#~ msgstr "nekonata flago: "
-
-# DP: ĉu traduki vimOption
-#~ msgid "unknown vimOption"
-#~ msgstr "nekonata vimOption"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "klavara interrompo"
-
-#~ msgid "vim error"
-#~ msgstr "eraro de Vim"
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr ""
-#~ "ne eblas krei komandon de bufro/fenestro: objekto estas forviÅiÄanta"
-
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr ""
-#~ "ne eblas registri postalvokan komandon: bufro/fenestro estas jam "
-#~ "forviÅiÄanta"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr ""
-#~ "E280: NERIPAREBLA TCL-ERARO: reflist difekta!? Bv. retpoÅti al vim-"
-#~ "dev@vim.org"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr ""
-#~ "ne eblas registri postalvokan komandon: referenco de bufro/fenestro ne "
-#~ "troveblas"
-
-#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E571: BedaÅ­rinde tiu komando estas malÅaltita: la biblioteko Tcl ne "
-#~ "Åargeblis."
-
-#~ msgid "E572: exit code %d"
-#~ msgstr "E572: elira kodo %d"
-
-#~ msgid "cannot get line"
-#~ msgstr "ne eblas akiri linion"
-
-#~ msgid "Unable to register a command server name"
-#~ msgstr "Ne eblas registri nomon de komanda servilo"
-
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: Sendo de komando al cela programo fiaskis"
-
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: Nevalida identigilo de servilo uzita: %s"
-
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr ""
-#~ "E251: Ecoj de registro de apero de VIM estas nevalide formata. ForviÅita!"
-
-#~ msgid "netbeans is not supported with this GUI\n"
-#~ msgstr "netbeans ne estas subtenata kun tiu grafika interfaco\n"
-
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "Tiu Vim ne estis kompilita kun la kompara eblo."
-
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "'-nb' ne uzeblas: malÅaltita dum kompilado\n"
-
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: Eraro: Fiaskis lanĉi gvim el NetBeans\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
-#~ msgstr ""
-#~ "\n"
-#~ "Kie uskleco estas ignorita antaÅ­aldonu / por igi flagon majuskla"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\tRegistri tiun gvim al OLE"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tMalregistri gvim de OLE"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tRuli per grafika interfaco (kiel \"gvim\")"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f aŭ --nofork\tMalfono: ne forki kiam lanĉas grafikan interfacon"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\tNe uzi newcli por malfermi fenestrojn"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <aparatdosiero>\t\tUzi <aparatdosiero>-n por eneligo"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\tUzi <gvimrc> anstataÅ­ iun ajn .gvimrc"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\tRedakti ĉifradan dosieron"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <ekrano>\tKonekti Vim al tiu X-servilo"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tNe konekti al X-servilo"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr "--remote <dosieroj>\tRedakti <dosieroj>-n en Vim-servilo se eblas"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr "--remote-silent <dosieroj> Same, sed ne plendi se ne estas servilo"
-
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr ""
-#~ "--remote-wait <dosieroj> Kiel --remote sed atendi Äis dosieroj estas "
-#~ "redaktitaj"
-
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-wait-silent <dosieroj> Same, sed ne plendi se ne estas servilo"
-
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <dosieroj> Kiel --remote sed uzi langeton "
-#~ "por ĉiu dosiero"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr "--remote-send <klavoj> Sendi <klavoj>-n al Vim-servilo kaj eliri"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr ""
-#~ "--remote-expr <espr>\tKomputi <espr> en Vim-servilo kaj afiÅi rezulton"
-
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr "--serverlist\t\tListigi haveblajn nomojn de Vim-serviloj kaj eliri"
-
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <nomo>\tSendu al/iÄi la Vim-servilo <nomo>"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumentoj agnoskitaj de gvim (versio Motif):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumentoj agnoskitaj de gvim (versio neXtaw):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumentoj agnoskitaj de gvim (versio Athena):\n"
-
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <ekrano>\tLanĉi vim sur <ekrano>"
-
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tLanĉi vim piktograme"
-
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr ""
-#~ "-background <koloro>\tUzi <koloro>-n por la fona koloro (ankaÅ­: -bg)"
-
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr ""
-#~ "-foreground <koloro>\tUzi <koloro>-n por la malfona koloro (ankaÅ­: -fg)"
-
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <tiparo>\tUzi <tiparo>-n por normala teksto (ankaÅ­: -fn)"
-
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <tiparo>\tUzi <tiparo>-n por grasa teksto"
-
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <tiparo>\tUzi <tiparo>-n por kursiva teksto"
-
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr "-geometry <geom>\tUzi <geom> kiel komenca geometrio (ankaÅ­: -geom)"
-
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr ""
-#~ "-borderwidth <larÄo>\tUzi <larÄo>-n kiel larÄo de bordero (ankaÅ­: -bw)"
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <larÄo> Uzi <larÄo>-n kiel larÄo de rulumskalo (ankaÅ­: -"
-#~ "sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr ""
-#~ "-menuheight <alto>\tUzi <alto>-n kiel alto de menuzona alto (ankaÅ­: -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tUzi inversan videon (ankaÅ­: -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tNe uzi inversan videon (ankaÅ­: +rv)"
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Ne eblas trovi dosieron \"%s\" en serĉvojo"
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <rimedo>\tAgordi la specifitan <rimedo>-n"
+#, c-format
+msgid "E799: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E799: Nevalida ID: %ld (devas esti egala aÅ­ pli granda ol 1)"
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumentoj agnoskitaj de gvim (versio GTK+):\n"
+#, c-format
+msgid "E801: ID already taken: %ld"
+msgstr "E801: ID jam uzata: %ld"
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <ekrano>\tLanĉi Vim sur tiu <ekrano> (ankaŭ: --display)"
+msgid "List or number required"
+msgstr "Listo aÅ­ nombro bezonata"
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr "--role <rolo>\tDoni unikan rolon por identigi la ĉefan fenestron"
+#, c-format
+msgid "E802: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E802: Nevalida ID: %ld (devas esti egala aÅ­ pli granda ol 1)"
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tMalfermi Vim en alia GTK fenestraĵo"
+#, c-format
+msgid "E803: ID not found: %ld"
+msgstr "E803: ID netrovita: %ld"
-#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
-#~ msgstr "--echo-wid\t\tIgas gvim afiÅi la identigilon de vindozo sur stdout"
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Ne eblis Åargi bibliotekon %s"
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <gepatra titolo>\tMalfermi Vim en gepatra aplikaĵo"
+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 "--windowid <HWND>\tOpen Vim inside another win32 widget"
-#~ msgstr "--windowid <HWND>\tMalfermi Vim en alia win32 fenestraĵo"
+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 "No display"
-#~ msgstr "Neniu ekrano"
+msgid "Edit with &multiple Vims"
+msgstr "Redakti per &pluraj Vim-oj"
-#~ msgid ": Send failed.\n"
-#~ msgstr ": Sendo fiaskis.\n"
+msgid "Edit with single &Vim"
+msgstr "Redakti per unuopa &Vim"
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": Sendo fiaskis. Provo de loka plenumo\n"
+msgid "Diff with Vim"
+msgstr "Kompari per Vim"
-#~ msgid "%d of %d edited"
-#~ msgstr "%d de %d redaktita(j)"
+msgid "Edit with &Vim"
+msgstr "Redakti per &Vim"
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "Neniu ekrano: Sendado de esprimo fiaskis.\n"
+#. Now concatenate
+msgid "Edit with existing Vim - "
+msgstr "Redakti per ekzistanta Vim - "
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": Sendado de esprimo fiaskis.\n"
+msgid "Edits the selected file(s) with Vim"
+msgstr "Redakti la apartigita(j)n dosiero(j)n per Vim"
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: Nevalida kodpaÄo"
+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 "E284: Cannot set IC values"
-#~ msgstr "E284: Ne eblas agordi valorojn de IC"
+msgid "gvimext.dll error"
+msgstr "Eraro de gvimext.dll"
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: Ne eblis krei enigan kuntekston"
+msgid "Path length too long!"
+msgstr "Serĉvojo estas tro longa!"
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: Ne eblis malfermi enigan metodon"
+msgid "--No lines in buffer--"
+msgstr "--Neniu linio en bufro--"
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
-#~ msgstr "E287: Averto: Ne eblis agordi detruan reagfunkcion al IM"
+#.
+#. * 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 "E288: input method doesn't support any style"
-#~ msgstr "E288: eniga metodo subtenas neniun stilon"
+msgid "E471: Argument required"
+msgstr "E471: Argumento bezonata"
-# DP: mi ne scias, kio estas "preedit"
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr "E289: eniga metodo ne subtenas mian antaÅ­redaktan tipon"
-
-#~ msgid "E843: Error while updating swap file crypt"
-#~ msgstr "E843: Eraro dum Äisdatigo de ĉifrada permutodosiero .swp"
-
-#~ msgid ""
-#~ "E833: %s is encrypted and this version of Vim does not support encryption"
-#~ msgstr "E833: %s estas ĉifrata kaj tiu versio de Vim ne subtenas ĉifradon"
-
-#~ msgid "Swap file is encrypted: \"%s\""
-#~ msgstr "Perumutodosiero .swp estas ĉifrata: \"%s\""
-
-#~ msgid ""
-#~ "\n"
-#~ "If you entered a new crypt key but did not write the text file,"
-#~ msgstr ""
-#~ "\n"
-#~ "Se vi tajpis novan Ålosilon de ĉifrado sed ne skribis la tekstan dosieron,"
-
-#~ msgid ""
-#~ "\n"
-#~ "enter the new crypt key."
-#~ msgstr ""
-#~ "\n"
-#~ "tajpu la novan Ålosilon de ĉifrado."
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ devus esti sekvita de /, ? aÅ­ &"
-#~ 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 "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr ""
+"E11: Nevalida en fenestro de komanda linio; <CR> plenumas, CTRL-C eliras"
-#~ msgid ""
-#~ "\n"
-#~ "to use the same key for text file and swap file"
-#~ msgstr ""
-#~ "\n"
-#~ "por uzi la saman Ålosilon por la teksta dosiero kaj permuto dosiero .swp"
+msgid "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 "Using crypt key from swap file for the text file.\n"
-#~ msgstr ""
-#~ "Uzas Ålosilon de ĉifrado el permuto dosiero .swp por la teksta dosiero.\n"
+msgid "E171: Missing :endif"
+msgstr "E171: Mankas \":endif\""
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [ne uzebla per tiu versio de Vim]"
+msgid "E600: Missing :endtry"
+msgstr "E600: Mankas \":endtry\""
-#~ msgid "Tear off this menu"
-#~ msgstr "Disigi tiun menuon"
+msgid "E170: Missing :endwhile"
+msgstr "E170: Mankas \":endwhile\""
-#~ msgid "Select Directory dialog"
-#~ msgstr "Dialogujo de dosiera elekto"
+msgid "E170: Missing :endfor"
+msgstr "E170: Mankas \":endfor\""
-#~ msgid "Save File dialog"
-#~ msgstr "Dialogujo de dosiera konservo"
+msgid "E588: :endwhile without :while"
+msgstr "E588: \":endwhile\" sen \":while\""
-#~ msgid "Open File dialog"
-#~ msgstr "Dialogujo de dosiera malfermo"
+msgid "E588: :endfor without :for"
+msgstr "E588: \":endfor\" sen \":for\""
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: BedaÅ­rinde ne estas dosierfoliumilo en konzola reÄimo"
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Dosiero ekzistas (aldonu ! por transpasi)"
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "Vim: konservo de dosieroj...\n"
+msgid "E472: Command failed"
+msgstr "E472: La komando malsukcesis"
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "Vim: Finita.\n"
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Nekonata familio de tiparo: %s"
-#~ msgid "ERROR: "
-#~ msgstr "ERARO: "
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Nekonata tiparo: %s"
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[bajtoj] totalaj disponigitaj/maldisponigitaj %<PRIu64>-%<PRIu64>, nun "
-#~ "uzataj %<PRIu64>, kulmina uzo %<PRIu64>\n"
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: La tiparo \"%s\" ne estas egallarÄa"
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[alvokoj] totalaj re/malloc() %<PRIu64>, totalaj free() %<PRIu64>\n"
-#~ "\n"
+msgid "E473: Internal error"
+msgstr "E473: Interna eraro"
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: Linio iÄas tro longa"
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Interna eraro: %s"
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: Interna eraro: lalloc(%<PRId64>, )"
+msgid "Interrupted"
+msgstr "Interrompita"
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: Nevalida formo de muskursoro"
+msgid "E14: Invalid address"
+msgstr "E14: Nevalida adreso"
-#~ msgid "Enter encryption key: "
-#~ msgstr "Tajpu la Ålosilon de ĉifrado: "
+msgid "E474: Invalid argument"
+msgstr "E474: Nevalida argumento"
-#~ msgid "Enter same key again: "
-#~ msgstr "Tajpu la Ålosilon denove: "
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Nevalida argumento: %s"
-#~ msgid "Keys don't match!"
-#~ msgstr "Åœlosiloj ne kongruas!"
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Nevalida esprimo: %s"
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Ne eblas konekti al Netbeans n-ro 2"
+msgid "E16: Invalid range"
+msgstr "E16: Nevalida amplekso"
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Ne eblas konekti al Netbeans"
+msgid "E476: Invalid command"
+msgstr "E476: Nevalida komando"
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr ""
-#~ "E668: Nevalida permeso de dosiero de informo de konekto NetBeans: \"%s\""
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" estas dosierujo"
-#~ msgid "read from Netbeans socket"
-#~ msgstr "lego el kontaktoskatolo de Netbeans"
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Alvoko al biblioteko malsukcesis por \"%s()\""
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: Konekto de NetBeans perdita por bufro %<PRId64>"
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Ne eblis Åargi bibliotekan funkcion %s"
-#~ msgid "E838: netbeans is not supported with this GUI"
-#~ msgstr "E838: netbeans ne estas subtenata kun tiu grafika interfaco"
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Marko havas nevalidan numeron de linio"
-#~ msgid "E511: netbeans already connected"
-#~ msgstr "E511: nebeans jam konektata"
+msgid "E20: Mark not set"
+msgstr "E20: Marko ne estas agordita"
-#~ msgid "E505: %s is read-only (add ! to override)"
-#~ msgstr "E505: %s estas nurlegebla (aldonu ! por transpasi)"
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Ne eblas fari ÅanÄojn, 'modifiable' estas malÅaltita"
-# DP: ĉu Eval devas esti tradukita?
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: Eval eblo ne disponeblas"
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Tro profunde ingitaj skriptoj"
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "malokupas %<PRId64> liniojn"
+msgid "E23: No alternate file"
+msgstr "E23: Neniu alterna dosiero"
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: term ne ÅanÄeblas en grafika interfaco"
+msgid "E24: No such abbreviation"
+msgstr "E24: Ne estas tia mallongigo"
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: Uzu \":gui\" por lanĉi la grafikan interfacon"
+msgid "E477: No ! allowed"
+msgstr "E477: Neniu ! permesebla"
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: Ne ÅanÄeblas en la grafika interfaco GTK+ 2"
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: Grafika interfaco ne uzeblas: MalÅaltita dum kompilado"
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: Nevalida(j) tiparo(j)"
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: La hebrea ne uzeblas: MalÅaltita dum kompilado\n"
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: ne eblas elekti tiparon"
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: La persa ne uzeblas: MalÅaltita dum kompilado\n"
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: Nevalida tiparo"
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: La araba ne uzeblas: MalÅaltita dum kompilado\n"
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: ne eblas elekti larÄan tiparon"
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Neniu grupo de emfazo kiel: %s"
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: Nevalida larÄa tiparo"
+msgid "E29: No inserted text yet"
+msgstr "E29: AnkoraÅ­ neniu enmetita teksto"
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: Neniu muso subtenata"
+msgid "E30: No previous command line"
+msgstr "E30: Neniu antaÅ­a komanda linio"
-#~ msgid "cannot open "
-#~ msgstr "ne eblas malfermi "
+msgid "E31: No such mapping"
+msgstr "E31: Neniu tiel mapo"
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: Ne eblas malfermi fenestron!\n"
+msgid "E479: No match"
+msgstr "E479: Neniu kongruo"
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Bezonas version 2.04 de Amigados aÅ­ pli novan\n"
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Neniu kongruo: %s"
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "Bezonas %s-on versio %<PRId64>\n"
+msgid "E32: No file name"
+msgstr "E32: Neniu dosiernomo"
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "Ne eblas malfermi NIL:\n"
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Neniu antaÅ­a regulesprimo de anstataÅ­igo"
-#~ msgid "Cannot create "
-#~ msgstr "Ne eblas krei "
+msgid "E34: No previous command"
+msgstr "E34: Neniu antaÅ­a komando"
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim eliras kun %d\n"
+msgid "E35: No previous regular expression"
+msgstr "E35: Neniu antaÅ­a regulesprimo"
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "ne eblas ÅanÄi reÄimon de konzolo?!\n"
+msgid "E481: No range allowed"
+msgstr "E481: Amplekso nepermesebla"
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: ne estas konzolo??\n"
+msgid "E36: Not enough room"
+msgstr "E36: Ne sufiĉe da spaco"
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: Ne eblas plenumi Åelon kun opcio -f"
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: neniu registrita servilo nomita \"%s\""
-#~ msgid "Cannot execute "
-#~ msgstr "Ne eblas plenumi "
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Ne eblas krei dosieron %s"
-#~ msgid "shell "
-#~ msgstr "Åelo "
+msgid "E483: Can't get temp file name"
+msgstr "E483: Ne eblas akiri provizoran dosiernomon"
-#~ msgid " returned\n"
-#~ msgstr " liveris\n"
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Ne eblas malfermi dosieron %s"
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE tro malgranda."
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Ne eblas legi dosieron %s"
-#~ msgid "I/O ERROR"
-#~ msgstr "ERARO DE ENIGO/ELIGO"
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Neniu skribo de post lasta ÅanÄo (aldonu ! por transpasi)"
-#~ msgid "Message"
-#~ msgstr "MesaÄo"
+msgid "E37: No write since last change"
+msgstr "E37: Neniu skribo de post lasta ÅanÄo"
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "'columns' ne estas 80, ne eblas plenumi eksternajn komandojn"
+msgid "E38: Null argument"
+msgstr "E38: Nula argumento"
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: Elekto de presilo fiaskis"
+msgid "E39: Number expected"
+msgstr "E39: Nombro atendita"
-#~ msgid "to %s on %s"
-#~ msgstr "al %s de %s"
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Ne eblas malfermi eraran dosieron %s"
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: Nekonata tiparo de presilo: %s"
+msgid "E233: cannot open display"
+msgstr "E233: ne eblas malfermi vidigon"
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: Eraro de presado: %s"
+msgid "E41: Out of memory!"
+msgstr "E41: Ne plu restas memoro!"
-#~ msgid "Printing '%s'"
-#~ msgstr "Presas '%s'"
+msgid "Pattern not found"
+msgstr "Åœablono ne trovita"
-#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
-#~ msgstr "E244: Nevalida nomo de signaro \"%s\" en nomo de tiparo \"%s\""
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Åœablono ne trovita: %s"
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: Nevalida signo '%c' en nomo de tiparo \"%s\""
+msgid "E487: Argument must be positive"
+msgstr "E487: La argumento devas esti pozitiva"
-#~ msgid "Vim: Double signal, exiting\n"
-#~ msgstr "Vim: Duobla signalo, eliranta\n"
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Ne eblas reiri al antaÅ­a dosierujo"
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "Vim: Kaptis mortigantan signalon %s\n"
+msgid "E42: No Errors"
+msgstr "E42: Neniu eraro"
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "Vim: Kaptis mortigantan signalon\n"
+msgid "E776: No location list"
+msgstr "E776: Neniu listo de lokoj"
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "Malfermo de vidigo X daÅ­ris %<PRId64> msek"
+msgid "E43: Damaged match string"
+msgstr "E43: Difekta kongruenda ĉeno"
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim: Alvenis X eraro\n"
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Difekta programo de regulesprimo"
-#~ msgid "Testing the X display failed"
-#~ msgstr "Testo de la vidigo X fiaskis"
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: La opcio 'readonly' estas Åaltita '(aldonu ! por transpasi)"
-#~ msgid "Opening the X display timed out"
-#~ msgstr "Tempolimo okazis dum malfermo de vidigo X"
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Ne eblas ÅanÄi nurlegeblan variablon \"%s\""
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ne eblas plenumi Åelon sh\n"
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: Ne eblas agordi variablon en la sabloludejo: \"%s\""
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ne eblas krei duktojn\n"
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Ne eblas uzi malplenan Ålosilon de Vortaro"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ne eblas forki\n"
+msgid "E715: Dictionary required"
+msgstr "E715: Vortaro bezonata"
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Komando terminigita\n"
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: indekso de listo ekster limoj: %ld"
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP perdis la konekton ICE"
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Tro da argumentoj por funkcio: %s"
-#~ msgid "Opening the X display failed"
-#~ msgstr "Malfermo de vidigo X fiaskis"
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: Åœlosilo malekzistas en Vortaro: %s"
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP: traktado de peto konservi-mem"
+msgid "E714: List required"
+msgstr "E714: Listo bezonata"
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP: malfermo de konekto"
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Argumento de %s devas esti Listo aÅ­ Vortaro"
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP: kontrolo de konekto ICE fiaskis"
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Eraro dum legado de erardosiero"
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP: SmcOpenConnection fiaskis: %s"
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Nepermesebla en sabloludejo"
-#~ msgid "At line"
-#~ msgstr "Ĉe linio"
+msgid "E523: Not allowed here"
+msgstr "E523: Nepermesebla tie"
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "Ne eblis Åargi vim32.dll!"
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: ReÄimo de ekrano ne subtenata"
-#~ msgid "VIM Error"
-#~ msgstr "Eraro de VIM"
+msgid "E49: Invalid scroll size"
+msgstr "E49: Nevalida grando de rulumo"
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "Ne eblis ripari referencojn de funkcioj al la DLL!"
+msgid "E91: 'shell' option is empty"
+msgstr "E91: La opcio 'shell' estas malplena"
-#~ msgid "shell returned %d"
-#~ msgstr "la Åelo liveris %d"
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Ne eblis legi datumojn de simboloj!"
-# DP: la eventoj estas tiuj, kiuj estas en la sekvantaj ĉenoj
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: Kaptis eventon %s\n"
+msgid "E72: Close error on swap file"
+msgstr "E72: Eraro dum malfermo de permutodosiero .swp"
-#~ msgid "close"
-#~ msgstr "fermo"
+msgid "E73: tag stack empty"
+msgstr "E73: malplena stako de etikedo"
-#~ msgid "logoff"
-#~ msgstr "elsaluto"
+msgid "E74: Command too complex"
+msgstr "E74: Komando tro kompleksa"
-#~ msgid "shutdown"
-#~ msgstr "sistemfermo"
+msgid "E75: Name too long"
+msgstr "E75: Nomo tro longa"
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: Netrovebla komando"
+msgid "E76: Too many ["
+msgstr "E76: Tro da ["
-#~ msgid ""
-#~ "VIMRUN.EXE not found in your $PATH.\n"
-#~ "External commands will not pause after completion.\n"
-#~ "See :help win32-vimrun for more information."
-#~ msgstr ""
-#~ "VIMRUN.EXE ne troveblas en via $PATH.\n"
-#~ "Eksteraj komandoj ne paÅ­zos post kompletigo.\n"
-#~ "Vidu :help win32-vimrun por pliaj informoj."
-
-#~ msgid "Vim Warning"
-#~ msgstr "Averto de Vim"
-
-#~ msgid "Error file"
-#~ msgstr "Erara Dosiero"
-
-#~ msgid "E868: Error building NFA with equivalence class!"
-#~ msgstr "E868: Eraro dum prekomputado de NFA kun ekvivalentoklaso!"
-
-#~ msgid "E999: (NFA regexp internal error) Should not process NOT node !"
-#~ msgstr ""
-#~ "E999: (interna eraro de NFA-regulesprimo) Ne devus procezi nodon 'NOT'!"
-
-#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!"
-#~ msgstr "E878: (NFA) Ne povis asigni memoron por traigi branĉojn!"
-
-#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
-#~ msgstr "Averto: Ne eblas trovi vortliston \"%s_%s.spl\" aÅ­ \"%s_ascii.spl\""
-
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "Konverto en %s nesubtenata"
-
-#~ msgid "E845: Insufficient memory, word list will be incomplete"
-#~ msgstr "E845: Ne sufiĉe da memoro, vortlisto estos nekompleta."
-
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: Vojo de etikeda dosiero trunkita por %s\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "nova Åelo lanĉita\n"
-
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "Uzis CUT_BUFFER0 anstataÅ­ malplenan apartigon"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "Malfaro neebla; daÅ­rigi tamene"
-
-#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
-#~ msgstr "E832: Ne ĉifrata dosiero havas ĉifratan malfaran dosieron: %s"
-
-#~ msgid "E826: Undo file decryption failed: %s"
-#~ msgstr "E826: Malĉifrado de malfara dosiero fiaskis: %s"
-
-#~ msgid "E827: Undo file is encrypted: %s"
-#~ msgstr "E827: Malfara dosiero estas ĉifrata: %s"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Grafika versio MS-Vindozo 16/32-bitoj"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Grafika versio MS-Vindozo 64-bitoj"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Grafika versio MS-Vindozo 32-bitoj"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " en reÄimo Win32s"
-
-#~ msgid " with OLE support"
-#~ msgstr " kun subteno de OLE"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio konzola MS-Vindozo 64-bitoj"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio konzola MS-Vindozo 32-bitoj"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio MS-Vindozo 16-bitoj"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio MS-DOS 32-bitoj"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio MS-DOS 16-bitoj"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio Mak OS X (unikso)"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio Mak OS X"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio Mak OS"
-
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio OpenVMS"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Granda versio "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Normala versio "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Malgranda versio "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Malgrandega versio "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "kun grafika interfaco GTK2-GNOME."
-
-#~ msgid "with GTK2 GUI."
-#~ msgstr "kun grafika interfaco GTK2."
-
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "kun grafika interfaco X11-Motif."
-
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "kun grafika interfaco X11-neXtaw."
-
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "kun grafika interfaco X11-Athena."
-
-#~ msgid "with Photon GUI."
-#~ msgstr "kun grafika interfaco Photon."
-
-#~ msgid "with GUI."
-#~ msgstr "sen grafika interfaco."
-
-#~ msgid "with Carbon GUI."
-#~ msgstr "kun grafika interfaco Carbon."
-
-#~ msgid "with Cocoa GUI."
-#~ msgstr "kun grafika interfaco Cocoa."
-
-#~ msgid "with (classic) GUI."
-#~ msgstr "kun (klasika) grafika interfaco."
-
-#~ msgid " system gvimrc file: \""
-#~ msgstr " sistema dosiero gvimrc: \""
-
-#~ msgid " user gvimrc file: \""
-#~ msgstr " dosiero gvimrc de uzanto: \""
-
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr " 2-a dosiero gvimrc de uzanto: \""
-
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr " 3-a dosiero gvimrc de uzanto: \""
-
-#~ msgid " system menu file: \""
-#~ msgstr " dosiero de sistema menuo: \""
-
-#~ msgid "Compiler: "
-#~ msgstr "Kompililo: "
+msgid "E77: Too many file names"
+msgstr "E77: Tro da dosiernomoj"
-# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "menuo Help->Orfinoj por pliaj informoj "
+msgid "E488: Trailing characters"
+msgstr "E488: Vostaj signoj"
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "RuliÄas senreÄime, tajpita teksto estas enmetita"
+msgid "E78: Unknown mark"
+msgstr "E78: Nekonata marko"
-# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "menuo Redakti->Mallokaj Agordoj->Baskuligi Enmetan ReÄimon"
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Ne eblas malvolvi ĵokerojn"
-# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#~ msgid " for two modes "
-#~ msgstr " por du reÄimoj "
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' ne rajtas esti malpli ol 'winminheight'"
-# DP: tiu ĉeno pli longas (mi ne volas igi ĉiujn aliajn ĉenojn
-# pli longajn)
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "menuo Redakti->Mallokaj Agordoj->Baskuligi ReÄimon Kongruan kun Vi"
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' ne rajtas esti malpli ol 'winminwidth'"
-# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#~ msgid " for Vim defaults "
-#~ msgstr " por defaÅ­ltoj de Vim "
+msgid "E80: Error while writing"
+msgstr "E80: Eraro dum skribado"
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "AVERTO: Trovis Vindozon 95/98/ME"
+msgid "Zero count"
+msgstr "Nul kvantoro"
-# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr "tajpu :help windows95<Enenklavo> por pliaj informoj "
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: Uzo de <SID> ekster kunteksto de skripto"
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: Ne eblis Åargi bibliotekon %s"
+msgid "E449: Invalid expression received"
+msgstr "E449: Nevalida esprimo ricevita"
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr ""
-#~ "BedaÅ­rinde tiu komando estas malÅaltita: la biblioteko de Perl ne "
-#~ "Åargeblis."
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Regiono estas gardita, ne eblas ÅanÄi"
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr ""
-#~ "E299: Plenumo de Perl esprimoj malpermesata en sabloludejo sen la modulo "
-#~ "Safe"
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans ne permesas ÅanÄojn en nurlegeblaj dosieroj"
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "Redakti per &pluraj Vim-oj"
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: Åablono uzas pli da memoro ol 'maxmempattern'"
-#~ msgid "Edit with single &Vim"
-#~ msgstr "Redakti per unuopa &Vim"
+msgid "E749: empty buffer"
+msgstr "E749: malplena bufro"
-#~ msgid "Diff with Vim"
-#~ msgstr "Kompari per Vim"
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: La bufro %ld ne ekzistas"
-#~ msgid "Edit with &Vim"
-#~ msgstr "Redakti per &Vim"
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Nevalida serĉa Åablono aÅ­ disigilo"
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "Redakti per ekzistanta Vim - "
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Dosiero estas Åargita en alia bufro"
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "Redakti la apartigita(j)n dosiero(j)n per Vim"
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: La opcio '%s' ne estas Åaltita"
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "Eraro dum kreo de procezo: Kontrolu ĉu gvim estas en via serĉvojo!"
+msgid "E850: Invalid register name"
+msgstr "E850: Nevalida nomo de reÄistro"
-#~ msgid "gvimext.dll error"
-#~ msgstr "Eraro de gvimext.dll"
+#, c-format
+msgid "E919: Directory not found in '%s': \"%s\""
+msgstr "E919: Dosierujo ne trovita en '%s': \"%s\""
-#~ msgid "Path length too long!"
-#~ msgstr "Serĉvojo estas tro longa!"
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "serĉo atingis SUPRON, daŭrigonte al SUBO"
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: Nekonata familio de tiparo: %s"
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "serĉo atingis SUBON, daŭrigonte al SUPRO"
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: Nekonata tiparo: %s"
+#, c-format
+msgid "Need encryption key for \"%s\""
+msgstr "Ŝlosilo de ĉifrado bezonata por \"%s\""
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: La tiparo \"%s\" ne estas egallarÄa"
+msgid "empty keys are not allowed"
+msgstr "malplenaj Ålosiloj nepermeseblaj"
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: Ne eblis Åargi bibliotekan funkcion %s"
+msgid "dictionary is locked"
+msgstr "vortaro estas Ålosita"
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr "E26: La hebrea ne uzeblas: MalÅaltita dum kompilado\n"
+msgid "list is locked"
+msgstr "listo estas Ålosita"
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: La persa ne uzeblas: MalÅaltita dum kompilado\n"
+#, c-format
+msgid "failed to add key '%s' to dictionary"
+msgstr "aldono de Ålosilo '%s' al vortaro malsukcesis"
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr "E800: La araba ne uzeblas: MalÅaltita dum kompilado\n"
+#, c-format
+msgid "index must be int or slice, not %s"
+msgstr "indekso devas esti 'int' aÅ­ 'slice', ne %s"
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: neniu registrita servilo nomita \"%s\""
+#, c-format
+msgid "expected str() or unicode() instance, but got %s"
+msgstr "atendis aperon de str() aÅ­ unicode(), sed ricevis %s"
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: ne eblas malfermi vidigon"
+#, c-format
+msgid "expected bytes() or str() instance, but got %s"
+msgstr "atendis aperon de bytes() aÅ­ str(), sed ricevis %s"
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: Nevalida esprimo ricevita"
+#, c-format
+msgid ""
+"expected int(), long() or something supporting coercing to long(), but got %s"
+msgstr "atendis int(), long() aÅ­ ion konverteblan al long(), sed ricevis %s"
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: Regiono estas gardita, ne eblas ÅanÄi"
+#, c-format
+msgid "expected int() or something supporting coercing to int(), but got %s"
+msgstr "atendis int() aÅ­ ion konverteblan al int(), sed ricevis %s"
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans ne permesas ÅanÄojn en nurlegeblaj dosieroj"
+msgid "value is too large to fit into C int type"
+msgstr "valoro estas tro grada por C-tipo 'int'"
-#~ msgid "Need encryption key for \"%s\""
-#~ msgstr "Ŝlosilo de ĉifrado bezonata por \"%s\""
+msgid "value is too small to fit into C int type"
+msgstr "valoro estas tro malgranda por C-tipo 'int'"
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "ne eblas forviÅi atributojn de OutputObject"
+msgid "number must be greater than zero"
+msgstr "nombro devas esti pli granda ol nul"
-#~ msgid "softspace must be an integer"
-#~ msgstr "malmolspaceto (softspace) devas esti entjero"
+msgid "number must be greater or equal to zero"
+msgstr "nombro devas esti egala aÅ­ pli granda ol nul"
-#~ msgid "invalid attribute"
-#~ msgstr "nevalida atributo"
+msgid "can't delete OutputObject attributes"
+msgstr "ne eblas forviÅi atributojn de OutputObject"
-#~ msgid "writelines() requires list of strings"
-#~ msgstr "writelines() bezonas liston de ĉenoj"
+#, c-format
+msgid "invalid attribute: %s"
+msgstr "nevalida atributo: %s"
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Pitono: Eraro de pravalorizo de eneligaj objektoj"
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Pitono: Eraro de pravalorizo de eneligaj objektoj"
-#~ msgid "empty keys are not allowed"
-#~ msgstr "malplenaj Ålosiloj nepermeseblaj"
+msgid "failed to change directory"
+msgstr "malsukcesis ÅanÄi dosierujon"
-#~ msgid "Cannot delete DictionaryObject attributes"
-#~ msgstr "ne eblas forviÅi atributojn de DictionaryObject"
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got %s"
+msgstr "atendis 3-opon kiel rezulto de imp.find_module(), sed ricevis %s"
-#~ msgid "Cannot modify fixed dictionary"
-#~ msgstr "Ne eblas ÅanÄi fiksan vortaron"
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
+msgstr "atendis 3-opon kiel rezulto de imp.find_module(), sed ricevis %d-opon"
-#~ msgid "Cannot set this attribute"
-#~ msgstr "Ne eblas agordi tiun atributon"
+msgid "internal error: imp.find_module returned tuple with NULL"
+msgstr "interna eraro: imp.find_module liveris opon kun NULL"
-#~ msgid "dict is locked"
-#~ msgstr "vortaro estas Ålosita"
+msgid "cannot delete vim.Dictionary attributes"
+msgstr "ne eblas forviÅi atributojn de 'vim.Dictionary'"
-#~ msgid "failed to add key to dictionary"
-#~ msgstr "aldono de Ålosilo al vortaro fiaskis"
+msgid "cannot modify fixed dictionary"
+msgstr "ne eblas ÅanÄi fiksan vortaron"
-#~ msgid "list index out of range"
-#~ msgstr "indekso de listo ekster limoj"
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "ne eblas agordi atributon %s"
-#~ msgid "internal error: failed to get vim list item"
-#~ msgstr "interna eraro: obteno de vim-a listero fiaskis"
+msgid "hashtab changed during iteration"
+msgstr "hakettabelo ÅanÄiÄis dum iteracio"
-#~ msgid "list is locked"
-#~ msgstr "listo estas Ålosita"
+#, c-format
+msgid "expected sequence element of size 2, but got sequence of size %d"
+msgstr "atendis 2-longan sekvencon, sed ricevis %d-longan sekvencon"
-#~ msgid "Failed to add item to list"
-#~ msgstr "Aldono de listero fiaskis"
+msgid "list constructor does not accept keyword arguments"
+msgstr "konstruilo de listo ne akceptas Ålosilvortajn argumentojn"
-#~ msgid "can only assign lists to slice"
-#~ msgstr "nur eblas pravalorizi listojn al segmento"
+msgid "list index out of range"
+msgstr "indekso de listo ekster limoj"
-#~ msgid "internal error: failed to add item to list"
-#~ msgstr "interna eraro: aldono de listero fiaskis"
+#. No more suitable format specifications in python-2.3
+#, c-format
+msgid "internal error: failed to get vim list item %d"
+msgstr "interna eraro: obteno de vim-a listero %d malsukcesis"
-#~ msgid "can only concatenate with lists"
-#~ msgstr "eblas nur kunmeti kun listoj"
+msgid "slice step cannot be zero"
+msgstr "paÅo de sekco ne povas esti nul"
-#~ msgid "cannot delete vim.dictionary attributes"
-#~ msgstr "ne eblas forviÅi atributojn de 'vim.dictionary'"
+#, c-format
+msgid "attempt to assign sequence of size greater than %d to extended slice"
+msgstr "provis valorizi sekvencon kun pli ol %d eroj en etendita sekco"
-#~ msgid "cannot modify fixed list"
-#~ msgstr "ne eblas ÅanÄi fiksan liston"
+#, c-format
+msgid "internal error: no vim list item %d"
+msgstr "interna eraro: neniu vim-a listero %d"
-#~ msgid "cannot set this attribute"
-#~ msgstr "ne eblas agordi tiun atributon"
+msgid "internal error: not enough list items"
+msgstr "interna eraro: ne sufiĉaj listeroj"
-#~ msgid "'self' argument must be a dictionary"
-#~ msgstr "argumento 'self' devas esti vortaro"
+msgid "internal error: failed to add item to list"
+msgstr "interna eraro: aldono de listero malsukcesis"
-#~ msgid "failed to run function"
-#~ msgstr "fiaskis ruli funkcion"
+#, c-format
+msgid "attempt to assign sequence of size %d to extended slice of size %d"
+msgstr "provis valorizi sekvencon kun %d eroj al etendita sekco kun %d eroj"
-#~ msgid "unable to unset global option"
-#~ msgstr "ne povis malÅalti mallokan opcion"
+msgid "failed to add item to list"
+msgstr "aldono de listero malsukcesis"
-#~ msgid "unable to unset option without global value"
-#~ msgstr "ne povis malÅalti opcion sen malloka valoro"
+msgid "cannot delete vim.List attributes"
+msgstr "ne eblas forviÅi atributojn de 'vim.List'"
-#~ msgid "object must be integer"
-#~ msgstr "objekto devas esti entjero."
+msgid "cannot modify fixed list"
+msgstr "ne eblas ÅanÄi fiksan liston"
-#~ msgid "object must be string"
-#~ msgstr "objekto devas esti ĉeno"
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "sennoma funkcio %s ne ekzistas"
-#~ msgid "attempt to refer to deleted tab page"
-#~ msgstr "provo de referenco al forviÅita langeto"
+#, c-format
+msgid "function %s does not exist"
+msgstr "funkcio %s ne ekzistas"
-#~ msgid "<tabpage object (deleted) at %p>"
-#~ msgstr "<langeta objekto (forviÅita) ĉe %p>"
+#, c-format
+msgid "failed to run function %s"
+msgstr "malsukcesis ruli funkcion %s"
-#~ msgid "<tabpage object (unknown) at %p>"
-#~ msgstr "<langeta objekto (nekonata) ĉe %p>"
+msgid "unable to get option value"
+msgstr "malsukcesis akiri valoron de opcio"
-#~ msgid "<tabpage %d>"
-#~ msgstr "<langeto %d>"
+msgid "internal error: unknown option type"
+msgstr "interna eraro: nekonata tipo de opcio"
-#~ msgid "no such tab page"
-#~ msgstr "ne estas tia langeto"
+msgid "problem while switching windows"
+msgstr "problemo dum salto al vindozoj"
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "provo de referenco al forviÅita fenestro"
+#, c-format
+msgid "unable to unset global option %s"
+msgstr "ne povis malÅalti mallokan opcion %s"
-#~ msgid "readonly attribute"
-#~ msgstr "nurlegebla atributo"
+#, c-format
+msgid "unable to unset option %s which does not have global value"
+msgstr "ne povis malÅalti opcion %s, kiu ne havas mallokan valoron"
-#~ msgid "cursor position outside buffer"
-#~ msgstr "kursoro poziciita ekster bufro"
+msgid "attempt to refer to deleted tab page"
+msgstr "provo de referenco al forviÅita langeto"
-#~ msgid "<window object (deleted) at %p>"
-#~ msgstr "<fenestra objekto (forviÅita) ĉe %p>"
+msgid "no such tab page"
+msgstr "ne estas tia langeto"
-#~ msgid "<window object (unknown) at %p>"
-#~ msgstr "<objekta fenestro (nekonata) ĉe %p>"
+msgid "attempt to refer to deleted window"
+msgstr "provo de referenco al forviÅita fenestro"
-#~ msgid "<window %d>"
-#~ msgstr "<fenestro %d>"
+msgid "readonly attribute: buffer"
+msgstr "nurlegebla atributo: buffer"
-#~ msgid "no such window"
-#~ msgstr "ne estas tia fenestro"
+msgid "cursor position outside buffer"
+msgstr "kursoro poziciita ekster bufro"
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "provo de referenco al forviÅita bufro"
+msgid "no such window"
+msgstr "ne estas tia fenestro"
-#~ msgid "<buffer object (deleted) at %p>"
-#~ msgstr "<bufra objekto (forviÅita) ĉe %p>"
+msgid "attempt to refer to deleted buffer"
+msgstr "provo de referenco al forviÅita bufro"
-#~ msgid "key must be integer"
-#~ msgstr "Ålosilo devas esti entjero."
+msgid "failed to rename buffer"
+msgstr "malsukcesis renomi bufron"
-#~ msgid "expected vim.buffer object"
-#~ msgstr "atendis objekton vim.buffer"
+msgid "mark name must be a single character"
+msgstr "nomo de marko devas esti unuopa signo"
-#~ msgid "failed to switch to given buffer"
-#~ msgstr "ne povis salti al la specifita bufro"
+#, c-format
+msgid "expected vim.Buffer object, but got %s"
+msgstr "atendis objekton vim.Buffer, sed ricevis %s"
-#~ msgid "expected vim.window object"
-#~ msgstr "atendis objekton vim.window"
+#, c-format
+msgid "failed to switch to buffer %d"
+msgstr "salto al la bufro %d malsukcesis"
-#~ msgid "failed to find window in the current tab page"
-#~ msgstr "ne povis trovi vindozon en la nuna langeto"
+#, c-format
+msgid "expected vim.Window object, but got %s"
+msgstr "atendis objekton vim.window, sed ricevis %s"
-#~ msgid "did not switch to the specified window"
-#~ msgstr "ne saltis al la specifita vindozo"
+msgid "failed to find window in the current tab page"
+msgstr "malsukcesis trovi vindozon en la nuna langeto"
-#~ msgid "expected vim.tabpage object"
-#~ msgstr "atendis objekton vim.tabpage"
+msgid "did not switch to the specified window"
+msgstr "ne saltis al la specifita vindozo"
-#~ msgid "did not switch to the specified tab page"
-#~ msgstr "ne saltis al la specifita langeto"
+#, c-format
+msgid "expected vim.TabPage object, but got %s"
+msgstr "atendis objekton vim.TabPage, sed ricevis %s"
-#~ msgid "failed to run the code"
-#~ msgstr "fiaskis ruli la kodon"
+msgid "did not switch to the specified tab page"
+msgstr "ne saltis al la specifita langeto"
-#~ msgid "E858: Eval did not return a valid python object"
-#~ msgstr "E858: Eval ne revenis kun valida python-objekto"
+msgid "failed to run the code"
+msgstr "malsukcesis ruli la kodon"
-#~ msgid "E859: Failed to convert returned python object to vim value"
-#~ msgstr "E859: Konverto de revena python-objekto al vim-valoro fiaskis"
+msgid "E858: Eval did not return a valid python object"
+msgstr "E858: Eval ne revenis kun valida python-objekto"
-#~ msgid "unable to convert to vim structure"
-#~ msgstr "ne povis konverti al vim-strukturo"
+msgid "E859: Failed to convert returned python object to vim value"
+msgstr "E859: Konverto de revena python-objekto al vim-valoro malsukcesis"
-#~ msgid "NULL reference passed"
-#~ msgstr "NULL-referenco argumento"
+#, c-format
+msgid "unable to convert %s to vim dictionary"
+msgstr "ne povis konverti %s al vim-vortaro"
-#~ msgid "internal error: invalid value type"
-#~ msgstr "interna eraro: nevalida tipo de valoro"
+#, c-format
+msgid "unable to convert %s to vim list"
+msgstr "ne povis konverti %s al vim-listo"
-#~ msgid "E863: return value must be an instance of str"
-#~ msgstr "E863: elira valoro devas esti apero de str"
+#, c-format
+msgid "unable to convert %s to vim structure"
+msgstr "ne povis konverti %s al vim-strukturo"
-#~ msgid "E860: Eval did not return a valid python 3 object"
-#~ msgstr "E860: Eval ne revenis kun valida python3-objekto"
+msgid "internal error: NULL reference passed"
+msgstr "interna eraro: NULL-referenco argumento"
-#~ msgid "E861: Failed to convert returned python 3 object to vim value"
-#~ msgstr "E861: Konverto de revena python3-objekto al vim-valoro fiaskis"
+msgid "internal error: invalid value type"
+msgstr "interna eraro: nevalida tipo de valoro"
-#~ msgid "Only boolean objects are allowed"
-#~ msgstr "Nur buleaj objektoj estas permeseblaj"
+msgid ""
+"Failed to set path hook: sys.path_hooks is not a list\n"
+"You should now do the following:\n"
+"- append vim.path_hook to sys.path_hooks\n"
+"- append vim.VIM_SPECIAL_PATH to sys.path\n"
+msgstr ""
+"Valorizo de sys.path_hooks malsukcesis: sys.path_hooks ne estas listo\n"
+"Vi nun devas fari tion:\n"
+"- postaldoni vim.path_hook al sys.path_hooks\n"
+"- postaldoni vim.VIM_SPECIAL_PATH al sys.path\n"
-#~ msgid "no such key in dictionary"
-#~ msgstr "tiu Ålosilo ne ekzistas en vortaro"
+msgid ""
+"Failed to set path: sys.path is not a list\n"
+"You should now append vim.VIM_SPECIAL_PATH to sys.path"
+msgstr ""
+"Agordo de serĉvojo malsukcesis: sys.path ne estas listo\n"
+"Vi nun devas aldoni vim.VIM_SPECIAL_PATH al sys.path"
diff --git a/src/nvim/po/fi.po b/src/nvim/po/fi.po
index d30faeb554..3551c07ff2 100644
--- a/src/nvim/po/fi.po
+++ b/src/nvim/po/fi.po
@@ -1,247 +1,419 @@
# Finnish translation for Vim.
# Copyright (C) 2003-2006 Free Software Foundation, Inc.
-# 2007-2010, Flammie Pirinen <flammie@iki.fi>
+# 2007-2016, Flammie Pirinen <flammie@iki.fi>
#
-# Vimin käyttäjät on nörttejä. Sanasto on jargonia :-p
-#
-# Lähinnä latin-1:tä, sillä vim pitää portata ilmeisen obskuureille
-# alustoille. Myös: pluralit puuttuu, ohjelman käyttöliittymän fontti
-# tasavälinen, tila rajattu, jne. jne., luovia ratkaisuja edessä.
+# Jargonia ei ole yritetty suotta kotoperäistää missä teknisempi lainasanasto
+# tulee paremmin kyseeseen.
#
# Sanastosta:
-# Fold on sellainen moderneissa ohjelmointi-IDE:issä oleva toiminto, jolla
-# lohko koodia esim. funktio piilotetaan näkymästä: suom. taitos alkup.
+# * Fold on sellainen moderneissa ohjelmointi-IDE:issä oleva toiminto, jolla
+# lohko koodia esim. funktio piilotetaan näkymästä: suom. taitos alkup.
# analogian mukaan
-# source v. lataa tiedoston, kuten bash-komento source (tai .)
+# * source, v. lataa tiedoston, kuten bash-komento source (tai .)
+# * dictionary (dict) on vaihtelevasti sanakirja tai tietorakenne
#
msgid ""
msgstr ""
"Project-Id-Version: Vim 7\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-05-26 14:21+0200\n"
-"PO-Revision-Date: 2010-08-09 02:35+0300\n"
-"Last-Translator: Flammie Pirinen <flammie@iki.fi>\n"
+"POT-Creation-Date: 2017-04-19 16:46+0200\n"
+"PO-Revision-Date: 2016-08-29 11:27+0200\n"
+"Last-Translator: Flammie A Pirinen <flammie@iki.fi>\n"
"Language-Team: Finnish <laatu@lokalisointi.org>\n"
"Language: fi\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: ../api/private/helpers.c:201
#, fuzzy
-msgid "Unable to get option value"
-msgstr "Roskaa argumentin perässä"
+#~ msgid "Index out of bounds"
+#~ msgstr "ei löytynyt "
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr ""
+#, fuzzy
+#~ msgid "Line index is too high"
+#~ msgstr "ikkunan indeksi alueen ulkopuolella"
+
+#~ msgid "Argument \"start\" is higher than \"end\""
+#~ msgstr ""
+
+#~ msgid "All items in the replacement array must be strings"
+#~ msgstr ""
+
+msgid "string cannot contain newlines"
+msgstr "merkkijono ei saa sisältää rivinvaihtoja"
+
+#, fuzzy
+#~ msgid "Failed to save undo information"
+#~ msgstr "ei voitu tallentaa kumoustietoja"
+
+#, fuzzy
+#~ msgid "Failed to delete line"
+#~ msgstr "ei voitu poistaa riviä"
+
+#~ msgid "Index value is too high"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "Failed to replace line"
+#~ msgstr "ei voitu korvata riviä"
+
+#, fuzzy
+#~ msgid "Failed to insert line"
+#~ msgstr "ei voitu lisätä riviä"
+
+#, fuzzy
+#~ msgid "Failed to rename buffer"
+#~ msgstr "ei voity uudelleennimetä puskuria"
+
+#, fuzzy
+#~ msgid "Mark name must be a single character"
+#~ msgstr "merkin nimen pitää olla yksi merkki"
+
+#, fuzzy
+#~ msgid "Invalid mark name"
+#~ msgstr "virheellinen merkin nimi"
+
+#, fuzzy
+#~ msgid "Line number outside range"
+#~ msgstr "rivinumero arvoalueen ulkopuolella"
+
+#, fuzzy
+#~ msgid "Column value outside range"
+#~ msgstr "rivinumero arvoalueen ulkopuolella"
+
+#, fuzzy
+#~ msgid "Keyboard interrupt"
+#~ msgstr "näppäimistökeskeytys"
+
+#, fuzzy
+#~ msgid "Key not found"
+#~ msgstr "ei löytynyt "
+
+#, fuzzy
+#~ msgid "Dictionary is locked"
+#~ msgstr "dictionary on lukittu"
+
+#, fuzzy
+#~ msgid "Empty variable names aren't allowed"
+#~ msgstr "tyhjiä avaimia ei voi käyttää"
+
+#, fuzzy
+#~ msgid "Key length is too high"
+#~ msgstr "Liian pitkä polku"
+
+#, c-format
+#~ msgid "Key is read-only: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Key is fixed: %s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "Key is locked: %s"
+#~ msgstr "E741: Arvo on lukittu: %s"
+
+#. Doesn't exist, fail
+#, fuzzy, c-format
+#~ msgid "Key does not exist: %s"
+#~ msgstr "Tiedostoa %s ei ole"
+
+#, fuzzy
+#~ msgid "Empty option name"
+#~ msgstr "E792: tyhjä valikkonimi"
+
+#, fuzzy, c-format
+#~ msgid "Invalid option name \"%s\""
+#~ msgstr "E755: Virheellinen alue kohteelle %s"
+
+#, fuzzy, c-format
+#~ msgid "Unable to get value for option \"%s\""
+#~ msgstr "ei voi tyhjentää yleistä asetusta %s"
+
+#, fuzzy, c-format
+#~ msgid "Unknown type for option \"%s\""
+#~ msgstr "E113: Tuntematon asetus: %s"
+
+#, fuzzy, c-format
+#~ msgid "Unable to unset option \"%s\""
+#~ msgstr "ei voi tyhjentää yleistä asetusta %s"
+
+#, fuzzy, c-format
+#~ msgid "Cannot unset option \"%s\" because it doesn't have a global value"
+#~ msgstr "ei voi tyhjentää asetusta %s jolla ei ole yleistä arvoa"
+
+#, c-format
+#~ msgid "Option \"%s\" requires a boolean value"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "Option \"%s\" requires an integer value"
+#~ msgstr "E709: [:] toimii vain listalla"
+
+#, c-format
+#~ msgid "Value for option \"%s\" is outside range"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "Option \"%s\" requires a string value"
+#~ msgstr "E709: [:] toimii vain listalla"
+
+#, fuzzy
+#~ msgid "Invalid buffer id"
+#~ msgstr "virheellinen puskurinumero"
+
+#, fuzzy
+#~ msgid "Invalid window id"
+#~ msgstr "E534: Viallinen leveä fontti"
+
+#, fuzzy
+#~ msgid "Invalid tabpage id"
+#~ msgstr "Väärä argumentti valitsimelle"
+
+#~ msgid "Integer value outside range"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "Empty dictionary keys aren't allowed"
+#~ msgstr "tyhjiä avaimia ei voi käyttää"
+
+#, fuzzy
+#~ msgid "Problem while switching windows"
+#~ msgstr "virhe ikkunaa vaihtaessa"
+
+#, fuzzy
+#~ msgid "UI already attached for channel"
+#~ msgstr "Vanhimmassa muutoksessa"
+
+#~ msgid "Expected width > 0 and height > 0"
+#~ msgstr ""
+
+#~ msgid "UI is not attached for channel"
+#~ msgstr ""
+
+#~ msgid "rgb must be a Boolean"
+#~ msgstr ""
+
+#~ msgid "popupmenu_external must be a Boolean"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "No such ui option"
+#~ msgstr "E24: Lyhennettä ei ole"
+
+#~ msgid "Function called with too many arguments."
+#~ msgstr ""
+
+#~ msgid "Error calling function."
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "String length is too high"
+#~ msgstr "Liian pitkä polku"
+
+#~ msgid "Directory string is too long"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "Failed to change directory"
+#~ msgstr "hakemistoa ei voitu muuttaa"
+
+#, fuzzy, c-format
+#~ msgid "Failed to switch to buffer %d"
+#~ msgstr "ei voitu vaihtaa puskuriin %d"
+
+#, fuzzy, c-format
+#~ msgid "Failed to switch to window %d"
+#~ msgstr "ei voitu vaihtaa puskuriin %d"
+
+#, fuzzy, c-format
+#~ msgid "Failed to switch to tabpage %d"
+#~ msgstr "ei voitu vaihtaa puskuriin %d"
+
+#~ msgid "All items in calls array must be arrays"
+#~ msgstr ""
+
+#~ msgid "All items in calls array must be arrays of size 2"
+#~ msgstr ""
+
+#~ msgid "name must be String"
+#~ msgstr ""
+
+#~ msgid "args must be Array"
+#~ msgstr ""
+
+# datarakenteita
+#, fuzzy
+#~ msgid "Argument \"pos\" must be a [row, col] array"
+#~ msgstr "E712: Argumentin %s pitää olla lista tai sanakirja"
+
+#, fuzzy
+#~ msgid "Cursor position outside buffer"
+#~ msgstr "kursorin sijainti puskurin ulkopuolella"
+
+#~ msgid "Height value outside range"
+#~ msgstr ""
+
+#~ msgid "Width value outside range"
+#~ msgstr ""
-#: ../buffer.c:92
msgid "[Location List]"
msgstr "[Sijaintiluettelo]"
-#: ../buffer.c:93
msgid "[Quickfix List]"
msgstr "[Pikakorjausluettelo]"
-#: ../buffer.c:94
-#, fuzzy
msgid "E855: Autocommands caused command to abort"
-msgstr "E812: Autocommands muutti puskurin tai sen nimen"
+msgstr "E855: Autocommands lopetti komennon"
-#: ../buffer.c:135
msgid "E82: Cannot allocate any buffer, exiting..."
-msgstr "E82: Mitään puskuria ei voitu varata, lopetetaan..."
+msgstr "E82: Mitään puskuria ei voitu varata, lopetetaan..."
-#: ../buffer.c:138
msgid "E83: Cannot allocate buffer, using other one..."
-msgstr "E83: Puskuria ei voitu varata, käytetään toista..."
+msgstr "E83: Puskuria ei voitu varata, käytetään toista..."
+
+#, fuzzy
+#~ msgid "E937: Attempt to delete a buffer that is in use"
+#~ msgstr "E934: Ei voida hypätä puskuriin jolla ei ole nimeä"
-#: ../buffer.c:763
msgid "E515: No buffers were unloaded"
msgstr "E515: Puskureita ei vapautettu"
-#: ../buffer.c:765
msgid "E516: No buffers were deleted"
msgstr "E516: Puskureita ei poistettu"
-#: ../buffer.c:767
msgid "E517: No buffers were wiped out"
msgstr "E517: Puskureita ei pyyhitty"
-#: ../buffer.c:772
msgid "1 buffer unloaded"
msgstr "1 puskuri vapautettiin"
-#: ../buffer.c:774
#, c-format
msgid "%d buffers unloaded"
msgstr "%d puskuria vapautettiin"
-#: ../buffer.c:777
msgid "1 buffer deleted"
msgstr "1 puskuri poistettu"
-#: ../buffer.c:779
#, c-format
msgid "%d buffers deleted"
msgstr "%d puskuria poistettu"
-#: ../buffer.c:782
msgid "1 buffer wiped out"
msgstr "1 puskuri pyyhitty"
-#: ../buffer.c:784
#, c-format
msgid "%d buffers wiped out"
msgstr "%d puskuria pyyhitty"
-#: ../buffer.c:806
msgid "E90: Cannot unload last buffer"
-msgstr "E90: Ei voi vapauttaa viimeistä puskuria"
+msgstr "E90: Ei voi vapauttaa viimeistä puskuria"
-#: ../buffer.c:874
msgid "E84: No modified buffer found"
msgstr "E84: Ei muokattuja puskureita"
#. back where we started, didn't find anything.
-#: ../buffer.c:903
msgid "E85: There is no listed buffer"
msgstr "E85: Luetteloitua puskuria ei ole"
-#: ../buffer.c:913
-#, c-format
-msgid "E86: Buffer %<PRId64> does not exist"
-msgstr "E86: Puskuria %<PRId64> ei ole"
-
-#: ../buffer.c:915
msgid "E87: Cannot go beyond last buffer"
-msgstr "E87: Viimeisen puskurin ohi ei voi edetä"
+msgstr "E87: Viimeisen puskurin ohi ei voi edetä"
-#: ../buffer.c:917
msgid "E88: Cannot go before first buffer"
-msgstr "E88: Ensimmäisen puskurin ohi ei voi edetä"
+msgstr "E88: Ensimmäisen puskurin ohi ei voi edetä"
-#: ../buffer.c:945
-#, c-format
+#, fuzzy, c-format
+#~ msgid "E89: %s will be killed(add ! to override)"
+#~ msgstr "E189: %s on jo olemassa (lisää komentoon ! ohittaaksesi)"
+
+#, fuzzy, c-format
msgid ""
"E89: No write since last change for buffer %<PRId64> (add ! to override)"
msgstr ""
-"E89: Puskurin %<PRId64> muutoksia ei ole tallennettu (lisää komentoon ! "
+"E89: Puskurin %ld muutoksia ei ole tallennettu (lisää komentoon ! "
"ohittaaksesi)"
#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
msgid "W14: Warning: List of file names overflow"
msgstr "W14: Varoitus: Tiedostonimiluettelon ylivuoto"
-#: ../buffer.c:1555 ../quickfix.c:3361
-#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: Puskuria %<PRId64> ei löydy"
+#, fuzzy, c-format
+#~ msgid "E92: Buffer %<PRId64> not found"
+#~ msgstr "E92: Puskuria %ld ei löydy"
-#: ../buffer.c:1798
#, c-format
msgid "E93: More than one match for %s"
-msgstr "E93: %s täsmää useampaan kuin yhteen puskuriin"
+msgstr "E93: %s täsmää useampaan kuin yhteen puskuriin"
-#: ../buffer.c:1800
#, c-format
msgid "E94: No matching buffer for %s"
-msgstr "E94: %s ei täsmää yhteenkään puskuriin"
+msgstr "E94: %s ei täsmää yhteenkään puskuriin"
-#: ../buffer.c:2161
-#, c-format
-msgid "line %<PRId64>"
-msgstr "rivi %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "line %<PRId64>"
+#~ msgstr "rivi %ld"
-#: ../buffer.c:2233
msgid "E95: Buffer with this name already exists"
msgstr "E95: Samanniminen puskuri on jo olemassa"
-#: ../buffer.c:2498
msgid " [Modified]"
msgstr " [Muokattu]"
-#: ../buffer.c:2501
msgid "[Not edited]"
msgstr "[Muokkaamaton]"
-#: ../buffer.c:2504
msgid "[New file]"
msgstr "[Uusi tiedosto]"
-#: ../buffer.c:2505
msgid "[Read errors]"
-msgstr "[Lukuvirheitä]"
+msgstr "[Lukuvirheitä]"
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
msgid "[RO]"
msgstr "[Luku]"
-#: ../buffer.c:2507 ../fileio.c:1807
msgid "[readonly]"
msgstr "[kirjoitussuojattu]"
-#: ../buffer.c:2524
#, c-format
msgid "1 line --%d%%--"
msgstr "1 rivi --%d %%--"
-#: ../buffer.c:2526
-#, c-format
-msgid "%<PRId64> lines --%d%%--"
-msgstr "%<PRId64> riviä --%d %%--"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines --%d%%--"
+#~ msgstr "%ld riviä --%d %%--"
-#: ../buffer.c:2530
-#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "rivi %<PRId64>/%<PRId64> --%d %%-- sarake "
+#, fuzzy, c-format
+#~ msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
+#~ msgstr "rivi %ld/%ld --%d %%-- sarake "
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
msgid "[No Name]"
-msgstr "[Nimetön]"
+msgstr "[Nimetön]"
#. must be a help buffer
-#: ../buffer.c:2667
msgid "help"
msgstr "ohje"
-#: ../buffer.c:3225 ../screen.c:4883
msgid "[Help]"
msgstr "[Ohje]"
-#: ../buffer.c:3254 ../screen.c:4887
msgid "[Preview]"
msgstr "[Esikatselu]"
# sijainti tiedostossa -indikaattoreja:
-# 4 merkkiä sais riittää
-#: ../buffer.c:3528
+# 4 merkkiä sais riittää
msgid "All"
msgstr "Kaik"
-#: ../buffer.c:3528
msgid "Bot"
msgstr "Loppu"
-#: ../buffer.c:3531
msgid "Top"
msgstr "Alku"
-#: ../buffer.c:4244
-msgid ""
-"\n"
-"# Buffer list:\n"
-msgstr ""
-"\n"
-"# Puskuriluettelo:\n"
-
-#: ../buffer.c:4289
msgid "[Scratch]"
msgstr "[Raapust]"
-#: ../buffer.c:4529
msgid ""
"\n"
"--- Signs ---"
@@ -249,795 +421,669 @@ msgstr ""
"\n"
"--- Merkit ---"
-#: ../buffer.c:4538
#, c-format
msgid "Signs for %s:"
msgstr "Merkit kohteelle %s:"
-#: ../buffer.c:4543
-#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " rivi=%<PRId64> id=%d nimi=%s"
+#, fuzzy, c-format
+#~ msgid " line=%<PRId64> id=%d name=%s"
+#~ msgstr " rivi=%ld id=%d nimi=%s"
-#: ../cursor_shape.c:68
msgid "E545: Missing colon"
msgstr "E545: Kaksoispiste puuttuu"
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
msgid "E546: Illegal mode"
msgstr "E546: Virheellinen tila"
-#: ../cursor_shape.c:134
msgid "E548: digit expected"
-msgstr "E548: pitää olla numero"
+msgstr "E548: pitää olla numero"
-#: ../cursor_shape.c:138
msgid "E549: Illegal percentage"
msgstr "E549: Virheellinen prosenttiluku"
-#: ../diff.c:146
-#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: Ei voi diffata enempää kuin %<PRId64> puskuria"
+#, fuzzy, c-format
+#~ msgid "E96: Cannot diff more than %<PRId64> buffers"
+#~ msgstr "E96: Ei voi diffata enempää kuin %ld puskuria"
-#: ../diff.c:753
msgid "E810: Cannot read or write temp files"
-msgstr "E810: Ei voi lukea tai kirjoittaa väliaikaistiedostoja"
+msgstr "E810: Ei voi lukea tai kirjoittaa väliaikaistiedostoja"
-#: ../diff.c:755
msgid "E97: Cannot create diffs"
-msgstr "E97: Ei voi luoda diffejä"
+msgstr "E97: Ei voi luoda diffejä"
-#: ../diff.c:966
msgid "E816: Cannot read patch output"
msgstr "E816: Ei voi lukea patchin tulostetta"
-#: ../diff.c:1220
msgid "E98: Cannot read diff output"
msgstr "E98: Ei voi lukea diffin tulostetta"
-#: ../diff.c:2081
msgid "E99: Current buffer is not in diff mode"
-msgstr "E99: Tämä puskuri ei ole diff-tilassa"
+msgstr "E99: Tämä puskuri ei ole diff-tilassa"
-#: ../diff.c:2100
msgid "E793: No other buffer in diff mode is modifiable"
-msgstr "E793: Yksikään muu diff-tilan puskurit ei ole muokattavissa"
+msgstr "E793: Yksikään muu diff-tilan puskurit ei ole muokattavissa"
-#: ../diff.c:2102
msgid "E100: No other buffer in diff mode"
-msgstr "E100: Yksikään muu puskuri ei ole diff-tilassa"
+msgstr "E100: Yksikään muu puskuri ei ole diff-tilassa"
-#: ../diff.c:2112
msgid "E101: More than two buffers in diff mode, don't know which one to use"
-msgstr "E101: Monta puskuria on diff-tilassa, käytettävän valinta ei onnistu"
+msgstr "E101: Monta puskuria on diff-tilassa, käytettävän valinta ei onnistu"
-#: ../diff.c:2141
#, c-format
msgid "E102: Can't find buffer \"%s\""
-msgstr "E102: Puskuria %s ei löydy"
+msgstr "E102: Puskuria %s ei löydy"
-#: ../diff.c:2152
#, c-format
msgid "E103: Buffer \"%s\" is not in diff mode"
msgstr "E103: Puskuri %s ei ole diff-tilassa"
-#: ../diff.c:2193
msgid "E787: Buffer changed unexpectedly"
msgstr "E787: Puskuri vaihtui odottamatta"
-#: ../digraph.c:1598
msgid "E104: Escape not allowed in digraph"
-msgstr "E104: Escapea ei voi käyttää digraafissa"
+msgstr "E104: Escapea ei voi käyttää digraafissa"
-#: ../digraph.c:1760
msgid "E544: Keymap file not found"
-msgstr "E544: Näppäinkarttaa ei löydy"
+msgstr "E544: Näppäinkarttaa ei löydy"
-#: ../digraph.c:1785
msgid "E105: Using :loadkeymap not in a sourced file"
-msgstr "E105: Käytetään :loadkeymapia ladatun tiedoston ulkopuolella"
+msgstr "E105: Käytetään :loadkeymapia ladatun tiedoston ulkopuolella"
-#: ../digraph.c:1821
msgid "E791: Empty keymap entry"
-msgstr "E791: Tyhjä keymap-kenttä"
+msgstr "E791: Tyhjä keymap-kenttä"
-#: ../edit.c:82
msgid " Keyword completion (^N^P)"
-msgstr " Avainsanatäydennys (^N^P)"
+msgstr " Avainsanatäydennys (^N^P)"
#. ctrl_x_mode == 0, ^P/^N compl.
-#: ../edit.c:83
msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
msgstr " ^X-tila (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
-#: ../edit.c:85
msgid " Whole line completion (^L^N^P)"
-msgstr " Täysrivitäydennys (^L^N^P)"
+msgstr " Täysrivitäydennys (^L^N^P)"
-#: ../edit.c:86
msgid " File name completion (^F^N^P)"
-msgstr " Tiedostonimitäydennys (^F^N^P)"
+msgstr " Tiedostonimitäydennys (^F^N^P)"
-#: ../edit.c:87
msgid " Tag completion (^]^N^P)"
-msgstr " Tägitäydennys (^]^N^P)"
+msgstr " Tägitäydennys (^]^N^P)"
-#: ../edit.c:88
msgid " Path pattern completion (^N^P)"
-msgstr " Polkukuviotäydennys (^N^P)"
+msgstr " Polkukuviotäydennys (^N^P)"
-#: ../edit.c:89
msgid " Definition completion (^D^N^P)"
-msgstr " Määritelmätäydennys (^D^N^P)"
+msgstr " Määritelmätäydennys (^D^N^P)"
-#: ../edit.c:91
msgid " Dictionary completion (^K^N^P)"
-msgstr " Sanakirjatäydennys (^K^N^P)"
+msgstr " Sanakirjatäydennys (^K^N^P)"
-#: ../edit.c:92
msgid " Thesaurus completion (^T^N^P)"
-msgstr " Thesaurus-täydennys (^T^N^P)"
+msgstr " Thesaurus-täydennys (^T^N^P)"
-#: ../edit.c:93
msgid " Command-line completion (^V^N^P)"
-msgstr " Komentorivitäydennys (^V^N^P)"
+msgstr " Komentorivitäydennys (^V^N^P)"
-#: ../edit.c:94
msgid " User defined completion (^U^N^P)"
-msgstr " Käyttäjän määrittelemä täydennys (^U^N^P)"
+msgstr " Käyttäjän määrittelemä täydennys (^U^N^P)"
-#: ../edit.c:95
msgid " Omni completion (^O^N^P)"
-msgstr " Omnitäydennys (^O^N^P)"
+msgstr " Omnitäydennys (^O^N^P)"
-#: ../edit.c:96
msgid " Spelling suggestion (s^N^P)"
msgstr " Oikaisulukuehdotus (s^N^P)"
-#: ../edit.c:97
msgid " Keyword Local completion (^N^P)"
-msgstr " Avainsanan paikallinen täydennys (^N^P)"
+msgstr " Avainsanan paikallinen täydennys (^N^P)"
-#: ../edit.c:100
msgid "Hit end of paragraph"
msgstr "Kappaleen loppu tuli vastaan"
-#: ../edit.c:101
-#, fuzzy
msgid "E839: Completion function changed window"
-msgstr "E813: Ei voi sulkea autocmd-ikkunaa"
+msgstr "E839: Täydennys vaihtoi ikkunaa"
-#: ../edit.c:102
msgid "E840: Completion function deleted text"
-msgstr ""
+msgstr "E840: Täydennys poisti tekstiä"
-#: ../edit.c:1847
msgid "'dictionary' option is empty"
-msgstr "dictionary-asetus on tyhjä"
+msgstr "dictionary-asetus on tyhjä"
-#: ../edit.c:1848
msgid "'thesaurus' option is empty"
-msgstr "thesaurus-asetus on tyhjä"
+msgstr "thesaurus-asetus on tyhjä"
-#: ../edit.c:2655
#, c-format
msgid "Scanning dictionary: %s"
msgstr "Luetaan sanakirjaa: %s"
-#: ../edit.c:3079
msgid " (insert) Scroll (^E/^Y)"
-msgstr " (syöttö) Vieritys (^E/^Y)"
+msgstr " (syöttö) Vieritys (^E/^Y)"
-#: ../edit.c:3081
msgid " (replace) Scroll (^E/^Y)"
msgstr " (korvaus) Vieritys (^E/^Y)"
-#: ../edit.c:3587
#, c-format
msgid "Scanning: %s"
msgstr "Luetaan: %s"
-#: ../edit.c:3614
msgid "Scanning tags."
-msgstr "Luetaan tägejä."
+msgstr "Luetaan tägejä."
-#: ../edit.c:4519
msgid " Adding"
-msgstr " Lisätään"
+msgstr " Lisätään"
#. showmode might reset the internal line pointers, so it must
#. * be called before line = ml_get(), or when this address is no
#. * longer needed. -- Acevedo.
#.
-#: ../edit.c:4562
msgid "-- Searching..."
msgstr "-- Haetaan..."
-#: ../edit.c:4618
msgid "Back at original"
-msgstr "Takaisin lähtöpisteessä"
+msgstr "Takaisin lähtöpisteessä"
-#: ../edit.c:4621
msgid "Word from other line"
-msgstr "Sana toisella rivillä"
+msgstr "Sana toisella rivillä"
-#: ../edit.c:4624
msgid "The only match"
-msgstr "Ainoa täsmäys"
+msgstr "Ainoa täsmäys"
-#: ../edit.c:4680
#, c-format
msgid "match %d of %d"
-msgstr "täsmäys %d/%d"
+msgstr "täsmäys %d/%d"
-#: ../edit.c:4684
#, c-format
msgid "match %d"
-msgstr "täsmäys %d"
+msgstr "täsmäys %d"
-#: ../eval.c:137
msgid "E18: Unexpected characters in :let"
-msgstr "E18: Odottamattomia merkkejä komennossa :let"
-
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: Indeksi %<PRId64> luettelon rajojen ulkopuolella"
+msgstr "E18: Odottamattomia merkkejä komennossa :let"
-#: ../eval.c:139
-#, c-format
-msgid "E121: Undefined variable: %s"
-msgstr "E121: Määrittelemätön muuttuja: %s"
-
-#: ../eval.c:140
msgid "E111: Missing ']'"
msgstr "E111: ] puuttuu"
-#: ../eval.c:141
#, c-format
msgid "E686: Argument of %s must be a List"
-msgstr "E686: Argumentin %s pitää olla lista"
+msgstr "E686: Argumentin %s pitää olla lista"
# datarakenteita
-#: ../eval.c:143
#, c-format
msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: Argumentin %s pitää olla lista tai sanakirja"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Sanakirjassa ei voi olla tyhjiä avaimia"
+msgstr "E712: Argumentin %s pitää olla lista tai sanakirja"
-#: ../eval.c:145
msgid "E714: List required"
msgstr "E714: Lista tarvitaan"
-#: ../eval.c:146
msgid "E715: Dictionary required"
msgstr "E715: Sanakirja tarvitaan"
-#: ../eval.c:147
+msgid "E928: String required"
+msgstr "E928: Merkkijono puuttuu"
+
#, c-format
msgid "E118: Too many arguments for function: %s"
msgstr "E118: Liikaa argumentteja funktiolle: %s"
-#: ../eval.c:148
#, c-format
msgid "E716: Key not present in Dictionary: %s"
msgstr "E716: Avainta %s ei ole sanakirjassa"
-#: ../eval.c:150
#, c-format
msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: Funktio %s on jo olemassa, lisää ! korvataksesi"
+msgstr "E122: Funktio %s on jo olemassa, lisää ! korvataksesi"
-#: ../eval.c:151
msgid "E717: Dictionary entry already exists"
msgstr "E717: Sanakirja-alkio on jo olemassa"
-#: ../eval.c:152
msgid "E718: Funcref required"
msgstr "E718: Funcref tarvitaan"
-#: ../eval.c:153
msgid "E719: Cannot use [:] with a Dictionary"
-msgstr "E719: Sanakirjassa ei voi käyttää merkintää [:]"
+msgstr "E719: Sanakirjassa ei voi käyttää merkintää [:]"
-#: ../eval.c:154
-#, c-format
-msgid "E734: Wrong variable type for %s="
-msgstr "E734: Väärä muuttujatyyppi muuttujalle %s="
-
-#: ../eval.c:155
#, c-format
msgid "E130: Unknown function: %s"
msgstr "E130: Tuntematon funktio: %s"
-#: ../eval.c:156
#, c-format
msgid "E461: Illegal variable name: %s"
msgstr "E461: Virheellinen muuttujanimi: %s"
-#: ../eval.c:157
-msgid "E806: using Float as a String"
-msgstr "E806: Float ei käy merkkijonosta"
+#, fuzzy, c-format
+#~ msgid "E46: Cannot change read-only variable \"%.*s\""
+#~ msgstr "E46: Kirjoitussuojattua muuttujaa %s ei voi muuttaa"
+
+#. TODO(ZyX-I): move to eval/executor
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Väärä muuttujatyyppi muuttujalle %s="
-#: ../eval.c:1830
msgid "E687: Less targets than List items"
-msgstr "E687: Kohteita on vähemmän kuin listan alkioita"
+msgstr "E687: Kohteita on vähemmän kuin listan alkioita"
-#: ../eval.c:1834
msgid "E688: More targets than List items"
-msgstr "E688: Kohteita on enemmän kuin listan alkioita"
+msgstr "E688: Kohteita on enemmän kuin listan alkioita"
-#: ../eval.c:1906
msgid "Double ; in list of variables"
-msgstr "Kaksi ;:ttä listan muuttujissa"
+msgstr "Kaksi ;:ttä listan muuttujissa"
-#: ../eval.c:2078
#, c-format
msgid "E738: Can't list variables for %s"
msgstr "E738: Kohteen %s muuttujia ei voi listata"
-#: ../eval.c:2391
+#, fuzzy, c-format
+#~ msgid "E121: Undefined variable: %.*s"
+#~ msgstr "E121: Määrittelemätön muuttuja: %s"
+
msgid "E689: Can only index a List or Dictionary"
-msgstr "E689: Vain listalla ja sanakirjalla voi olla indeksejä"
+msgstr "E689: Vain listalla ja sanakirjalla voi olla indeksejä"
-#: ../eval.c:2396
msgid "E708: [:] must come last"
-msgstr "E708: [:]:n pitää olla viimeisenä"
+msgstr "E708: [:]:n pitää olla viimeisenä"
+
+#, fuzzy
+#~ msgid "E713: Cannot use empty key after ."
+#~ msgstr "E713: Sanakirjassa ei voi olla tyhjiä avaimia"
-#: ../eval.c:2439
msgid "E709: [:] requires a List value"
msgstr "E709: [:] toimii vain listalla"
-#: ../eval.c:2674
msgid "E710: List value has more items than target"
-msgstr "E710: Listalla on enemmän alkioita kuin kohteella"
+msgstr "E710: Listalla on enemmän alkioita kuin kohteella"
-#: ../eval.c:2678
msgid "E711: List value has not enough items"
msgstr "E711: Listalla ei ole tarpeeksi alkioita"
-#: ../eval.c:2867
msgid "E690: Missing \"in\" after :for"
msgstr "E690: :for-kommenolta puuttuu in"
-#: ../eval.c:3063
#, c-format
msgid "E107: Missing parentheses: %s"
msgstr "E107: Sulkeita puuttuu: %s"
-#: ../eval.c:3263
#, c-format
msgid "E108: No such variable: \"%s\""
msgstr "E108: Muuttujaa %s ei ole"
-#: ../eval.c:3333
-msgid "E743: variable nested too deep for (un)lock"
-msgstr "E743: muuttujassa liian monta tasoa lukituksen käsittelyyn"
+#. For historical reasons this error is not given for Lists and
+#. Dictionaries. E.g. b: dictionary may be locked/unlocked.
+#, fuzzy, c-format
+#~ msgid "E940: Cannot lock or unlock variable %s"
+#~ msgstr "E46: Kirjoitussuojattua muuttujaa %s ei voi muuttaa"
-#: ../eval.c:3630
msgid "E109: Missing ':' after '?'"
-msgstr "E109: ?:n jälkeen puuttuu :"
+msgstr "E109: ?:n jälkeen puuttuu :"
-#: ../eval.c:3893
msgid "E691: Can only compare List with List"
msgstr "E691: Listaa voi verrata vain listaan"
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
+msgid "E692: Invalid operation for List"
msgstr "E692: Virheellinen toiminto listalle"
-#: ../eval.c:3915
msgid "E735: Can only compare Dictionary with Dictionary"
msgstr "E735: Sanakirjaa voi verrata vain sanakirjaan"
-#: ../eval.c:3917
msgid "E736: Invalid operation for Dictionary"
msgstr "E736: Virheellinen toiminto sanakirjalle"
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: Funcrefiä voi verrata vain funcrefiin"
-
-#: ../eval.c:3934
msgid "E694: Invalid operation for Funcrefs"
msgstr "E694: Virheellinen toiminto funcrefille"
-#: ../eval.c:4277
msgid "E804: Cannot use '%' with Float"
-msgstr "E804: Ei voi käyttää '%':a Floatin kanssa"
+msgstr "E804: Ei voi käyttää '%':a Floatin kanssa"
-#: ../eval.c:4478
msgid "E110: Missing ')'"
msgstr "E110: ) puuttuu"
-#: ../eval.c:4609
msgid "E695: Cannot index a Funcref"
-msgstr "E695: Funcrefiä ei voi indeksoida"
+msgstr "E695: Funcrefiä ei voi indeksoida"
+
+msgid "E909: Cannot index a special variable"
+msgstr "E909: erikoismuuttujaa ei voi indeksoida"
-#: ../eval.c:4839
#, c-format
msgid "E112: Option name missing: %s"
msgstr "E112: Asetuksen nimi puuttuu: %s"
-#: ../eval.c:4855
#, c-format
msgid "E113: Unknown option: %s"
msgstr "E113: Tuntematon asetus: %s"
-#: ../eval.c:4904
#, c-format
msgid "E114: Missing quote: %s"
msgstr "E114: Puuttuva lainausmerkki: %s"
-#: ../eval.c:5020
#, c-format
msgid "E115: Missing quote: %s"
msgstr "E115: Puuttuva lainausmerkki: %s"
-#: ../eval.c:5084
#, c-format
msgid "E696: Missing comma in List: %s"
msgstr "E696: Listasta puuttuu pilkku: %s"
-#: ../eval.c:5091
#, c-format
msgid "E697: Missing end of List ']': %s"
msgstr "E697: Listan lopusta puuttuu ]: %s"
-#: ../eval.c:6475
+msgid "Not enough memory to set references, garbage collection aborted!"
+msgstr ""
+"Ei tarpeeksi muistia viitteiden asettamista varten, roskiekeruu peruttiin."
+
#, c-format
msgid "E720: Missing colon in Dictionary: %s"
msgstr "E720: Sanakirjasta puuttuu kaksoispiste: %s"
-#: ../eval.c:6499
#, c-format
msgid "E721: Duplicate key in Dictionary: \"%s\""
msgstr "E721: Kaksi samaa avainta sanakirjassa: %s"
-#: ../eval.c:6517
#, c-format
msgid "E722: Missing comma in Dictionary: %s"
msgstr "E722: Sanakirjasta puuttuu pilkku: %s"
-#: ../eval.c:6524
#, c-format
msgid "E723: Missing end of Dictionary '}': %s"
msgstr "E723: Sanakirjan lopusta puuttuu }: %s"
-#: ../eval.c:6555
-msgid "E724: variable nested too deep for displaying"
-msgstr "E724: muuttuja on upotettu liian syvälle näytettäväksi"
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Virheellinen argumentti: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Kaksoiskappale argumentin nimestä: %s"
-#: ../eval.c:7188
#, c-format
msgid "E740: Too many arguments for function %s"
msgstr "E740: Liikaa argumentteja funktiolle %s"
-#: ../eval.c:7190
#, c-format
msgid "E116: Invalid arguments for function %s"
-msgstr "E116: Vääriä argumentteja funktiolle %s"
+msgstr "E116: Vääriä argumentteja funktiolle %s"
-#: ../eval.c:7377
#, c-format
msgid "E117: Unknown function: %s"
msgstr "E117: Tuntematon funktio: %s"
-#: ../eval.c:7383
+#, c-format
+msgid "E933: Function was deleted: %s"
+msgstr "E933: Funktion nimi poistettu: %s"
+
#, c-format
msgid "E119: Not enough arguments for function: %s"
msgstr "E119: Liikaa argumentteja funktiolle %s"
-#: ../eval.c:7387
#, c-format
msgid "E120: Using <SID> not in a script context: %s"
msgstr "E120: <SID> skriptin ulkopuolella: %s"
-#: ../eval.c:7391
#, c-format
msgid "E725: Calling dict function without Dictionary: %s"
msgstr "E725: dict-funktio ilman sanakirjaa: %s"
-#: ../eval.c:7453
-msgid "E808: Number or Float required"
-msgstr "E808: Number tai Float vaaditaan"
+#, fuzzy, c-format
+#~ msgid "Error converting the call result: %s"
+#~ msgstr "virhe Schemestä Vimiin konversiossa"
-#: ../eval.c:7503
-#, fuzzy
msgid "add() argument"
-msgstr "-c-argumentti"
+msgstr "add()-argumentti"
-#: ../eval.c:7907
msgid "E699: Too many arguments"
msgstr "E699: Liikaa argumentteja"
-#: ../eval.c:8073
msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete() toimii vain syöttötilassa"
+msgstr "E785: complete() toimii vain syöttötilassa"
-#: ../eval.c:8156
msgid "&Ok"
msgstr "&Ok"
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: Avain on jo olemassa: %s"
-
-#: ../eval.c:8692
#, fuzzy
+#~ msgid "dictwatcheradd() argument"
+#~ msgstr "add()-argumentti"
+
msgid "extend() argument"
-msgstr "--cmd-argumentti"
+msgstr "extend()-argumentti"
-#: ../eval.c:8915
-#, fuzzy
msgid "map() argument"
-msgstr "-c-argumentti"
+msgstr "map()-argumentti"
-#: ../eval.c:8916
-#, fuzzy
msgid "filter() argument"
-msgstr "-c-argumentti"
+msgstr "filter()-argumentti"
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld riviä: "
+#, fuzzy, c-format
+#~ msgid "+-%s%3ld lines: "
+#~ msgstr "+-%s%3ld rivi: "
-#: ../eval.c:9291
#, c-format
msgid "E700: Unknown function: %s"
msgstr "E700: Tuntematon funktio: %s"
-#: ../eval.c:10729
+msgid "E922: expected a dict"
+msgstr "E922: odotettiin dictiä"
+
+# datarakenteita
+msgid "E923: Second argument of function() must be a list or a dict"
+msgstr "E923: toisen function()-argumentin pitää olla lista tai sanakirja"
+
+#, fuzzy
+#~ msgid "E5000: Cannot find tab number."
+#~ msgstr "E695: Funcrefiä ei voi indeksoida"
+
+#~ msgid "E5001: Higher scope cannot be -1 if lower scope is >= 0."
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E5002: Cannot find window number."
+#~ msgstr "E671: Ikkunan otsikkoa ei löydy %s"
+
msgid "called inputrestore() more often than inputsave()"
msgstr "inputrestore() suoritettu useammin kuin inputsave()"
-#: ../eval.c:10771
-#, fuzzy
msgid "insert() argument"
-msgstr "-c-argumentti"
+msgstr "insert()-argumentti"
-#: ../eval.c:10841
msgid "E786: Range not allowed"
-msgstr "E786: Aluetta ei voi käyttää"
+msgstr "E786: Aluetta ei voi käyttää"
+
+#~ msgid "Invalid stream on rpc job, use jobclose(id, 'rpc')"
+#~ msgstr ""
+
+#~ msgid "Invalid job stream: Not an rpc job"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Invalid job stream \"%s\""
+#~ msgstr ""
+
+#~ msgid "Can't send data to the job: stdin is closed"
+#~ msgstr ""
+
+#~ msgid "Can't send raw data to rpc channel"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E474: Failed to convert list to string"
+#~ msgstr "ei voitu konvertoida tyypistä %s vim-listaksi"
+
+#, fuzzy, c-format
+#~ msgid "E474: Failed to parse %.*s"
+#~ msgstr "E241: Kohteeseen %s lähettäminen ei onnistunut"
-#: ../eval.c:11140
msgid "E701: Invalid type for len()"
msgstr "E701: Virheellinen tyyppi funktiolle len()"
-#: ../eval.c:11980
+#, fuzzy, c-format
+#~ msgid "msgpackdump() argument, index %i"
+#~ msgstr "map()-argumentti"
+
+#, fuzzy
+#~ msgid "E5070: Character number must not be less than zero"
+#~ msgstr "luvun on oltava nollaa suurempi"
+
+#, fuzzy, c-format
+#~ msgid "E5071: Character number must not be greater than INT_MAX (%i)"
+#~ msgstr "luvun on oltava nollaa suurempi"
+
msgid "E726: Stride is zero"
msgstr "E726: Stride on nolla"
-#: ../eval.c:11982
msgid "E727: Start past end"
-msgstr "E727: Alku on lopun jälkeen"
+msgstr "E727: Alku on lopun jälkeen"
-#: ../eval.c:12024 ../eval.c:15297
msgid "<empty>"
-msgstr "<tyhjä>"
+msgstr "<tyhjä>"
-#: ../eval.c:12282
-#, fuzzy
msgid "remove() argument"
-msgstr "--cmd-argumentti"
+msgstr "remove()-argumentti"
-#: ../eval.c:12466
msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: Liikaa symbolisia linkkejä (mahdollinen sykli)"
+msgstr "E655: Liikaa symbolisia linkkejä (mahdollinen sykli)"
-#: ../eval.c:12593
-#, fuzzy
msgid "reverse() argument"
-msgstr "-c-argumentti"
+msgstr "reverse()-argumentti"
+
+#, c-format
+msgid "E927: Invalid action: '%s'"
+msgstr "E927: Viallinen toiminto: %s"
-#: ../eval.c:13721
-#, fuzzy
msgid "sort() argument"
-msgstr "-c-argumentti"
+msgstr "sort()-argumentti"
-#: ../eval.c:13721
-#, fuzzy
msgid "uniq() argument"
-msgstr "-c-argumentti"
+msgstr "uniq()-argumentti"
-#: ../eval.c:13776
msgid "E702: Sort compare function failed"
msgstr "E702: Lajittelun vertausfunktio ei onnistunut"
-#: ../eval.c:13806
-#, fuzzy
msgid "E882: Uniq compare function failed"
-msgstr "E702: Lajittelun vertausfunktio ei onnistunut"
+msgstr "E882: Uniqin vertausfunktio ei onnistunut"
-#: ../eval.c:14085
msgid "(Invalid)"
msgstr "(Virheellinen)"
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: Väliaikaistiedostoon kirjoittaminen ei onnistunut"
+#, c-format
+msgid "E935: invalid submatch number: %d"
+msgstr "E935: Virheellinen alitäsmäyksen numero: %d"
-#: ../eval.c:16159
-msgid "E805: Using a Float as a Number"
-msgstr "E805: Float ei käy Numberista"
+#~ msgid "Can only call this function in an unmodified buffer"
+#~ msgstr ""
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr "E703: Funcref ei käy Numberista"
+msgid "E921: Invalid callback argument"
+msgstr "E921: Virheellinen callback-argumentti"
-#: ../eval.c:16170
-msgid "E745: Using a List as a Number"
-msgstr "E745: Lista ei käy Numberista"
+#, fuzzy, c-format
+#~ msgid "E80: Error while writing: %s"
+#~ msgstr "E80: Kirjoitusvirhe"
-#: ../eval.c:16173
-msgid "E728: Using a Dictionary as a Number"
-msgstr "E728: Sanakirja ei käy Numberista"
+#. Using %s, p and not %c, *p to preserve multibyte characters
+#, fuzzy, c-format
+#~ msgid "E5060: Unknown flag: %s"
+#~ msgstr "E235: Tuntematon fontti: %s"
-#: ../eval.c:16259
-msgid "E729: using Funcref as a String"
-msgstr "E729: Funcref ei käy merkkijonosta"
+#, fuzzy
+#~ msgid "E482: Can't open file with an empty name"
+#~ msgstr "E212: Tiedoston avaus kirjoittamista varten ei onnistu"
-#: ../eval.c:16262
-msgid "E730: using List as a String"
-msgstr "E730: Lista ei käy merkkijonosta"
+#, fuzzy, c-format
+#~ msgid "E482: Can't open file %s for writing: %s"
+#~ msgstr "E212: Tiedoston avaus kirjoittamista varten ei onnistu"
-#: ../eval.c:16265
-msgid "E731: using Dictionary as a String"
-msgstr "E731: Sanakirja ei käy merkkijonosta"
+#, fuzzy, c-format
+#~ msgid "E80: Error when closing file %s: %s"
+#~ msgstr "E209: Virhe suljettaessa tiedostoa %s"
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: Muuttujatyyppi ei täsmää: %s"
+#, fuzzy, c-format
+#~ msgid "E794: Cannot set variable in the sandbox: \"%.*s\""
+#~ msgstr "E794: Muuttujaa ei voi asettaa hiekkalaatikossa: %s"
-#: ../eval.c:16705
-#, c-format
-msgid "E795: Cannot delete variable %s"
-msgstr "E795: Muuttujaa %s ei voi poistaa"
+#, fuzzy, c-format
+#~ msgid "E795: Cannot delete variable %.*s"
+#~ msgstr "E795: Muuttujaa %s ei voi poistaa"
-#: ../eval.c:16724
#, c-format
msgid "E704: Funcref variable name must start with a capital: %s"
-msgstr "E704: Funcrefin muuttujanimen pitää alkaa suuraakkosella: %s"
+msgstr "E704: Funcrefin muuttujanimen pitää alkaa suuraakkosella: %s"
-#: ../eval.c:16732
#, c-format
msgid "E705: Variable name conflicts with existing function: %s"
msgstr "E705: Muuttujanimi on sama kuin olemassaolevan funktion: %s"
-#: ../eval.c:16763
-#, c-format
-msgid "E741: Value is locked: %s"
-msgstr "E741: Arvo on lukittu: %s"
-
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
-msgid "Unknown"
-msgstr "Tuntematon"
-
-#: ../eval.c:16768
-#, c-format
-msgid "E742: Cannot change value of %s"
-msgstr "E742: Ei voi muuttaa muuttujan %s arvoa"
-
-#: ../eval.c:16838
msgid "E698: variable nested too deep for making a copy"
-msgstr "E698: muuttuja on upotettu liian syvälle kopioitavaksi"
+msgstr "E698: muuttuja on upotettu liian syvälle kopioitavaksi"
-#: ../eval.c:17249
#, c-format
msgid "E123: Undefined function: %s"
msgstr "E123: Tuntematon funktio: %s"
-#: ../eval.c:17260
#, c-format
msgid "E124: Missing '(': %s"
msgstr "E124: ( puuttuu: %s"
-#: ../eval.c:17293
-#, fuzzy
msgid "E862: Cannot use g: here"
-msgstr "E284: Ei voi asettaa IC-arvoja"
+msgstr "E862: g: ei toimi täällä"
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: Virheellinen argumentti: %s"
-
-#: ../eval.c:17323
#, fuzzy, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "Kaksoiskappale kentän nimestä: %s"
+#~ msgid "E932: Closure function should not be at top level: %s"
+#~ msgstr "E932 Sulkeumafunktio ei voi olla uloimmalla tasolla: %s"
-#: ../eval.c:17416
msgid "E126: Missing :endfunction"
msgstr "E126: :endfunction puuttuu"
-#: ../eval.c:17537
#, c-format
msgid "E707: Function name conflicts with variable: %s"
msgstr "E707: Funktion nimi on ristiriidassa muuttujan kanssa: %s"
-#: ../eval.c:17549
#, c-format
msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: Funktiota %s ei voi määritellä uudestaan, koska se on käytössä"
+msgstr "E127: Funktiota %s ei voi määritellä uudestaan, koska se on käytössä"
-#: ../eval.c:17604
#, c-format
msgid "E746: Function name does not match script file name: %s"
msgstr "E746: Funktion nimi ei ole sama kuin skriptin tiedostonnimi: %s"
-#: ../eval.c:17716
msgid "E129: Function name required"
msgstr "E129: Funktion nimi puuttuu"
-#: ../eval.c:17824
-#, fuzzy, c-format
+#, c-format
msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr ""
-"E128: Funktion nimen pitää alkaa suuraakkosella tai sisältää kaksoispisteen: "
-"%s"
+msgstr "E128: Funktion nimen pitää alkaa suuraakkosella tai merkeillä ’s:’: %s"
-#: ../eval.c:17833
-#, fuzzy, c-format
+#, c-format
msgid "E884: Function name cannot contain a colon: %s"
-msgstr ""
-"E128: Funktion nimen pitää alkaa suuraakkosella tai sisältää kaksoispisteen: "
-"%s"
+msgstr "E884: Funktion nimessä ei saa olla kaksoispistettä: %s"
-#: ../eval.c:18336
#, c-format
msgid "E131: Cannot delete function %s: It is in use"
msgstr "E131: Funktiota %s ei voi poistaa"
-#: ../eval.c:18441
+#, fuzzy, c-format
+#~ msgid "Cannot delete function %s: It is being used internally"
+#~ msgstr "E131: Funktiota %s ei voi poistaa"
+
msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: Funktiokutsujen syvyys on enemmän kuin maxfuncdepth"
+msgstr "E132: Funktiokutsujen syvyys on enemmän kuin maxfuncdepth"
-#: ../eval.c:18568
#, c-format
msgid "calling %s"
msgstr "kutsutaan funktiota %s"
-#: ../eval.c:18651
#, c-format
msgid "%s aborted"
msgstr "%s keskeytettiin"
-#: ../eval.c:18653
-#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s palaa kohdassa #%<PRId64>"
+#, fuzzy, c-format
+#~ msgid "%s returning #%<PRId64>"
+#~ msgstr "%s palaa kohdassa #%ld"
-#: ../eval.c:18670
#, c-format
msgid "%s returning %s"
msgstr "%s palaa kohdassa %s"
-#: ../eval.c:18691 ../ex_cmds2.c:2695
#, c-format
msgid "continuing in %s"
msgstr "jatkaa kohdassa %s"
-#: ../eval.c:18795
msgid "E133: :return not inside a function"
-msgstr "E133: :return ei ole funktion sisällä"
+msgstr "E133: :return ei ole funktion sisällä"
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# globaalit muuttujat:\n"
-
-#: ../eval.c:19254
msgid ""
"\n"
"\tLast set from "
@@ -1045,154 +1091,396 @@ msgstr ""
"\n"
"\tViimeksi asetettu kohteesta "
-#: ../eval.c:19272
msgid "No old files"
msgstr "Ei vanhoja tiedostoja"
-# puhutaan merkin ulkoasusta snprintf(..., c, c, c, c)
-#: ../ex_cmds.c:122
#, c-format
-msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
-msgstr "<%s>%s%s %d, heksana %02x, oktaalina %03o"
+#~ msgid "E474: Expected comma before list item: %s"
+#~ msgstr ""
-#: ../ex_cmds.c:145
#, c-format
-msgid "> %d, Hex %04x, Octal %o"
-msgstr "> %d, heksana %04x, oktaalina %o"
+#~ msgid "E474: Expected colon before dictionary value: %s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E474: Expected string key: %s"
+#~ msgstr "E415: odotuksenvastainen =-merkki: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Expected comma before dictionary key: %s"
+#~ msgstr "E722: Sanakirjasta puuttuu pilkku: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Unfinished escape sequence: %.*s"
+#~ msgstr "E540: Sulkematon lausekesarja"
-#: ../ex_cmds.c:146
#, c-format
-msgid "> %d, Hex %08x, Octal %o"
-msgstr "> %d, hekdana %08x, oktaalina %o"
+#~ msgid "E474: Unfinished unicode escape sequence: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:684
-msgid "E134: Move lines into themselves"
-msgstr "E134: Rivien siirto itsejensä päälle"
+#, c-format
+#~ msgid "E474: Expected four hex digits after \\u: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:747
-msgid "1 line moved"
-msgstr "1 rivi siirretty"
+#, fuzzy, c-format
+#~ msgid "E474: Unknown escape sequence: %.*s"
+#~ msgstr "E409: Tuntematon ryhmän nimi: %s"
-#: ../ex_cmds.c:749
#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "%<PRId64> riviä siirretty"
+#~ msgid "E474: ASCII control characters cannot be present inside string: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1175
#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "%<PRId64> riviä suodatettu"
+#~ msgid "E474: Only UTF-8 strings allowed: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1194
-msgid "E135: *Filter* Autocommands must not change current buffer"
-msgstr "E135: *Filter*-autocommand ei voi vaihtaa puskuria"
+#, c-format
+#~ msgid ""
+#~ "E474: Only UTF-8 code points up to U+10FFFF are allowed to appear unescaped: "
+#~ "%.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1244
-msgid "[No write since last change]\n"
-msgstr "[Viimeisintä muutosta ei ole kirjoitettu]\n"
+#, fuzzy, c-format
+#~ msgid "E474: Expected string end: %.*s"
+#~ msgstr "E415: odotuksenvastainen =-merkki: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Leading zeroes are not allowed: %.*s"
+#~ msgstr "E786: Aluetta ei voi käyttää"
+
+#, fuzzy, c-format
+#~ msgid "E474: Missing number after minus sign: %.*s"
+#~ msgstr "E526: Lukuarvo puuttuu merkkijonon <%s> jälkeen"
+
+#, fuzzy, c-format
+#~ msgid "E474: Missing number after decimal dot: %.*s"
+#~ msgstr "E526: Lukuarvo puuttuu merkkijonon <%s> jälkeen"
+
+#, fuzzy, c-format
+#~ msgid "E474: Missing exponent: %.*s"
+#~ msgstr "E114: Puuttuva lainausmerkki: %s"
-#: ../ex_cmds.c:1424
#, c-format
-msgid "%sviminfo: %s in line: "
-msgstr "%sviminfo: %s rivillä: "
+#~ msgid ""
+#~ "E685: internal error: while converting number \"%.*s\" to float string2float "
+#~ "consumed %zu bytes in place of %zu"
+#~ msgstr ""
-#: ../ex_cmds.c:1431
-msgid "E136: viminfo: Too many errors, skipping rest of file"
-msgstr "E136: viminfo: liikaa virheitä, ohitetaan lopputiedosto"
+#, c-format
+#~ msgid ""
+#~ "E685: internal error: while converting number \"%.*s\" to integer vim_str2nr "
+#~ "consumed %i bytes in place of %zu"
+#~ msgstr ""
+
+#~ msgid "E474: Attempt to decode a blank string"
+#~ msgstr ""
-#: ../ex_cmds.c:1458
#, c-format
-msgid "Reading viminfo file \"%s\"%s%s%s"
-msgstr "Luetaan viminfo-tiedostoa \"%s\"%s%s%s"
+#~ msgid "E474: No container to close: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1460
-msgid " info"
-msgstr " info"
+#, c-format
+#~ msgid "E474: Closing list with curly bracket: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1461
-msgid " marks"
-msgstr " merkit"
+#, fuzzy, c-format
+#~ msgid "E474: Closing dictionary with square bracket: %.*s"
+#~ msgstr "E725: dict-funktio ilman sanakirjaa: %s"
-#: ../ex_cmds.c:1462
-msgid " oldfiles"
-msgstr " vanhaatiedostoa"
+#, fuzzy, c-format
+#~ msgid "E474: Trailing comma: %.*s"
+#~ msgstr "E488: Ylimääräisiä merkkejä perässä"
-#: ../ex_cmds.c:1463
-msgid " FAILED"
-msgstr " EPÄONNISTUI"
+#, c-format
+#~ msgid "E474: Expected value after colon: %.*s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E474: Expected value: %.*s"
+#~ msgstr "E415: odotuksenvastainen =-merkki: %s"
-#. avoid a wait_return for this message, it's annoying
-#: ../ex_cmds.c:1541
#, c-format
-msgid "E137: Viminfo file is not writable: %s"
-msgstr "E137: Viminfo-tiedostoon ei voitu kirjoittaa: %s"
+#~ msgid "E474: Comma not inside container: %.*s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E474: Duplicate comma: %.*s"
+#~ msgstr "E721: Kaksi samaa avainta sanakirjassa: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Comma after colon: %.*s"
+#~ msgstr "E254: Väriä %s ei voi määritellä"
+
+#, fuzzy, c-format
+#~ msgid "E474: Using comma in place of colon: %.*s"
+#~ msgstr "E722: Sanakirjasta puuttuu pilkku: %s"
-#: ../ex_cmds.c:1626
#, c-format
-msgid "E138: Can't write viminfo file %s!"
-msgstr "E138: Viminfo-tiedoston kirjoittaminen ei onnistu %s"
+#~ msgid "E474: Leading comma: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1635
#, c-format
-msgid "Writing viminfo file \"%s\""
-msgstr "Kirjoitetaan viminfo-tiedostoa %s"
+#~ msgid "E474: Colon not inside container: %.*s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E474: Using colon not in dictionary: %.*s"
+#~ msgstr "E720: Sanakirjasta puuttuu kaksoispiste: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Unexpected colon: %.*s"
+#~ msgstr "E415: odotuksenvastainen =-merkki: %s"
-#. Write the info:
-#: ../ex_cmds.c:1720
#, c-format
-msgid "# This viminfo file was generated by Vim %s.\n"
-msgstr "# Vimin %s generoima viminfo-tiedosto.\n"
+#~ msgid "E474: Colon after comma: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1722
-msgid ""
-"# You may edit it if you're careful!\n"
-"\n"
-msgstr ""
-"# Muokkaa varovasti!\n"
-"\n"
+#, fuzzy, c-format
+#~ msgid "E474: Duplicate colon: %.*s"
+#~ msgstr "E721: Kaksi samaa avainta sanakirjassa: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Expected null: %.*s"
+#~ msgstr "E415: odotuksenvastainen =-merkki: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Expected true: %.*s"
+#~ msgstr "E270: odotuksenvastainen redo"
+
+#, fuzzy, c-format
+#~ msgid "E474: Expected false: %.*s"
+#~ msgstr "E415: odotuksenvastainen =-merkki: %s"
-#: ../ex_cmds.c:1723
-msgid "# Value of 'encoding' when this file was written\n"
-msgstr "# encoding-muuttujan arvo tiedostoa kirjoitettaessa\n"
+#, fuzzy, c-format
+#~ msgid "E474: Unidentified byte: %.*s"
+#~ msgstr "E121: Määrittelemätön muuttuja: %s"
-#: ../ex_cmds.c:1800
-msgid "Illegal starting char"
-msgstr "Virheellinen aloitusmerkki"
+#, fuzzy, c-format
+#~ msgid "E474: Trailing characters: %.*s"
+#~ msgstr "E488: Ylimääräisiä merkkejä perässä"
+
+#, fuzzy, c-format
+#~ msgid "E474: Unexpected end of input: %.*s"
+#~ msgstr "E415: odotuksenvastainen =-merkki: %s"
+
+#, c-format
+#~ msgid "key %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "key %s at index %i from special map"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "index %i"
+#~ msgstr ""
+
+#~ msgid "partial"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "argument %i"
+#~ msgstr "-c-argumentti"
+
+#, fuzzy
+#~ msgid "partial self dictionary"
+#~ msgstr "ei voida muuttaa kiinnitettyä sanakirjaa"
+
+#~ msgid "itself"
+#~ msgstr ""
+
+#. Only give this message once for a recursive call to avoid
+#. flooding the user with errors.
+#~ msgid "E724: unable to correctly dump variable with self-referencing container"
+#~ msgstr ""
+
+#~ msgid "E474: Unable to represent NaN value in JSON"
+#~ msgstr ""
+
+#~ msgid "E474: Unable to represent infinity in JSON"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "E474: String \"%.*s\" contains byte that does not start any UTF-8 character"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "E474: UTF-8 string contains code point which belongs to a surrogate pair: "
+#~ "%.*s"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E474: Unable to convert EXT string to JSON"
+#~ msgstr "E620: Tulostuskoodaukseen %s muunto ei onnistu"
+
+#, c-format
+#~ msgid "E474: Error while dumping %s, %s: attempt to dump function reference"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E474: Invalid key in special dictionary"
+#~ msgstr "E736: Virheellinen toiminto sanakirjalle"
+
+#, c-format
+#~ msgid "E5004: Error while dumping %s, %s: attempt to dump function reference"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E5005: Unable to dump %s: container references itself in %s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E684: list index out of range: %<PRId64>"
+#~ msgstr "E684: Indeksi %ld luettelon rajojen ulkopuolella"
+
+#~ msgid "E6000: Argument is not a function or function name"
+#~ msgstr ""
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Avain on jo olemassa: %s"
+
+#, fuzzy
+#~ msgid "tv_clear() argument"
+#~ msgstr "filter()-argumentti"
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: muuttujassa liian monta tasoa lukituksen käsittelyyn"
+
+#, fuzzy, c-format
+#~ msgid "E741: Value is locked: %.*s"
+#~ msgstr "E741: Arvo on lukittu: %s"
+
+#, fuzzy, c-format
+#~ msgid "E742: Cannot change value of %.*s"
+#~ msgstr "E742: Ei voi muuttaa muuttujan %s arvoa"
+
+msgid "Unknown"
+msgstr "Tuntematon"
+
+#, fuzzy
+#~ msgid "E805: Expected a Number or a String, Float found"
+#~ msgstr "E807: Odotettiin Float-argumenttia printf():lle"
+
+#~ msgid "E703: Expected a Number or a String, Funcref found"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E745: Expected a Number or a String, List found"
+#~ msgstr "E807: Odotettiin Float-argumenttia printf():lle"
+
+#~ msgid "E728: Expected a Number or a String, Dictionary found"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E5300: Expected a Number or a String"
+#~ msgstr "E807: Odotettiin Float-argumenttia printf():lle"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: Lista ei käy Numberista"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Sanakirja ei käy Numberista"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: Float ei käy Numberista"
+
+#, fuzzy
+#~ msgid "E685: using an invalid value as a Number"
+#~ msgstr "E908: huono arvo merkkijonolle"
+
+msgid "E730: using List as a String"
+msgstr "E730: Lista ei käy merkkijonosta"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Sanakirja ei käy merkkijonosta"
+
+msgid "E908: using an invalid value as a String"
+msgstr "E908: huono arvo merkkijonolle"
+
+msgid "E891: Using a Funcref as a Float"
+msgstr "E891: Funcref ei käy Floatista"
+
+msgid "E892: Using a String as a Float"
+msgstr "E892: String ei käy Floatista"
+
+msgid "E893: Using a List as a Float"
+msgstr "E893: Lista ei käy Floatista"
+
+msgid "E894: Using a Dictionary as a Float"
+msgstr "E894: Sanakirja ei käy Floatista"
+
+msgid "E907: Using a special value as a Float"
+msgstr "E907: Käytettiin erikoisarvoa Floattina"
+
+msgid "E808: Number or Float required"
+msgstr "E808: Number tai Float vaaditaan"
+
+# puhutaan merkin ulkoasusta snprintf(..., c, c, c, c)
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, heksana %02x, oktaalina %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, heksana %04x, oktaalina %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, hekdana %08x, oktaalina %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Rivien siirto itsejensä päälle"
+
+msgid "1 line moved"
+msgstr "1 rivi siirretty"
+
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines moved"
+#~ msgstr "%ld riviä siirretty"
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Tiedostoa %s ei voi luoda"
+
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines filtered"
+#~ msgstr "%ld riviä suodatettu"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: *Filter*-autocommand ei voi vaihtaa puskuria"
+
+msgid "[No write since last change]\n"
+msgstr "[Viimeisintä muutosta ei ole kirjoitettu]\n"
-#: ../ex_cmds.c:2162
msgid "Write partial file?"
msgstr "Kirjoita osittainen tiedosto"
-#: ../ex_cmds.c:2166
msgid "E140: Use ! to write partial buffer"
-msgstr "E140: Käytä !-komentoa osittaisen puskurin kirjoittamiseen"
+msgstr "E140: Käytä !-komentoa osittaisen puskurin kirjoittamiseen"
-#: ../ex_cmds.c:2281
#, c-format
msgid "Overwrite existing file \"%s\"?"
msgstr "Ylikirjoitetaanko olemassaoleva tiedosto %s?"
-#: ../ex_cmds.c:2317
#, c-format
msgid "Swap file \"%s\" exists, overwrite anyway?"
msgstr "Swap-tiedosto %s on olemassa, ylikirjoitetaanko?"
-#: ../ex_cmds.c:2326
#, c-format
msgid "E768: Swap file exists: %s (:silent! overrides)"
msgstr "E768: Swap-tiedosto on jo olemassa: %s (komento :silent! ohittaa)"
-#: ../ex_cmds.c:2381
-#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: Ei tiedostonimeä puskurille %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "E141: No file name for buffer %<PRId64>"
+#~ msgstr "E141: Ei tiedostonimeä puskurille %ld"
-#: ../ex_cmds.c:2412
msgid "E142: File not written: Writing is disabled by 'write' option"
msgstr ""
-"E142: Tiedostoa ei kirjoitettu; write-asetus poistaa kirjoituksen käytöstä"
+"E142: Tiedostoa ei kirjoitettu; write-asetus poistaa kirjoituksen käytöstä"
-#: ../ex_cmds.c:2434
#, c-format
msgid ""
"'readonly' option is set for \"%s\".\n"
@@ -1201,7 +1489,6 @@ msgstr ""
"readonly asetettu tiedostolle \"%s\".\n"
"Kirjoitetaanko?"
-#: ../ex_cmds.c:2439
#, c-format
msgid ""
"File permissions of \"%s\" are read-only.\n"
@@ -1210,799 +1497,599 @@ msgid ""
msgstr ""
"Tiedosto %s on kirjoitussuojattu.\n"
"Siihen saattaa voida silti kirjoittaa.\n"
-"Yritetäänkö?"
+"Yritetäänkö?"
-#: ../ex_cmds.c:2451
#, c-format
msgid "E505: \"%s\" is read-only (add ! to override)"
-msgstr "E505: %s on kirjoitussuojattu (lisää komentoon ! ohittaaksesi)"
+msgstr "E505: %s on kirjoitussuojattu (lisää komentoon ! ohittaaksesi)"
-#: ../ex_cmds.c:3120
#, c-format
msgid "E143: Autocommands unexpectedly deleted new buffer %s"
msgstr "E143: Autocommand poisti uuden puskurin odotuksen vastaisesti %s"
-#: ../ex_cmds.c:3313
msgid "E144: non-numeric argument to :z"
msgstr "E144: :z:n argumentti ei ole numero"
-#: ../ex_cmds.c:3404
-msgid "E145: Shell commands not allowed in rvim"
-msgstr "E145: Kuoren komennot eivät toimi rvimissä"
+#, fuzzy
+#~ msgid "E145: Shell commands not allowed in restricted mode"
+#~ msgstr "E145: Kuoren komennot eivät toimi rvimissä"
-#: ../ex_cmds.c:3498
msgid "E146: Regular expressions can't be delimited by letters"
-msgstr "E146: Säännöllistä ilmausta ei voi rajata kirjaimilla"
+msgstr "E146: Säännöllistä ilmausta ei voi rajata kirjaimilla"
-#: ../ex_cmds.c:3964
#, c-format
msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
msgstr "korvaa kohteella %s (y/n/a/q/l/^E/^Y)?"
-#: ../ex_cmds.c:4379
msgid "(Interrupted) "
msgstr "(Keskeytetty)"
-#: ../ex_cmds.c:4384
msgid "1 match"
-msgstr "1 täsmäys"
+msgstr "1 täsmäys"
-#: ../ex_cmds.c:4384
msgid "1 substitution"
msgstr "1 korvaus"
-#: ../ex_cmds.c:4387
-#, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> täsmäystä"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> matches"
+#~ msgstr "%ld täsmäystä"
-#: ../ex_cmds.c:4388
-#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> korvausta"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> substitutions"
+#~ msgstr "%ld korvausta"
-#: ../ex_cmds.c:4392
msgid " on 1 line"
-msgstr " 1 rivillä"
+msgstr " 1 rivillä"
-#: ../ex_cmds.c:4395
-#, c-format
-msgid " on %<PRId64> lines"
-msgstr " %<PRId64> rivillä"
+#, fuzzy, c-format
+#~ msgid " on %<PRId64> lines"
+#~ msgstr " %ld rivillä"
-#: ../ex_cmds.c:4438
msgid "E147: Cannot do :global recursive"
msgstr "E147: :globalia ei voi suorittaa rekursiivisesti"
-#: ../ex_cmds.c:4467
msgid "E148: Regular expression missing from global"
-msgstr "E148: Säännöllinen ilmaus puuttuu globaalista"
+msgstr "E148: Säännöllinen ilmaus puuttuu globaalista"
-#: ../ex_cmds.c:4508
#, c-format
msgid "Pattern found in every line: %s"
-msgstr "Kuvio löytyi joka riviltä: %s"
+msgstr "Kuvio löytyi joka riviltä: %s"
-#: ../ex_cmds.c:4510
-#, fuzzy, c-format
+#, c-format
msgid "Pattern not found: %s"
-msgstr "Kuviota ei löydy"
-
-#: ../ex_cmds.c:4587
-msgid ""
-"\n"
-"# Last Substitute String:\n"
-"$"
-msgstr ""
-"\n"
-"# Viimeisin korvausmerkkijono:\n"
-"$"
+msgstr "Kuviota ei löydy: %s"
-#: ../ex_cmds.c:4679
msgid "E478: Don't panic!"
-msgstr "E478: Älä panikoi."
+msgstr "E478: Älä panikoi."
-#: ../ex_cmds.c:4717
#, c-format
msgid "E661: Sorry, no '%s' help for %s"
-msgstr "E661: Sori, ei löydy %s-ohjetta kohteelle %s"
+msgstr "E661: ei löydy %s-ohjetta kohteelle %s"
-#: ../ex_cmds.c:4719
#, c-format
msgid "E149: Sorry, no help for %s"
-msgstr "E149: Sori, ei löydy ohjetta kohteelle %s"
+msgstr "E149: ei löydy ohjetta kohteelle %s"
-#: ../ex_cmds.c:4751
#, c-format
msgid "Sorry, help file \"%s\" not found"
-msgstr "Sori, ohjetiedostoa %s ei löydy"
+msgstr "ohjetiedostoa %s ei löydy"
-#: ../ex_cmds.c:5323
-#, c-format
-msgid "E150: Not a directory: %s"
-msgstr "E150: Ei ole hakemisto: %s"
-
-#: ../ex_cmds.c:5446
#, c-format
msgid "E152: Cannot open %s for writing"
msgstr "E152: Ei voi avata tiedostoa %s kirjoittamista varten"
-#: ../ex_cmds.c:5471
#, c-format
msgid "E153: Unable to open %s for reading"
msgstr "E153: Ei voi avata tiedostoa %s lukemista varten"
-#: ../ex_cmds.c:5500
#, c-format
msgid "E670: Mix of help file encodings within a language: %s"
-msgstr "E670: Monia ohjetiedostokoodauksia kielessä: %s"
+msgstr "E670: Monia ohjetiedostokoodauksia kielessä: %s"
-#: ../ex_cmds.c:5565
#, c-format
msgid "E154: Duplicate tag \"%s\" in file %s/%s"
-msgstr "E154: Kaksoiskappale tägistä %s tiedostossa %s/%s"
+msgstr "E154: Kaksoiskappale tägistä %s tiedostossa %s/%s"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Ei ole hakemisto: %s"
-#: ../ex_cmds.c:5687
#, c-format
msgid "E160: Unknown sign command: %s"
msgstr "E160: Tuntematon merkkikomento: %s"
-#: ../ex_cmds.c:5704
msgid "E156: Missing sign name"
msgstr "E156: Merkki puuttuu"
-#: ../ex_cmds.c:5746
msgid "E612: Too many signs defined"
-msgstr "E612: Liikaa merkkejä määritelty"
+msgstr "E612: Liikaa merkkejä määritelty"
-#: ../ex_cmds.c:5813
#, c-format
msgid "E239: Invalid sign text: %s"
msgstr "E239: Virheellinen merkkiteksti: %s"
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
#, c-format
msgid "E155: Unknown sign: %s"
msgstr "E155: Tuntematon merkki: %s"
-#: ../ex_cmds.c:5877
msgid "E159: Missing sign number"
msgstr "E159: Merkin numero puuttuu"
-#: ../ex_cmds.c:5971
#, c-format
msgid "E158: Invalid buffer name: %s"
msgstr "E158: Virheellinen puskurin nimi: %s"
-#: ../ex_cmds.c:6008
+msgid "E934: Cannot jump to a buffer that does not have a name"
+msgstr "E934: Ei voida hypätä puskuriin jolla ei ole nimeä"
+
+#, fuzzy, c-format
+#~ msgid "E157: Invalid sign ID: %<PRId64>"
+#~ msgstr "E157: Virheellinen merkin tunnus: %ld"
+
#, c-format
-msgid "E157: Invalid sign ID: %<PRId64>"
-msgstr "E157: Virheellinen merkin tunnus: %<PRId64>"
+msgid "E885: Not possible to change sign %s"
+msgstr "E885: Ei voida muuttaa merkkiä %s"
-#: ../ex_cmds.c:6066
msgid " (not supported)"
msgstr " (ei tuettu)"
-#: ../ex_cmds.c:6169
msgid "[Deleted]"
msgstr "[Poistettu]"
-#: ../ex_cmds2.c:139
msgid "Entering Debug mode. Type \"cont\" to continue."
-msgstr "Siirrytään vianetsintätilaan, kirjoita cont jatkaaksesi."
+msgstr "Siirrytään vianetsintätilaan, kirjoita cont jatkaaksesi."
-#: ../ex_cmds2.c:143 ../ex_docmd.c:759
-#, c-format
-msgid "line %<PRId64>: %s"
-msgstr "rivi %<PRId64>: %s"
+#, fuzzy, c-format
+#~ msgid "line %<PRId64>: %s"
+#~ msgstr "rivi %ld: %s"
-#: ../ex_cmds2.c:145
#, c-format
msgid "cmd: %s"
msgstr "kmnt: %s"
-#: ../ex_cmds2.c:322
+msgid "frame is zero"
+msgstr "kehys on nolla"
+
#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "Katkaisukohta %s%s rivillä %<PRId64>"
+msgid "frame at highest level: %d"
+msgstr "kehys ylimmällä tasolla: %d"
+
+#, fuzzy, c-format
+#~ msgid "Breakpoint in \"%s%s\" line %<PRId64>"
+#~ msgstr "Katkaisukohta %s%s rivillä %ld"
-#: ../ex_cmds2.c:581
#, c-format
msgid "E161: Breakpoint not found: %s"
msgstr "E161: Katkaisukohta puuttuu: %s"
-#: ../ex_cmds2.c:611
msgid "No breakpoints defined"
msgstr "Ei katkaisukohtia"
-#: ../ex_cmds2.c:617
-#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s rivi %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "%3d %s %s line %<PRId64>"
+#~ msgstr "%3d %s %s rivi %ld"
-#: ../ex_cmds2.c:942
msgid "E750: First use \":profile start {fname}\""
-msgstr "E750: Aloita käskyllä :profile start {fname}"
+msgstr "E750: Aloita käskyllä :profile start {fname}"
-#: ../ex_cmds2.c:1269
#, c-format
msgid "Save changes to \"%s\"?"
msgstr "Tallennetaanko muutokset tiedostoon %s?"
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
msgid "Untitled"
-msgstr "Nimetön"
+msgstr "Nimetön"
-#: ../ex_cmds2.c:1421
#, c-format
msgid "E162: No write since last change for buffer \"%s\""
-msgstr "E162: Muutoksia ei ole kirjoitettu puskurin %s viime muutoksen jälkeen"
+msgstr "E162: Muutoksia ei ole kirjoitettu puskurin %s viime muutoksen jälkeen"
-#: ../ex_cmds2.c:1480
msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
msgstr "Varoitus: Puskuri vaihtui odottamatta (tarkista autocommands)"
-#: ../ex_cmds2.c:1826
msgid "E163: There is only one file to edit"
msgstr "E163: Vain yksi tiedosto muokattavana"
-#: ../ex_cmds2.c:1828
msgid "E164: Cannot go before first file"
-msgstr "E164: Ensimmäisen tiedoston ohi ei voi mennä"
+msgstr "E164: Ensimmäisen tiedoston ohi ei voi mennä"
-#: ../ex_cmds2.c:1830
msgid "E165: Cannot go beyond last file"
-msgstr "E165: Viimeisen tiedoston ohi ei voi mennä"
+msgstr "E165: Viimeisen tiedoston ohi ei voi mennä"
-#: ../ex_cmds2.c:2175
#, c-format
msgid "E666: compiler not supported: %s"
-msgstr "E666: kääntäjää ei tueta: %s"
+msgstr "E666: kääntäjää ei tueta: %s"
-#: ../ex_cmds2.c:2257
#, c-format
msgid "Searching for \"%s\" in \"%s\""
-msgstr "Etsitään ilmausta %s kohteesta %s"
+msgstr "Etsitään ilmausta %s kohteesta %s"
-#: ../ex_cmds2.c:2284
#, c-format
msgid "Searching for \"%s\""
-msgstr "Etsitään ilmausta %s"
+msgstr "Etsitään ilmausta %s"
-#: ../ex_cmds2.c:2307
#, c-format
-msgid "not found in 'runtimepath': \"%s\""
-msgstr "ei löydy runtimepathista: %s"
+msgid "not found in '%s': \"%s\""
+msgstr "'%s' ei löydy kohteesta: %s"
-#: ../ex_cmds2.c:2472
#, c-format
msgid "Cannot source a directory: \"%s\""
msgstr "Hakemistoa ei voi ladata: %s"
-#: ../ex_cmds2.c:2518
#, c-format
msgid "could not source \"%s\""
msgstr "ei voitu ladata %s"
-#: ../ex_cmds2.c:2520
-#, c-format
-msgid "line %<PRId64>: could not source \"%s\""
-msgstr "rivi %<PRId64>: ei voitu ladata %s"
+#, fuzzy, c-format
+#~ msgid "line %<PRId64>: could not source \"%s\""
+#~ msgstr "rivi %ld: ei voitu ladata %s"
-#: ../ex_cmds2.c:2535
#, c-format
msgid "sourcing \"%s\""
msgstr "ladataan %s"
-#: ../ex_cmds2.c:2537
-#, c-format
-msgid "line %<PRId64>: sourcing \"%s\""
-msgstr "rivi %<PRId64>: ladataan %s"
+#, fuzzy, c-format
+#~ msgid "line %<PRId64>: sourcing \"%s\""
+#~ msgstr "rivi %ld: ladataan %s"
-#: ../ex_cmds2.c:2693
#, c-format
msgid "finished sourcing %s"
msgstr "ladattu %s"
-#: ../ex_cmds2.c:2765
msgid "modeline"
msgstr "mode-rivi"
-#: ../ex_cmds2.c:2767
msgid "--cmd argument"
msgstr "--cmd-argumentti"
-#: ../ex_cmds2.c:2769
msgid "-c argument"
msgstr "-c-argumentti"
-#: ../ex_cmds2.c:2771
msgid "environment variable"
-msgstr "ympäristömuuttuja"
+msgstr "ympäristömuuttuja"
-#: ../ex_cmds2.c:2773
msgid "error handler"
-msgstr "virhekäsittelin"
+msgstr "virhekäsittelin"
-#: ../ex_cmds2.c:3020
msgid "W15: Warning: Wrong line separator, ^M may be missing"
-msgstr "W15: Varoitus: Väärä rivierotin, ^M saattaa puuttua"
+msgstr "W15: Varoitus: Väärä rivierotin, ^M saattaa puuttua"
-#: ../ex_cmds2.c:3139
msgid "E167: :scriptencoding used outside of a sourced file"
msgstr "E167: :scriptencoding ladatun tiedoston ulkopuolella"
-#: ../ex_cmds2.c:3166
msgid "E168: :finish used outside of a sourced file"
msgstr "E168: :finish ladatun tiedoston ulkopuolella"
-#: ../ex_cmds2.c:3389
#, c-format
msgid "Current %slanguage: \"%s\""
-msgstr "Käytössä oleva %skieli: %s"
+msgstr "Käytössä oleva %skieli: %s"
-#: ../ex_cmds2.c:3404
#, c-format
msgid "E197: Cannot set language to \"%s\""
-msgstr "E197: Kieleksi ei voitu asettaa kieltä %s"
+msgstr "E197: Kieleksi ei voitu asettaa kieltä %s"
#. don't redisplay the window
#. don't wait for return
-#: ../ex_docmd.c:387
msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
-msgstr "Siirrytään Ex-tilaan, kirjoita visual palataksesi normaaliin tilaan."
+msgstr "Siirrytään Ex-tilaan, kirjoita visual palataksesi normaaliin tilaan."
-#: ../ex_docmd.c:428
msgid "E501: At end-of-file"
msgstr "E501: Tiedoston lopussa"
-#: ../ex_docmd.c:513
msgid "E169: Command too recursive"
msgstr "E169: Liian rekursiivinen komento"
-#: ../ex_docmd.c:1006
+#, fuzzy
+#~ msgid "line %"
+#~ msgstr "rivi %ld"
+
#, c-format
msgid "E605: Exception not caught: %s"
msgstr "E605: Kiinniottamaton poikkeus: %s"
-#: ../ex_docmd.c:1085
msgid "End of sourced file"
msgstr "Ladatun tiedoston loppu"
-#: ../ex_docmd.c:1086
msgid "End of function"
msgstr "Funktion loppu"
-#: ../ex_docmd.c:1628
msgid "E464: Ambiguous use of user-defined command"
-msgstr "E464: Käyttäjän määrittelemän komennon monimerkityksinen käyttö"
+msgstr "E464: Käyttäjän määrittelemän komennon monimerkityksinen käyttö"
-#: ../ex_docmd.c:1638
msgid "E492: Not an editor command"
msgstr "E492: Ei ole editorikomento"
-#: ../ex_docmd.c:1729
msgid "E493: Backwards range given"
msgstr "E493: Takaperoinen arvoalue annettu"
-#: ../ex_docmd.c:1733
msgid "Backwards range given, OK to swap"
-msgstr "Takaperoinen arvoalue annettu, OK kääntää"
+msgstr "Takaperoinen arvoalue annettu, OK kääntää"
#. append
#. typed wrong
-#: ../ex_docmd.c:1787
msgid "E494: Use w or w>>"
-msgstr "E494: Käytä w:tä tai w>>:aa"
-
-#: ../ex_docmd.c:3454
-msgid "E319: The command is not available in this version"
-msgstr "E319: Komento ei ole käytettävissä tässä versiossa"
+msgstr "E494: Käytä w:tä tai w>>:aa"
-#: ../ex_docmd.c:3752
-msgid "E172: Only one file name allowed"
-msgstr "E172: Vain yksi tiedostonimi sallitaan"
+#, fuzzy
+#~ msgid "E319: The command is not available in this version"
+#~ msgstr "E319: Komento ei ole käytettävissä tässä versiossa"
-#: ../ex_docmd.c:4238
msgid "1 more file to edit. Quit anyway?"
-msgstr "vielä 1 tiedosto muokattavana, lopetaanko silti?"
+msgstr "vielä 1 tiedosto muokattavana, lopetaanko silti?"
-#: ../ex_docmd.c:4242
#, c-format
msgid "%d more files to edit. Quit anyway?"
-msgstr "vielä %d tiedostoa muokattavana, lopetetaanko silti?"
+msgstr "vielä %d tiedostoa muokattavana, lopetetaanko silti?"
-#: ../ex_docmd.c:4248
msgid "E173: 1 more file to edit"
-msgstr "E173: vielä 1 tiedosto muokattavana"
+msgstr "E173: vielä 1 tiedosto muokattavana"
-#: ../ex_docmd.c:4250
-#, c-format
-msgid "E173: %<PRId64> more files to edit"
-msgstr "E173: vielä %<PRId64> tiedostoa muokattavana"
+#, fuzzy, c-format
+#~ msgid "E173: %<PRId64> more files to edit"
+#~ msgstr "E173: vielä %ld tiedostoa muokattavana"
-#: ../ex_docmd.c:4320
msgid "E174: Command already exists: add ! to replace it"
-msgstr "E174: Komento on jo olemassa, käytä !:ä korvataksesi"
+msgstr "E174: Komento on jo olemassa, käytä !:ä korvataksesi"
-#: ../ex_docmd.c:4432
msgid ""
"\n"
-" Name Args Range Complete Definition"
+" Name Args Address Complete Definition"
msgstr ""
"\n"
-" Nimi Arg Arvot Valmis Määritelmä"
+" Nimi Argumentit Osoite Valmis Määritelmä"
-#: ../ex_docmd.c:4516
msgid "No user-defined commands found"
-msgstr "Ei käyttäjän määrittelemiä komentoja"
+msgstr "Ei käyttäjän määrittelemiä komentoja"
-#: ../ex_docmd.c:4538
msgid "E175: No attribute specified"
-msgstr "E175: Ei attribuutteja määriteltynä"
+msgstr "E175: Ei attribuutteja määriteltynä"
-#: ../ex_docmd.c:4583
msgid "E176: Invalid number of arguments"
-msgstr "E176: Väärä määrä attribuutteja"
+msgstr "E176: Väärä määrä attribuutteja"
-#: ../ex_docmd.c:4594
msgid "E177: Count cannot be specified twice"
-msgstr "E177: Lukumäärää ei voi määritellä kahdesti"
+msgstr "E177: Lukumäärää ei voi määritellä kahdesti"
-#: ../ex_docmd.c:4603
msgid "E178: Invalid default value for count"
-msgstr "E178: Lukumäärän oletusarvo on väärä"
+msgstr "E178: Lukumäärän oletusarvo on väärä"
-#: ../ex_docmd.c:4625
msgid "E179: argument required for -complete"
msgstr "E179: -complete vaatii argumentin"
-#: ../ex_docmd.c:4635
+msgid "E179: argument required for -addr"
+msgstr "E179: -addr vaatii argumentin"
+
#, c-format
msgid "E181: Invalid attribute: %s"
msgstr "E181: Virheellinen attribuutti: %s"
-#: ../ex_docmd.c:4678
msgid "E182: Invalid command name"
msgstr "E182: Virheellinen komennon nimi"
-#: ../ex_docmd.c:4691
msgid "E183: User defined commands must start with an uppercase letter"
-msgstr "E183: Käyttäjän määrittelemän komennon pitää alkaa suuraakkosella"
+msgstr "E183: Käyttäjän määrittelemän komennon pitää alkaa suuraakkosella"
-#: ../ex_docmd.c:4696
-#, fuzzy
msgid "E841: Reserved name, cannot be used for user defined command"
-msgstr "E464: Käyttäjän määrittelemän komennon monimerkityksinen käyttö"
+msgstr "E841: Varattua nimeä ei voi käyttää käyttäjän määrittelemänä komentona"
-#: ../ex_docmd.c:4751
#, c-format
msgid "E184: No such user-defined command: %s"
-msgstr "E184: Käyttäjän komentoa ei ole olemassa: %s"
+msgstr "E184: Käyttäjän komentoa ei ole olemassa: %s"
+
+#, c-format
+msgid "E180: Invalid address type value: %s"
+msgstr "E180: Virheellinen osoitetyyppiarvo: %s"
-#: ../ex_docmd.c:5219
#, c-format
msgid "E180: Invalid complete value: %s"
-msgstr "E180: Virheellinen täydennysarvo: %s"
+msgstr "E180: Virheellinen täydennysarvo: %s"
-#: ../ex_docmd.c:5225
msgid "E468: Completion argument only allowed for custom completion"
-msgstr "E468: Täydennysargumentti sopii vain itse määriteltyyn täydennykseen"
+msgstr "E468: Täydennysargumentti sopii vain itse määriteltyyn täydennykseen"
-#: ../ex_docmd.c:5231
msgid "E467: Custom completion requires a function argument"
-msgstr "E467: Itse määritelty täydennys vaatii funktioargumentin"
+msgstr "E467: Itse määritelty täydennys vaatii funktioargumentin"
-#: ../ex_docmd.c:5257
-#, fuzzy, c-format
+#, c-format
msgid "E185: Cannot find color scheme '%s'"
-msgstr "E185: Väriteemaa %s ei löydy"
+msgstr "E185: Väriteemaa %s ei löydy"
-#: ../ex_docmd.c:5263
msgid "Greetings, Vim user!"
-msgstr "Tervehdys, Vimin käyttäjä."
+msgstr "Tervehdys, Vimin käyttäjä."
-#: ../ex_docmd.c:5431
msgid "E784: Cannot close last tab page"
-msgstr "E784: Viimeistä välilehteä ei voi sulkea"
+msgstr "E784: Viimeistä välilehteä ei voi sulkea"
-#: ../ex_docmd.c:5462
msgid "Already only one tab page"
-msgstr "Vain yksi välilehti jäljellä enää"
+msgstr "Vain yksi välilehti jäljellä enää"
-#: ../ex_docmd.c:6004
#, c-format
msgid "Tab page %d"
msgstr "Tabisivu %d"
-#: ../ex_docmd.c:6295
msgid "No swap file"
msgstr "Ei swap-tiedostoa"
-#: ../ex_docmd.c:6478
-msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
-msgstr ""
-"E747: Hakemistoa ei voida muuttaa, puskuria on muokattu (lisää komentoon ! "
-"ohittaaksesi"
-
-#: ../ex_docmd.c:6485
msgid "E186: No previous directory"
-msgstr "E186: Ei edellistä hakemistoa"
+msgstr "E186: Ei edellistä hakemistoa"
-#: ../ex_docmd.c:6530
msgid "E187: Unknown"
msgstr "E187: Tuntematon"
-#: ../ex_docmd.c:6610
msgid "E465: :winsize requires two number arguments"
msgstr "E465: :winsize vaatii kaksi numeroargumenttia"
-#: ../ex_docmd.c:6655
-msgid "E188: Obtaining window position not implemented for this platform"
-msgstr "E188: Ikkunan sijainnin selvitys ei toimi tällä alustalla"
-
-#: ../ex_docmd.c:6662
-msgid "E466: :winpos requires two number arguments"
-msgstr "E466: :winpos vaatii kaksi lukuargumenttia"
-
-#: ../ex_docmd.c:7241
-#, c-format
-msgid "E739: Cannot create directory: %s"
-msgstr "E739: hakemistoa ei voi luoda: %s"
-
-#: ../ex_docmd.c:7268
#, c-format
msgid "E189: \"%s\" exists (add ! to override)"
-msgstr "E189: %s on jo olemassa (lisää komentoon ! ohittaaksesi)"
+msgstr "E189: %s on jo olemassa (lisää komentoon ! ohittaaksesi)"
-#: ../ex_docmd.c:7273
#, c-format
msgid "E190: Cannot open \"%s\" for writing"
msgstr "E190: Tiedostoa %s ei voitu avata kirjoittamista varten"
#. set mark
-#: ../ex_docmd.c:7294
msgid "E191: Argument must be a letter or forward/backward quote"
-msgstr "E191: Argumentin eteen- tai taaksepäin lainaukseen pitää olla kirjain"
+msgstr "E191: Argumentin eteen- tai taaksepäin lainaukseen pitää olla kirjain"
-#: ../ex_docmd.c:7333
msgid "E192: Recursive use of :normal too deep"
-msgstr "E192: :normalin liian syvä rekursio"
+msgstr "E192: :normalin liian syvä rekursio"
-#: ../ex_docmd.c:7807
msgid "E194: No alternate file name to substitute for '#'"
-msgstr "E194: Ei vaihtoehtoista tiedostonimeä #:lle"
+msgstr "E194: Ei vaihtoehtoista tiedostonimeä #:lle"
-#: ../ex_docmd.c:7841
msgid "E495: no autocommand file name to substitute for \"<afile>\""
msgstr "E495: ei autocommand-tiedostoa kohteelle <afile>"
-#: ../ex_docmd.c:7850
msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
msgstr "E496: ei autocommand-puskurinumeroa kohteelle <abuf>"
-#: ../ex_docmd.c:7861
msgid "E497: no autocommand match name to substitute for \"<amatch>\""
-msgstr "E497: ei autocommand-täsmäysnimeä kohteella <amatch>"
+msgstr "E497: ei autocommand-täsmäysnimeä kohteella <amatch>"
-#: ../ex_docmd.c:7870
msgid "E498: no :source file name to substitute for \"<sfile>\""
-msgstr "E498: ei :source-tiedostonimeä kohteelle <sfile>"
+msgstr "E498: ei :source-tiedostonimeä kohteelle <sfile>"
-#: ../ex_docmd.c:7876
-#, fuzzy
msgid "E842: no line number to use for \"<slnum>\""
-msgstr "E498: ei :source-tiedostonimeä kohteelle <sfile>"
+msgstr "E842: ei rivinumeroa kohteelle <slnum>"
-#: ../ex_docmd.c:7903
#, fuzzy, c-format
-msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
-msgstr "E499: Tyhjä tiedostonimi kohteissa % tai # toimii vain :p:h"
+#~ msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+#~ msgstr "E499: Tyhjä tiedostonimi kohteissa % tai # toimii vain :p:h"
-#: ../ex_docmd.c:7905
msgid "E500: Evaluates to an empty string"
-msgstr "E500: Loppuarvo on tyhjä merkkijono"
-
-#: ../ex_docmd.c:8838
-msgid "E195: Cannot open viminfo file for reading"
-msgstr "E195: Viminfoa ei voi avata lukemista varten"
+msgstr "E500: Loppuarvo on tyhjä merkkijono"
-#: ../ex_eval.c:464
msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
-msgstr "E608: Vim-alkuisia poikkeuksia ei voi heittää :throw-komennolla"
+msgstr "E608: Vim-alkuisia poikkeuksia ei voi heittää :throw-komennolla"
#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
#, c-format
msgid "Exception thrown: %s"
msgstr "Poikkeus heitetty: %s"
-#: ../ex_eval.c:545
+#. always scroll up, don't overwrite
#, c-format
msgid "Exception finished: %s"
msgstr "Poikkeus lopeteltu: %s"
-#: ../ex_eval.c:546
#, c-format
msgid "Exception discarded: %s"
msgstr "Poikkeus poistettu: %s"
-#: ../ex_eval.c:588 ../ex_eval.c:634
-#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, rivi %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "%s, line %<PRId64>"
+#~ msgstr "%s, rivi %ld"
#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
#, c-format
msgid "Exception caught: %s"
msgstr "Poikkeus otettu kiinni: %s"
-#: ../ex_eval.c:676
#, c-format
msgid "%s made pending"
msgstr "%s odotutettu"
-#: ../ex_eval.c:679
#, c-format
msgid "%s resumed"
msgstr "%s palautettu"
-#: ../ex_eval.c:683
#, c-format
msgid "%s discarded"
msgstr "%s poistettu"
-#: ../ex_eval.c:708
msgid "Exception"
msgstr "Poikkeus"
-#: ../ex_eval.c:713
msgid "Error and interrupt"
msgstr "Virhe ja keskeytys"
-#: ../ex_eval.c:715
msgid "Error"
msgstr "Virhe"
#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
msgid "Interrupt"
msgstr "Keskeytys"
-#: ../ex_eval.c:795
msgid "E579: :if nesting too deep"
msgstr "E579: liian monta kerrosta :if-komennossa"
-#: ../ex_eval.c:830
msgid "E580: :endif without :if"
msgstr "E580: :endif ilman komentoa :if"
-#: ../ex_eval.c:873
msgid "E581: :else without :if"
msgstr "E581: :else ilman komentoa :if"
-#: ../ex_eval.c:876
msgid "E582: :elseif without :if"
msgstr "E582: :elseif ilman komentoa :if"
-#: ../ex_eval.c:880
msgid "E583: multiple :else"
msgstr "E583: :else monta kertaa"
-#: ../ex_eval.c:883
msgid "E584: :elseif after :else"
-msgstr "E584: :elseif komennon :else jälkeen"
+msgstr "E584: :elseif komennon :else jälkeen"
-#: ../ex_eval.c:941
msgid "E585: :while/:for nesting too deep"
msgstr "E585: liian monta tasoa :while- tai :for-komennoissa"
-#: ../ex_eval.c:1028
msgid "E586: :continue without :while or :for"
msgstr "E586: :continue ilman komentoa :while tai :for"
-#: ../ex_eval.c:1061
msgid "E587: :break without :while or :for"
msgstr "E587: :break ilman komentoa :while tai :for"
-#: ../ex_eval.c:1102
msgid "E732: Using :endfor with :while"
msgstr "E732: :endfor ilman komentoa :while"
-#: ../ex_eval.c:1104
msgid "E733: Using :endwhile with :for"
msgstr "E733: :endwhile ilman komentoa :for"
-#: ../ex_eval.c:1247
msgid "E601: :try nesting too deep"
msgstr "E601: liian monta tasoa :try-komennossa"
-#: ../ex_eval.c:1317
msgid "E603: :catch without :try"
msgstr "E603: :catch ilman komentoa :try"
#. Give up for a ":catch" after ":finally" and ignore it.
#. * Just parse.
-#: ../ex_eval.c:1332
msgid "E604: :catch after :finally"
msgstr "E604: :catch ilman komentoa :finally"
-#: ../ex_eval.c:1451
msgid "E606: :finally without :try"
msgstr "E606: :finally ilman komentoa :try"
#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
msgid "E607: multiple :finally"
msgstr "E607: :finally monta kertaa"
-#: ../ex_eval.c:1571
msgid "E602: :endtry without :try"
msgstr "E602: :endtry ilman komentoa :try"
-#: ../ex_eval.c:2026
msgid "E193: :endfunction not inside a function"
msgstr "E193: :endfunction funktion ulkopuolella"
-#: ../ex_getln.c:1643
msgid "E788: Not allowed to edit another buffer now"
msgstr "E788: Puskuria ei voi muokata nyt"
-#: ../ex_getln.c:1656
msgid "E811: Not allowed to change buffer information now"
msgstr "E811: Puskuria ei voi vaihtaa nyt"
-#: ../ex_getln.c:3178
msgid "tagname"
-msgstr "täginimi"
+msgstr "täginimi"
-#: ../ex_getln.c:3181
msgid " kind file\n"
msgstr " -tiedostotyyppi\n"
-#: ../ex_getln.c:4799
msgid "'history' option is zero"
msgstr "history-asetus on nolla"
-#: ../ex_getln.c:5046
-#, c-format
-msgid ""
-"\n"
-"# %s History (newest to oldest):\n"
-msgstr ""
-"\n"
-"# %s Historia (uusimmasta alkaen):\n"
-
-#: ../ex_getln.c:5047
-msgid "Command Line"
-msgstr "Komentorivi"
-
-#: ../ex_getln.c:5048
-msgid "Search String"
-msgstr "Hakujono"
-
-#: ../ex_getln.c:5049
-msgid "Expression"
-msgstr "Ilmaus"
-
-#: ../ex_getln.c:5050
-msgid "Input Line"
-msgstr "Syöterivi"
-
-#: ../ex_getln.c:5117
msgid "E198: cmd_pchar beyond the command length"
msgstr "E198: cmd_pchar komennon pituuden ulkopuolella"
-#: ../ex_getln.c:5279
msgid "E199: Active window or buffer deleted"
msgstr "E199: Aktiivinen ikkuna tai puskuri poistettu"
-#: ../file_search.c:203
msgid "E854: path too long for completion"
-msgstr ""
+msgstr "E854: polku on liian pitkä täydennykseen"
-#: ../file_search.c:446
#, c-format
msgid ""
"E343: Invalid path: '**[number]' must be at the end of the path or be "
@@ -2011,376 +2098,296 @@ msgstr ""
"E343: Virheellinen polku: '**[numero]' kuuluu polun loppuun tai ennen kohtaa "
"%s."
-#: ../file_search.c:1505
#, c-format
msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: Hakemistoa %s ei löydy cdpathista"
+msgstr "E344: Hakemistoa %s ei löydy cdpathista"
-#: ../file_search.c:1508
#, c-format
msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: Tiedostoa %s ei löydy polulta"
+msgstr "E345: Tiedostoa %s ei löydy polulta"
-#: ../file_search.c:1512
#, c-format
msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: Hakemisto %s ei ole enää cdpathissa"
+msgstr "E346: Hakemisto %s ei ole enää cdpathissa"
-#: ../file_search.c:1515
#, c-format
msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: Tiedosto %s ei ole enää polulla"
+msgstr "E347: Tiedosto %s ei ole enää polulla"
-#: ../fileio.c:137
msgid "E812: Autocommands changed buffer or buffer name"
msgstr "E812: Autocommands muutti puskurin tai sen nimen"
-#: ../fileio.c:368
msgid "Illegal file name"
msgstr "Virheellinen tiedostonimi"
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
msgid "is a directory"
msgstr "on hakemisto"
-#: ../fileio.c:397
msgid "is not a file"
msgstr "ei ole tiedosto"
-#: ../fileio.c:508 ../fileio.c:3522
msgid "[New File]"
msgstr "[Uusi tiedosto]"
-#: ../fileio.c:511
msgid "[New DIRECTORY]"
msgstr "[uusi HAKEMISTO]"
-#: ../fileio.c:529 ../fileio.c:532
+#. libuv only returns -errno in Unix and in Windows open() does not
+#. set EOVERFLOW
msgid "[File too big]"
msgstr "[Liian iso tiedosto]"
-#: ../fileio.c:534
msgid "[Permission Denied]"
msgstr "[Lupa kielletty]"
-#: ../fileio.c:653
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr ""
-"E200: *ReadPre-autocommand-komennot tekivät tiedostosta lukukelvottoman"
+"E200: *ReadPre-autocommand-komennot tekivät tiedostosta lukukelvottoman"
-#: ../fileio.c:655
msgid "E201: *ReadPre autocommands must not change current buffer"
-msgstr "E201: *ReadPre-autocommand-komennot eivät saa muuttaa puskuria"
-
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
-msgstr "Vim: Luetaan vakiosyötteestä...\n"
+msgstr "E201: *ReadPre-autocommand-komennot eivät saa muuttaa puskuria"
#. Re-opening the original file failed!
-#: ../fileio.c:909
msgid "E202: Conversion made file unreadable!"
msgstr "E202: Muunnos teki tiedostosta lukukelvottoman."
#. fifo or socket
-#: ../fileio.c:1782
msgid "[fifo/socket]"
msgstr "[fifo t. soketti]"
#. fifo
-#: ../fileio.c:1788
msgid "[fifo]"
msgstr "[fifo]"
#. or socket
-#: ../fileio.c:1794
msgid "[socket]"
msgstr "[soketti]"
#. or character special
-#: ../fileio.c:1801
msgid "[character special]"
msgstr "[merkki erikoinen]"
-# Carriage Return elikkä rivinvaihtomerkin eräs muoto/osa (vrt. LF)
-#: ../fileio.c:1815
+# Carriage Return elikkä rivinvaihtomerkin eräs muoto/osa (vrt. LF)
msgid "[CR missing]"
msgstr "[CR puuttuu]"
-#: ../fileio.c:1819
msgid "[long lines split]"
-msgstr "[pitkät rivit hajotettu]"
+msgstr "[pitkät rivit hajotettu]"
-#: ../fileio.c:1823 ../fileio.c:3512
msgid "[NOT converted]"
msgstr "[EI muunnettu]"
-#: ../fileio.c:1826 ../fileio.c:3515
msgid "[converted]"
msgstr "[muunnettu]"
-#: ../fileio.c:1831
-#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[MUUNNOSVIRHE rivillä %<PRId64>]"
+#, fuzzy, c-format
+#~ msgid "[CONVERSION ERROR in line %<PRId64>]"
+#~ msgstr "[MUUNNOSVIRHE rivillä %ld]"
-#: ../fileio.c:1835
-#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[VIRHEELLINEN OKTETTI rivillä %<PRId64>]"
+#, fuzzy, c-format
+#~ msgid "[ILLEGAL BYTE in line %<PRId64>]"
+#~ msgstr "[VIRHEELLINEN OKTETTI rivillä %ld]"
-#: ../fileio.c:1838
msgid "[READ ERRORS]"
-msgstr "[LUKUVIRHEITÄ]"
+msgstr "[LUKUVIRHEITÄ]"
-#: ../fileio.c:2104
msgid "Can't find temp file for conversion"
-msgstr "Ei voi löytää väliaikaistiedstoa muuntamiseksi"
+msgstr "Ei voi löytää väliaikaistiedstoa muuntamiseksi"
-#: ../fileio.c:2110
msgid "Conversion with 'charconvert' failed"
-msgstr "Muunnos charconvert epäonnistui"
+msgstr "Muunnos charconvert epäonnistui"
-#: ../fileio.c:2113
msgid "can't read output of 'charconvert'"
msgstr "charconvertin tulostetta ei voida lukea"
-#: ../fileio.c:2437
msgid "E676: No matching autocommands for acwrite buffer"
msgstr "E676: Ei autocommand-komentoa acwrite-puskurille"
-#: ../fileio.c:2466
msgid "E203: Autocommands deleted or unloaded buffer to be written"
msgstr ""
"E203: Autocommand-komennot poistivat tai vapauttivat puskurin, johon piti "
"kirjoittaa"
-#: ../fileio.c:2486
msgid "E204: Autocommand changed number of lines in unexpected way"
-msgstr "E204: Autocommand-komento muutti rivien määrä odottamatta"
+msgstr "E204: Autocommand-komento muutti rivien määrä odottamatta"
-#: ../fileio.c:2548 ../fileio.c:2565
msgid "is not a file or writable device"
msgstr "ei ole tiedosto tai kirjoitettava laite"
-#: ../fileio.c:2601
msgid "is read-only (add ! to override)"
-msgstr "on kirjoitussuojattu (lisää komentoon ! ohittaaksesi)"
+msgstr "on kirjoitussuojattu (lisää komentoon ! ohittaaksesi)"
-#: ../fileio.c:2886
msgid "E506: Can't write to backup file (add ! to override)"
msgstr ""
-"E506: Ei voi kirjoittaa varmuuskopiotiedostoon (lisää komentoon ! "
+"E506: Ei voi kirjoittaa varmuuskopiotiedostoon (lisää komentoon ! "
"ohittaaksesi)"
-#: ../fileio.c:2898
-msgid "E507: Close error for backup file (add ! to override)"
-msgstr ""
-"E507: Varmuuskopiotiedoston sulkeminen ei onnistu (lisää komentoon ! "
-"ohittaaksesi)"
+#, fuzzy, c-format
+#~ msgid "E507: Close error for backup file (add ! to override): %s"
+#~ msgstr ""
+#~ "E507: Varmuuskopiotiedoston sulkeminen ei onnistu (lisää komentoon ! "
+#~ "ohittaaksesi)"
-#: ../fileio.c:2901
msgid "E508: Can't read file for backup (add ! to override)"
msgstr ""
-"E508: Varmuuskopiotiedostoa ei voi lukea (lisää komentoon ! ohittaaksesi)"
+"E508: Varmuuskopiotiedostoa ei voi lukea (lisää komentoon ! ohittaaksesi)"
-#: ../fileio.c:2923
msgid "E509: Cannot create backup file (add ! to override)"
msgstr ""
-"E509: Ei voi luoda varmuuskopiotiedostoa (lisää komentoon ! ohittaaksesi)"
+"E509: Ei voi luoda varmuuskopiotiedostoa (lisää komentoon ! ohittaaksesi)"
-#: ../fileio.c:3008
msgid "E510: Can't make backup file (add ! to override)"
msgstr ""
-"E510: Ei voi tehdä varmuuskopiotiedostoa (lisää komentoon ! ohittaaksesi)"
+"E510: Ei voi tehdä varmuuskopiotiedostoa (lisää komentoon ! ohittaaksesi)"
#. Can't write without a tempfile!
-#: ../fileio.c:3121
msgid "E214: Can't find temp file for writing"
-msgstr "E214: Ei voi löytää väliaikaistiedostoa kirjoitettavaksi"
+msgstr "E214: Ei voi löytää väliaikaistiedostoa kirjoitettavaksi"
-#: ../fileio.c:3134
msgid "E213: Cannot convert (add ! to write without conversion)"
msgstr ""
-"E213: Muunnos ei onnistu (lisää komentoon ! kirjoittaaksesi muuntamatta)"
+"E213: Muunnos ei onnistu (lisää komentoon ! kirjoittaaksesi muuntamatta)"
-#: ../fileio.c:3169
msgid "E166: Can't open linked file for writing"
msgstr "E166: Linkitetyn tiedoston avaus kirjoittamista varten ei onnistu"
-#: ../fileio.c:3173
-msgid "E212: Can't open file for writing"
-msgstr "E212: Tiedoston avaus kirjoittamista varten ei onnistu"
+#, fuzzy, c-format
+#~ msgid "E212: Can't open file for writing: %s"
+#~ msgstr "E212: Tiedoston avaus kirjoittamista varten ei onnistu"
-#: ../fileio.c:3363
-msgid "E667: Fsync failed"
-msgstr "E667: Fsync ei onnistunut"
+#, fuzzy, c-format
+#~ msgid "E667: Fsync failed: %s"
+#~ msgstr "E667: Fsync ei onnistunut"
-#: ../fileio.c:3398
-msgid "E512: Close failed"
-msgstr "E512: Sulkeminen ei onnistunut"
+#, fuzzy, c-format
+#~ msgid "E512: Close failed: %s"
+#~ msgstr "E512: Sulkeminen ei onnistunut"
-#: ../fileio.c:3436
msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
-msgstr "E513: kirjoitusvirhe, muunnos epäonnistui (tyhjää fenc ohittaaksesi)"
+msgstr "E513: kirjoitusvirhe, muunnos epäonnistui (tyhjää fenc ohittaaksesi)"
-#: ../fileio.c:3441
-#, c-format
-msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
-"override)"
-msgstr ""
-"E513: kirjoitusvirhe, muunnos epäonnistui rivillä %<PRId64>(tyhjää fenc "
-"ohittaaksesi)"
+#, fuzzy
+#~ msgid "E513: write error, conversion failed in line %"
+#~ msgstr ""
+#~ "E513: kirjoitusvirhe, muunnos epäonnistui rivillä %ld(tyhjää fenc "
+#~ "ohittaaksesi)"
-#: ../fileio.c:3448
msgid "E514: write error (file system full?)"
-msgstr "E514: kirjoitusvirhe (tiedostojärjestelmä täysi)"
+msgstr "E514: kirjoitusvirhe (tiedostojärjestelmä täysi)"
-#: ../fileio.c:3506
msgid " CONVERSION ERROR"
msgstr " MUUNNOSVIRHE"
-#: ../fileio.c:3509
-#, c-format
-msgid " in line %<PRId64>;"
-msgstr " rivillä %<PRId64>"
+#, fuzzy, c-format
+#~ msgid " in line %<PRId64>;"
+#~ msgstr " rivillä %ld"
-#: ../fileio.c:3519
msgid "[Device]"
msgstr "[Laite]"
-#: ../fileio.c:3522
msgid "[New]"
msgstr "[Uusi]"
-#: ../fileio.c:3535
msgid " [a]"
msgstr " [a]"
-#: ../fileio.c:3535
msgid " appended"
-msgstr " lisätty"
+msgstr " lisätty"
-#: ../fileio.c:3537
msgid " [w]"
msgstr " [w]"
-#: ../fileio.c:3537
msgid " written"
msgstr " kirjoitettu"
-#: ../fileio.c:3579
msgid "E205: Patchmode: can't save original file"
-msgstr "E205: Patch-tilassa ei voi tallentaa alkuperäistiedostoa"
+msgstr "E205: Patch-tilassa ei voi tallentaa alkuperäistiedostoa"
-#: ../fileio.c:3602
msgid "E206: patchmode: can't touch empty original file"
-msgstr "E206: patch-tilassa ei voi muuttaa tyhjää alkuperäistiedostoa"
+msgstr "E206: patch-tilassa ei voi muuttaa tyhjää alkuperäistiedostoa"
-#: ../fileio.c:3616
msgid "E207: Can't delete backup file"
msgstr "E207: Ei voi poistaa varmuuskopiota"
-#: ../fileio.c:3672
+#. Set highlight for error messages.
msgid ""
"\n"
"WARNING: Original file may be lost or damaged\n"
msgstr ""
"\n"
-"VAROITUS: Alkuperäistiedosto voi hävitä tai vahingoittua\n"
+"VAROITUS: Alkuperäistiedosto voi hävitä tai vahingoittua\n"
-#: ../fileio.c:3675
msgid "don't quit the editor until the file is successfully written!"
-msgstr "älä lopeta editoria kesken tallentamisen."
+msgstr "älä lopeta editoria kesken tallentamisen."
-#: ../fileio.c:3795
-msgid "[dos]"
-msgstr "[dos]"
-
-#: ../fileio.c:3795
msgid "[dos format]"
msgstr "[dos-muoto]"
-#: ../fileio.c:3801
-msgid "[mac]"
-msgstr "[mac]"
+msgid "[dos]"
+msgstr "[dos]"
-#: ../fileio.c:3801
msgid "[mac format]"
msgstr "[mac-muoto]"
-#: ../fileio.c:3807
-msgid "[unix]"
-msgstr "[unix]"
+msgid "[mac]"
+msgstr "[mac]"
-#: ../fileio.c:3807
msgid "[unix format]"
msgstr "[unix-muoto]"
-#: ../fileio.c:3831
+msgid "[unix]"
+msgstr "[unix]"
+
msgid "1 line, "
msgstr "1 rivi, "
-#: ../fileio.c:3833
-#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> riviä, "
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines, "
+#~ msgstr "%ld riviä, "
-#: ../fileio.c:3836
msgid "1 character"
msgstr "1 merkki"
-#: ../fileio.c:3838
-#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> merkkiä"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> characters"
+#~ msgstr "%lld merkkiä"
+
+msgid "[Incomplete last line]"
+msgstr "[Vajaa viimeinen rivi]"
# ei rivinvaihtoja
-#: ../fileio.c:3849
msgid "[noeol]"
msgstr "[eiriviv.]"
-#: ../fileio.c:3849
-msgid "[Incomplete last line]"
-msgstr "[Vajaa viimeinen rivi]"
-
-# Jos aukiolevaa tiedostoa sörkkii toisella ohjelmalla
-#. don't overwrite messages here
-#. must give this prompt
-#. don't use emsg() here, don't want to flush the buffers
-#: ../fileio.c:3865
+# Jos aukiolevaa tiedostoa sörkkii toisella ohjelmalla
+#. Don't overwrite messages here.
+#. Must give this prompt.
+#. Don't use emsg() here, don't want to flush the buffers.
msgid "WARNING: The file has been changed since reading it!!!"
-msgstr "VAROITUS: tiedosto on muuttunut viime lukukerran jälkeen!"
+msgstr "VAROITUS: tiedosto on muuttunut viime lukukerran jälkeen!"
-#: ../fileio.c:3867
msgid "Do you really want to write to it"
msgstr "Kirjoitetaanko"
-#: ../fileio.c:4648
#, c-format
msgid "E208: Error writing to \"%s\""
msgstr "E208: Virhe kirjoitettaessa tiedostoon %s"
-#: ../fileio.c:4655
#, c-format
msgid "E209: Error closing \"%s\""
msgstr "E209: Virhe suljettaessa tiedostoa %s"
-#: ../fileio.c:4657
#, c-format
msgid "E210: Error reading \"%s\""
msgstr "E210: Virhe luettaessa tiedostoa %s"
-#: ../fileio.c:4883
msgid "E246: FileChangedShell autocommand deleted buffer"
msgstr "E246: FileChangedShell-autocommand poisti puskurin"
-#: ../fileio.c:4894
#, c-format
msgid "E211: File \"%s\" no longer available"
-msgstr "E211: Tiedostoa %s ei ole enää"
+msgstr "E211: Tiedostoa %s ei ole enää"
-#: ../fileio.c:4906
#, c-format
msgid ""
"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
@@ -2389,41 +2396,33 @@ msgstr ""
"W12: Varoitus: Tiedostoa %s on muutettu ja Vimin puskurissa on muutoksia "
"tiedostoon"
-#: ../fileio.c:4907
msgid "See \":help W12\" for more info."
-msgstr ":help W12 kertoo lisätietoja."
+msgstr ":help W12 kertoo lisätietoja."
-#: ../fileio.c:4910
#, c-format
msgid "W11: Warning: File \"%s\" has changed since editing started"
-msgstr "W11: Varoitus: Tiedostoa %s on muutettu muokkauksen aloituksen jälkeen"
+msgstr "W11: Varoitus: Tiedostoa %s on muutettu muokkauksen aloituksen jälkeen"
-#: ../fileio.c:4911
msgid "See \":help W11\" for more info."
-msgstr ":help W11 kertoo lisätietoja."
+msgstr ":help W11 kertoo lisätietoja."
-#: ../fileio.c:4914
#, c-format
msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
msgstr ""
"W16: Varoitus: Tiedoston %s oikeuksia on muutettu muokkauksen aloituksen "
-"jälkeen"
+"jälkeen"
-#: ../fileio.c:4915
msgid "See \":help W16\" for more info."
-msgstr ":help W16 kertoo lisätietoja."
+msgstr ":help W16 kertoo lisätietoja."
-#: ../fileio.c:4927
#, c-format
msgid "W13: Warning: File \"%s\" has been created after editing started"
-msgstr "W13: Varoitus: Tiedosto %s on luotu muokkauksen aloituksen jälkeen"
+msgstr "W13: Varoitus: Tiedosto %s on luotu muokkauksen aloituksen jälkeen"
-#: ../fileio.c:4947
msgid "Warning"
msgstr "Varoitus"
-# yllä olevien varoitusten ratkaisut
-#: ../fileio.c:4948
+# yllä olevien varoitusten ratkaisut
msgid ""
"&OK\n"
"&Load File"
@@ -2431,48 +2430,46 @@ msgstr ""
"&OK\n"
"&Avaa tiedosto uudelleen"
-#: ../fileio.c:5065
#, c-format
msgid "E462: Could not prepare for reloading \"%s\""
msgstr "E462: Ei voitu valmistella uudelleen avausta %s"
-#: ../fileio.c:5078
#, c-format
msgid "E321: Could not reload \"%s\""
msgstr "E321: Ei voitu uudelleenavata %s"
-#: ../fileio.c:5601
msgid "--Deleted--"
msgstr "--Poistettu--"
-#: ../fileio.c:5732
#, c-format
msgid "auto-removing autocommand: %s <buffer=%d>"
msgstr "poistetaan autocommand automaattisesti: %s <puskuri=%d>"
#. the group doesn't exist
-#: ../fileio.c:5772
#, c-format
msgid "E367: No such group: \"%s\""
-msgstr "E367: Ryhmää ei ole: %s"
+msgstr "E367: Ryhmää ei ole: %s"
+
+#, fuzzy
+#~ msgid "E936: Cannot delete the current group"
+#~ msgstr "E351: Taitosta ei voi poistaa tällä foldmethodilla"
+
+msgid "W19: Deleting augroup that is still in use"
+msgstr "W19: käytössä oleva augroup poistetaan"
-#: ../fileio.c:5897
#, c-format
msgid "E215: Illegal character after *: %s"
-msgstr "E215: Virheellinen merkki *:n jälkeen: %s"
+msgstr "E215: Virheellinen merkki *:n jälkeen: %s"
-#: ../fileio.c:5905
#, c-format
msgid "E216: No such event: %s"
-msgstr "E216: Eventtiä ei ole: %s"
+msgstr "E216: Eventtiä ei ole: %s"
-#: ../fileio.c:5907
#, c-format
msgid "E216: No such group or event: %s"
-msgstr "E216: Ryhmää tai eventtiä ei ole: %s"
+msgstr "E216: Ryhmää tai eventtiä ei ole: %s"
#. Highlight title
-#: ../fileio.c:6090
msgid ""
"\n"
"--- Auto-Commands ---"
@@ -2480,762 +2477,611 @@ msgstr ""
"\n"
"--- Autocommandit ---"
-#: ../fileio.c:6293
#, c-format
msgid "E680: <buffer=%d>: invalid buffer number "
msgstr "E680: <puskuri=%d>: virheellinen puskurinumero"
-#: ../fileio.c:6370
msgid "E217: Can't execute autocommands for ALL events"
msgstr "E217: Ei voi suorittaa autocommandsia kaikille eventeille"
-#: ../fileio.c:6393
msgid "No matching autocommands"
-msgstr "Ei täsmääviä autocommandsia"
+msgstr "Ei täsmääviä autocommandsia"
-#: ../fileio.c:6831
msgid "E218: autocommand nesting too deep"
msgstr "E218: liian monta tasoa autocommandissa"
-#: ../fileio.c:7143
#, c-format
msgid "%s Auto commands for \"%s\""
msgstr "%s Autocommands kohteelle %s"
-#: ../fileio.c:7149
#, c-format
msgid "Executing %s"
msgstr "Suoritetaan %s"
-#: ../fileio.c:7211
#, c-format
msgid "autocommand %s"
msgstr "autocommand %s"
-#: ../fileio.c:7795
msgid "E219: Missing {."
msgstr "E219: { puuttuu."
-#: ../fileio.c:7797
msgid "E220: Missing }."
msgstr "E220: } puuttuu."
-#: ../fold.c:93
msgid "E490: No fold found"
msgstr "E490: taitos puuttuu"
-#: ../fold.c:544
msgid "E350: Cannot create fold with current 'foldmethod'"
-msgstr "E350: Taitoksia ei voi tehdä tällä foldmethodilla"
+msgstr "E350: Taitoksia ei voi tehdä tällä foldmethodilla"
-#: ../fold.c:546
msgid "E351: Cannot delete fold with current 'foldmethod'"
-msgstr "E351: Taitosta ei voi poistaa tällä foldmethodilla"
+msgstr "E351: Taitosta ei voi poistaa tällä foldmethodilla"
-#: ../fold.c:1784
-#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld riviä taitettu pois "
+#, fuzzy, c-format
+#~ msgid "+--%3ld lines folded "
+#~ msgstr "+--%3ld rivi taitettu pois "
#. buffer has already been read
-#: ../getchar.c:273
msgid "E222: Add to read buffer"
-msgstr "E222: Lisää lukupuskuriin"
+msgstr "E222: Lisää lukupuskuriin"
-#: ../getchar.c:2040
msgid "E223: recursive mapping"
msgstr "E223: rekursiivinen kuvaus"
-#: ../getchar.c:2849
#, c-format
msgid "E224: global abbreviation already exists for %s"
-msgstr "E224: globaali lyhenne merkinnälle %s on jo olemassa"
+msgstr "E224: globaali lyhenne merkinnälle %s on jo olemassa"
-#: ../getchar.c:2852
#, c-format
msgid "E225: global mapping already exists for %s"
-msgstr "E225: globaali kuvaus merkinnälle %s on jo olemassa"
+msgstr "E225: globaali kuvaus merkinnälle %s on jo olemassa"
-#: ../getchar.c:2952
#, c-format
msgid "E226: abbreviation already exists for %s"
msgstr "E226: lyhenne on jo olemassa %s"
-#: ../getchar.c:2955
#, c-format
msgid "E227: mapping already exists for %s"
msgstr "E227: kuvaus on jo olemassa %s"
-#: ../getchar.c:3008
msgid "No abbreviation found"
-msgstr "Lyhennettä ei löydy"
+msgstr "Lyhennettä ei löydy"
-#: ../getchar.c:3010
msgid "No mapping found"
-msgstr "Kuvausta ei löydy"
+msgstr "Kuvausta ei löydy"
-#: ../getchar.c:3974
msgid "E228: makemap: Illegal mode"
msgstr "E228: makemap: Virheellinen tila"
#. key value of 'cedit' option
#. type of cmdline window or 0
#. result of cmdline window or 0
-#: ../globals.h:924
msgid "--No lines in buffer--"
-msgstr "--Ei rivejä puskurissa--"
+msgstr "--Ei rivejä puskurissa--"
#.
#. * The error messages that can be shared are included here.
#. * Excluded are errors that are only used once and debugging messages.
#.
-#: ../globals.h:996
msgid "E470: Command aborted"
msgstr "E470: Komento peruttu"
-#: ../globals.h:997
+#, fuzzy
+#~ msgid "E905: Cannot set this option after startup"
+#~ msgstr "E529: Termiä ei voi asettaa tyhjäksi merkkijonoksi"
+
+#, fuzzy
+#~ msgid "E903: Could not spawn API job"
+#~ msgstr "E623: Cscope-prosessin luonti epäonnistui"
+
msgid "E471: Argument required"
msgstr "E471: Argumentti puuttuu"
-#: ../globals.h:998
msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: \\:n jälkeen pitää tulla /, ? tai &"
+msgstr "E10: \\:n jälkeen pitää tulla /, ? tai &"
-#: ../globals.h:1000
msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
msgstr "E11: Virheellinen komentorivi-ikkuna, <CR> suorittaa, Ctrl C lopettaa"
-#: ../globals.h:1002
msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
msgstr ""
-"E12: Komentoa ei tueta exrc:ssä tai vimrc:ssä tässä hakemistossa tai "
-"tägihaussa"
+"E12: Komentoa ei tueta exrc:ssä tai vimrc:ssä tässä hakemistossa tai "
+"tägihaussa"
-#: ../globals.h:1003
msgid "E171: Missing :endif"
msgstr "E171: :endif puuttuu"
-#: ../globals.h:1004
msgid "E600: Missing :endtry"
msgstr "E600: :endtry puuttuu"
-#: ../globals.h:1005
msgid "E170: Missing :endwhile"
msgstr "E170: :endwhile puuttuu"
-#: ../globals.h:1006
msgid "E170: Missing :endfor"
msgstr "E170: :endfor puuttuu"
-#: ../globals.h:1007
msgid "E588: :endwhile without :while"
msgstr "E588: :endwhile ilman komentoa :while"
-#: ../globals.h:1008
msgid "E588: :endfor without :for"
msgstr "E588: :endfor ilman komentoa :for"
-#: ../globals.h:1009
msgid "E13: File exists (add ! to override)"
-msgstr "E13: Tiedosto on jo olemassa (lisää ! ohittaaksesi)"
+msgstr "E13: Tiedosto on jo olemassa (lisää ! ohittaaksesi)"
-#: ../globals.h:1010
msgid "E472: Command failed"
-msgstr "E472: Komento epäonnistui"
+msgstr "E472: Komento epäonnistui"
-#: ../globals.h:1011
msgid "E473: Internal error"
-msgstr "E473: Sisäinen virhe"
+msgstr "E473: Sisäinen virhe"
-#: ../globals.h:1012
msgid "Interrupted"
msgstr "Keskeytetty"
-#: ../globals.h:1013
msgid "E14: Invalid address"
msgstr "E14: Virheellinen osoite"
-#: ../globals.h:1014
msgid "E474: Invalid argument"
msgstr "E474: Virheellinen argumentti"
-#: ../globals.h:1015
#, c-format
msgid "E475: Invalid argument: %s"
msgstr "E475: Virheellinen argumentti: %s"
-#: ../globals.h:1016
#, c-format
msgid "E15: Invalid expression: %s"
msgstr "E15: Virheellinen ilmaus: %s"
-#: ../globals.h:1017
msgid "E16: Invalid range"
msgstr "E16: Virheellinen arvoalue"
-#: ../globals.h:1018
msgid "E476: Invalid command"
msgstr "E476: Virheellinen komento"
-#: ../globals.h:1019
#, c-format
msgid "E17: \"%s\" is a directory"
msgstr "E17: %s on hakemisto"
-#: ../globals.h:1020
#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: Virheellinen vierityskoko"
+#~ msgid "E900: Invalid job id"
+#~ msgstr "E916: ei ole job"
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
+#~ msgid "E901: Job table is full"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E903: Process failed to start: %s: \"%s\""
+#~ msgstr "E852: Lapsiprosesi ei voinut käynnistää käyttöliittymää"
+
+#, fuzzy
+#~ msgid "E904: Job is not connected to a pty"
+#~ msgstr "E902: Ei voi yhdistää porttiin"
-#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: Kirjastukutsu %s() epäonnistui"
+msgstr "E364: Kirjastukutsu %s() epäonnistui"
+
+#, fuzzy, c-format
+#~ msgid "E739: Cannot create directory %s: %s"
+#~ msgstr "E739: hakemistoa ei voi luoda: %s"
-#: ../globals.h:1026
msgid "E19: Mark has invalid line number"
-msgstr "E19: Merkillä on virheellinen rivinumero"
+msgstr "E19: Merkillä on virheellinen rivinumero"
-#: ../globals.h:1027
msgid "E20: Mark not set"
-msgstr "E20: Merkkiä ei asetettu"
+msgstr "E20: Merkkiä ei asetettu"
-#: ../globals.h:1029
msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: Ei voi tehdä muutoksia, modifiable on pois päältä"
+msgstr "E21: Ei voi tehdä muutoksia, modifiable on pois päältä"
-#: ../globals.h:1030
msgid "E22: Scripts nested too deep"
-msgstr "E22: Liian monta tasoa skripteissä"
+msgstr "E22: Liian monta tasoa skripteissä"
-#: ../globals.h:1031
msgid "E23: No alternate file"
msgstr "E23: Eo vaihtoehtoista tiedostoa"
-#: ../globals.h:1032
msgid "E24: No such abbreviation"
-msgstr "E24: Lyhennettä ei ole"
+msgstr "E24: Lyhennettä ei ole"
-#: ../globals.h:1033
msgid "E477: No ! allowed"
msgstr "E477: ! ei sallittu"
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: GUIta ei voi käyttää, koska sitä ei käännetty mukaan"
+#~ msgid "E25: Nvim does not have a built-in GUI"
+#~ msgstr ""
-#: ../globals.h:1036
#, c-format
msgid "E28: No such highlight group name: %s"
-msgstr "E28: Korostusryhmää ei ole nimellä: %s"
+msgstr "E28: Korostusryhmää ei ole nimellä: %s"
-#: ../globals.h:1037
msgid "E29: No inserted text yet"
-msgstr "E29: Tekstiä ei ole syötetty vielä"
+msgstr "E29: Tekstiä ei ole syötetty vielä"
-#: ../globals.h:1038
msgid "E30: No previous command line"
-msgstr "E30: Ei edellistä komentoriviä"
+msgstr "E30: Ei edellistä komentoriviä"
-#: ../globals.h:1039
msgid "E31: No such mapping"
msgstr "E31: Kuvausta ei ole"
-#: ../globals.h:1040
msgid "E479: No match"
-msgstr "E479: Ei täsmää"
+msgstr "E479: Ei täsmää"
-#: ../globals.h:1041
#, c-format
msgid "E480: No match: %s"
-msgstr "E480: Ei tsämää: %s"
+msgstr "E480: Ei tsämää: %s"
-#: ../globals.h:1042
msgid "E32: No file name"
-msgstr "E32: Ei tiedostonimeä"
+msgstr "E32: Ei tiedostonimeä"
-#: ../globals.h:1044
msgid "E33: No previous substitute regular expression"
-msgstr "E33: Ei edellistä korvausta säännölliselle ilmaukselle"
+msgstr "E33: Ei edellistä korvausta säännölliselle ilmaukselle"
-#: ../globals.h:1045
msgid "E34: No previous command"
-msgstr "E34: Ei edellistä komentoa"
+msgstr "E34: Ei edellistä komentoa"
-#: ../globals.h:1046
msgid "E35: No previous regular expression"
-msgstr "E35: Ei edellistä säännöllistä ilmausta"
+msgstr "E35: Ei edellistä säännöllistä ilmausta"
-#: ../globals.h:1047
msgid "E481: No range allowed"
msgstr "E481: Arvoalue ei sallittu"
-#: ../globals.h:1048
msgid "E36: Not enough room"
-msgstr "E36: Tila ei riitä"
+msgstr "E36: Tila ei riitä"
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: Tiedostoa %s ei voi luoda"
-
-#: ../globals.h:1050
msgid "E483: Can't get temp file name"
-msgstr "E483: väliaikaistiedoston nimeä ei saada selville"
+msgstr "E483: väliaikaistiedoston nimeä ei saada selville"
-#: ../globals.h:1051
#, c-format
msgid "E484: Can't open file %s"
msgstr "E484: Ei voi avata tiedostoa %s"
-#: ../globals.h:1052
#, c-format
msgid "E485: Can't read file %s"
msgstr "E485: Ei voi lukea tiedostoa %s"
-#: ../globals.h:1054
msgid "E37: No write since last change (add ! to override)"
msgstr ""
-"E37: Viimeisen muutoksen jälkeen ei ole kirjoitettu (lisää ! ohittaaksesi)"
+"E37: Viimeisen muutoksen jälkeen ei ole kirjoitettu (lisää ! ohittaaksesi)"
-#: ../globals.h:1055
-#, fuzzy
msgid "E37: No write since last change"
-msgstr "[Viimeisintä muutosta ei ole kirjoitettu]\n"
+msgstr "E37: Viimeisimmän muutoksen jälkeen ei ole kirjoitettu mitään"
-#: ../globals.h:1056
msgid "E38: Null argument"
msgstr "E38: Null-argumentti"
-#: ../globals.h:1057
msgid "E39: Number expected"
-msgstr "E39: Pitää olla numero"
+msgstr "E39: Pitää olla numero"
-#: ../globals.h:1058
#, c-format
msgid "E40: Can't open errorfile %s"
msgstr "E40: virhetiedostoa %s ei voi avata"
-#: ../globals.h:1059
msgid "E41: Out of memory!"
msgstr "E41: Muisti loppui"
-#: ../globals.h:1060
msgid "Pattern not found"
-msgstr "Kuviota ei löydy"
+msgstr "Kuviota ei löydy"
-#: ../globals.h:1061
#, c-format
msgid "E486: Pattern not found: %s"
-msgstr "E486: Kuviota ei löydy: %s"
+msgstr "E486: Kuviota ei löydy: %s"
-#: ../globals.h:1062
msgid "E487: Argument must be positive"
-msgstr "E487: Argumentin pitää olla positiivinen"
+msgstr "E487: Argumentin pitää olla positiivinen"
-#: ../globals.h:1064
msgid "E459: Cannot go back to previous directory"
-msgstr "E459: Ei voi siirtyä edelliseen hakemistoon"
+msgstr "E459: Ei voi siirtyä edelliseen hakemistoon"
# ;-)
-#: ../globals.h:1066
msgid "E42: No Errors"
-msgstr "E42: Ei virheitä"
+msgstr "E42: Ei virheitä"
-#: ../globals.h:1067
msgid "E776: No location list"
msgstr "E776: Ei sijaintilistaa"
-#: ../globals.h:1068
msgid "E43: Damaged match string"
-msgstr "E43: Viallinen täsmäysmerkkijono"
+msgstr "E43: Viallinen täsmäysmerkkijono"
-#: ../globals.h:1069
msgid "E44: Corrupted regexp program"
msgstr "E44: Viallinen regexp-ohjelma"
-#: ../globals.h:1071
msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: readonly asetettu (lisää ! ohittaaksesi)"
-
-#: ../globals.h:1073
-#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: Kirjoitussuojattua muuttujaa %s ei voi muuttaa"
-
-#: ../globals.h:1075
-#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E794: Muuttujaa ei voi asettaa hiekkalaatikossa: %s"
+msgstr "E45: readonly asetettu (lisää ! ohittaaksesi)"
-#: ../globals.h:1076
msgid "E47: Error while reading errorfile"
msgstr "E47: Virhe virhetiedostoa luettaessa"
-#: ../globals.h:1078
msgid "E48: Not allowed in sandbox"
msgstr "E48: Ei sallittu hiekkalaatikossa"
-#: ../globals.h:1080
msgid "E523: Not allowed here"
-msgstr "E523: Ei sallittu täällä"
+msgstr "E523: Ei sallittu täällä"
-#: ../globals.h:1082
msgid "E359: Screen mode setting not supported"
-msgstr "E359: Näyttötila-asetus ei tuettu"
+msgstr "E359: Näyttötila-asetus ei tuettu"
-#: ../globals.h:1083
msgid "E49: Invalid scroll size"
msgstr "E49: Virheellinen vierityskoko"
-#: ../globals.h:1084
msgid "E91: 'shell' option is empty"
-msgstr "E91: shell-asetus on tyhjä"
+msgstr "E91: shell-asetus on tyhjä"
-#: ../globals.h:1085
msgid "E255: Couldn't read in sign data!"
msgstr "E255: Merkkidatan luku ei onnistu"
-#: ../globals.h:1086
msgid "E72: Close error on swap file"
msgstr "E72: Swap-tiedoston sulkemisvirhe"
-#: ../globals.h:1087
msgid "E73: tag stack empty"
-msgstr "E73: tägipino tyhjä"
+msgstr "E73: tägipino tyhjä"
-#: ../globals.h:1088
msgid "E74: Command too complex"
msgstr "E74: Liian monimutkainen komento"
-#: ../globals.h:1089
msgid "E75: Name too long"
-msgstr "E75: Liian pitkä nimi"
+msgstr "E75: Liian pitkä nimi"
-#: ../globals.h:1090
msgid "E76: Too many ["
msgstr "E76: Liian monta [:a"
-#: ../globals.h:1091
msgid "E77: Too many file names"
-msgstr "E77: Liikaa tiedostonimiä"
+msgstr "E77: Liikaa tiedostonimiä"
-#: ../globals.h:1092
msgid "E488: Trailing characters"
-msgstr "E488: Ylimääräisiä merkkejä perässä"
+msgstr "E488: Ylimääräisiä merkkejä perässä"
-#: ../globals.h:1093
msgid "E78: Unknown mark"
msgstr "E78: Tuntematon merkki"
-#: ../globals.h:1094
msgid "E79: Cannot expand wildcards"
msgstr "E79: Jokerimerkkien avaus ei onnistu"
-#: ../globals.h:1096
msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
msgstr "E591: winheight ei voi olla pienempi kuin winminheight"
-#: ../globals.h:1098
msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
msgstr "E592: winwidth ei voi olla pienempi kuin winminwidth"
-#: ../globals.h:1099
msgid "E80: Error while writing"
msgstr "E80: Kirjoitusvirhe"
-#: ../globals.h:1100
msgid "Zero count"
msgstr "Nollalaskuri"
-#: ../globals.h:1101
msgid "E81: Using <SID> not in a script context"
msgstr "E81: <SID> skriptin ulkopuolella"
-#: ../globals.h:1102
#, c-format
msgid "E685: Internal error: %s"
-msgstr "E685: Sisäinen virhe: %s"
+msgstr "E685: Sisäinen virhe: %s"
-#: ../globals.h:1104
msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: kuvio käyttää enemmän muistia kuin maxmempattern on"
+msgstr "E363: kuvio käyttää enemmän muistia kuin maxmempattern on"
-#: ../globals.h:1105
msgid "E749: empty buffer"
-msgstr "E749: tyhjä puskuri"
+msgstr "E749: tyhjä puskuri"
+
+#, fuzzy, c-format
+#~ msgid "E86: Buffer %<PRId64> does not exist"
+#~ msgstr "E86: Puskuria %ld ei ole"
-#: ../globals.h:1108
msgid "E682: Invalid search pattern or delimiter"
msgstr "E682: Virheellinen hakulauseke tai erotin"
-#: ../globals.h:1109
msgid "E139: File is loaded in another buffer"
msgstr "E139: Tiedosto on ladattu toiseen puskuriin"
-#: ../globals.h:1110
#, c-format
msgid "E764: Option '%s' is not set"
msgstr "E764: Asetus %s on asettamatta"
-#: ../globals.h:1111
-#, fuzzy
msgid "E850: Invalid register name"
-msgstr "E354: Virheellinen rekisterin nimi: %s"
+msgstr "E850: Virheellinen rekisterin nimi"
+
+#, c-format
+msgid "E919: Directory not found in '%s': \"%s\""
+msgstr "E919: Hakemisto puuttuu kohteesta %s: %s"
+
+msgid "E519: Option not supported"
+msgstr "E519: Asetusta ei tueta"
+
+#, fuzzy
+#~ msgid "E856: Filename too long"
+#~ msgstr "E75: Liian pitkä nimi"
+
+msgid "E806: using Float as a String"
+msgstr "E806: Float ei käy merkkijonosta"
-#: ../globals.h:1114
msgid "search hit TOP, continuing at BOTTOM"
-msgstr "haku pääsi ALKUUN, jatketaan LOPUSTA"
+msgstr "haku pääsi ALKUUN, jatketaan LOPUSTA"
-#: ../globals.h:1115
msgid "search hit BOTTOM, continuing at TOP"
-msgstr "haku pääsi LOPPUUN, jatketaan ALUSTA"
+msgstr "haku pääsi LOPPUUN, jatketaan ALUSTA"
-#: ../hardcopy.c:240
msgid "E550: Missing colon"
msgstr "E550: kaksoispiste puuttuu"
-#: ../hardcopy.c:252
msgid "E551: Illegal component"
msgstr "E551: Virheellinen komponentti"
-#: ../hardcopy.c:259
msgid "E552: digit expected"
-msgstr "E552: pitäisi olla numero"
+msgstr "E552: pitäisi olla numero"
-#: ../hardcopy.c:473
#, c-format
msgid "Page %d"
msgstr "Sivu %d"
-#: ../hardcopy.c:597
msgid "No text to be printed"
-msgstr "Ei tekstiä tulostettavaksi"
+msgstr "Ei tekstiä tulostettavaksi"
-#: ../hardcopy.c:668
-#, c-format
-msgid "Printing page %d (%d%%)"
-msgstr "Tulostetaan sivua %d (%d %%)"
+#, fuzzy, c-format
+#~ msgid "Printing page %d (%zu%%)"
+#~ msgstr "Tulostetaan sivua %d (%d %%)"
-#: ../hardcopy.c:680
#, c-format
msgid " Copy %d of %d"
msgstr " Kopio %d/%d"
-#: ../hardcopy.c:733
#, c-format
msgid "Printed: %s"
msgstr "Tulostettu: %s"
-#: ../hardcopy.c:740
msgid "Printing aborted"
msgstr "Tulostus peruttu"
-#: ../hardcopy.c:1365
msgid "E455: Error writing to PostScript output file"
-msgstr "E455: Virhe kirjoitettaessa PostScriptiä tiedostoon"
+msgstr "E455: Virhe kirjoitettaessa PostScriptiä tiedostoon"
-#: ../hardcopy.c:1747
#, c-format
msgid "E624: Can't open file \"%s\""
msgstr "E624: Ei voi avata tiedostoa %s"
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
#, c-format
msgid "E457: Can't read PostScript resource file \"%s\""
msgstr "E457: Ei voi lukea PostScript-resurssitiedostoa %s"
-#: ../hardcopy.c:1772
#, c-format
msgid "E618: file \"%s\" is not a PostScript resource file"
msgstr "E618: tiedosto %s ei ole PostScript-resurssitiedosto"
-#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844
#, c-format
msgid "E619: file \"%s\" is not a supported PostScript resource file"
msgstr "E619: tiedosto %s ei ole tuettu PostScript-resurssitiedosto"
-#: ../hardcopy.c:1856
#, c-format
msgid "E621: \"%s\" resource file has wrong version"
-msgstr "E621: resurssitiedoston %s versio on väärä"
+msgstr "E621: resurssitiedoston %s versio on väärä"
-#: ../hardcopy.c:2225
msgid "E673: Incompatible multi-byte encoding and character set."
-msgstr "E673: Tukematon monitvauinen merkistökoodaus ja merkistö."
+msgstr "E673: Tukematon monitvauinen merkistökoodaus ja merkistö."
-#: ../hardcopy.c:2238
msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
-msgstr "E674: printmbcharset ei voi olla tyhjä monitavuiselle koodaukselle."
+msgstr "E674: printmbcharset ei voi olla tyhjä monitavuiselle koodaukselle."
-#: ../hardcopy.c:2254
msgid "E675: No default font specified for multi-byte printing."
msgstr "E675: Ei oletusfonttia monitavuiseen tulostukseen"
-#: ../hardcopy.c:2426
msgid "E324: Can't open PostScript output file"
msgstr "E324: PostScript-tulostetiedoston avaus ei onnistu"
-#: ../hardcopy.c:2458
#, c-format
msgid "E456: Can't open file \"%s\""
msgstr "E456: Tiedoston %s avaus ei onnistu"
-#: ../hardcopy.c:2583
msgid "E456: Can't find PostScript resource file \"prolog.ps\""
-msgstr "E456: PostScript-resurssitiedostoa prolog.ps ei löydy"
+msgstr "E456: PostScript-resurssitiedostoa prolog.ps ei löydy"
-#: ../hardcopy.c:2593
msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
-msgstr "E456: PostScript-resurssitiedostoa cidfont.ps ei löydy"
+msgstr "E456: PostScript-resurssitiedostoa cidfont.ps ei löydy"
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
#, c-format
msgid "E456: Can't find PostScript resource file \"%s.ps\""
-msgstr "E456: Postscript-resurssitiedosta %s.ps ei löydy"
+msgstr "E456: Postscript-resurssitiedosta %s.ps ei löydy"
-#: ../hardcopy.c:2654
#, c-format
msgid "E620: Unable to convert to print encoding \"%s\""
msgstr "E620: Tulostuskoodaukseen %s muunto ei onnistu"
-#: ../hardcopy.c:2877
msgid "Sending to printer..."
-msgstr "Lähetetään tulostimelle..."
+msgstr "Lähetetään tulostimelle..."
-#: ../hardcopy.c:2881
msgid "E365: Failed to print PostScript file"
-msgstr "E365: PostScript-tiedoston tulostus epäonnistui"
+msgstr "E365: PostScript-tiedoston tulostus epäonnistui"
-#: ../hardcopy.c:2883
msgid "Print job sent."
-msgstr "Tulostustyö lähetetty."
+msgstr "Tulostustyö lähetetty."
-#: ../if_cscope.c:85
msgid "Add a new database"
-msgstr "Lisää uusi tietokanta"
+msgstr "Lisää uusi tietokanta"
-#: ../if_cscope.c:87
msgid "Query for a pattern"
msgstr "Hae kuviota"
-#: ../if_cscope.c:89
msgid "Show this message"
-msgstr "Näytä tämä viesti"
+msgstr "Näytä tämä viesti"
-#: ../if_cscope.c:91
msgid "Kill a connection"
msgstr "Tapa yhteys"
-#: ../if_cscope.c:93
msgid "Reinit all connections"
msgstr "Alusta uudelleen yhteydet"
-#: ../if_cscope.c:95
msgid "Show connections"
-msgstr "Näytä yhteydet"
+msgstr "Näytä yhteydet"
-#: ../if_cscope.c:101
#, c-format
msgid "E560: Usage: cs[cope] %s"
-msgstr "E560: Käyttö: cs[cope] %s"
+msgstr "E560: Käyttö: cs[cope] %s"
-#: ../if_cscope.c:225
msgid "This cscope command does not support splitting the window.\n"
-msgstr "Tämä cscope-komento ei tue ikkunan jakamista.\n"
+msgstr "Tämä cscope-komento ei tue ikkunan jakamista.\n"
-#: ../if_cscope.c:266
msgid "E562: Usage: cstag <ident>"
-msgstr "E562: Käyttö: cstag <ident>"
+msgstr "E562: Käyttö: cstag <ident>"
-#: ../if_cscope.c:313
msgid "E257: cstag: tag not found"
-msgstr "E257: cstag: tägia ei löydy"
+msgstr "E257: cstag: tägia ei löydy"
-#: ../if_cscope.c:461
#, c-format
msgid "E563: stat(%s) error: %d"
msgstr "E563: stat(%s)-virhe: %d"
-#: ../if_cscope.c:551
#, c-format
msgid "E564: %s is not a directory or a valid cscope database"
-msgstr "E564: %s ei ole hakemisto eikä cscope-tietokanta"
+msgstr "E564: %s ei ole hakemisto eikä cscope-tietokanta"
-#: ../if_cscope.c:566
#, c-format
msgid "Added cscope database %s"
-msgstr "Lisätty cscope-tietokanta %s"
+msgstr "Lisätty cscope-tietokanta %s"
-#: ../if_cscope.c:616
-#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: Virhe luettaessa cscope-yhteyttä %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "E262: error reading cscope connection %<PRIu64>"
+#~ msgstr "E262: Virhe luettaessa cscope-yhteyttä %ld"
-#: ../if_cscope.c:711
msgid "E561: unknown cscope search type"
msgstr "E561: tuntematon cscope-hakutyyppi"
-#: ../if_cscope.c:752 ../if_cscope.c:789
msgid "E566: Could not create cscope pipes"
msgstr "E566: Ei voitu luoda cscope-putkia"
-#: ../if_cscope.c:767
msgid "E622: Could not fork for cscope"
msgstr "E622: Ei voitu haarauttaa cscopea"
-#: ../if_cscope.c:849
-#, fuzzy
msgid "cs_create_connection setpgid failed"
-msgstr "cs_create_connection epäonnistui"
+msgstr "cs_create_connection setpgid epäonnistui"
-#: ../if_cscope.c:853 ../if_cscope.c:889
msgid "cs_create_connection exec failed"
-msgstr "cs_create_connection epäonnistui"
+msgstr "cs_create_connection epäonnistui"
-#: ../if_cscope.c:863 ../if_cscope.c:902
msgid "cs_create_connection: fdopen for to_fp failed"
-msgstr "cs_create_connection: fdopen to_fp epäonnistui"
+msgstr "cs_create_connection: fdopen to_fp epäonnistui"
-#: ../if_cscope.c:865 ../if_cscope.c:906
msgid "cs_create_connection: fdopen for fr_fp failed"
-msgstr "cs_create_connection: fdopen fr_fp epäonnistui"
+msgstr "cs_create_connection: fdopen fr_fp epäonnistui"
-#: ../if_cscope.c:890
msgid "E623: Could not spawn cscope process"
-msgstr "E623: Cscope-prosessin luonti epäonnistui"
+msgstr "E623: Cscope-prosessin luonti epäonnistui"
-#: ../if_cscope.c:932
msgid "E567: no cscope connections"
-msgstr "E567: ei cscope-yhteyksiä"
+msgstr "E567: ei cscope-yhteyksiä"
-#: ../if_cscope.c:1009
#, c-format
msgid "E469: invalid cscopequickfix flag %c for %c"
msgstr "E469: virheellinen cscopequickfix-asetus %c kohteelle %c"
-#: ../if_cscope.c:1058
#, c-format
msgid "E259: no matches found for cscope query %s of %s"
-msgstr "E259: ei täsmäyksiä cscope-hakuun %s/%s"
+msgstr "E259: ei täsmäyksiä cscope-hakuun %s/%s"
-#: ../if_cscope.c:1142
msgid "cscope commands:\n"
msgstr "cscope-komennot:\n"
-#: ../if_cscope.c:1150
#, c-format
msgid "%-5s: %s%*s (Usage: %s)"
-msgstr "%-5s: %s%*s (Käyttö: %s)"
+msgstr "%-5s: %s%*s (Käyttö: %s)"
-#: ../if_cscope.c:1155
-#, fuzzy
msgid ""
"\n"
+" a: Find assignments to this symbol\n"
" c: Find functions calling this function\n"
" d: Find functions called by this function\n"
" e: Find this egrep pattern\n"
@@ -3246,40 +3092,36 @@ msgid ""
" t: Find this text string\n"
msgstr ""
"\n"
-" c: Etsi tätä funktiota kutsuvat funktiot\n"
-" d: Etsi tämän funktion kutsumat funktiot\n"
-" e: Etsi tämä egrep-lauseke\n"
-" f: Find tämä tiedosto\n"
-" g: Etsi tämä määritys\n"
-" i: Etsi tiedostoja jotka #inkluudaavat tämän\n"
-" s: Etsi tämä C-symboli\n"
+" a: Etsi sijotukset tähän symboliin\n"
+" c: Etsi tätä funktiota kutsuvat funktiot\n"
+" d: Etsi tämän funktion kutsumat funktiot\n"
+" e: Etsi tämä egrep-lauseke\n"
+" f: Etsi tämä tiedosto\n"
+" g: Etsi tämä määritys\n"
+" i: Etsi tiedostoja jotka #inkluudaavat tämän\n"
+" s: Etsi tämä C-symboli\n"
" t: Etsi sijoitukset muuttujaan \n"
-#: ../if_cscope.c:1226
msgid "E568: duplicate cscope database not added"
-msgstr "E568: kaksoiskappaletta cscope-tietokannasta ei lisätty"
+msgstr "E568: kaksoiskappaletta cscope-tietokannasta ei lisätty"
-#: ../if_cscope.c:1335
#, c-format
msgid "E261: cscope connection %s not found"
msgstr "E261: cscope-yhteys %s puuttuu"
-#: ../if_cscope.c:1364
#, c-format
msgid "cscope connection %s closed"
msgstr "cscope-yhteys %s on katkaistu"
#. should not reach here
-#: ../if_cscope.c:1486
msgid "E570: fatal error in cs_manage_matches"
msgstr "E570: kriittinen virhe cs_manage_matches-funktiossa"
-#: ../if_cscope.c:1693
#, c-format
msgid "Cscope tag: %s"
-msgstr "Cscope-tägi: %s"
+msgstr "Cscope-tägi: %s"
-#: ../if_cscope.c:1711
+#. Column headers for match number, line number and filename.
msgid ""
"\n"
" # line"
@@ -3287,326 +3129,272 @@ msgstr ""
"\n"
" # rivi"
-#: ../if_cscope.c:1713
msgid "filename / context / line\n"
msgstr "tiedosto / konteksti / rivi\n"
-#: ../if_cscope.c:1809
#, c-format
msgid "E609: Cscope error: %s"
msgstr "E609: Cscope-virhe: %s"
-#: ../if_cscope.c:2053
msgid "All cscope databases reset"
msgstr "Kaikki cscope-tietokannat nollattu"
-#: ../if_cscope.c:2123
msgid "no cscope connections\n"
-msgstr "ei cscope-yhteyksiä\n"
+msgstr "ei cscope-yhteyksiä\n"
-#: ../if_cscope.c:2126
msgid " # pid database name prepend path\n"
-msgstr " # pid tietokanta lisäyspolku\n"
+msgstr " # pid tietokanta lisäyspolku\n"
+
+#. Error messages
+msgid "Argument missing after"
+msgstr "Argumentti puuttuu kohdasta"
+
+msgid "Garbage after option argument"
+msgstr "Roskaa argumentin perässä"
-#: ../main.c:144
msgid "Unknown option argument"
msgstr "Tuntematon asetusargumentti"
-#: ../main.c:146
msgid "Too many edit arguments"
msgstr "Liikaa muokkausargumentteja"
-#: ../main.c:148
-msgid "Argument missing after"
-msgstr "Argumentti puuttuu kohdasta"
-
-#: ../main.c:150
-msgid "Garbage after option argument"
-msgstr "Roskaa argumentin perässä"
-
-#: ../main.c:152
msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
msgstr "Liikaa +komentoja, -c-komentoja tai --cmd-komentoja"
-#: ../main.c:154
-msgid "Invalid argument for"
-msgstr "Väärä argumentti valitsimelle"
-
-#: ../main.c:294
-#, c-format
-msgid "%d files to edit\n"
-msgstr "%d tiedostoa muokattavana\n"
-
-#: ../main.c:1342
msgid "Attempt to open script file again: \""
msgstr "Yritettiin avata skriptitiedostoa uudestaan:"
-#: ../main.c:1350
msgid "Cannot open for reading: \""
msgstr "Ei voi avata luettavaksi: "
-#: ../main.c:1393
msgid "Cannot open for script output: \""
msgstr "Ei voi avata skriptin tulostetta varten: "
-#: ../main.c:1622
msgid "Vim: Warning: Output is not to a terminal\n"
msgstr "Vim: Varoitus: Tuloste ei mene terminaalille\n"
-#: ../main.c:1624
msgid "Vim: Warning: Input is not from a terminal\n"
-msgstr "Vim: Varoitus: Syöte ei tule terminaalilta\n"
+msgstr "Vim: Varoitus: Syöte ei tule terminaalilta\n"
#. just in case..
-#: ../main.c:1891
msgid "pre-vimrc command line"
msgstr "esi-vimrc-komentorivi"
-#: ../main.c:1964
#, c-format
msgid "E282: Cannot read from \"%s\""
msgstr "E282: Ei voida lukea kohteesta %s"
-#: ../main.c:2149
+#, fuzzy
msgid ""
"\n"
-"More info with: \"vim -h\"\n"
+"More info with \""
msgstr ""
"\n"
-"Lisätietoja: \"vim -h\"\n"
-
-#: ../main.c:2178
-msgid "[file ..] edit specified file(s)"
-msgstr "[tiedosto ..] muokkaa tiedostoja"
-
-#: ../main.c:2179
-msgid "- read text from stdin"
-msgstr "- lue vakiosyötteestä"
+"Lisätietoja: \"vim -h\"\n"
-#: ../main.c:2180
-msgid "-t tag edit file where tag is defined"
-msgstr "-t tägi muokkaa tiedostoa tägistä"
+#. kill us with CTRL-C here, if you like
+#, fuzzy
+#~ msgid "Usage:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "\n"
+#~ "käyttö:"
-#: ../main.c:2181
-msgid "-q [errorfile] edit file with first error"
-msgstr "-q [virhetiedosto] muokkaa tiedostoa ensimmäisestä virheestä"
+#, fuzzy
+#~ msgid " nvim [arguments] [file ...] Edit specified file(s)\n"
+#~ msgstr "[tiedosto ..] muokkaa tiedostoja"
-#: ../main.c:2187
-msgid ""
-"\n"
-"\n"
-"usage:"
-msgstr ""
-"\n"
-"\n"
-"käyttö:"
+#, fuzzy
+#~ msgid " nvim [arguments] - Read text from stdin\n"
+#~ msgstr "- lue vakiosyötteestä"
-#: ../main.c:2189
-msgid " vim [arguments] "
-msgstr " vim [argumentit] "
+#, fuzzy
+#~ msgid " nvim [arguments] -t <tag> Edit file where tag is defined\n"
+#~ msgstr "-t tägi muokkaa tiedostoa tägistä"
-#: ../main.c:2193
-msgid ""
-"\n"
-" or:"
-msgstr ""
-"\n"
-" tai:"
+#, fuzzy
+#~ msgid " nvim [arguments] -q [errorfile] Edit file with first error\n"
+#~ msgstr "-q [virhetiedosto] muokkaa tiedostoa ensimmäisestä virheestä"
-#: ../main.c:2196
+#, fuzzy
msgid ""
"\n"
-"\n"
"Arguments:\n"
msgstr ""
"\n"
"\n"
"Argumentit:\n"
-#: ../main.c:2197
-msgid "--\t\t\tOnly file names after this"
-msgstr "--\t\t\tvain tiedostonimiä tämän jälkeen"
-
-#: ../main.c:2199
-msgid "--literal\t\tDon't expand wildcards"
-msgstr "--literal\t\tÄlä käsittele jokerimerkkejä "
-
-#: ../main.c:2201
-msgid "-v\t\t\tVi mode (like \"vi\")"
-msgstr "-v\t\t\tVi-tila (kuten villä)"
+#, fuzzy
+#~ msgid " -- Only file names after this\n"
+#~ msgstr "--\t\t\tvain tiedostonimiä tämän jälkeen"
-#: ../main.c:2202
-msgid "-e\t\t\tEx mode (like \"ex\")"
-msgstr "-e\t\t\tEx-tila (kute exillä)"
+#, fuzzy
+#~ msgid " --literal Don't expand wildcards\n"
+#~ msgstr "--literal\t\tÄlä käsittele jokerimerkkejä "
-#: ../main.c:2203
-msgid "-E\t\t\tImproved Ex mode"
-msgstr ""
+#, fuzzy
+#~ msgid " -e Ex mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2204
-msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
-msgstr "-s\t\t\tHiljainen (eräajo)tila (vain exillä)"
+#, fuzzy
+#~ msgid " -E Improved Ex mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2205
-msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
-msgstr "-d\t\t\tDiff-tila (kuten vimdiffillä)"
+#, fuzzy
+#~ msgid " -s Silent (batch) mode (only for ex mode)\n"
+#~ msgstr "-s\t\t\tHiljainen (eräajo)tila (vain exillä)"
-#: ../main.c:2206
-msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
-msgstr "-y\t\t\tHelppokäyttötila (kuten evimissä, ilman tiloja)"
+#, fuzzy
+#~ msgid " -d Diff mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2207
-msgid "-R\t\t\tReadonly mode (like \"view\")"
-msgstr "-R\t\t\tKirjoitussuojattu tila (kuten view'lla)"
+#, fuzzy
+#~ msgid " -R Read-only mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2208
-msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
-msgstr "-Z\t\t\tRajoitettu tila (kuten rvimillä)"
+#, fuzzy
+#~ msgid " -Z Restricted mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2209
-msgid "-m\t\t\tModifications (writing files) not allowed"
-msgstr "-m\t\t\tMuokkaukset (kirjoittaminen tiedostoon) pois käytöstä"
+#, fuzzy
+#~ msgid " -m Modifications (writing files) not allowed\n"
+#~ msgstr "-m\t\t\tMuokkaukset (kirjoittaminen tiedostoon) pois käytöstä"
-#: ../main.c:2210
-msgid "-M\t\t\tModifications in text not allowed"
-msgstr "-M\t\t\tTekstin muokkaus pois käytöstä"
+#, fuzzy
+#~ msgid " -M Modifications in text not allowed\n"
+#~ msgstr "-M\t\t\tTekstin muokkaus pois käytöstä"
-#: ../main.c:2211
-msgid "-b\t\t\tBinary mode"
-msgstr "-b\t\t\tBinääritila"
+#, fuzzy
+#~ msgid " -b Binary mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2212
-msgid "-l\t\t\tLisp mode"
-msgstr "-l\t\t\tLisp-tila"
+#, fuzzy
+#~ msgid " -l Lisp mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2213
-msgid "-C\t\t\tCompatible with Vi: 'compatible'"
-msgstr "-C\t\t\tVi-yhteensopivuustila: compatible"
+#, fuzzy
+#~ msgid " -A Arabic mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2214
-msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
-msgstr "-N\t\t\tEi Vi-yhteensopivuutta: nocompatible"
+#, fuzzy
+#~ msgid " -F Farsi mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2215
-msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
-msgstr ""
-"-V[N][tnimi]\t\tMonisanainen tuloste [Taso N] [kirjoita tuloste tnimeen] "
+#, fuzzy
+#~ msgid " -H Hebrew mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2216
-msgid "-D\t\t\tDebugging mode"
-msgstr "-D\t\t\tVianetsintätila"
+#, fuzzy
+#~ msgid " -V[N][file] Be verbose [level N][log messages to file]\n"
+#~ msgstr ""
+#~ "-V[N][tnimi]\t\tMonisanainen tuloste [Taso N] [kirjoita tuloste tnimeen] "
-#: ../main.c:2217
-msgid "-n\t\t\tNo swap file, use memory only"
-msgstr "-n\t\t\tEi swap-tiedostoja, käytä muistia"
+#, fuzzy
+#~ msgid " -D Debugging mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2218
-msgid "-r\t\t\tList swap files and exit"
-msgstr "-r\t\t\tLuetteloi swap-tiedostot ja poistu"
+#, fuzzy
+#~ msgid " -n No swap file, use memory only\n"
+#~ msgstr "-n\t\t\tEi swap-tiedostoja, käytä muistia"
-#: ../main.c:2219
-msgid "-r (with file name)\tRecover crashed session"
-msgstr "-r (tiedostonimi)\tPalauta kaatunut sessio"
+#, fuzzy
+#~ msgid " -r, -L List swap files and exit\n"
+#~ msgstr "-r\t\t\tLuetteloi swap-tiedostot ja poistu"
-#: ../main.c:2220
-msgid "-L\t\t\tSame as -r"
-msgstr "-L\t\t\tkuten -r"
+#, fuzzy
+#~ msgid " -r <file> Recover crashed session\n"
+#~ msgstr "-r (tiedostonimi)\tPalauta kaatunut sessio"
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
-msgstr "-A\t\t\tkäynnistä arabia-tilassa"
+#, fuzzy
+#~ msgid " -u <vimrc> Use <vimrc> instead of the default\n"
+#~ msgstr "-u <vimrc>\t\tKäytä <vimrc>-tiedostoa .vimrc:iden sijasta"
-#: ../main.c:2222
-msgid "-H\t\t\tStart in Hebrew mode"
-msgstr "-H\t\t\tkäynnistä heprea-tilassa"
+#~ msgid " -i <shada> Use <shada> instead of the default\n"
+#~ msgstr ""
-#: ../main.c:2223
-msgid "-F\t\t\tStart in Farsi mode"
-msgstr "-F\t\t\tkäynnistä farsi-tilassa"
+#, fuzzy
+#~ msgid " --noplugin Don't load plugin scripts\n"
+#~ msgstr "--noplugin\t\tÄlä lataa liitännäisiä"
-#: ../main.c:2224
-msgid "-T <terminal>\tSet terminal type to <terminal>"
-msgstr "-T <terminaali>\tAseta terminaalin tyypiksi <terminaali>"
+#, fuzzy
+#~ msgid " -o[N] Open N windows (default: one for each file)\n"
+#~ msgstr "-o[N]\t\tAvaa N ikkunaa (oletus: yksi per tiedosto)"
-#: ../main.c:2225
-msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
-msgstr "-u <vimrc>\t\tKäytä <vimrc>-tiedostoa .vimrc:iden sijasta"
+#, fuzzy
+#~ msgid " -O[N] Like -o but split vertically\n"
+#~ msgstr "-O[N]\t\tKuten -o, mutta jaa pystysuunnassa"
-#: ../main.c:2226
-msgid "--noplugin\t\tDon't load plugin scripts"
-msgstr "--noplugin\t\tÄlä lataa liitännäisiä"
+#, fuzzy
+#~ msgid " -p[N] Open N tab pages (default: one for each file)\n"
+#~ msgstr "-p[N]\t\tAvaa N välilehteä (oletus: yksi per tiedosto)"
-#: ../main.c:2227
-msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
-msgstr "-p[N]\t\tAvaa N välilehteä (oletus: yksi per tiedosto)"
+#, fuzzy
+#~ msgid " + Start at end of file\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2228
-msgid "-o[N]\t\tOpen N windows (default: one for each file)"
-msgstr "-o[N]\t\tAvaa N ikkunaa (oletus: yksi per tiedosto)"
+#, fuzzy
+#~ msgid " +<linenum> Start at line <linenum>\n"
+#~ msgstr "+<rivi>\t\t\tAloita riviltä <rivi>"
-#: ../main.c:2229
-msgid "-O[N]\t\tLike -o but split vertically"
-msgstr "-O[N]\t\tKuten -o, mutta jaa pystysuunnassa"
+#~ msgid " +/<pattern> Start at first occurrence of <pattern>\n"
+#~ msgstr ""
-#: ../main.c:2230
-msgid "+\t\t\tStart at end of file"
-msgstr "+\t\t\tAloita tiedoston lopusta"
+#, fuzzy
+#~ msgid " --cmd <command> Execute <command> before loading any vimrc\n"
+#~ msgstr "--cmd <komento>\tSuorita <komento> ennen vimrc:iden latausta"
-#: ../main.c:2231
-msgid "+<lnum>\t\tStart at line <lnum>"
-msgstr "+<rivi>\t\t\tAloita riviltä <rivi>"
+#, fuzzy
+msgid ""
+" -c <command> Execute <command> after loading the first file\n"
+msgstr "-c <komento>\t\tSuorita <komento> ensimmäisen tiedoston latauduttua"
-#: ../main.c:2232
-msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
-msgstr "--cmd <komento>\tSuorita <komento> ennen vimrc:iden latausta"
+#, fuzzy
+#~ msgid " -S <session> Source <session> after loading the first file\n"
+#~ msgstr "-S <sessio>\t\tLataa <sessio> ensimmäisen tiedoston latauduttua"
-#: ../main.c:2233
-msgid "-c <command>\t\tExecute <command> after loading the first file"
-msgstr "-c <komento>\t\tSuorita <komento> ensimmäisen tiedoston latauduttua"
+#, fuzzy
+#~ msgid " -s <scriptin> Read Normal mode commands from <scriptin>\n"
+#~ msgstr "-s <skripti>\tLue normaalitilan komentoja <skripti>-tiedostosta"
-#: ../main.c:2235
-msgid "-S <session>\t\tSource file <session> after loading the first file"
-msgstr "-S <sessio>\t\tLataa <sessio> ensimmäisen tiedoston latauduttua"
+#, fuzzy
+#~ msgid " -w <scriptout> Append all typed characters to <scriptout>\n"
+#~ msgstr "-w <skripti>\tLisää kirjoitetut komennot <skripti>-tiedostoon"
-#: ../main.c:2236
-msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
-msgstr "-s <skripti>\tLue normaalitilan komentoja <skripti>-tiedostosta"
+#, fuzzy
+#~ msgid " -W <scriptout> Write all typed characters to <scriptout>\n"
+#~ msgstr "-W <skripti>\tKirjoita komennot <skripti>-tiedostoon"
-#: ../main.c:2237
-msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
-msgstr "-w <skripti>\tLisää kirjoitetut komennot <skripti>-tiedostoon"
+#, fuzzy
+#~ msgid " --startuptime <file> Write startup timing messages to <file>\n"
+#~ msgstr "--startuptime <file>\tKirjoita käynnistysaikaviestit tiedostoon <file>"
-#: ../main.c:2238
-msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
-msgstr "-W <skripti>\tKirjoita komennot <skripti>-tiedostoon"
+#~ msgid ""
+#~ " --api-info Dump API metadata serialized to msgpack and exit\n"
+#~ msgstr ""
-#: ../main.c:2240
-msgid "--startuptime <file>\tWrite startup timing messages to <file>"
-msgstr "--startuptime <file>\tKirjoita käynnistysaikaviestit tiedostoon <file>"
+#~ msgid " --embed Use stdin/stdout as a msgpack-rpc channel\n"
+#~ msgstr ""
-#: ../main.c:2242
-msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
-msgstr "-i <viminfo>\t\tKäytä <viminfo>-tiedostoa .viminfon sijaan"
+#~ msgid " --headless Don't start a user interface\n"
+#~ msgstr ""
-#: ../main.c:2243
-msgid "-h or --help\tPrint Help (this message) and exit"
-msgstr "-h tai --help\tTulosta ohje (tämä viesti) ja lopeta"
+#, fuzzy
+#~ msgid " -v, --version Print version information and exit\n"
+#~ msgstr "--version\t\t\tTulosta versiotiedot ja lopeta"
-#: ../main.c:2244
-msgid "--version\t\tPrint version information and exit"
-msgstr "--version\t\t\tTulosta versiotiedot ja lopeta"
+#, fuzzy
+#~ msgid " -h, --help Print this help message and exit\n"
+#~ msgstr "-h tai --help\tTulosta ohje (tämä viesti) ja lopeta"
-#: ../mark.c:676
msgid "No marks set"
-msgstr "Ei asetettuja merkkejä"
+msgstr "Ei asetettuja merkkejä"
-#: ../mark.c:678
#, c-format
msgid "E283: No marks matching \"%s\""
-msgstr "E283: Mikään merkki ei täsmää ilmaukseen \"%s\""
+msgstr "E283: Mikään merkki ei täsmää ilmaukseen \"%s\""
#. Highlight title
-#: ../mark.c:687
msgid ""
"\n"
"mark line col file/text"
@@ -3615,7 +3403,6 @@ msgstr ""
"merkki rivi sarake tiedosto/teksti"
#. Highlight title
-#: ../mark.c:789
msgid ""
"\n"
" jump line col file/text"
@@ -3624,7 +3411,6 @@ msgstr ""
"hyppy rivi sarake tiedosto/teksti"
#. Highlight title
-#: ../mark.c:831
msgid ""
"\n"
"change line col text"
@@ -3632,138 +3418,85 @@ msgstr ""
"\n"
"muutos rivi sarake teksti"
-#: ../mark.c:1238
-msgid ""
-"\n"
-"# File marks:\n"
-msgstr ""
-"\n"
-"# Tiedoston merkit:\n"
-
-#. Write the jumplist with -'
-#: ../mark.c:1271
-msgid ""
-"\n"
-"# Jumplist (newest first):\n"
-msgstr ""
-"\n"
-"# Hyppylista (uusin ensiksi):\n"
-
-#: ../mark.c:1352
-msgid ""
-"\n"
-"# History of marks within files (newest to oldest):\n"
-msgstr ""
-"\n"
-"# Tiedostojen merkkien historia (uusimmasta vanhimpaan):\n"
-
-#: ../mark.c:1431
-msgid "Missing '>'"
-msgstr "> puuttuu"
-
-#: ../memfile.c:426
msgid "E293: block was not locked"
msgstr "E293: lohkoa ei ole lukittu"
-#: ../memfile.c:799
msgid "E294: Seek error in swap file read"
msgstr "E294: Hakuvirhe swap-tiedostoa luettaessa"
-#: ../memfile.c:803
msgid "E295: Read error in swap file"
msgstr "E295: Lukuvirhe swap-tiedostossa"
-#: ../memfile.c:849
msgid "E296: Seek error in swap file write"
msgstr "E296: Hakuvirhe swap-tiedostoa kirjoitettaessa"
-#: ../memfile.c:865
msgid "E297: Write error in swap file"
msgstr "E297: Kirjoitusvirhe swap-tiedostossa"
-#: ../memfile.c:1036
msgid "E300: Swap file already exists (symlink attack?)"
-msgstr "E300: Swaptiedosto on jo olemassa (symlink-hyökkäys?)"
+msgstr "E300: Swaptiedosto on jo olemassa (symlink-hyökkäys?)"
-#: ../memline.c:318
msgid "E298: Didn't get block nr 0?"
msgstr "E298: Lohko 0:aa ei saatu?"
-#: ../memline.c:361
msgid "E298: Didn't get block nr 1?"
-msgstr "E298: Lohko 1:tä ei saatu?"
+msgstr "E298: Lohko 1:tä ei saatu?"
-#: ../memline.c:377
msgid "E298: Didn't get block nr 2?"
msgstr "E298: Lohko 2:ta ei saatu?"
#. could not (re)open the swap file, what can we do????
-#: ../memline.c:465
msgid "E301: Oops, lost the swap file!!!"
-msgstr "E301: Hups, swap-tiedosto hävisi!"
+msgstr "E301: Hups, swap-tiedosto hävisi!"
-#: ../memline.c:477
msgid "E302: Could not rename swap file"
msgstr "E302: Swap-tiedoston uudellennimeys ei onnistu"
-#: ../memline.c:554
#, c-format
msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
msgstr "E303: Swap-tiedostoa %s ei voi avata, palautus ei onnistu"
-#: ../memline.c:666
msgid "E304: ml_upd_block0(): Didn't get block 0??"
msgstr "E304: ml_upd_block0(): Lohko 0:aa ei saatu?"
#. no swap files found
-#: ../memline.c:830
#, c-format
msgid "E305: No swap file found for %s"
msgstr "E305: Ei swap-tiedostoa tiedostolle %s"
-#: ../memline.c:839
msgid "Enter number of swap file to use (0 to quit): "
msgstr "Anna swap-tiedoston numero tai 0 lopettaaksesi: "
-#: ../memline.c:879
#, c-format
msgid "E306: Cannot open %s"
msgstr "E306: Ei voi avata tiedostoa %s"
-#: ../memline.c:897
msgid "Unable to read block 0 from "
msgstr "Ei voi lukea lohkoa 0 kohteesta "
-#: ../memline.c:900
msgid ""
"\n"
"Maybe no changes were made or Vim did not update the swap file."
msgstr ""
"\n"
-"Muutoksia ei tehty, tai Vim ei päivittänyt swap-tiedostoa."
+"Muutoksia ei tehty, tai Vim ei päivittänyt swap-tiedostoa."
-#: ../memline.c:909
msgid " cannot be used with this version of Vim.\n"
-msgstr " ei toimi tämän version Vimin kanssa.\n"
+msgstr " ei toimi tämän version Vimin kanssa.\n"
-#: ../memline.c:911
msgid "Use Vim version 3.0.\n"
-msgstr "Käytä Vimin versiota 3.0\n"
+msgstr "Käytä Vimin versiota 3.0\n"
-#: ../memline.c:916
#, c-format
msgid "E307: %s does not look like a Vim swap file"
msgstr "E307: %s ei ole Vimin swap-tiedosto"
-#: ../memline.c:922
msgid " cannot be used on this computer.\n"
-msgstr " ei toimi tällä koneella.\n"
+msgstr " ei toimi tällä koneella.\n"
-#: ../memline.c:924
msgid "The file was created on "
msgstr "Tiedosto luotiin "
-#: ../memline.c:928
msgid ""
",\n"
"or the file has been damaged."
@@ -3771,100 +3504,78 @@ msgstr ""
",\n"
"tai tiedosto on vahingoittunut."
-#: ../memline.c:945
msgid " has been damaged (page size is smaller than minimum value).\n"
-msgstr " on vioittunut (sivun koko on vähimmäisarvoa pienempi).\n"
+msgstr " on vioittunut (sivun koko on vähimmäisarvoa pienempi).\n"
-#: ../memline.c:974
#, c-format
msgid "Using swap file \"%s\""
-msgstr "Käytetään swap-tiedostoa %s"
+msgstr "Käytetään swap-tiedostoa %s"
-#: ../memline.c:980
#, c-format
msgid "Original file \"%s\""
-msgstr "Alkuperäinen tiedosto %s"
+msgstr "Alkuperäinen tiedosto %s"
-#: ../memline.c:995
msgid "E308: Warning: Original file may have been changed"
-msgstr "E308: Varoitus: Alkuperäistä tiedostoa saattaa olla muutettu"
+msgstr "E308: Varoitus: Alkuperäistä tiedostoa saattaa olla muutettu"
-#: ../memline.c:1061
#, c-format
msgid "E309: Unable to read block 1 from %s"
msgstr "E309: Ei voitu lukea lohkoa 1 tiedostosta %s"
-#: ../memline.c:1065
msgid "???MANY LINES MISSING"
-msgstr "???PALJON RIVEJÄ PUUTTUU"
+msgstr "???PALJON RIVEJÄ PUUTTUU"
-#: ../memline.c:1076
msgid "???LINE COUNT WRONG"
-msgstr "???RIVIMÄÄRÄ PIELESSÄ"
+msgstr "???RIVIMÄÄRÄ PIELESSÄ"
-#: ../memline.c:1082
msgid "???EMPTY BLOCK"
-msgstr "???TYHJÄ LOHKO"
+msgstr "???TYHJÄ LOHKO"
-#: ../memline.c:1103
msgid "???LINES MISSING"
-msgstr "???RIVEJÄ PUUTTUU"
+msgstr "???RIVEJÄ PUUTTUU"
-#: ../memline.c:1128
#, c-format
msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
-msgstr "E310: Lohon 1 tunniste väärä (%s ei ole .swp-tiedosto?)"
+msgstr "E310: Lohon 1 tunniste väärä (%s ei ole .swp-tiedosto?)"
-#: ../memline.c:1133
msgid "???BLOCK MISSING"
msgstr "???LOHKO PUUTTUU"
-#: ../memline.c:1147
msgid "??? from here until ???END lines may be messed up"
-msgstr "??? tästä kohtaan ???LOPPU rivejä sekaisin"
+msgstr "??? tästä kohtaan ???LOPPU rivejä sekaisin"
-#: ../memline.c:1164
msgid "??? from here until ???END lines may have been inserted/deleted"
-msgstr "??? tästä kohtaan ???LOPPU rivejä saattaa olla lisätty tai poistettu"
+msgstr "??? tästä kohtaan ???LOPPU rivejä saattaa olla lisätty tai poistettu"
-#: ../memline.c:1181
msgid "???END"
msgstr "???LOPPU"
-#: ../memline.c:1238
msgid "E311: Recovery Interrupted"
msgstr "E311: Palautus keskeytetty"
-#: ../memline.c:1243
msgid ""
"E312: Errors detected while recovering; look for lines starting with ???"
-msgstr "E312: Palautuksessa oli virheitä, etsi rivejä, jotka alkavat ???"
+msgstr "E312: Palautuksessa oli virheitä, etsi rivejä, jotka alkavat ???"
-#: ../memline.c:1245
msgid "See \":help E312\" for more information."
-msgstr ":help E312 kertoo lisätietoja"
+msgstr ":help E312 kertoo lisätietoja"
-#: ../memline.c:1249
msgid "Recovery completed. You should check if everything is OK."
-msgstr "Palautus onnistui. Tarkista, että kaikki on kunnossa."
+msgstr "Palautus onnistui. Tarkista, että kaikki on kunnossa."
-#: ../memline.c:1251
msgid ""
"\n"
"(You might want to write out this file under another name\n"
msgstr ""
"\n"
-"(Saattaa kannattaa kirjoittaa tämä tiedosto toisella nimellä\n"
+"(Saattaa kannattaa kirjoittaa tämä tiedosto toisella nimellä\n"
-#: ../memline.c:1252
msgid "and run diff with the original file to check for changes)"
-msgstr "ja katso diffillä muutokset alkuperäiseen tiedostoon)"
+msgstr "ja katso diffillä muutokset alkuperäiseen tiedostoon)"
-#: ../memline.c:1254
msgid "Recovery completed. Buffer contents equals file contents."
-msgstr "Palautus onnistui. Puskurin ja tiedoston sisällöt täsmäävät."
+msgstr "Palautus onnistui. Puskurin ja tiedoston sisällöt täsmäävät."
-#: ../memline.c:1255
msgid ""
"\n"
"You may want to delete the .swp file now.\n"
@@ -3875,51 +3586,42 @@ msgstr ""
"\n"
#. use msg() to start the scrolling properly
-#: ../memline.c:1327
msgid "Swap files found:"
-msgstr "Swap-tiedostoja löytyi:"
+msgstr "Swap-tiedostoja löytyi:"
-#: ../memline.c:1446
msgid " In current directory:\n"
-msgstr " Tässä hakemistossa:\n"
+msgstr " Tässä hakemistossa:\n"
-#: ../memline.c:1448
msgid " Using specified name:\n"
-msgstr " Määritellyllä nimellä:\n"
+msgstr " Määritellyllä nimellä:\n"
-#: ../memline.c:1450
msgid " In directory "
msgstr " Hakemistossa "
-#: ../memline.c:1465
msgid " -- none --\n"
-msgstr " -- ei mitään --\n"
+msgstr " -- ei mitään --\n"
-#: ../memline.c:1527
msgid " owned by: "
msgstr " omistaja: "
-#: ../memline.c:1529
msgid " dated: "
msgstr " ajalta: "
-#: ../memline.c:1532 ../memline.c:3231
msgid " dated: "
msgstr " ajalta:"
-#: ../memline.c:1548
msgid " [from Vim version 3.0]"
msgstr " [Vimin 3.0-versiosta]"
-#: ../memline.c:1550
msgid " [does not look like a Vim swap file]"
-msgstr " [ei näytä Vimin swap-tiedostolta]"
+msgstr " [ei näytä Vimin swap-tiedostolta]"
+
+#~ msgid " [garbled strings (not nul terminated)]"
+#~ msgstr ""
-#: ../memline.c:1552
msgid " file name: "
msgstr " tiedostonimi: "
-#: ../memline.c:1558
msgid ""
"\n"
" modified: "
@@ -3927,27 +3629,22 @@ msgstr ""
"\n"
" muokattu: "
-#: ../memline.c:1559
msgid "YES"
-msgstr "KYLLÄ"
+msgstr "KYLLÄ"
-#: ../memline.c:1559
msgid "no"
msgstr "ei"
-#: ../memline.c:1562
msgid ""
"\n"
" user name: "
msgstr ""
"\n"
-" käyttäjänimi: "
+" käyttäjänimi: "
-#: ../memline.c:1568
msgid " host name: "
msgstr " laitenimi: "
-#: ../memline.c:1570
msgid ""
"\n"
" host name: "
@@ -3955,7 +3652,6 @@ msgstr ""
"\n"
" laitenimi: "
-#: ../memline.c:1575
msgid ""
"\n"
" process ID: "
@@ -3963,190 +3659,143 @@ msgstr ""
"\n"
" prosessin tunniste: "
-#: ../memline.c:1579
msgid " (still running)"
-msgstr " (käynnissä)"
+msgstr " (käynnissä)"
-#: ../memline.c:1586
msgid ""
"\n"
" [not usable on this computer]"
msgstr ""
"\n"
-" [ei toimi tällä koneella]"
+" [ei toimi tällä koneella]"
-#: ../memline.c:1590
msgid " [cannot be read]"
msgstr " [ei voi lukea]"
-#: ../memline.c:1593
msgid " [cannot be opened]"
msgstr " [ei voi avata]"
-#: ../memline.c:1698
msgid "E313: Cannot preserve, there is no swap file"
-msgstr "E313: Ei voi säilyttää, swap-tiedostoa ei ole"
+msgstr "E313: Ei voi säilyttää, swap-tiedostoa ei ole"
-#: ../memline.c:1747
msgid "File preserved"
-msgstr "Tiedosto säilytetty"
+msgstr "Tiedosto säilytetty"
-#: ../memline.c:1749
msgid "E314: Preserve failed"
-msgstr "E314: Säilyttäminen epäonnistui"
+msgstr "E314: Säilyttäminen epäonnistui"
-#: ../memline.c:1819
-#, c-format
-msgid "E315: ml_get: invalid lnum: %<PRId64>"
-msgstr "E315: ml_get: virheellinen lnum: %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "E315: ml_get: invalid lnum: %<PRId64>"
+#~ msgstr "E315: ml_get: virheellinen lnum: %ld"
-#: ../memline.c:1851
-#, c-format
-msgid "E316: ml_get: cannot find line %<PRId64>"
-msgstr "E316: ml_get: riviä %<PRId64> ei löydy"
+#, fuzzy, c-format
+#~ msgid "E316: ml_get: cannot find line %<PRId64>"
+#~ msgstr "E316: ml_get: riviä %ld ei löydy"
-#: ../memline.c:2236
msgid "E317: pointer block id wrong 3"
-msgstr "E317: osoitinlohkon tunnus väärä 3"
+msgstr "E317: osoitinlohkon tunnus väärä 3"
-#: ../memline.c:2311
msgid "stack_idx should be 0"
-msgstr "stack_idx pitää olla 0"
+msgstr "stack_idx pitää olla 0"
-#: ../memline.c:2369
msgid "E318: Updated too many blocks?"
-msgstr "E318: Päivitetty liikaa lohkoja"
+msgstr "E318: Päivitetty liikaa lohkoja"
-#: ../memline.c:2511
msgid "E317: pointer block id wrong 4"
-msgstr "E317: osoitinlohkon tunnus väärä 4"
+msgstr "E317: osoitinlohkon tunnus väärä 4"
-#: ../memline.c:2536
msgid "deleted block 1?"
msgstr "poistettu lohko 1?"
-#: ../memline.c:2707
-#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: Riviä %<PRId64> ei löydy"
+#, fuzzy, c-format
+#~ msgid "E320: Cannot find line %<PRId64>"
+#~ msgstr "E320: Riviä %ld ei löydy"
-#: ../memline.c:2916
msgid "E317: pointer block id wrong"
-msgstr "E317: osoitinlohkon tunnus väärä"
+msgstr "E317: osoitinlohkon tunnus väärä"
-#: ../memline.c:2930
msgid "pe_line_count is zero"
msgstr "pe_line_count on nolla"
-#: ../memline.c:2955
-#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: rivinumero arvoalueen ulkopuoleta: %<PRId64> on loppua suurempi"
+#, fuzzy, c-format
+#~ msgid "E322: line number out of range: %<PRId64> past the end"
+#~ msgstr "E322: rivinumero arvoalueen ulkopuoleta: %ld on loppua suurempi"
-#: ../memline.c:2959
-#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: rivimäärä väärin lohkossa %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "E323: line count wrong in block %<PRId64>"
+#~ msgstr "E323: rivimäärä väärin lohkossa %ld"
-#: ../memline.c:2999
msgid "Stack size increases"
msgstr "Pinon koko kasvaa"
-#: ../memline.c:3038
msgid "E317: pointer block id wrong 2"
-msgstr "E317: osoitinlohon tunnus väärä 2"
+msgstr "E317: osoitinlohon tunnus väärä 2"
-#: ../memline.c:3070
#, c-format
msgid "E773: Symlink loop for \"%s\""
msgstr "E773: Symlinkkisilmukka kohteelle %s"
-#: ../memline.c:3221
msgid "E325: ATTENTION"
msgstr "E325: HUOMAA"
-#: ../memline.c:3222
msgid ""
"\n"
"Found a swap file by the name \""
msgstr ""
"\n"
-"Swap-tiedosto löytyi: \""
+"Swap-tiedosto löytyi: \""
-#: ../memline.c:3226
msgid "While opening file \""
msgstr "Avattaessa tiedostoa "
-#: ../memline.c:3239
msgid " NEWER than swap file!\n"
msgstr " joka on UUDEMPI kuin swap-tiedosto!\n"
-#: ../memline.c:3244
-#, fuzzy
+#. Some of these messages are long to allow translation to
+#. * other languages.
msgid ""
"\n"
"(1) Another program may be editing the same file. If this is the case,\n"
" be careful not to end up with two different instances of the same\n"
-" file when making changes."
+" file when making changes. Quit, or continue with caution.\n"
msgstr ""
"\n"
-"(1) Toinen ohjelma saattaa käyttää samaa tiedostoa.\n"
-" Jos näin on, varo, ettet muokkaa saman tiedoston\n"
-" kahta instanssia yhtä aikaa.\n"
-
-#: ../memline.c:3245
-#, fuzzy
-msgid " Quit, or continue with caution.\n"
-msgstr " Lopeta, tai jatka.\n"
+"(1) Toinen ohjelma saattaa käyttää samaa tiedostoa.\n"
+" Jos näin on, varo, ettet muokkaa saman tiedoston\n"
+" kahta instanssia yhtä aikaa. Lopeta tai jatka varoen.\n"
-#: ../memline.c:3246
-#, fuzzy
msgid "(2) An edit session for this file crashed.\n"
-msgstr ""
-"\n"
-"(2) Ohjelma on kaatunut muokatessa tiedostoa.\n"
+msgstr "(2) Tiedostonmuokkausistunto on kaatunut.\n"
-#: ../memline.c:3247
msgid " If this is the case, use \":recover\" or \"vim -r "
-msgstr " Jos näin on, käytä komentoa :recover tai vim -r "
+msgstr " Jos näin on, käytä komentoa :recover tai vim -r "
-#: ../memline.c:3249
msgid ""
"\"\n"
" to recover the changes (see \":help recovery\").\n"
msgstr ""
"\"\n"
-" palauttaaksesi muutokset (lisätietoja: \":help recovery\").\n"
+" palauttaaksesi muutokset (lisätietoja: \":help recovery\").\n"
-#: ../memline.c:3250
msgid " If you did this already, delete the swap file \""
-msgstr " Jos teit jo näin, poista swap-tiedosto "
+msgstr " Jos teit jo näin, poista swap-tiedosto "
-#: ../memline.c:3252
msgid ""
"\"\n"
" to avoid this message.\n"
msgstr ""
"\"\n"
-" välttääksesi tämän viestin.\n"
+" välttääksesi tämän viestin.\n"
-#: ../memline.c:3450 ../memline.c:3452
msgid "Swap file \""
msgstr "Swap-tiedosto "
-#: ../memline.c:3451 ../memline.c:3455
msgid "\" already exists!"
msgstr " on jo olemassa"
-#: ../memline.c:3457
msgid "VIM - ATTENTION"
msgstr "VIM - HUOMAUTUS"
-#: ../memline.c:3459
-msgid "Swap file already exists!"
-msgstr "Swap-tiedosto on jo olemassa"
-
-#: ../memline.c:3464
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4160,7 +3809,6 @@ msgstr ""
"&Lopeta\n"
"P&eru"
-#: ../memline.c:3467
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4184,48 +3832,48 @@ msgstr ""
#.
#. ".s?a"
#. ".saa": tried enough, give up
-#: ../memline.c:3528
msgid "E326: Too many swap files found"
msgstr "E326: Liian monta swap-tiedostoa"
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: Muisti loppui! (varattaessa %<PRIu64> tavua)"
+#, fuzzy, c-format
+msgid ""
+"E303: Unable to create directory \"%s\" for swap file, recovery impossible: "
+"%s"
+msgstr "E303: Swap-tiedostoa %s ei voi avata, palautus ei onnistu"
+
+#, fuzzy
+#~ msgid "Vim: Data too large to fit into virtual memory space\n"
+#~ msgstr "arvo on liian suuri mahtumaan C:n int-tyyppiin"
+
+#, fuzzy, c-format
+#~ msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
+#~ msgstr "E342: Muisti loppui! (varattaessa %lu tavua)"
-#: ../menu.c:62
msgid "E327: Part of menu-item path is not sub-menu"
msgstr "E327: Valikkokohtapolun osa ei ole alivalikko"
-#: ../menu.c:63
msgid "E328: Menu only exists in another mode"
msgstr "E328: Valikko on olemassa vain toisessa tilassa"
-#: ../menu.c:64
#, c-format
msgid "E329: No menu \"%s\""
msgstr "E329: Ei valikkoa %s"
#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
msgid "E792: Empty menu name"
-msgstr "E792: tyhjä valikkonimi"
+msgstr "E792: tyhjä valikkonimi"
-#: ../menu.c:340
msgid "E330: Menu path must not lead to a sub-menu"
msgstr "E330: Valikkopolku ei saa johtaa alivalikkoon"
-#: ../menu.c:365
msgid "E331: Must not add menu items directly to menu bar"
-msgstr "E331: Valikkokohtia ei saa lisätä suoraan valikkopalkkiin"
+msgstr "E331: Valikkokohtia ei saa lisätä suoraan valikkopalkkiin"
-#: ../menu.c:370
msgid "E332: Separator cannot be part of a menu path"
msgstr "E332: Erotin ei voi olla valikkopolun osa"
#. Now we have found the matching menu, and we list the mappings
#. Highlight title
-#: ../menu.c:762
msgid ""
"\n"
"--- Menus ---"
@@ -4233,87 +3881,64 @@ msgstr ""
"\n"
"--- Valikot ---"
-#: ../menu.c:1313
msgid "E333: Menu path must lead to a menu item"
msgstr "E333: Valikkopolun on johdettava valikkokohtaan"
-#: ../menu.c:1330
#, c-format
msgid "E334: Menu not found: %s"
-msgstr "E334: Valikkoa ei löydy: %s"
+msgstr "E334: Valikkoa ei löydy: %s"
-#: ../menu.c:1396
#, c-format
msgid "E335: Menu not defined for %s mode"
-msgstr "E335: Valikkoa ei ole määritelty %s-tilassa"
-
-#: ../menu.c:1426
-msgid "E336: Menu path must lead to a sub-menu"
-msgstr "E336: Valikkopolun pitää johtaa alivalikkoon"
+msgstr "E335: Valikkoa ei ole määritelty %s-tilassa"
-#: ../menu.c:1447
-msgid "E337: Menu not found - check menu names"
-msgstr "E337: Valikkoa ei löytynyt - tarkista valikkojen nimet"
-
-#: ../message.c:423
#, c-format
msgid "Error detected while processing %s:"
msgstr "Virhe suoritettaessa komentoja %s:"
-#: ../message.c:445
#, c-format
msgid "line %4ld:"
msgstr "rivi %4ld:"
-#: ../message.c:617
#, c-format
msgid "E354: Invalid register name: '%s'"
msgstr "E354: Virheellinen rekisterin nimi: %s"
-#: ../message.c:986
msgid "Interrupt: "
msgstr "Keskeytys: "
-#: ../message.c:988
msgid "Press ENTER or type command to continue"
-msgstr "Paina enteriä tai kirjoita komento aloittaaksesi "
+msgstr "Paina enteriä tai kirjoita komento aloittaaksesi "
-#: ../message.c:1843
-#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s rivi %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "%s line %<PRId64>"
+#~ msgstr "%s rivi %ld"
-#: ../message.c:2392
msgid "-- More --"
-msgstr "-- Lisää --"
+msgstr "-- Lisää --"
-#: ../message.c:2398
msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
-msgstr " SPACE/d/j: ruutu/sivu/rivi alas, b/u/k: ylös, q: lopeta "
+msgstr " SPACE/d/j: ruutu/sivu/rivi alas, b/u/k: ylös, q: lopeta "
-#: ../message.c:3021 ../message.c:3031
msgid "Question"
msgstr "Kysymys"
-#: ../message.c:3023
msgid ""
"&Yes\n"
"&No"
msgstr ""
-"&Kyllä\n"
+"&Kyllä\n"
"&Ei"
-#: ../message.c:3033
msgid ""
"&Yes\n"
"&No\n"
"&Cancel"
msgstr ""
-"&Kyllä\n"
+"&Kyllä\n"
"&Ei\n"
"&Peru"
-#: ../message.c:3045
msgid ""
"&Yes\n"
"&No\n"
@@ -4321,180 +3946,165 @@ msgid ""
"&Discard All\n"
"&Cancel"
msgstr ""
-"&Kyllä\n"
+"&Kyllä\n"
"&Ei\n"
"&Tallenna kaikki\n"
"T&uhoa kaikki\n"
"&Peru"
-#: ../message.c:3058
-msgid "E766: Insufficient arguments for printf()"
-msgstr "E766: printf():lle ei annettu tarpeeksi argumentteja"
-
-#: ../message.c:3119
-msgid "E807: Expected Float argument for printf()"
-msgstr "E807: Odotettiin Float-argumenttia printf():lle"
-
-#: ../message.c:3873
-msgid "E767: Too many arguments to printf()"
-msgstr "E767: printf():lle annettiin liikaa argumentteja"
-
-#: ../misc1.c:2256
msgid "W10: Warning: Changing a readonly file"
msgstr "W10: Varoitus: Muutetaan kirjoitussuojattua tiedostoa"
-#: ../misc1.c:2537
msgid "Type number and <Enter> or click with mouse (empty cancels): "
-msgstr "Kirjoita numero ja <Enter> tai valitse hiirellä (tyhjä peruu): "
+msgstr "Kirjoita numero ja <Enter> tai valitse hiirellä (tyhjä peruu): "
-#: ../misc1.c:2539
msgid "Type number and <Enter> (empty cancels): "
-msgstr "Valitse numero ja <Enter> (tyhjä peruu): "
+msgstr "Valitse numero ja <Enter> (tyhjä peruu): "
-#: ../misc1.c:2585
msgid "1 more line"
-msgstr "1 rivi lisää"
+msgstr "1 rivi lisää"
-#: ../misc1.c:2588
msgid "1 line less"
-msgstr "1 rivi vähemmän"
+msgstr "1 rivi vähemmän"
-#: ../misc1.c:2593
-#, c-format
-msgid "%<PRId64> more lines"
-msgstr "%<PRId64> riviä lisää"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> more lines"
+#~ msgstr "%ld riviä lisää"
-#: ../misc1.c:2596
-#, c-format
-msgid "%<PRId64> fewer lines"
-msgstr "%<PRId64> riviä vähemmän"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> fewer lines"
+#~ msgstr "%ld riviä vähemmän"
-#: ../misc1.c:2599
msgid " (Interrupted)"
msgstr " (Keskeytetty)"
-#: ../misc1.c:2635
msgid "Beep!"
msgstr "Piip!"
-#: ../misc2.c:738
#, c-format
msgid "Calling shell to execute: \"%s\""
msgstr "Kutsutaan kuorta suorittamaan: %s"
-#: ../normal.c:183
+#, c-format
+#~ msgid "Invalid channel: %<PRIu64>"
+#~ msgstr ""
+
+#~ msgid "Message is not an array"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "Message is empty"
+#~ msgstr "Viesti"
+
+#~ msgid "Message type must be an integer"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "Unknown message type"
+#~ msgstr "E574: Tuntematon rekisterityyppi %d"
+
+#~ msgid "Request array size must be 4 (request) or 3 (notification)"
+#~ msgstr ""
+
+#~ msgid "ID must be a positive integer"
+#~ msgstr ""
+
+#~ msgid "Method must be a string"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "Parameters must be an array"
+#~ msgstr "merkin nimen pitää olla yksi merkki"
+
+#.
+#. * nv_*(): functions called to handle Normal and Visual mode commands.
+#. * n_*(): functions called to handle Normal mode commands.
+#. * v_*(): functions called to handle Visual mode commands.
+#.
msgid "E349: No identifier under cursor"
msgstr "E349: Ei tunnistetta osoittimen alla"
-#: ../normal.c:1866
msgid "E774: 'operatorfunc' is empty"
-msgstr "E774: operatorfunc on tyhjä"
+msgstr "E774: operatorfunc on tyhjä"
-#: ../normal.c:2637
msgid "Warning: terminal cannot highlight"
msgstr "Varoitus: terminaalista puuttuu korostus"
-#: ../normal.c:2807
msgid "E348: No string under cursor"
msgstr "E348: Ei merkkijonoa kursorin alla"
-#: ../normal.c:3937
msgid "E352: Cannot erase folds with current 'foldmethod'"
-msgstr "E352: taitoksia ei voi poistaa tällä foldmethodilla"
+msgstr "E352: taitoksia ei voi poistaa tällä foldmethodilla"
-#: ../normal.c:5897
msgid "E664: changelist is empty"
-msgstr "E664: muutoslista on tyhjä"
+msgstr "E664: muutoslista on tyhjä"
-#: ../normal.c:5899
msgid "E662: At start of changelist"
msgstr "E662: Muutoslistan alussa"
-#: ../normal.c:5901
msgid "E663: At end of changelist"
msgstr "E663: Muutoslistan lopussa"
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
-msgstr "Komento :quit<Enter> lopettaa Vimin"
+#, fuzzy
+#~ msgid "Type :quit<Enter> to exit Nvim"
+#~ msgstr "Komento :quit<Enter> lopettaa Vimin"
-#: ../ops.c:248
#, c-format
msgid "1 line %sed 1 time"
-msgstr "1 riviä %s kerran"
+msgstr "1 riviä %s kerran"
-#: ../ops.c:250
#, c-format
msgid "1 line %sed %d times"
-msgstr "1 riviä %s %d kertaa"
+msgstr "1 riviä %s %d kertaa"
-#: ../ops.c:253
-#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> riviä %s kerran"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines %sed 1 time"
+#~ msgstr "%ld riviä %s kerran"
-#: ../ops.c:256
-#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> riviä %s %d kertaa"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines %sed %d times"
+#~ msgstr "%ld riviä %s %d kertaa"
-#: ../ops.c:592
-#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "%<PRId64> riviä sisennettävänä..."
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines to indent... "
+#~ msgstr "%ld riviä sisennettävänä..."
-#: ../ops.c:634
msgid "1 line indented "
msgstr "1 rivi sisennetty "
-#: ../ops.c:636
-#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "%<PRId64> riviä sisennetty "
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines indented "
+#~ msgstr "%ld riviä sisennetty "
-#: ../ops.c:938
msgid "E748: No previously used register"
-msgstr "E748: Ei aiemmin käytettyjä rekisterejä"
+msgstr "E748: Ei aiemmin käytettyjä rekisterejä"
-#. must display the prompt
-#: ../ops.c:1433
-msgid "cannot yank; delete anyway"
-msgstr "Ei voi kopioida; poista joka tapauksessa"
-
-#: ../ops.c:1929
msgid "1 line changed"
msgstr "1 rivi muuttui"
-#: ../ops.c:1931
-#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "%<PRId64> riviä muuttui"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines changed"
+#~ msgstr "%ld riviä muuttui"
-#: ../ops.c:2521
msgid "block of 1 line yanked"
msgstr "1 rivin lohko kopioitu"
-#: ../ops.c:2523
msgid "1 line yanked"
msgstr "1 rivi kopioitu"
-#: ../ops.c:2525
-#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "lohko %<PRId64> riviltä kopioitu"
+#, fuzzy, c-format
+#~ msgid "block of %<PRId64> lines yanked"
+#~ msgstr "lohko %ld riviltä kopioitu"
-#: ../ops.c:2528
-#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "%<PRId64> riviä kopioitu"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines yanked"
+#~ msgstr "%ld riviä kopioitu"
-#: ../ops.c:2710
#, c-format
msgid "E353: Nothing in register %s"
-msgstr "E353: Rekisterissä %s ei ole mitään"
+msgstr "E353: Rekisterissä %s ei ole mitään"
#. Highlight title
-#: ../ops.c:3185
msgid ""
"\n"
"--- Registers ---"
@@ -4502,207 +4112,142 @@ msgstr ""
"\n"
"--- Rekisterit ---"
-#: ../ops.c:4455
-msgid "Illegal register name"
-msgstr "Virheellinen rekisterin nimi"
-
-#: ../ops.c:4533
msgid ""
-"\n"
-"# Registers:\n"
+"E883: search pattern and expression register may not contain two or more "
+"lines"
msgstr ""
-"\n"
-"# Rekisterit:\n"
+"E883: hakulauseke- ja -ilmausrekisteri ei voi sisältää kahta tai useampaa "
+"riviä"
-#: ../ops.c:4575
-#, c-format
-msgid "E574: Unknown register type %d"
-msgstr "E574: Tuntematon rekisterityyppi %d"
-
-#: ../ops.c:5089
-#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> saraketta, "
+#, fuzzy, c-format
+#~ msgid "%<PRId64> Cols; "
+#~ msgstr "%ld saraketta, "
-#: ../ops.c:5097
-#, c-format
+#, fuzzy, c-format
msgid ""
"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
"%<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Valittu %s%<PRId64>/%<PRId64> riviä, %<PRId64>/%<PRId64> sanaa, %<PRId64>/"
-"%<PRId64> tavua"
+msgstr "Valittu %s%ld/%ld riviä, %lld/%lld sanaa, %lld/%lld tavua"
-#: ../ops.c:5105
-#, c-format
+#, fuzzy, c-format
msgid ""
"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
msgstr ""
-"Valittu %s%<PRId64>/%<PRId64> riviä, %<PRId64>/%<PRId64> sanaa, %<PRId64>/"
-"%<PRId64> merkkiä, %<PRId64>/%<PRId64> tavua"
+"Valittu %s%ld/%ld riviä, %lld/%lld sanaa, %lld/%lld merkkiä, %lld/%lld tavua"
-#: ../ops.c:5123
-#, c-format
+#, fuzzy, c-format
msgid ""
"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
"%<PRId64> of %<PRId64>"
-msgstr ""
-"Sarake %s/%s, Rivi %<PRId64>/%<PRId64>, sana %<PRId64>/%<PRId64>, tavu "
-"%<PRId64>/%<PRId64>"
+msgstr "Sarake %s/%s, Rivi %ld/%ld, sana %lld/%lld, tavu %lld/%lld"
-#: ../ops.c:5133
-#, c-format
+#, fuzzy, c-format
msgid ""
"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
msgstr ""
-"Sarake %s/%s, rivi %<PRId64>/%<PRId64>, sana %<PRId64>/%<PRId64>, merkki "
-"%<PRId64>/%<PRId64>, tavu %<PRId64>/%<PRId64>"
+"Sarake %s/%s, rivi %ld/%ld, sana %lld/%lld, merkki %lld/%lld, tavu %lld/%lld"
# Unicode Byte Order Mark
-#: ../ops.c:5146
-#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> BOMista)"
-
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr "%<%f%h%m%=Sivu %N"
-
-#: ../option.c:1574
-msgid "Thanks for flying Vim"
-msgstr "Kiitos että ajoit Vimiä"
+#, fuzzy, c-format
+#~ msgid "(+%<PRId64> for BOM)"
+#~ msgstr "(+%ld BOMista)"
#. found a mismatch: skip
-#: ../option.c:2698
msgid "E518: Unknown option"
msgstr "E518: Tuntematon asetus"
-#: ../option.c:2709
-msgid "E519: Option not supported"
-msgstr "E519: Asetusta ei tueta"
-
-#: ../option.c:2740
msgid "E520: Not allowed in a modeline"
-msgstr "E520: Ei sallitu modeline-rivillä"
+msgstr "E520: Ei sallitu modeline-rivillä"
-#: ../option.c:2815
msgid "E846: Key code not set"
-msgstr ""
+msgstr "E846: Avainkoodi puuttuu"
-#: ../option.c:2924
msgid "E521: Number required after ="
-msgstr "E521: =:n jälkeen tarvitaan luku"
-
-#: ../option.c:3226 ../option.c:3864
-msgid "E522: Not found in termcap"
-msgstr "E522: Puuttuu termcapista"
+msgstr "E521: =:n jälkeen tarvitaan luku"
-#: ../option.c:3335
#, c-format
msgid "E539: Illegal character <%s>"
msgstr "E539: Virheellinen merkki <%s>"
-#: ../option.c:3862
-msgid "E529: Cannot set 'term' to empty string"
-msgstr "E529: Termiä ei voi asettaa tyhjäksi merkkijonoksi"
+#, c-format
+msgid "For option %s"
+msgstr "Asetukselle %s"
-#: ../option.c:3885
msgid "E589: 'backupext' and 'patchmode' are equal"
msgstr "E589: backupext ja patchmod ovat samat"
-#: ../option.c:3964
msgid "E834: Conflicts with value of 'listchars'"
msgstr "E834: listcharsin arvoissa on ristiriitoja"
-#: ../option.c:3966
msgid "E835: Conflicts with value of 'fillchars'"
msgstr "E835: fillcharsin arvossa on ristiriitoja"
-#: ../option.c:4163
msgid "E524: Missing colon"
msgstr "E524: Kaksoispiste puuttuu"
-#: ../option.c:4165
msgid "E525: Zero length string"
msgstr "E525: Nollan pituinen merkkijono"
-#: ../option.c:4220
#, c-format
msgid "E526: Missing number after <%s>"
-msgstr "E526: Lukuarvo puuttuu merkkijonon <%s> jälkeen"
+msgstr "E526: Lukuarvo puuttuu merkkijonon <%s> jälkeen"
-#: ../option.c:4232
msgid "E527: Missing comma"
msgstr "E527: Pilkku puuttuu"
-#: ../option.c:4239
msgid "E528: Must specify a ' value"
-msgstr "E528: '-arvo pitää antaa"
+msgstr "E528: '-arvo pitää antaa"
-#: ../option.c:4271
msgid "E595: contains unprintable or wide character"
-msgstr "E595: Sisältää tulostumattomia tai leveitä merkkejä"
+msgstr "E595: Sisältää tulostumattomia tai leveitä merkkejä"
-#: ../option.c:4469
#, c-format
msgid "E535: Illegal character after <%c>"
-msgstr "E535: Virheellinen merkki merkin <%c> jälkeen"
+msgstr "E535: Virheellinen merkki merkin <%c> jälkeen"
-#: ../option.c:4534
msgid "E536: comma required"
msgstr "E536: pilkku puuttuu"
-#: ../option.c:4543
#, c-format
msgid "E537: 'commentstring' must be empty or contain %s"
-msgstr "E537: commentstringin pitää olla tyhjä tai sisältää %s"
+msgstr "E537: commentstringin pitää olla tyhjä tai sisältää %s"
-#: ../option.c:4928
msgid "E540: Unclosed expression sequence"
msgstr "E540: Sulkematon lausekesarja"
-#: ../option.c:4932
msgid "E541: too many items"
msgstr "E541: liikaa kohteita"
-#: ../option.c:4934
msgid "E542: unbalanced groups"
-msgstr "E542: epätasapainoisia ryhmiä"
+msgstr "E542: epätasapainoisia ryhmiä"
-#: ../option.c:5148
msgid "E590: A preview window already exists"
msgstr "E590: Esikatseluikkuna on jo olemassa"
-#: ../option.c:5311
msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
-msgstr "W17: Arabialle pitää olla UTF-8:aa, aseta :set encoding=utf-8"
+msgstr "W17: Arabialle pitää olla UTF-8:aa, aseta :set encoding=utf-8"
-#: ../option.c:5623
#, c-format
msgid "E593: Need at least %d lines"
-msgstr "E593: Tarvitaan ainakin %d riviä"
+msgstr "E593: Tarvitaan ainakin %d riviä"
-#: ../option.c:5631
#, c-format
msgid "E594: Need at least %d columns"
msgstr "E594: Tarvitaan ainakin %d saraketta"
-#: ../option.c:6011
#, c-format
msgid "E355: Unknown option: %s"
msgstr "E355: Tuntematon asetus: %s"
#. There's another character after zeros or the string
-#. * is empty. In both cases, we are trying to set a
-#. * num option using a string.
-#: ../option.c:6037
+#. is empty. In both cases, we are trying to set a
+#. num option using a string.
#, c-format
msgid "E521: Number required: &%s = '%s'"
msgstr "E521: tarvitaan luku: &%s = '%s'"
-#: ../option.c:6149
msgid ""
"\n"
"--- Terminal codes ---"
@@ -4710,7 +4255,6 @@ msgstr ""
"\n"
"--- Terminaalikoodit ---"
-#: ../option.c:6151
msgid ""
"\n"
"--- Global option values ---"
@@ -4718,7 +4262,6 @@ msgstr ""
"\n"
"--- Globaalit asetukset ---"
-#: ../option.c:6153
msgid ""
"\n"
"--- Local option values ---"
@@ -4726,7 +4269,6 @@ msgstr ""
"\n"
"--- Paikalliset asetukset ---"
-#: ../option.c:6155
msgid ""
"\n"
"--- Options ---"
@@ -4734,29 +4276,24 @@ msgstr ""
"\n"
"--- Asetukset ---"
-#: ../option.c:6816
msgid "E356: get_varp ERROR"
msgstr "E356: get_varp-virhe"
-#: ../option.c:7696
#, c-format
msgid "E357: 'langmap': Matching character missing for %s"
-msgstr "E357: langmap: Merkkiin %s täsmäävä merkki puuttuu"
+msgstr "E357: langmap: Merkkiin %s täsmäävä merkki puuttuu"
-#: ../option.c:7715
#, c-format
msgid "E358: 'langmap': Extra characters after semicolon: %s"
-msgstr "E358: langmap: ylimääräisiä merkkejä puolipisteen jälkeen: %s"
+msgstr "E358: langmap: ylimääräisiä merkkejä puolipisteen jälkeen: %s"
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"Kuoren suoritus ei onnistu "
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = %s"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Virhe luettaessa syötettä, poistutaan...\n"
-#: ../os/shell.c:439
msgid ""
"\n"
"shell returned "
@@ -4764,8 +4301,18 @@ msgstr ""
"\n"
"kuoren palautusarvo "
-# mikä security context?
-#: ../os_unix.c:465 ../os_unix.c:471
+#~ msgid ""
+#~ "\n"
+#~ "shell failed to start: "
+#~ msgstr ""
+
+#. Can happen if system() tries to send input to a shell command that was
+#. backgrounded (:call system("cat - &", "foo")). #3529 #5241
+#, fuzzy, c-format
+#~ msgid "E5677: Error writing input to shell-command: %s"
+#~ msgstr "E677: Väliaikaistiedostoon kirjoittaminen ei onnistunut"
+
+# mikä security context?
msgid ""
"\n"
"Could not get security context for "
@@ -4773,7 +4320,6 @@ msgstr ""
"\n"
"Ei saatu turvallisuuskontekstia kohteelle "
-#: ../os_unix.c:479
msgid ""
"\n"
"Could not set security context for "
@@ -4781,947 +4327,897 @@ msgstr ""
"\n"
"Ei voitu asettaa turvallisuuskontekstia kohteelle "
-#: ../os_unix.c:1558 ../os_unix.c:1647
-#, c-format
-msgid "dlerror = \"%s\""
-msgstr "dlerror = %s"
-
-#: ../path.c:1449
#, c-format
msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: Tiedosto %s ei löydy polulta"
+msgstr "E447: Tiedosto %s ei löydy polulta"
-#: ../quickfix.c:359
#, c-format
msgid "E372: Too many %%%c in format string"
msgstr "E372: Liikaa %%%c-juttuja muotoilumerkkijonossa"
-#: ../quickfix.c:371
#, c-format
msgid "E373: Unexpected %%%c in format string"
msgstr "E373: Odottamaton %%%c muotoilumerkkijonossa"
-#: ../quickfix.c:420
msgid "E374: Missing ] in format string"
msgstr "E374: ] puuttuu muotoilemerkkijonosta"
-#: ../quickfix.c:431
#, c-format
msgid "E375: Unsupported %%%c in format string"
msgstr "E375: Tukematon %%%c muotoilumerkkijonossa"
-#: ../quickfix.c:448
#, c-format
msgid "E376: Invalid %%%c in format string prefix"
msgstr "E376: Virheellinen %%%c muotoilumerkkijonon alussa"
-#: ../quickfix.c:454
#, c-format
msgid "E377: Invalid %%%c in format string"
msgstr "E377: Virheellinen %%%c muotoilumerkkijonossa"
#. nothing found
-#: ../quickfix.c:477
msgid "E378: 'errorformat' contains no pattern"
msgstr "E378: errorformatissa ei ole kuvioita"
-#: ../quickfix.c:695
msgid "E379: Missing or empty directory name"
-msgstr "E379: Puuttuva tai tyhjä hakemiston nimi"
+msgstr "E379: Puuttuva tai tyhjä hakemiston nimi"
-#: ../quickfix.c:1305
msgid "E553: No more items"
-msgstr "E553: Ei enää kohteita"
+msgstr "E553: Ei enää kohteita"
+
+msgid "E924: Current window was closed"
+msgstr "E924: Nykyinen ikkuna on suljettu"
+
+msgid "E925: Current quickfix was changed"
+msgstr "E925: Nykyinen quickfix on muuttunut"
+
+msgid "E926: Current location list was changed"
+msgstr "E926: Nykyinen sijaintiluettelo on muuttunut"
-#: ../quickfix.c:1674
#, c-format
msgid "(%d of %d)%s%s: "
msgstr "(%d/%d)%s%s: "
-#: ../quickfix.c:1676
msgid " (line deleted)"
msgstr " (rivi poistettu)"
-#: ../quickfix.c:1863
+#, c-format
+msgid "%serror list %d of %d; %d errors "
+msgstr "%svirhelista %d/%d, %d virhettä"
+
msgid "E380: At bottom of quickfix stack"
msgstr "E380: quickfix-pinon pohjalla"
-#: ../quickfix.c:1869
msgid "E381: At top of quickfix stack"
msgstr "E381: quickfix-pinon huipulla"
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "virhelista %d/%d, %d virhettä"
+msgid "No entries"
+msgstr "Ei kenttiä"
-#: ../quickfix.c:2427
msgid "E382: Cannot write, 'buftype' option is set"
msgstr "E382: Ei voi kirjoittaa, buftype asetettu"
-#: ../quickfix.c:2812
msgid "E683: File name missing or invalid pattern"
msgstr "E683: Tiedostonimi puuttuu tai kuvio on viallinen"
-#: ../quickfix.c:2911
#, c-format
msgid "Cannot open file \"%s\""
msgstr "Tiedostoa %s ei voi avata"
-#: ../quickfix.c:3429
msgid "E681: Buffer is not loaded"
msgstr "E681: Puskuria ei ole ladattu"
-#: ../quickfix.c:3487
msgid "E777: String or List expected"
-msgstr "E777: Pitää olla merkkijono tai lista"
+msgstr "E777: Pitää olla merkkijono tai lista"
-#: ../regexp.c:359
#, c-format
msgid "E369: invalid item in %s%%[]"
msgstr "E369: virheellinen olio kohdassa %s%%[]"
-#: ../regexp.c:374
#, c-format
msgid "E769: Missing ] after %s["
-msgstr "E769: ] puuttuu merkinnän %s[ jäljestä"
+msgstr "E769: ] puuttuu merkinnän %s[ jäljestä"
-#: ../regexp.c:375
#, c-format
msgid "E53: Unmatched %s%%("
msgstr "E53: Pariton %s%%("
-#: ../regexp.c:376
#, c-format
msgid "E54: Unmatched %s("
msgstr "E54: Pariton %s("
-#: ../regexp.c:377
#, c-format
msgid "E55: Unmatched %s)"
msgstr "E55: Pariton %s)"
-#: ../regexp.c:378
msgid "E66: \\z( not allowed here"
-msgstr "E66: \\z( ei ole sallittu tässä"
+msgstr "E66: \\z( ei ole sallittu tässä"
-#: ../regexp.c:379
msgid "E67: \\z1 et al. not allowed here"
-msgstr "E67: \\z1 jne. ei ole sallittu tässä"
+msgstr "E67: \\z1 jne. ei ole sallittu tässä"
-#: ../regexp.c:380
#, c-format
msgid "E69: Missing ] after %s%%["
-msgstr "E69: ] puuttuu merkinnän %s%%[ jäljestä"
+msgstr "E69: ] puuttuu merkinnän %s%%[ jäljestä"
-#: ../regexp.c:381
#, c-format
msgid "E70: Empty %s%%[]"
-msgstr "E70: Tyhjä %s%%[]"
+msgstr "E70: Tyhjä %s%%[]"
-#: ../regexp.c:1209 ../regexp.c:1224
msgid "E339: Pattern too long"
-msgstr "E339: Liian pitkä kuvio"
+msgstr "E339: Liian pitkä kuvio"
-#: ../regexp.c:1371
msgid "E50: Too many \\z("
-msgstr "E50: Liikaa merkkejä \\z("
+msgstr "E50: Liikaa merkkejä \\z("
-#: ../regexp.c:1378
#, c-format
msgid "E51: Too many %s("
-msgstr "E51: Liikaa merkkejä %s("
+msgstr "E51: Liikaa merkkejä %s("
-#: ../regexp.c:1427
msgid "E52: Unmatched \\z("
msgstr "E52: Pariton \\z("
-#: ../regexp.c:1637
#, c-format
msgid "E59: invalid character after %s@"
-msgstr "E59: virheellinen merkki kohdan %s@ jälkeen"
+msgstr "E59: virheellinen merkki kohdan %s@ jälkeen"
-#: ../regexp.c:1672
#, c-format
msgid "E60: Too many complex %s{...}s"
msgstr "E60: Liikaa monimutkaisia ilmauksia %s{...}s"
-#: ../regexp.c:1687
#, c-format
msgid "E61: Nested %s*"
-msgstr "E61: Sisäkkäistetty %s*"
+msgstr "E61: Sisäkkäistetty %s*"
-#: ../regexp.c:1690
#, c-format
msgid "E62: Nested %s%c"
-msgstr "E62: Sisäkkäistetty %s%c"
+msgstr "E62: Sisäkkäistetty %s%c"
-#: ../regexp.c:1800
msgid "E63: invalid use of \\_"
-msgstr "E63: väärinkäytetty \\_"
+msgstr "E63: väärinkäytetty \\_"
-#: ../regexp.c:1850
#, c-format
msgid "E64: %s%c follows nothing"
-msgstr "E64: %s%c jälkeen ei minkään"
+msgstr "E64: %s%c jälkeen ei minkään"
-#: ../regexp.c:1902
msgid "E65: Illegal back reference"
-msgstr "E65: Virheellinen täsmäysviittaus"
+msgstr "E65: Virheellinen täsmäysviittaus"
-#: ../regexp.c:1943
msgid "E68: Invalid character after \\z"
-msgstr "E68: Virheellinen merkki ilmauksen \\z jälkeen"
+msgstr "E68: Virheellinen merkki ilmauksen \\z jälkeen"
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
#, c-format
msgid "E678: Invalid character after %s%%[dxouU]"
-msgstr "E678: Virheellinen merkki merkinnän %s%%[dxouU] jäljessä"
+msgstr "E678: Virheellinen merkki merkinnän %s%%[dxouU] jäljessä"
-#: ../regexp.c:2107
#, c-format
msgid "E71: Invalid character after %s%%"
-msgstr "E71: Virheellinen merkki merkinnän %s%% jäljessä"
+msgstr "E71: Virheellinen merkki merkinnän %s%% jäljessä"
+
+#, c-format
+msgid "E888: (NFA regexp) cannot repeat %s"
+msgstr "E888: (NFA-säänn. ilmaus) ei voi toistaa kohdetta %s"
-#: ../regexp.c:3017
#, c-format
msgid "E554: Syntax error in %s{...}"
msgstr "E554: Syntaksivirhe ilmauksessa %s{...}"
-#: ../regexp.c:3805
msgid "External submatches:\n"
-msgstr "Ulkoisia alitäsmäyksiä:\n"
+msgstr "Ulkoisia alitäsmäyksiä:\n"
-#: ../regexp.c:7022
msgid ""
"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
"used "
msgstr ""
+"E864: \\%#=-merkkien perään voi tulla vain 0, 1 tai 2. Käytetään "
+"automaattista engineä "
-#: ../regexp_nfa.c:239
-msgid "E865: (NFA) Regexp end encountered prematurely"
-msgstr ""
-
-#: ../regexp_nfa.c:240
-#, c-format
-msgid "E866: (NFA regexp) Misplaced %c"
-msgstr ""
-
-#: ../regexp_nfa.c:242
-#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr ""
-
-#: ../regexp_nfa.c:1261
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\z%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1387
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1802
-#, c-format
-msgid "E869: (NFA) Unknown operator '\\@%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1831
-msgid "E870: (NFA regexp) Error reading repetition limits"
-msgstr ""
-
-#. Can't have a multi follow a multi.
-#: ../regexp_nfa.c:1895
-msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
-msgstr ""
-
-#. Too many `('
-#: ../regexp_nfa.c:2037
-msgid "E872: (NFA regexp) Too many '('"
-msgstr ""
-
-#: ../regexp_nfa.c:2042
-#, fuzzy
-msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E50: Liikaa merkkejä \\z("
-
-#: ../regexp_nfa.c:2066
-msgid "E873: (NFA regexp) proper termination error"
-msgstr ""
-
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
-msgstr ""
-
-#: ../regexp_nfa.c:3298
-msgid ""
-"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
-"left on stack"
-msgstr ""
-
-#: ../regexp_nfa.c:3302
-msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
-msgstr ""
-
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
-msgstr ""
+msgid "Switching to backtracking RE engine for pattern: "
+msgstr "Vaihdetaan käyttämään backtrackkaavaa RE-engineä ilmaukselle: "
-#: ../regexp_nfa.c:4840
-#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr ""
-
-#: ../regexp_nfa.c:6049
-#, fuzzy
-msgid "Could not open temporary log file for writing "
-msgstr "E828: Kumoustiedoston avaus kirjoittamista varten ei onnistu: %s"
+#~ msgid " TERMINAL"
+#~ msgstr ""
# tiloja
-#: ../screen.c:7435
msgid " VREPLACE"
msgstr " VKORVAUS"
-#: ../screen.c:7437
msgid " REPLACE"
msgstr " KORVAUS"
-#: ../screen.c:7440
msgid " REVERSE"
-msgstr " KÄÄNTEIS"
+msgstr " KÄÄNTEIS"
-#: ../screen.c:7441
msgid " INSERT"
-msgstr " SYÖTTÖ"
+msgstr " SYÖTTÖ"
-#: ../screen.c:7443
msgid " (insert)"
-msgstr " (syöttö)"
+msgstr " (syöttö)"
-#: ../screen.c:7445
msgid " (replace)"
msgstr " (korvaus)"
-#: ../screen.c:7447
msgid " (vreplace)"
msgstr " (vkorvaus)"
-#: ../screen.c:7449
msgid " Hebrew"
msgstr " Heprea"
-#: ../screen.c:7454
msgid " Arabic"
msgstr " Arabia"
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (kieli)"
-
-#: ../screen.c:7459
msgid " (paste)"
msgstr " (liitos)"
-#: ../screen.c:7469
msgid " VISUAL"
msgstr " VALINTA"
-#: ../screen.c:7470
msgid " VISUAL LINE"
msgstr " VALINTARIVI"
-#: ../screen.c:7471
msgid " VISUAL BLOCK"
msgstr " VALINTALOHKO"
-#: ../screen.c:7472
msgid " SELECT"
msgstr " WALINTA"
-#: ../screen.c:7473
msgid " SELECT LINE"
msgstr " WALINTARIVI"
-#: ../screen.c:7474
msgid " SELECT BLOCK"
msgstr " WALINTALOHKO"
-#: ../screen.c:7486 ../screen.c:7541
msgid "recording"
msgstr "tallennetaan"
-#: ../search.c:487
#, c-format
msgid "E383: Invalid search string: %s"
msgstr "E383: Viallinen hakujono: %s"
-#: ../search.c:832
#, c-format
msgid "E384: search hit TOP without match for: %s"
-msgstr "E384: Haku pääsi alkuun löytämättä jonoa: %s"
+msgstr "E384: Haku pääsi alkuun löytämättä jonoa: %s"
-#: ../search.c:835
#, c-format
msgid "E385: search hit BOTTOM without match for: %s"
-msgstr "E385: Haku pääsi loppuun löytämättä jonoa: %s"
+msgstr "E385: Haku pääsi loppuun löytämättä jonoa: %s"
-#: ../search.c:1200
msgid "E386: Expected '?' or '/' after ';'"
-msgstr "E386: ;:n jälkeen pitää olla ? tai /"
+msgstr "E386: ;:n jälkeen pitää olla ? tai /"
-#: ../search.c:4085
msgid " (includes previously listed match)"
-msgstr " (sisältää viimeksi luetellun täsmäyksen)"
+msgstr " (sisältää viimeksi luetellun täsmäyksen)"
#. cursor at status line
-#: ../search.c:4104
msgid "--- Included files "
-msgstr "--- Sisällytetyt tiedostot "
+msgstr "--- Sisällytetyt tiedostot "
-#: ../search.c:4106
msgid "not found "
-msgstr "ei löytynyt "
+msgstr "ei löytynyt "
-#: ../search.c:4107
msgid "in path ---\n"
msgstr "polusta ---\n"
-#: ../search.c:4168
msgid " (Already listed)"
msgstr " (Jo lueteltu)"
-#: ../search.c:4170
msgid " NOT FOUND"
-msgstr " EI LÖYTYNYT"
+msgstr " EI LÖYTYNYT"
-#: ../search.c:4211
#, c-format
msgid "Scanning included file: %s"
-msgstr "Haku sisälsi tiedoston: %s"
+msgstr "Haku sisälsi tiedoston: %s"
-#: ../search.c:4216
#, c-format
msgid "Searching included file %s"
-msgstr "Haku sisälsi tiedoston %s"
+msgstr "Haku sisälsi tiedoston %s"
-#: ../search.c:4405
msgid "E387: Match is on current line"
-msgstr "E387: Täsmäys tällä rivillä"
+msgstr "E387: Täsmäys tällä rivillä"
-#: ../search.c:4517
msgid "All included files were found"
-msgstr "Kaikki sisällytetyt rivit löytyivät"
+msgstr "Kaikki sisällytetyt rivit löytyivät"
-#: ../search.c:4519
msgid "No included files"
-msgstr "Ei sisällytettyjä tiedostoja"
+msgstr "Ei sisällytettyjä tiedostoja"
-#: ../search.c:4527
msgid "E388: Couldn't find definition"
-msgstr "E388: Määritelmä ei löydy"
+msgstr "E388: Määritelmä ei löydy"
-#: ../search.c:4529
msgid "E389: Couldn't find pattern"
-msgstr "E389: kuvio ei löydy"
+msgstr "E389: kuvio ei löydy"
+
+#~ msgid "too few bytes read"
+#~ msgstr ""
-#: ../search.c:4668
-msgid "Substitute "
-msgstr "Korvaa "
+#, fuzzy, c-format
+#~ msgid "System error while skipping in ShaDa file: %s"
+#~ msgstr "E782: virhe luettaessa .sug-tiedostoa: %s"
-#: ../search.c:4681
#, c-format
-msgid ""
-"\n"
-"# Last %sSearch Pattern:\n"
-"~"
-msgstr ""
-"\n"
-"# Edellinen %sHakulauseke:\n"
-"~"
+#~ msgid ""
+#~ "Error while reading ShaDa file: last entry specified that it occupies "
+#~ "%<PRIu64> bytes, but file ended earlier"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "System error while closing ShaDa file: %s"
+#~ msgstr "E782: virhe luettaessa .sug-tiedostoa: %s"
+
+#, fuzzy, c-format
+#~ msgid "System error while writing ShaDa file: %s"
+#~ msgstr "E782: virhe luettaessa .sug-tiedostoa: %s"
+
+#, fuzzy, c-format
+#~ msgid "Reading ShaDa file \"%s\"%s%s%s"
+#~ msgstr "Luetaan viminfo-tiedostoa \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " info"
+
+msgid " marks"
+msgstr " merkit"
+
+msgid " oldfiles"
+msgstr " vanhaatiedostoa"
+
+msgid " FAILED"
+msgstr " EPÄONNISTUI"
+
+#, c-format
+#~ msgid "System error while opening ShaDa file %s for reading: %s"
+#~ msgstr ""
+
+#~ msgid "additional elements of ShaDa "
+#~ msgstr ""
+
+#~ msgid "additional data of ShaDa "
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "Failed to write variable %s"
+#~ msgstr "ei voitu vaihtaa puskuriin %d"
+
+#, c-format
+#~ msgid ""
+#~ "Failed to parse ShaDa file due to a msgpack parser error at position "
+#~ "%<PRIu64>"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "Failed to parse ShaDa file: incomplete msgpack string at position %<PRIu64>"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "Failed to parse ShaDa file: extra bytes in msgpack string at position "
+#~ "%<PRIu64>"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "System error while opening ShaDa file %s for reading to merge before writing "
+#~ "it: %s"
+#~ msgstr ""
+
+#. Tried names from .tmp.a to .tmp.z, all failed. Something must be
+#. wrong then.
+#, c-format
+#~ msgid "E138: All %s.tmp.X files exist, cannot write ShaDa file!"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "System error while opening temporary ShaDa file %s for writing: %s"
+#~ msgstr "Väliaikaislokitiedoston avaus kirjoittamista varten ei onnistu"
+
+#, c-format
+#~ msgid "Failed to create directory %s for writing ShaDa file: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "System error while opening ShaDa file %s for writing: %s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "Writing ShaDa file \"%s\""
+#~ msgstr "Kirjoitetaan viminfo-tiedostoa %s"
+
+#, fuzzy, c-format
+#~ msgid "Failed setting uid and gid for file %s: %s"
+#~ msgstr "Ladattu kumoustiedoto %s"
+
+#, fuzzy, c-format
+#~ msgid "E137: ShaDa file is not writable: %s"
+#~ msgstr "E137: Viminfo-tiedostoon ei voitu kirjoittaa: %s"
+
+#, fuzzy, c-format
+#~ msgid "Can't rename ShaDa file from %s to %s!"
+#~ msgstr "E886: Viminfo-tiedostoa ei voit uudelleennimetä nimelle %s"
+
+#, fuzzy, c-format
+#~ msgid "Did not rename %s because %s does not looks like a ShaDa file"
+#~ msgstr " [ei näytä Vimin swap-tiedostolta]"
+
+#, c-format
+#~ msgid "Did not rename %s to %s because there were errors during writing it"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Do not forget to remove %s or rename it manually to %s."
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "System error while reading ShaDa file: %s"
+#~ msgstr "E782: virhe luettaessa .sug-tiedostoa: %s"
+
+#, fuzzy, c-format
+#~ msgid "System error while reading integer from ShaDa file: %s"
+#~ msgstr "E782: virhe luettaessa .sug-tiedostoa: %s"
+
+#, c-format
+#~ msgid ""
+#~ "Error while reading ShaDa file: expected positive integer at position "
+#~ "%<PRIu64>, but got nothing"
+#~ msgstr ""
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: Muotoiluvirhe oikolukutiedostossa"
+#, c-format
+#~ msgid ""
+#~ "Error while reading ShaDa file: expected positive integer at position "
+#~ "%<PRIu64>"
+#~ msgstr ""
+
+#. kSDItemUnknown cannot possibly pass that far because it is -1 and that
+#. will fail in msgpack_read_uint64. But kSDItemMissing may and it will
+#. otherwise be skipped because (1 << 0) will never appear in flags.
+#, c-format
+#~ msgid ""
+#~ "Error while reading ShaDa file: there is an item at position %<PRIu64> that "
+#~ "must not be there: Missing items are for internal uses only"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+#~ "entry that is not a dictionary"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+#~ "entry with invalid line number"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+#~ "entry with invalid column number"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+#~ "entry that does not have a file name"
+#~ msgstr ""
+
+#. values for ts_isdiff
+#. no different byte (yet)
+#. different byte found
+#. inserting character
+#. values for ts_flags
+#. already checked that prefix is OK
+#. tried split at this point
+#. did a delete, "ts_delidx" has index
+#. special values ts_prefixdepth
+#. not using prefixes
+#. walking through the prefix tree
+#. highest value that's not special
+#. mode values for find_word
+#. find word case-folded
+#. find keep-case word
+#. find word after prefix
+#. find case-folded compound word
+#. find keep-case compound word
+#, fuzzy
+#~ msgid "E759: Format error in spell file"
+#~ msgstr "E297: Kirjoitusvirhe swap-tiedostossa"
+
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Oikaisuluku ei ole päällä"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr "Varoitus: Ei löydetty sanalistaa %s.%s.spl tai %s.ascii.spl"
+
+#. This is probably an error. Give a warning and
+#. accept the words anyway.
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Varoitus: osaa %s ei tueta"
+
+msgid "Sorry, no suggestions"
+msgstr "ei ehdotuksia"
+
+#, fuzzy, c-format
+#~ msgid "Sorry, only %<PRId64> suggestions"
+#~ msgstr "vain %ld ehdotusta"
+
+#. 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"
-#: ../spell.c:952
msgid "E758: Truncated spell file"
msgstr "E758: Oikolukutiedosto katkaistu"
-#: ../spell.c:953
#, c-format
msgid "Trailing text in %s line %d: %s"
-msgstr "Tekstiä rivin perässä tiedostossa %s rivillä %d: %s"
+msgstr "Tekstiä rivin perässä tiedostossa %s rivillä %d: %s"
-#: ../spell.c:954
#, c-format
msgid "Affix name too long in %s line %d: %s"
-msgstr "Affiksin nimi on liian pitkä tiedostossa %s rivillä %d: %s"
+msgstr "Affiksin nimi on liian pitkä tiedostossa %s rivillä %d: %s"
-#: ../spell.c:955
msgid "E761: Format error in affix file FOL, LOW or UPP"
msgstr "E761: Affiksitiedoston FOL-, LOW- tai UPP-muotovirhe "
-#: ../spell.c:957
msgid "E762: Character in FOL, LOW or UPP is out of range"
-msgstr "E762: Merkki FOL:ssä, LOW:ssä tai UPP:ssä ei kuulu arvoalueeseen"
+msgstr "E762: Merkki FOL:ssä, LOW:ssä tai UPP:ssä ei kuulu arvoalueeseen"
-#: ../spell.c:958
msgid "Compressing word tree..."
-msgstr "Tiivistetään sanapuuta..."
-
-#: ../spell.c:1951
-msgid "E756: Spell checking is not enabled"
-msgstr "E756: Oikaisuluku ei ole päällä"
-
-#: ../spell.c:2249
-#, c-format
-msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
-msgstr "Varoitus: Ei löydetty sanalistaa %s.%s.spl tai %s.ascii.spl"
+msgstr "Tiivistetään sanapuuta..."
-#: ../spell.c:2473
#, c-format
msgid "Reading spell file \"%s\""
msgstr "Luetaan oikaisulukutiedosta %s"
-#: ../spell.c:2496
msgid "E757: This does not look like a spell file"
msgstr "E757: Ei vaikuta oikaisulukutiedostolta"
-#: ../spell.c:2501
+#, fuzzy, c-format
+#~ msgid "E5042: Failed to read spell file %s: %s"
+#~ msgstr "E482: Tiedostoa %s ei voi luoda"
+
msgid "E771: Old spell file, needs to be updated"
-msgstr "E771: Vanha oikaisulukutiedosto vaatii päivittämistä"
+msgstr "E771: Vanha oikaisulukutiedosto vaatii päivittämistä"
-#: ../spell.c:2504
msgid "E772: Spell file is for newer version of Vim"
msgstr "E772: Oikaisulukutiedosto on uudemmalle Vimille"
-#: ../spell.c:2602
msgid "E770: Unsupported section in spell file"
msgstr "E770: Tukematon osio oikaisulukutiedostossa"
-#: ../spell.c:3762
#, c-format
-msgid "Warning: region %s not supported"
-msgstr "Varoitus: osaa %s ei tueta"
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Ei vaikuta .sug-tiedostolta: %s"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Vanha .sug-tiedosto pitää päivittää: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: .sug-tiedosto on uudemmalle Vimille: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: .sug-tiedosto ei täsmää .spl-tiedostoon: %s"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: virhe luettaessa .sug-tiedostoa: %s"
-#: ../spell.c:4550
#, c-format
msgid "Reading affix file %s ..."
msgstr "Luetaan affiksitiedostoa %s..."
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
msgid "Conversion failure for word in %s line %d: %s"
-msgstr "Muunnosvirhe sanalle %s rivillä %d: %s"
+msgstr "Muunnosvirhe sanalle %s rivillä %d: %s"
-#: ../spell.c:4630 ../spell.c:6170
#, c-format
msgid "Conversion in %s not supported: from %s to %s"
msgstr "Muunnosta kohteessa %s ei tueta: kohteesta %s kohteeseen %s"
-#: ../spell.c:4642
#, c-format
msgid "Invalid value for FLAG in %s line %d: %s"
-msgstr "Tuntematon FLAG kohteessa %s rivillä %d: %s"
+msgstr "Tuntematon FLAG kohteessa %s rivillä %d: %s"
-#: ../spell.c:4655
#, c-format
msgid "FLAG after using flags in %s line %d: %s"
-msgstr "FLAG kohteessa %s lippujen jälkeen rivillä %d: %s"
+msgstr "FLAG kohteessa %s lippujen jälkeen rivillä %d: %s"
-#: ../spell.c:4723
#, c-format
msgid ""
"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
"%d"
msgstr ""
-"COMPOUNDFORBIDFLAG PFX:n jälkeen voi antaa vääriä tuloksia kohteessa %s "
-"rivillä %d"
+"COMPOUNDFORBIDFLAG PFX:n jälkeen voi antaa vääriä tuloksia kohteessa %s "
+"rivillä %d"
-#: ../spell.c:4731
#, c-format
msgid ""
"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
"%d"
msgstr ""
-"COMPOUNDPERMITFLAG PFX:n jälkeen voi antaa vääriä tuloksia kohteessa %s "
-"rivillä %d"
+"COMPOUNDPERMITFLAG PFX:n jälkeen voi antaa vääriä tuloksia kohteessa %s "
+"rivillä %d"
-#: ../spell.c:4747
#, c-format
msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
-msgstr "Väärä COMPOUNDRULES-arvo kohteessa %s rivillä %d: %s"
+msgstr "Väärä COMPOUNDRULES-arvo kohteessa %s rivillä %d: %s"
-#: ../spell.c:4771
#, c-format
msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
-msgstr "Väärä COMPOUNDWORDMAX-arvo kohteessa %s rivillä %d: %s"
+msgstr "Väärä COMPOUNDWORDMAX-arvo kohteessa %s rivillä %d: %s"
-#: ../spell.c:4777
#, c-format
msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
-msgstr "Väärä COMPOUNDMIN-arvo kohteessa %s rivillä %d: %s"
+msgstr "Väärä COMPOUNDMIN-arvo kohteessa %s rivillä %d: %s"
-#: ../spell.c:4783
#, c-format
msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
-msgstr "Väärä COMPOUNDSYLMAX-arvo kohteessa %s rivillä %d: %s"
+msgstr "Väärä COMPOUNDSYLMAX-arvo kohteessa %s rivillä %d: %s"
-#: ../spell.c:4795
#, c-format
msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
-msgstr "Väärä CHECKCOMPOUNDPATTERN-arvo kohteessa %s rivillä %d: %s"
+msgstr "Väärä CHECKCOMPOUNDPATTERN-arvo kohteessa %s rivillä %d: %s"
-#: ../spell.c:4847
#, c-format
msgid "Different combining flag in continued affix block in %s line %d: %s"
msgstr ""
-"Eri yhdistelmälippu jatketussa affiksilohkossa kohteessa %s rivillä %d: %s"
+"Eri yhdistelmälippu jatketussa affiksilohkossa kohteessa %s rivillä %d: %s"
-#: ../spell.c:4850
#, c-format
msgid "Duplicate affix in %s line %d: %s"
-msgstr "Kaksoiskappale affiksista kohteessa %s rivillä %d: %s"
+msgstr "Kaksoiskappale affiksista kohteessa %s rivillä %d: %s"
-#: ../spell.c:4871
-#, c-format
+#, fuzzy, c-format
msgid ""
-"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
+"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGESTin %s "
"line %d: %s"
msgstr ""
-"Affiksia käytetty myös BAD-, RARE-, KEEPCASE-, NEEDAFFIX-, NEEDCOMPOUND- tai "
-"NOSUGGEST-arvossa kohteessa %s rivillä %d: %s"
+"Affiksia käytetty myös BAD-, RARE-, KEEPCASE-, NEEDAFFIX-, NEEDCOMPOUND- tai "
+"NOSUGGEST-arvossa kohteessa %s rivillä %d: %s"
-#: ../spell.c:4893
#, c-format
msgid "Expected Y or N in %s line %d: %s"
-msgstr "Odotettiin Y:tä tai N:ää kohteessa %s rivillä %d: %s"
+msgstr "Odotettiin Y:tä tai N:ää kohteessa %s rivillä %d: %s"
-#: ../spell.c:4968
#, c-format
msgid "Broken condition in %s line %d: %s"
-msgstr "Viallinen ehto kohteessa %s rivillä %d: %s"
+msgstr "Viallinen ehto kohteessa %s rivillä %d: %s"
-#: ../spell.c:5091
#, c-format
msgid "Expected REP(SAL) count in %s line %d"
-msgstr "Odotettiin REP(SAL)-arvoa kohteessa %s rivillä %d"
+msgstr "Odotettiin REP(SAL)-arvoa kohteessa %s rivillä %d"
-#: ../spell.c:5120
#, c-format
msgid "Expected MAP count in %s line %d"
-msgstr "Odotettiin MAP-arvoa kohteessa %s rivillä %d"
+msgstr "Odotettiin MAP-arvoa kohteessa %s rivillä %d"
-#: ../spell.c:5132
#, c-format
msgid "Duplicate character in MAP in %s line %d"
-msgstr "Kaksoiskappale merkistä MAP:ssä kohteessa %s rivillä %d"
+msgstr "Kaksoiskappale merkistä MAP:ssä kohteessa %s rivillä %d"
-#: ../spell.c:5176
#, c-format
msgid "Unrecognized or duplicate item in %s line %d: %s"
-msgstr "Tunnistamaton tai kaksoiskappale arvosta kohteessa %s rivillä %d: %s"
+msgstr "Tunnistamaton tai kaksoiskappale arvosta kohteessa %s rivillä %d: %s"
-#: ../spell.c:5197
#, c-format
msgid "Missing FOL/LOW/UPP line in %s"
msgstr "Puuttuva FOL, LOW tai UPP rivi kohteessa %s"
-#: ../spell.c:5220
msgid "COMPOUNDSYLMAX used without SYLLABLE"
msgstr "COMPOUNDSYLMAX ilman SYLLABLEa"
-#: ../spell.c:5236
msgid "Too many postponed prefixes"
-msgstr "Liikaa jälkikäteistettyjä prefiksejä"
+msgstr "Liikaa jälkikäteistettyjä prefiksejä"
-#: ../spell.c:5238
msgid "Too many compound flags"
msgstr "Liikaa yhdyssanalippuja"
-#: ../spell.c:5240
msgid "Too many postponed prefixes and/or compound flags"
-msgstr "Liikaa jälkikäteistettyjä prefiksejä tai yhdyssanalippuja"
+msgstr "Liikaa jälkikäteistettyjä prefiksejä tai yhdyssanalippuja"
-#: ../spell.c:5250
#, c-format
msgid "Missing SOFO%s line in %s"
msgstr "Puuttuva SOFO%s-rivi kohteessa %s"
-#: ../spell.c:5253
#, c-format
msgid "Both SAL and SOFO lines in %s"
msgstr "SAL- ja SOFO-rivit kohteessa %s"
-#: ../spell.c:5331
#, c-format
msgid "Flag is not a number in %s line %d: %s"
-msgstr "Lippu ei ole lukuarvo kohteessa %s rivillä %d: %s"
+msgstr "Lippu ei ole lukuarvo kohteessa %s rivillä %d: %s"
-#: ../spell.c:5334
#, c-format
msgid "Illegal flag in %s line %d: %s"
-msgstr "Tuntematon lippu kohteessa %s rivillä %d: %s"
+msgstr "Tuntematon lippu kohteessa %s rivillä %d: %s"
-#: ../spell.c:5493 ../spell.c:5501
#, c-format
msgid "%s value differs from what is used in another .aff file"
msgstr "%s-arvo eroaa toisessa .aff-tiedostossa olevasta"
-#: ../spell.c:5602
#, c-format
msgid "Reading dictionary file %s ..."
msgstr "Luetaan sanakirjatiedostoa %s"
-#: ../spell.c:5611
#, c-format
msgid "E760: No word count in %s"
msgstr "E760: Ei sanalaskuria kohteessa %s"
-#: ../spell.c:5669
#, c-format
msgid "line %6d, word %6d - %s"
msgstr "rivi %6d, sana %6d - %s"
-#: ../spell.c:5691
#, c-format
msgid "Duplicate word in %s line %d: %s"
-msgstr "Toistettu sana kohteessa %s rivillä %d: %s"
+msgstr "Toistettu sana kohteessa %s rivillä %d: %s"
-#: ../spell.c:5694
#, c-format
msgid "First duplicate word in %s line %d: %s"
-msgstr "Ensimmäinen kappale kohteessa %s rivillä %d: %s"
+msgstr "Ensimmäinen kappale kohteessa %s rivillä %d: %s"
-#: ../spell.c:5746
#, c-format
msgid "%d duplicate word(s) in %s"
msgstr "toistettuja sanoja %d kohteessa %s"
-#: ../spell.c:5748
#, c-format
msgid "Ignored %d word(s) with non-ASCII characters in %s"
msgstr "Ei-ASCII-merkkien takia ohitettuja sanoja %d kohteessa %s"
-#: ../spell.c:6115
#, c-format
msgid "Reading word file %s ..."
msgstr "Luetaan sanatiedostoa %s..."
-#: ../spell.c:6155
#, c-format
msgid "Duplicate /encoding= line ignored in %s line %d: %s"
-msgstr "Toistettu /encoding= ohitettu kohteessa %s rivillä %d: %s"
+msgstr "Toistettu /encoding= ohitettu kohteessa %s rivillä %d: %s"
-#: ../spell.c:6159
#, c-format
msgid "/encoding= line after word ignored in %s line %d: %s"
-msgstr "/encoding= sanojen jälkeen ohitettu kohteessa %s rivillä %d: %s"
+msgstr "/encoding= sanojen jälkeen ohitettu kohteessa %s rivillä %d: %s"
-#: ../spell.c:6180
#, c-format
msgid "Duplicate /regions= line ignored in %s line %d: %s"
-msgstr "Toistettu /regions= ohitettu kohteessa %s rivillä %d: %s"
+msgstr "Toistettu /regions= ohitettu kohteessa %s rivillä %d: %s"
-#: ../spell.c:6185
#, c-format
msgid "Too many regions in %s line %d: %s"
-msgstr "Liikaa regionseja kohteessa %s rivillä %d: %s"
+msgstr "Liikaa regionseja kohteessa %s rivillä %d: %s"
-#: ../spell.c:6198
#, c-format
msgid "/ line ignored in %s line %d: %s"
-msgstr "/ ohitettu kohteessa %s rivillä %d: %s"
+msgstr "/ ohitettu kohteessa %s rivillä %d: %s"
-#: ../spell.c:6224
#, c-format
msgid "Invalid region nr in %s line %d: %s"
-msgstr "Virheellinen region-luku kohteessa %s rivillä %d: %s"
+msgstr "Virheellinen region-luku kohteessa %s rivillä %d: %s"
-#: ../spell.c:6230
#, c-format
msgid "Unrecognized flags in %s line %d: %s"
-msgstr "Tunnistamaton lippu kohteessa %s rivillä %d: %s"
+msgstr "Tunnistamaton lippu kohteessa %s rivillä %d: %s"
-#: ../spell.c:6257
#, c-format
msgid "Ignored %d words with non-ASCII characters"
msgstr "Ei-ASCIIn takia ohitettuja sanoja %d"
-#: ../spell.c:6656
#, c-format
msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
-msgstr "Tiivistetty %d/%d noodia. %d (%d %%) jäljellä"
+msgstr "Tiivistetty %d/%d noodia. %d (%d %%) jäljellä"
-#: ../spell.c:7340
msgid "Reading back spell file..."
msgstr "Luetaan taas oikaisulukutiedostoa..."
#. Go through the trie of good words, soundfold each word and add it to
#. the soundfold trie.
-#: ../spell.c:7357
msgid "Performing soundfolding..."
-msgstr "Ääntämyksen mukaan yhdistellään..."
+msgstr "Ääntämyksen mukaan yhdistellään..."
-#: ../spell.c:7368
-#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "Sanoja ääntämysyhdistelyn jälkeen: %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "Number of words after soundfolding: %<PRId64>"
+#~ msgstr "Sanoja ääntämysyhdistelyn jälkeen: %ld"
-#: ../spell.c:7476
#, c-format
msgid "Total number of words: %d"
-msgstr "Sanoja yhteensä: %d"
+msgstr "Sanoja yhteensä: %d"
-#: ../spell.c:7655
#, c-format
msgid "Writing suggestion file %s ..."
msgstr "Kirjoitetaan ehdotustiedostoa %s..."
-#: ../spell.c:7707 ../spell.c:7927
#, c-format
msgid "Estimated runtime memory use: %d bytes"
-msgstr "Arvioitu käyttömuisti: %d tavua"
+msgstr "Arvioitu käyttömuisti: %d tavua"
-#: ../spell.c:7820
msgid "E751: Output file name must not have region name"
-msgstr "E751: Tulostetiedostonimessä ei saa olla alueen nimeä"
+msgstr "E751: Tulostetiedostonimessä ei saa olla alueen nimeä"
-#: ../spell.c:7822
msgid "E754: Only up to 8 regions supported"
-msgstr "E754: Enintään 8 aluetta tuetaan"
+msgstr "E754: Enintään 8 aluetta tuetaan"
-#: ../spell.c:7846
#, c-format
msgid "E755: Invalid region in %s"
msgstr "E755: Virheellinen alue kohteelle %s"
-#: ../spell.c:7907
msgid "Warning: both compounding and NOBREAK specified"
-msgstr "Varoitus: sekä yhdyssanamuodostus että NOBREAK käytössä"
+msgstr "Varoitus: sekä yhdyssanamuodostus että NOBREAK käytössä"
-#: ../spell.c:7920
#, c-format
msgid "Writing spell file %s ..."
msgstr "Kirjoitetaan oikaisulukutiedostoa %s..."
-#: ../spell.c:7925
msgid "Done!"
msgstr "Valmista."
-#: ../spell.c:8034
-#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: spellfile ei sisällä %<PRId64> kohtaa"
-
-#: ../spell.c:8074
#, fuzzy, c-format
-msgid "Word '%.*s' removed from %s"
-msgstr "Sana poistettu kohteesta %s"
+#~ msgid "E765: 'spellfile' does not have %<PRId64> entries"
+#~ msgstr "E765: spellfile ei sisällä %ld kohtaa"
-#: ../spell.c:8117
-#, fuzzy, c-format
-msgid "Word '%.*s' added to %s"
-msgstr "Sana lisätty kohteeseen %s"
-
-#: ../spell.c:8381
-msgid "E763: Word characters differ between spell files"
-msgstr "E763: Sanan merkit muuttuvat oikaisulukutiedostojen välillä"
-
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "Sori, ei ehdotuksia"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "Sori, vain %<PRId64> ehdotusta"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "Muuta %.*s:"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < %.*s"
-
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: Ei edellistä oikaisulukukorjausta"
-
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: Ei löytynyt: %s"
-
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: Ei vaikuta .sug-tiedostolta: %s"
-
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: Vanha .sug-tiedosto pitää päivittää: %s"
-
-#: ../spell.c:9286
#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: .sug-tiedosto on uudemmalle Vimille: %s"
+msgid "Word '%.*s' removed from %s"
+msgstr "Sana %.*s poistettu kohteesta %s"
-#: ../spell.c:9295
#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr "E781: .sug-tiedosto ei täsmää .spl-tiedostoon: %s"
+msgid "Word '%.*s' added to %s"
+msgstr "Sana %.*s lisätty kohteeseen %s"
-#: ../spell.c:9305
-#, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E782: virhe luettaessa .sug-tiedostoa: %s"
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Sanan merkit muuttuvat oikaisulukutiedostojen välillä"
#. This should have been checked when generating the .spl
#. file.
-#: ../spell.c:11575
msgid "E783: duplicate char in MAP entry"
-msgstr "E783: kaksoiskappale merkistä MAP-kohdassa"
+msgstr "E783: kaksoiskappale merkistä MAP-kohdassa"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: printf():lle ei annettu tarpeeksi argumentteja"
+
+msgid "E807: Expected Float argument for printf()"
+msgstr "E807: Odotettiin Float-argumenttia printf():lle"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: printf():lle annettiin liikaa argumentteja"
-#: ../syntax.c:266
msgid "No Syntax items defined for this buffer"
-msgstr "Ei syntaksikohteita tälle puskurille"
+msgstr "Ei syntaksikohteita tälle puskurille"
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
#, c-format
msgid "E390: Illegal argument: %s"
msgstr "E390: Virheellinen argumentti: %s"
-#: ../syntax.c:3299
+msgid "syntax iskeyword "
+msgstr "syntax iskeyword "
+
#, c-format
msgid "E391: No such syntax cluster: %s"
msgstr "E391: Syntaksiklusteri puuttuu: %s"
-#: ../syntax.c:3433
msgid "syncing on C-style comments"
msgstr "synkkaa C-tyylin kommentteihin"
-#: ../syntax.c:3439
msgid "no syncing"
msgstr "ei synkkausta"
-#: ../syntax.c:3441
msgid "syncing starts "
msgstr "synkkaus aloitettu "
-#: ../syntax.c:3443 ../syntax.c:3506
msgid " lines before top line"
-msgstr " riviä ennen alkua"
+msgstr " riviä ennen alkua"
-#: ../syntax.c:3448
msgid ""
"\n"
"--- Syntax sync items ---"
@@ -5729,7 +5225,6 @@ msgstr ""
"\n"
"--- Syntax sync -kohteet ---"
-#: ../syntax.c:3452
msgid ""
"\n"
"syncing on items"
@@ -5737,7 +5232,6 @@ msgstr ""
"\n"
"synkataan kohteisiin"
-#: ../syntax.c:3457
msgid ""
"\n"
"--- Syntax items ---"
@@ -5745,2314 +5239,2499 @@ msgstr ""
"\n"
"--- Syntax-kohteet ---"
-#: ../syntax.c:3475
#, c-format
msgid "E392: No such syntax cluster: %s"
msgstr "E392: syntaksiklusteria ei ole: %s"
-#: ../syntax.c:3497
msgid "minimal "
-msgstr "vähintään "
+msgstr "vähintään "
-#: ../syntax.c:3503
msgid "maximal "
-msgstr "enitntään "
+msgstr "enitntään "
-#: ../syntax.c:3513
msgid "; match "
-msgstr "; täsmää "
+msgstr "; täsmää "
-#: ../syntax.c:3515
msgid " line breaks"
msgstr " rivinvaihdot"
-#: ../syntax.c:4076
msgid "E395: contains argument not accepted here"
-msgstr "E395: contains ei sovi tähän"
+msgstr "E395: contains ei sovi tähän"
-#: ../syntax.c:4096
-#, fuzzy
msgid "E844: invalid cchar value"
-msgstr "E474: Virheellinen argumentti"
+msgstr "E844: Virheellinen cchar-arvo"
-#: ../syntax.c:4107
msgid "E393: group[t]here not accepted here"
-msgstr "E393: group[t]here ei sovi tähän"
+msgstr "E393: group[t]here ei sovi tähän"
-#: ../syntax.c:4126
#, c-format
msgid "E394: Didn't find region item for %s"
-msgstr "E394: Aluetta nimelle %s ei löydy"
+msgstr "E394: Aluetta nimelle %s ei löydy"
-#: ../syntax.c:4188
msgid "E397: Filename required"
msgstr "E397: Tiedostonimi puuttuu"
-#: ../syntax.c:4221
-#, fuzzy
msgid "E847: Too many syntax includes"
-msgstr "E77: Liikaa tiedostonimiä"
+msgstr "E847: Liikaa syntax includeja"
-#: ../syntax.c:4303
#, c-format
msgid "E789: Missing ']': %s"
msgstr "E789: ] puuttuu: %s"
-#: ../syntax.c:4531
+#, c-format
+msgid "E890: trailing char after ']': %s]%s"
+msgstr "E890: Ylimääräisiä merkkejä merkin ] perässä: %s]%s"
+
#, c-format
msgid "E398: Missing '=': %s"
msgstr "E398: = puuttuu: %s"
-#: ../syntax.c:4666
#, c-format
msgid "E399: Not enough arguments: syntax region %s"
msgstr "E399: Argumentteja puuttuu: syntaksialue %s"
-#: ../syntax.c:4870
-#, fuzzy
msgid "E848: Too many syntax clusters"
-msgstr "E391: Syntaksiklusteri puuttuu: %s"
+msgstr "E848: Liikaa syntaksiklustereita"
-#: ../syntax.c:4954
msgid "E400: No cluster specified"
-msgstr "E400: klusteri määrittelemättä"
+msgstr "E400: klusteri määrittelemättä"
#. end delimiter not found
-#: ../syntax.c:4986
#, c-format
msgid "E401: Pattern delimiter not found: %s"
msgstr "E401: Kuvoin erotin puuttuu: %s"
-#: ../syntax.c:5049
#, c-format
msgid "E402: Garbage after pattern: %s"
-msgstr "E402: Roskia kuvion jäljessä: %s"
+msgstr "E402: Roskia kuvion jäljessä: %s"
-#: ../syntax.c:5120
msgid "E403: syntax sync: line continuations pattern specified twice"
-msgstr "E403: syntax sync: rivinjatkamiskuvio määritelty kahdesti"
+msgstr "E403: syntax sync: rivinjatkamiskuvio määritelty kahdesti"
-#: ../syntax.c:5169
#, c-format
msgid "E404: Illegal arguments: %s"
msgstr "E404: Virheelliset argumentit: %s"
-#: ../syntax.c:5217
#, c-format
msgid "E405: Missing equal sign: %s"
msgstr "E405: = puuttuu: %s"
-#: ../syntax.c:5222
#, c-format
msgid "E406: Empty argument: %s"
-msgstr "E406: Tyhjä argumentti: %s"
+msgstr "E406: Tyhjä argumentti: %s"
-#: ../syntax.c:5240
#, c-format
msgid "E407: %s not allowed here"
-msgstr "E407: %s ei sovi tähän"
+msgstr "E407: %s ei sovi tähän"
-#: ../syntax.c:5246
#, c-format
msgid "E408: %s must be first in contains list"
msgstr "E408: %s kuuluu contains-listan alkuun"
-#: ../syntax.c:5304
#, c-format
msgid "E409: Unknown group name: %s"
-msgstr "E409: Tuntematon ryhmän nimi: %s"
+msgstr "E409: Tuntematon ryhmän nimi: %s"
-#: ../syntax.c:5512
#, c-format
msgid "E410: Invalid :syntax subcommand: %s"
msgstr "E410: Virheelluinen :syntax-osakomento: %s"
-#: ../syntax.c:5854
msgid ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
msgstr ""
+" KAIKKI MÄÄRÄ TÄSMÄYS HITAIN KEKSIARVO NIMI ILMAUS"
-#: ../syntax.c:6146
msgid "E679: recursive loop loading syncolor.vim"
-msgstr "E679: rekursiivinen silmukka syncolor.vimissä"
+msgstr "E679: rekursiivinen silmukka syncolor.vimissä"
-#: ../syntax.c:6256
#, c-format
msgid "E411: highlight group not found: %s"
-msgstr "E411: korostusryhmää ei löytynyt: %s"
+msgstr "E411: korostusryhmää ei löytynyt: %s"
-#: ../syntax.c:6278
#, c-format
msgid "E412: Not enough arguments: \":highlight link %s\""
msgstr "E412: Argumentteja puuttuu: :highlight link %s"
-#: ../syntax.c:6284
#, c-format
msgid "E413: Too many arguments: \":highlight link %s\""
msgstr "E413: Liikaa argumentteja: :highlight link %s"
-#: ../syntax.c:6302
msgid "E414: group has settings, highlight link ignored"
-msgstr "E414: ryhmällä on asetuksia, highlight link -komento ohitetaan"
+msgstr "E414: ryhmällä on asetuksia, highlight link -komento ohitetaan"
-#: ../syntax.c:6367
#, c-format
msgid "E415: unexpected equal sign: %s"
msgstr "E415: odotuksenvastainen =-merkki: %s"
-#: ../syntax.c:6395
#, c-format
msgid "E416: missing equal sign: %s"
msgstr "E416: puuttuva =-merkki: %s"
-#: ../syntax.c:6418
#, c-format
msgid "E417: missing argument: %s"
msgstr "E417: puuttuva argumentti: %s"
-#: ../syntax.c:6446
#, c-format
msgid "E418: Illegal value: %s"
msgstr "E418: Viallinen arvo: %s"
-#: ../syntax.c:6496
msgid "E419: FG color unknown"
-msgstr "E419: edustaväri tuntematon"
+msgstr "E419: edustaväri tuntematon"
-#: ../syntax.c:6504
msgid "E420: BG color unknown"
-msgstr "E420: taustaväri tuntematon"
+msgstr "E420: taustaväri tuntematon"
-#: ../syntax.c:6564
#, c-format
msgid "E421: Color name or number not recognized: %s"
-msgstr "E421: Värin nimi tai numero tuntematon: %s"
-
-#: ../syntax.c:6714
-#, c-format
-msgid "E422: terminal code too long: %s"
-msgstr "E422: terminaalikoodi liian pitkä: %s"
+msgstr "E421: Värin nimi tai numero tuntematon: %s"
-#: ../syntax.c:6753
#, c-format
msgid "E423: Illegal argument: %s"
msgstr "E423: Virheellinen argumentti: %s"
-#: ../syntax.c:6925
msgid "E424: Too many different highlighting attributes in use"
msgstr "E424: Liikaa eri korostusattribuutteja"
-#: ../syntax.c:7427
msgid "E669: Unprintable character in group name"
-msgstr "E669: Tulostuskelvoton merkki ryhmän nimessä"
+msgstr "E669: Tulostuskelvoton merkki ryhmän nimessä"
-#: ../syntax.c:7434
msgid "W18: Invalid character in group name"
-msgstr "W18: Virheellinen merkki ryhmän nimessä"
+msgstr "W18: Virheellinen merkki ryhmän nimessä"
-#: ../syntax.c:7448
msgid "E849: Too many highlight and syntax groups"
-msgstr ""
+msgstr "E849: Liikaa korostuksia ja syntaksiryhmiä"
-#: ../tag.c:104
msgid "E555: at bottom of tag stack"
-msgstr "E555: tägipinon pohja"
+msgstr "E555: tägipinon pohja"
-#: ../tag.c:105
msgid "E556: at top of tag stack"
-msgstr "E556: tägipinon huippu"
+msgstr "E556: tägipinon huippu"
-#: ../tag.c:380
msgid "E425: Cannot go before first matching tag"
-msgstr "E425: Ei voida mennä ensimmäistä täsmäävää tägiä alummaksi"
+msgstr "E425: Ei voida mennä ensimmäistä täsmäävää tägiä alummaksi"
-#: ../tag.c:504
#, c-format
msgid "E426: tag not found: %s"
-msgstr "E426: tägi puuttuu: %s"
+msgstr "E426: tägi puuttuu: %s"
-#: ../tag.c:528
msgid " # pri kind tag"
-msgstr " # arvo tyyppi tägi"
+msgstr " # arvo tyyppi tägi"
-#: ../tag.c:531
msgid "file\n"
msgstr "tiedosto\n"
-#: ../tag.c:829
msgid "E427: There is only one matching tag"
-msgstr "E427: Vain yksi tägi täsmää"
+msgstr "E427: Vain yksi tägi täsmää"
-#: ../tag.c:831
msgid "E428: Cannot go beyond last matching tag"
-msgstr "E428: Ei voida edetä viimeisen täsmäävän tägin ohi"
+msgstr "E428: Ei voida edetä viimeisen täsmäävän tägin ohi"
-#: ../tag.c:850
#, c-format
msgid "File \"%s\" does not exist"
msgstr "Tiedostoa %s ei ole"
#. Give an indication of the number of matching tags
-#: ../tag.c:859
#, c-format
msgid "tag %d of %d%s"
-msgstr "tägi %d/%d%s"
+msgstr "tägi %d/%d%s"
-#: ../tag.c:862
msgid " or more"
msgstr " tai useammasta"
-#: ../tag.c:864
msgid " Using tag with different case!"
-msgstr " Tägissä eri kirjaintaso"
+msgstr " Tägissä eri kirjaintaso"
-#: ../tag.c:909
#, c-format
msgid "E429: File \"%s\" does not exist"
msgstr "E429: Tiedostoa %s ei ole"
#. Highlight title
-#: ../tag.c:960
msgid ""
"\n"
" # TO tag FROM line in file/text"
msgstr ""
"\n"
-" # TILL tagg FRÅN LINJE i fil/text"
+" # TILL tagg FRÃ…N LINJE i fil/text"
-#: ../tag.c:1303
#, c-format
msgid "Searching tags file %s"
-msgstr "Etsitään tägitiedostoa %s"
+msgstr "Etsitään tägitiedostoa %s"
-#: ../tag.c:1545
msgid "Ignoring long line in tags file"
-msgstr "Ohitetaan pitkä rivi tägitiedostossa"
+msgstr "Ohitetaan pitkä rivi tägitiedostossa"
-#: ../tag.c:1915
#, c-format
msgid "E431: Format error in tags file \"%s\""
-msgstr "E431: Muotovirh tägitiedostossa %s"
+msgstr "E431: Muotovirh tägitiedostossa %s"
-#: ../tag.c:1917
-#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "Ennen tavua %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "Before byte %<PRId64>"
+#~ msgstr "Ennen tavua %ld"
-#: ../tag.c:1929
#, c-format
msgid "E432: Tags file not sorted: %s"
-msgstr "E432: Tägitiedosto ei ole järjestetty: %s"
+msgstr "E432: Tägitiedosto ei ole järjestetty: %s"
#. never opened any tags file
-#: ../tag.c:1960
msgid "E433: No tags file"
-msgstr "E433: Ei tägitiedostoja"
+msgstr "E433: Ei tägitiedostoja"
-#: ../tag.c:2536
msgid "E434: Can't find tag pattern"
-msgstr "E434: Tägikuviota ei löydy"
+msgstr "E434: Tägikuviota ei löydy"
-#: ../tag.c:2544
msgid "E435: Couldn't find tag, just guessing!"
-msgstr "E435: Tägiä ei löydy, arvataan."
+msgstr "E435: Tägiä ei löydy, arvataan."
-#: ../tag.c:2797
#, c-format
msgid "Duplicate field name: %s"
-msgstr "Kaksoiskappale kentän nimestä: %s"
-
-#: ../term.c:1442
-msgid "' not known. Available builtin terminals are:"
-msgstr " ei tunnettu. Tuetut terminaalit:"
-
-#: ../term.c:1463
-msgid "defaulting to '"
-msgstr "oletusarvona "
-
-#: ../term.c:1731
-msgid "E557: Cannot open termcap file"
-msgstr "E557: Ei voi avata termcap-tiedostoa"
-
-#: ../term.c:1735
-msgid "E558: Terminal entry not found in terminfo"
-msgstr "E558: Terminaalia ei löytynyt terminfosta"
-
-#: ../term.c:1737
-msgid "E559: Terminal entry not found in termcap"
-msgstr "E559: Terminaalia ei löytynyt termcapista"
-
-#: ../term.c:1878
-#, c-format
-msgid "E436: No \"%s\" entry in termcap"
-msgstr "E436: %s ei löytynyt termcapista"
-
-#: ../term.c:2249
-msgid "E437: terminal capability \"cm\" required"
-msgstr "E437: terminaalilla pitää olla cm kyvyissään"
-
-#. Highlight title
-#: ../term.c:4376
-msgid ""
-"\n"
-"--- Terminal keys ---"
-msgstr ""
-"\n"
-"--- Terminaalinäppäimet ---"
-
-#: ../ui.c:481
-msgid "Vim: Error reading input, exiting...\n"
-msgstr "Vim: Virhe luettaessa syötettä, poistutaan...\n"
+msgstr "Kaksoiskappale kentän nimestä: %s"
#. This happens when the FileChangedRO autocommand changes the
#. * file in a way it becomes shorter.
-#: ../undo.c:379
-#, fuzzy
msgid "E881: Line count changed unexpectedly"
-msgstr "E834: Rivimäärä vaihtui odottamatta"
+msgstr "E881: Rivimäärä vaihtui odottamatta"
-#: ../undo.c:627
#, c-format
msgid "E828: Cannot open undo file for writing: %s"
msgstr "E828: Kumoustiedoston avaus kirjoittamista varten ei onnistu: %s"
-#: ../undo.c:717
+#, fuzzy, c-format
+#~ msgid "E5003: Unable to create directory \"%s\" for undo file: %s"
+#~ msgstr "E346: Hakemisto %s ei ole enää cdpathissa"
+
#, c-format
msgid "E825: Corrupted undo file (%s): %s"
msgstr "E825: Pilaanntunut kumoustiedosto (%s): %s"
-#: ../undo.c:1039
msgid "Cannot write undo file in any directory in 'undodir'"
-msgstr "Ei voitu lukea kumoustiedostoa mistään undodir-muuttujan hakemistosta"
+msgstr "Ei voitu lukea kumoustiedostoa mistään undodir-muuttujan hakemistosta"
-#: ../undo.c:1074
#, c-format
msgid "Will not overwrite with undo file, cannot read: %s"
msgstr "Ei ylikirjoitetat kumoustiedostolla, koska ei voida lukea: %s"
-#: ../undo.c:1092
#, c-format
msgid "Will not overwrite, this is not an undo file: %s"
-msgstr "Ei ylikirjoiteta, koska tämä ei ole kumoustiedosto: %s"
+msgstr "Ei ylikirjoiteta, koska tämä ei ole kumoustiedosto: %s"
-#: ../undo.c:1108
msgid "Skipping undo file write, nothing to undo"
msgstr "Ohitetaan kumoustiedoston kirjoitus, koska ei ole peruutettavia"
-#: ../undo.c:1121
#, c-format
msgid "Writing undo file: %s"
msgstr "Kirjoitetaan kumoustiedostoa: %s"
-#: ../undo.c:1213
#, c-format
msgid "E829: write error in undo file: %s"
msgstr "E829: Kirjoitusvirhe kumoustiedostossa: %s"
-#: ../undo.c:1280
#, c-format
msgid "Not reading undo file, owner differs: %s"
msgstr "Ei lueta kumoustiedosto jonka omistaja on eri: %s"
-#: ../undo.c:1292
#, c-format
msgid "Reading undo file: %s"
msgstr "Luetaan kumoustiedostoa: %s"
-#: ../undo.c:1299
#, c-format
msgid "E822: Cannot open undo file for reading: %s"
msgstr "E822: Kumoustiedostoa ei voi avata lukemista varten: %s"
-#: ../undo.c:1308
#, c-format
msgid "E823: Not an undo file: %s"
msgstr "E823: Ei ole kumoustiedosto: %s"
-#: ../undo.c:1313
#, c-format
msgid "E824: Incompatible undo file: %s"
-msgstr "E824: Epäyhteensopiva kumoustiedosto: %s"
+msgstr "E824: Epäyhteensopiva kumoustiedosto: %s"
-#: ../undo.c:1328
msgid "File contents changed, cannot use undo info"
msgstr ""
-"Tiedoston sisältö on muuttunut, joen kumoustiedot ovat käyttökelvottomia"
+"Tiedoston sisältö on muuttunut, joen kumoustiedot ovat käyttökelvottomia"
-#: ../undo.c:1497
#, c-format
msgid "Finished reading undo file %s"
msgstr "Ladattu kumoustiedoto %s"
-#: ../undo.c:1586 ../undo.c:1812
msgid "Already at oldest change"
msgstr "Vanhimmassa muutoksessa"
-#: ../undo.c:1597 ../undo.c:1814
msgid "Already at newest change"
msgstr "Nuorimmassa muutoksessa"
-#: ../undo.c:1806
-#, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E830: Kumouslukua %<PRId64> ei löydy"
+#, fuzzy, c-format
+#~ msgid "E830: Undo number %<PRId64> not found"
+#~ msgstr "E830: Kumouslukua %ld ei löydy"
-#: ../undo.c:1979
msgid "E438: u_undo: line numbers wrong"
-msgstr "E438: u_undo: väärät rivinumerot"
+msgstr "E438: u_undo: väärät rivinumerot"
-#: ../undo.c:2183
msgid "more line"
-msgstr "rivi lisää"
+msgstr "rivi lisää"
-#: ../undo.c:2185
msgid "more lines"
-msgstr "riviä lisää"
+msgstr "riviä lisää"
-#: ../undo.c:2187
msgid "line less"
-msgstr "rivi vähemmän"
+msgstr "rivi vähemmän"
-#: ../undo.c:2189
msgid "fewer lines"
-msgstr "riviä vähemmän"
+msgstr "riviä vähemmän"
-#: ../undo.c:2193
msgid "change"
msgstr "muutos"
-#: ../undo.c:2195
msgid "changes"
msgstr "muutosta"
-# eka %s yläpuolelta, toka %s alapuolelta, kolmas %s aika
-#: ../undo.c:2225
-#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s, %s #%<PRId64> %s"
+# eka %s yläpuolelta, toka %s alapuolelta, kolmas %s aika
+#, fuzzy, c-format
+#~ msgid "%<PRId64> %s; %s #%<PRId64> %s"
+#~ msgstr "%ld %s, %s #%ld %s"
+
+msgid "after"
+msgstr "jälkeen muutoksen"
-#: ../undo.c:2228
msgid "before"
msgstr "ennen muutosta"
-#: ../undo.c:2228
-msgid "after"
-msgstr "jälkeen muutoksen"
-
-#: ../undo.c:2325
msgid "Nothing to undo"
msgstr "Ei kumottavaa"
-#: ../undo.c:2330
-#, fuzzy
msgid "number changes when saved"
-msgstr "muutoksia aika tallennettu"
+msgstr "numero muutoksia aika tallennettu"
-#: ../undo.c:2360
-#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> sekuntia sitten"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> seconds ago"
+#~ msgstr "%ld sekuntia sitten"
-#: ../undo.c:2372
msgid "E790: undojoin is not allowed after undo"
-msgstr "E790: undojoin ei toimi undon jälkeen"
+msgstr "E790: undojoin ei toimi undon jälkeen"
-#: ../undo.c:2466
msgid "E439: undo list corrupt"
msgstr "E439: kumouslista rikki"
-#: ../undo.c:2495
msgid "E440: undo line missing"
msgstr "E440: kumousrivi puuttuu"
-#: ../version.c:600
-msgid ""
-"\n"
-"Included patches: "
-msgstr ""
-"\n"
-"Pätsit: "
-
-#: ../version.c:627
msgid ""
"\n"
"Extra patches: "
msgstr ""
"\n"
-"Muita pätsejä: "
-
-#: ../version.c:639 ../version.c:864
-msgid "Modified by "
-msgstr "Muokannut "
+"Muita pätsejä: "
-#: ../version.c:646
msgid ""
"\n"
"Compiled "
msgstr ""
"\n"
-"Kääntänyt "
+"Kääntänyt "
-#: ../version.c:649
msgid "by "
msgstr ": "
-#: ../version.c:660
+#, fuzzy
msgid ""
"\n"
-"Huge version "
-msgstr ""
"\n"
-"Huge-versio "
-
-#: ../version.c:661
-msgid "without GUI."
-msgstr "ilman GUIta."
-
-#: ../version.c:662
-msgid " Features included (+) or not (-):\n"
+"Optional features included (+) or not (-): "
msgstr " Ominaisuudet mukana (+) ja poissa (-):\n"
-#: ../version.c:667
msgid " system vimrc file: \""
-msgstr " järjestelmän vimrc: \""
-
-#: ../version.c:672
-msgid " user vimrc file: \""
-msgstr " käyttäjän vimrc: \""
-
-#: ../version.c:677
-msgid " 2nd user vimrc file: \""
-msgstr " 2. käyttäjän vimrc: \""
+msgstr " järjestelmän vimrc: \""
-#: ../version.c:682
-msgid " 3rd user vimrc file: \""
-msgstr " 3. käyttäjän vimrc: \""
-
-#: ../version.c:687
-msgid " user exrc file: \""
-msgstr " käyttäjän exrc: \""
-
-#: ../version.c:692
-msgid " 2nd user exrc file: \""
-msgstr " 2. käyttäjän exrc: \""
-
-#: ../version.c:699
msgid " fall-back for $VIM: \""
msgstr " $VIMin fallback: \""
-#: ../version.c:705
msgid " f-b for $VIMRUNTIME: \""
msgstr " $VIMRUNTIMEn f-b: \""
-#: ../version.c:709
-msgid "Compilation: "
-msgstr "Käännös: "
-
-#: ../version.c:712
-msgid "Linking: "
-msgstr "Linkitys: "
-
-#: ../version.c:717
-msgid " DEBUG BUILD"
-msgstr " DEBUG-versio"
-
-#: ../version.c:767
-msgid "VIM - Vi IMproved"
-msgstr "VIM - Vi IMproved"
-
-#: ../version.c:769
-msgid "version "
-msgstr "versio "
-
-#: ../version.c:770
msgid "by Bram Moolenaar et al."
-msgstr "tekijät Bram Moolenaar et al."
+msgstr "tekijät Bram Moolenaar et al."
-#: ../version.c:774
-msgid "Vim is open source and freely distributable"
-msgstr "Vim on avointa lähdekoodia ja vapaasti jaossa"
+#, fuzzy
+#~ msgid "Nvim is open source and freely distributable"
+#~ msgstr "Vim on avointa lähdekoodia ja vapaasti jaossa"
-#: ../version.c:776
-msgid "Help poor children in Uganda!"
-msgstr "Auta Ugandan köyhiä lapsia"
+#~ msgid "https://neovim.io/community"
+#~ msgstr ""
-#: ../version.c:777
-msgid "type :help iccf<Enter> for information "
-msgstr "kirjoita :help iccf<Enter> lisätietoa varten "
+#, fuzzy
+#~ msgid "type :help nvim<Enter> if you are new! "
+#~ msgstr "kirjoita :help iccf<Enter> lisätietoa varten "
+
+#, fuzzy
+#~ msgid "type :CheckHealth<Enter> to optimize Nvim"
+#~ msgstr "kirjoita :help iccf<Enter> lisätietoa varten "
-#: ../version.c:779
msgid "type :q<Enter> to exit "
msgstr "kirjoita :q<Enter> lopettaaksesi "
-#: ../version.c:780
-msgid "type :help<Enter> or <F1> for on-line help"
-msgstr "kirjoita :help<Enter> tai <F1> ohjetta varten "
-
-#: ../version.c:781
-msgid "type :help version7<Enter> for version info"
-msgstr "kirjoita :help version7<Enter> versiotietoja varten "
-
-#: ../version.c:784
-msgid "Running in Vi compatible mode"
-msgstr "Suoritetaan Vi-yhteensopivuustilaa"
+#, fuzzy
+#~ msgid "type :help<Enter> for help "
+#~ msgstr "kirjoita :q<Enter> lopettaaksesi "
-#: ../version.c:785
-msgid "type :set nocp<Enter> for Vim defaults"
-msgstr "kirjoita :set nocp<Enter> Vimin oletuksiin "
+msgid "Help poor children in Uganda!"
+msgstr "Auta Ugandan köyhiä lapsia"
-#: ../version.c:786
-msgid "type :help cp-default<Enter> for info on this"
-msgstr "kirjoita :help cp-default<Enter> ohjetta oletuksista varten"
+msgid "type :help iccf<Enter> for information "
+msgstr "kirjoita :help iccf<Enter> lisätietoa varten "
-#: ../version.c:827
msgid "Sponsor Vim development!"
-msgstr "Tue Vimin kehitystä"
+msgstr "Tue Vimin kehitystä"
-#: ../version.c:828
msgid "Become a registered Vim user!"
-msgstr "Rekisteröidy Vim-käyttäjäksi."
+msgstr "Rekisteröidy Vim-käyttäjäksi."
-#: ../version.c:831
msgid "type :help sponsor<Enter> for information "
-msgstr "kirjoita :help sponsor<Enter> lisätietoja varten"
+msgstr "kirjoita :help sponsor<Enter> lisätietoja varten"
-#: ../version.c:832
msgid "type :help register<Enter> for information "
-msgstr "kirjoita :help register<Enter> lisätietoja varten"
+msgstr "kirjoita :help register<Enter> lisätietoja varten"
-#: ../version.c:834
msgid "menu Help->Sponsor/Register for information "
-msgstr "valikko Ohje->Sponsoroi/Rekisteröi lisätietoja varten"
+msgstr "valikko Ohje->Sponsoroi/Rekisteröi lisätietoja varten"
-#: ../window.c:119
msgid "Already only one window"
-msgstr "Enää yksi ikkuna jäljellä"
+msgstr "Enää yksi ikkuna jäljellä"
-#: ../window.c:224
msgid "E441: There is no preview window"
msgstr "E441: Ei esikatseluikkunaa"
-#: ../window.c:559
msgid "E442: Can't split topleft and botright at the same time"
-msgstr "E442: Ei voi jakaa vasenta ylänurkkaa ja oikeaa alanurkkaa yhtäaikaa"
+msgstr "E442: Ei voi jakaa vasenta ylänurkkaa ja oikeaa alanurkkaa yhtäaikaa"
-#: ../window.c:1228
msgid "E443: Cannot rotate when another window is split"
-msgstr "E443: Ei voi kiertää kun toinen ikkuna on jaettu"
+msgstr "E443: Ei voi kiertää kun toinen ikkuna on jaettu"
-#: ../window.c:1803
msgid "E444: Cannot close last window"
-msgstr "E444: Ei voi sulkea viimeistä ikkunaa"
+msgstr "E444: Ei voi sulkea viimeistä ikkunaa"
-#: ../window.c:1810
msgid "E813: Cannot close autocmd window"
msgstr "E813: Ei voi sulkea autocmd-ikkunaa"
-#: ../window.c:1814
msgid "E814: Cannot close window, only autocmd window would remain"
-msgstr "E814: Ei voi sulkea viimeistä ikkunaa, joka ei ole autocmd-ikkuna"
+msgstr "E814: Ei voi sulkea viimeistä ikkunaa, joka ei ole autocmd-ikkuna"
-#: ../window.c:2717
msgid "E445: Other window contains changes"
-msgstr "E445: Toinen ikkuna sisältää muutoksia"
+msgstr "E445: Toinen ikkuna sisältää muutoksia"
-#: ../window.c:4805
msgid "E446: No file name under cursor"
-msgstr "E446: Ei tiedostonimeä kursorin alla"
+msgstr "E446: Ei tiedostonimeä kursorin alla"
-#~ msgid "E831: bf_key_init() called with empty password"
-#~ msgstr "E831: bf_key_init() tyhjällä salasanalla"
+msgid "List or number required"
+msgstr "Lista tai luku tarvitaan"
-#~ msgid "E820: sizeof(uint32_t) != 4"
-#~ msgstr "E820: sizeof(uint32_t) != 4"
+#~ msgid ""
+#~ "Failed to set path: sys.path is not a list\n"
+#~ "You should now append vim.VIM_SPECIAL_PATH to sys.path"
+#~ msgstr ""
+#~ "Ei onnistuttu asettaman polkua: sys.path ei ole list\n"
+#~ "Lisää vim.VIM_SPECIAL_PATH muuttujaan sys.path"
-#~ msgid "E817: Blowfish big/little endian use wrong"
-#~ msgstr "E817: Blowfishin tavujärjestys väärä"
+#~ msgid ""
+#~ "Failed to set path hook: sys.path_hooks is not a list\n"
+#~ "You should now do the following:\n"
+#~ "- append vim.path_hook to sys.path_hooks\n"
+#~ "- append vim.VIM_SPECIAL_PATH to sys.path\n"
+#~ msgstr ""
+#~ "Ei voitu asettaa polkukoukkua: sys.path_hooks ei ole lista\n"
+#~ "Koeta seuraavaa:\n"
+#~ "- lisää vim.path_hook muuttujaan sys.path_hooks\n"
+#~ "- lisää vim.VIM_SPECIAL_PATH muuttujaan sys.path\n"
-#~ msgid "E818: sha256 test failed"
-#~ msgstr "E818: sha256-testi epäonnistui failed"
+#~ msgid "internal error: invalid value type"
+#~ msgstr "sisäinen virhe: huono arvotyyppi"
-#~ msgid "E819: Blowfish test failed"
-#~ msgstr "E819: Blowfish-testi epäonnistui"
+#~ msgid "internal error: NULL reference passed"
+#~ msgstr "sisäinen virhe: NULL-viite annettu"
-#~ msgid "Patch file"
-#~ msgstr "Patch-tiedosto"
+#~ msgid "unable to convert %s to vim structure"
+#~ msgstr "ei voi konvertoida oliota %s vim-tietorakenteeksi"
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "&OK\n"
-#~ "&Peru"
+#~ msgid "unable to convert %s to vim dictionary"
+#~ msgstr "ei voitu konvertoida oliota %s vim-sanakirjaksi"
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Ei yhteyttä vim-palvelimeen"
+#~ msgid "E859: Failed to convert returned python object to vim value"
+#~ msgstr "E859: Ei voitu konvertoida python-oliota vim-arvoksi"
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: Kohteeseen %s lähettäminen ei onnistunut"
+#~ msgid "E858: Eval did not return a valid python object"
+#~ msgstr "E858: Eval ei palauttanut python-oliota"
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: Palvelimen vastauksen lukeminen ei onnistunut"
+#~ msgid "failed to run the code"
+#~ msgstr "ei voitu suorittaa koodia"
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: Asiakkaalle lähetys ei onnistunut"
+#~ msgid "did not switch to the specified tab page"
+#~ msgstr "ei voitu vaihtaa annetulle välilehtisivulle"
-#~ msgid "Save As"
-#~ msgstr "Tallenna nimellä"
+#~ msgid "expected vim.TabPage object, but got %s"
+#~ msgstr "odotettiin vim.TabPage-oliota, saatiin %s"
-#~ msgid "Source Vim script"
-#~ msgstr "Lataa vim-skripti"
+#~ msgid "did not switch to the specified window"
+#~ msgstr "ei vaihdettu annettuun ikkunaan"
-#~ msgid "Edit File"
-#~ msgstr "Muokkaa tiedostoa"
+#~ msgid "failed to find window in the current tab page"
+#~ msgstr "ei voitu löytää ikkunaa nykyiselle välilehtisivulle"
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (EI LÖYTYNYT)"
+#~ msgid "expected vim.Window object, but got %s"
+#~ msgstr "odotettiin vim.Window-oliota, saatiin %s"
-#~ msgid "unknown"
-#~ msgstr "tuntematon"
+#~ msgid "expected vim.Buffer object, but got %s"
+#~ msgstr "odotettiin vim.Buffer-oliota, ei %s"
-#~ msgid "Edit File in new window"
-#~ msgstr "Muokkaa uudessa ikkunassa"
+#~ msgid "attempt to refer to deleted buffer"
+#~ msgstr "yritettiin viitata poistettuun puskuriin"
-#~ msgid "Append File"
-#~ msgstr "Lisää tiedostoon"
+#~ msgid "no such window"
+#~ msgstr "ikkunaa ei ole"
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "Ikkunan sijainti: X %d, Y %d"
+#~ msgid "readonly attribute: buffer"
+#~ msgstr "kirjoitussuojausattribuutti: puskuri"
-#~ msgid "Save Redirection"
-#~ msgstr "Tallenna uudelleenosoitus"
+#~ msgid "attempt to refer to deleted window"
+#~ msgstr "yritettiin viitata poistettuun ikkunaan"
-#~ msgid "Save View"
-#~ msgstr "Tallenna näkymä"
+#~ msgid "no such tab page"
+#~ msgstr "välilehteä ei ole"
-#~ msgid "Save Session"
-#~ msgstr "Tallenna sessio"
+#~ msgid "attempt to refer to deleted tab page"
+#~ msgstr "yritettiin viitata poistettuun välilehteen"
-#~ msgid "Save Setup"
-#~ msgstr "Tallenna asetukset"
+#~ msgid "internal error: unknown option type"
+#~ msgstr "sisäinen virhe: tuntematon asetustyyppi"
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: #< ei ole käytössä jollei +eval ole päällä"
+#~ msgid "unable to get option value"
+#~ msgstr "ei voitu hakea asetuksen arvoa"
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: Digraafeja ei ole tässä versiossa"
+#~ msgid "failed to run function %s"
+#~ msgstr "ei voitu suorittaa funktiota %s"
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr "on laite (ei käytössä opendevice-asetuksen takia)"
+#~ msgid "function %s does not exist"
+#~ msgstr "funktiota %s ei ole"
-#~ msgid "Reading from stdin..."
-#~ msgstr "Luetaan vakiosyötteestä"
+#~ msgid "unnamed function %s does not exist"
+#~ msgstr "nimetöntä funktiota %s ei ole"
-#~ msgid "[crypted]"
-#~ msgstr "[salattu]"
+#~ msgid "cannot modify fixed list"
+#~ msgstr "ei voida muokata kiinitettyä listaa"
-#~ msgid "E821: File is encrypted with unknown method"
-#~ msgstr "E821: Tiedoston salaus on tuntematon"
+#~ msgid "cannot delete vim.List attributes"
+#~ msgstr "ei voi poistaa vim.List-attribuutteja"
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans ei salli kirjoittaa muokkaamattomiin puskureihin"
+#~ msgid "failed to add item to list"
+#~ msgstr "ei voitu lisätä kohtaa listaan"
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "Osittaiset kirjoitukset kielletty NetBeans-puskureissa"
+#~ msgid "attempt to assign sequence of size %d to extended slice of size %d"
+#~ msgstr ""
+#~ "yritettiin asettaa sekvenssiä jonka koko on %d sliceen jonka koko on %d"
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "laitteeseen kirjoittaminen pois käytöstä opendevice-asetuksella"
+#~ msgid "internal error: failed to add item to list"
+#~ msgstr "sisäinen virhe: ei voitu lisätä kohtaa listaan"
-# tietääkseni resurssiforkki on applen tiedostojärjestelmän tunnistejuttujuttu
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: resurssiosa häviäisi (lisää komentoon ! ohittaaksesi)"
+#~ msgid "internal error: not enough list items"
+#~ msgstr "sisäinen virhe: ei tarpeeksi listan kohtia"
-#~ msgid "<cannot open> "
-#~ msgstr "<ei voi avata> "
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: ei saada fonttia %s"
+#~ msgid "internal error: no vim list item %d"
+#~ msgstr "sisäinen virhe: ei vim-listan indeksiä %d"
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: nykyiseen hakemistoon ei voi palata"
+#~ msgid "attempt to assign sequence of size greater than %d to extended slice"
+#~ msgstr ""
+#~ "yritettiin sijoittaa sekvenssiä jonka koko on enemmän kuin %d sliceen"
-#~ msgid "Pathname:"
-#~ msgstr "Polku:"
+#~ msgid "slice step cannot be zero"
+#~ msgstr "slicen askel ei voi olla nolla"
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: nykyistä hakemistoa ei saada selville"
+#~ msgid "internal error: failed to get vim list item %d"
+#~ msgstr "sisäinen virhe: ei pystytty hakea vimin listan indeksiä %d"
-#~ msgid "OK"
-#~ msgstr "OK"
+#~ msgid "list index out of range"
+#~ msgstr "listaindeksi arvoalueen ulkopuolelta"
-#~ msgid "Cancel"
-#~ msgstr "Peru"
+#~ msgid "list constructor does not accept keyword arguments"
+#~ msgstr "listakonstruktori ei tue avainsanaparametrejä"
-#~ msgid "Vim dialog"
-#~ msgstr "Vim-ikkuna"
+#~ msgid "expected sequence element of size 2, but got sequence of size %d"
+#~ msgstr "sekvenssin elementin koon pitäisi olla 2, ei %d"
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr "Vierityspalkki: Pixmapin geometria ei selviä"
+#~ msgid "hashtab changed during iteration"
+#~ msgstr "hashtab muuttui kesken iteraation"
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: Ei voi luoda BalloonEvalia viestille ja callbackille"
+#~ msgid "cannot set attribute %s"
+#~ msgstr "ei voi asettaa attribuuttia %s"
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: GUIn käynnistys ei onnistu"
+#~ msgid "cannot delete vim.Dictionary attributes"
+#~ msgstr "ei voi poistaa vim.Dictionary-attribuutteja"
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: Ei voi lukea kohteesta %s"
+#~ msgid "internal error: imp.find_module returned tuple with NULL"
+#~ msgstr ""
+#~ "sisäinen virhe: imp.find_module palautti tuplen joka sisältää nullin"
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr "E665: Ei voi avata GUIta, sopivaa fonttia ei löydy"
+#~ msgid ""
+#~ "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
+#~ msgstr ""
+#~ "odotettiin 3-tuple tuloksnea imp.find_module()-kutsulle, mutta tuplen "
+#~ "koko onkin %d"
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: guifontwide virheellinen"
+#~ msgid "expected 3-tuple as imp.find_module() result, but got %s"
+#~ msgstr "odotettiin 3-tuplea tuloksena imp.find_module()-kutsulle, ei %s"
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: imactivatekeyn arvo on virheellinen"
+#~ msgid "E264: Python: Error initialising I/O objects"
+#~ msgstr "E264: Python: Virhe IO-olioiden alustuksessa"
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: Väriä %s ei voi määritellä"
+#~ msgid "invalid attribute: %s"
+#~ msgstr "virheellinen attribuutti: %s"
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "Ei täsmäystä kursorin alla, etsitään seuraava"
+#~ msgid "can't delete OutputObject attributes"
+#~ msgstr "ei voi poistaa OutputObject-attribuutteja"
-#~ msgid "Input _Methods"
-#~ msgstr "Syöte_menetelmät"
+#~ msgid "number must be greater or equal to zero"
+#~ msgstr "luvun on oltava yhtä suuri tai suurempi kuin nolla"
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - Etsi ja korvaa..."
+#~ msgid "value is too small to fit into C int type"
+#~ msgstr "arvo on liian pieni mahtumaan C:n int-tyyppiin"
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - Etsi..."
+#~ msgid "expected int() or something supporting coercing to int(), but got %s"
+#~ msgstr ""
+#~ "odotettiin tyyppiä int() tai jotain joka muuntuu tyyppiin int(), ei %s"
-#~ msgid "Find what:"
-#~ msgstr "Etsi:"
+#~ msgid ""
+#~ "expected int(), long() or something supporting coercing to long(), but "
+#~ "got %s"
+#~ msgstr ""
+#~ "odotettiin instanssia tyypeistä int(), long() tai mitä tahansa joka "
+#~ "muuntuisi tyyppiin long(), ei %s"
-#~ msgid "Replace with:"
-#~ msgstr "Korvaa:"
+#~ msgid "expected bytes() or str() instance, but got %s"
+#~ msgstr "odotettiin instanssia tyypeistä bytes() tai str(), ei %s"
-#~ msgid "Match whole word only"
-#~ msgstr "Korvaa kokonaisia sanoja"
+#~ msgid "expected str() or unicode() instance, but got %s"
+#~ msgstr "odottettiin insanssia tyypeistä str() tai unicode(), ei %s"
-#~ msgid "Match case"
-#~ msgstr "Kirjaintaso"
+#~ msgid "index must be int or slice, not %s"
+#~ msgstr "indeksin pitää olla int tai slice, ei %s"
-#~ msgid "Direction"
-#~ msgstr "Suunta"
+#~ msgid "failed to add key '%s' to dictionary"
+#~ msgstr "avaimen %s lisääminen sanakirjaan ei onnistu"
-#~ msgid "Up"
-#~ msgstr "Ylös"
+#~ msgid "list is locked"
+#~ msgstr "luettelo on lukittu"
-#~ msgid "Down"
-#~ msgstr "Alas"
+#~ msgid "Need encryption key for \"%s\""
+#~ msgstr "Tarvitaan salausavain kohteelle %s "
-#~ msgid "Find Next"
-#~ msgstr "Etsi seuraava"
+#~ msgid "E744: NetBeans does not allow changes in read-only files"
+#~ msgstr "E744: NetBeans ei tue muutoksia kirjoitussuojattuihin tiedostoihin"
-#~ msgid "Replace"
-#~ msgstr "Korvaa"
+#~ msgid "E463: Region is guarded, cannot modify"
+#~ msgstr "E463: Alue on suojattu, muuttaminen ei onnistu"
-#~ msgid "Replace All"
-#~ msgstr "Korvaa kaikki"
+#~ msgid "E449: Invalid expression received"
+#~ msgstr "E449: Virheellinen ilmaus saatu"
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: sessiomanageri lähetti die-pyynnön\n"
+#~ msgid "E233: cannot open display"
+#~ msgstr "E233: näyttöä ei voi avata"
-#~ msgid "Close"
-#~ msgstr "Sulje"
+#~ msgid "E247: no registered server named \"%s\""
+#~ msgstr "E247: palvelinta %s ei ole rekisteröitynä"
-#~ msgid "New tab"
-#~ msgstr "Uusi välilehti"
+#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+#~ msgstr "E800: Arabiaa ei voi käyttää, koska sitä ei käännetty mukaan\n"
-#~ msgid "Open Tab..."
-#~ msgstr "Avaa välilehti..."
+#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+#~ msgstr "E27: Farsia ei voi käyttää, koska sitä ei käännetty mukaan\n"
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: Pääikkuna tuhoutui odottamatta\n"
+#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+#~ msgstr "E26: Hepreaa ei voi käyttää, koska sitä ei käännetty mukaan\n"
-#~ msgid "&Filter"
-#~ msgstr "&Suodata"
+#~ msgid "E25: GUI cannot be used: Not enabled at compile time"
+#~ msgstr "E25: GUIta ei voi käyttää, koska sitä ei käännetty mukaan"
-#~ msgid "&Cancel"
-#~ msgstr "&Peru"
+#~ msgid "E448: Could not load library function %s"
+#~ msgstr "E448: Ei voitu ladta kirjastofunktiota %s"
-#~ msgid "Directories"
-#~ msgstr "Hakemistot"
+#~ msgid "E236: Font \"%s\" is not fixed-width"
+#~ msgstr "E236: Fontti %s ei ole tasavälinen"
-#~ msgid "Filter"
-#~ msgstr "Suodatus"
+#~ msgid "E234: Unknown fontset: %s"
+#~ msgstr "E234: Tuntematon fontset: %s"
-#~ msgid "&Help"
-#~ msgstr "O&hje"
+#~ msgid "gvimext.dll error"
+#~ msgstr "gvimext.dll-virhe"
-#~ msgid "Files"
-#~ msgstr "Tiedostot"
+#~ msgid "Error creating process: Check if gvim is in your path!"
+#~ msgstr "Virhe prosessin käynnistämisessä, varmista että gvim on polulla"
-#~ msgid "&OK"
-#~ msgstr "&Ok"
+#~ msgid "Edits the selected file(s) with Vim"
+#~ msgstr "Muokkaa valittuja tiedostoja Vimillä"
-#~ msgid "Selection"
-#~ msgstr "Valinta"
+#~ msgid "Edit with existing Vim - "
+#~ msgstr "Muokkaa olemassaolevalla Vimillä - "
-#~ msgid "Find &Next"
-#~ msgstr "Hae &seuraava"
+#~ msgid "Edit with &Vim"
+#~ msgstr "Muokkaa &Vimillä"
-#~ msgid "&Replace"
-#~ msgstr "Ko&rvaa"
+#~ msgid "Diff with Vim"
+#~ msgstr "Diffi Vimillä"
-#~ msgid "Replace &All"
-#~ msgstr "Korvaa k&aikki"
+#~ msgid "Edit with single &Vim"
+#~ msgstr "Muokkaa yhdellä &Vimillä"
-#~ msgid "&Undo"
-#~ msgstr "&Kumoa"
+#~ msgid "Edit with &multiple Vims"
+#~ msgstr "&Muokkaa usealla Vimillä"
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: Ikkunan otsikkoa ei löydy %s"
+#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+#~ msgstr "E299: Perl-suoritus kielletty hiekkalaatikossa ilman Safe-moduulia"
-# OLE on object linking and embedding på windowska
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: Argumenttia ei tueta: -%s, käytä OLE-versiota"
+#~ msgid ""
+#~ "Sorry, this command is disabled: the Perl library could not be loaded."
+#~ msgstr "komento ei toimi, Perl kirjastoa ei voinut ladata."
-# MDI eli windowsin moni-ikkunasovellus
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: Ikkunaa ei voitu avata MDI-sovellukseen"
+#~ msgid "E370: Could not load library %s"
+#~ msgstr "E370: Kirjaston %s lataaminen ei onnistu"
-#~ msgid "Close tab"
-#~ msgstr "Sulje välilehti"
+#~ msgid "type :help windows95<Enter> for info on this"
+#~ msgstr "kirjoita :help windows95<Enter> lisätietoja varten"
-#~ msgid "Open tab..."
-#~ msgstr "Avaa välilehti..."
+#~ msgid "WARNING: Windows 95/98/ME detected"
+#~ msgstr "VAROITUS: Window 95/98/ME havaittu"
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "Etsi merkkijonoa (\\\\:llä löytää \\:t)"
+#~ msgid " for Vim defaults "
+#~ msgstr " Vim-oletuksia varten"
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "Etsi ja korvaa (\\\\:llä löytää \\:t)"
+#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+#~ msgstr "valikko Muokkaa->Yleiset asetukset->Vaihda Vi-yhteensopivuutta"
-#~ msgid "Not Used"
-#~ msgstr "Ei käytössä"
+#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
+#~ msgstr "valikko Muokkaa->Yleiset asetukset->Vaihda syötetilaa"
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "Hakemisto\t*.nothing\n"
+#~ msgid "Running modeless, typed text is inserted"
+#~ msgstr "Suoritetaan tilattomana, kirjoitettu teksti syötetään"
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr ""
-#~ "Vim E458: Ei voi varata värikartan alkiota, värit voivat mennä väärin"
+#~ msgid "menu Help->Orphans for information "
+#~ msgstr "valikko Ohje->Orvot lisätietoja varten "
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr "E250: Seuraavien merkistöjoukkojen fontit puuttuvat fontsetistä %s:"
+#~ msgid "type :help cp-default<Enter> for info on this"
+#~ msgstr "kirjoita :help cp-default<Enter> ohjetta oletuksista varten"
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: Fontsetin nimi: %s"
+#~ msgid "type :set nocp<Enter> for Vim defaults"
+#~ msgstr "kirjoita :set nocp<Enter> Vimin oletuksiin "
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "Fontti %s ei ole tasavälinen"
+#~ msgid "Running in Vi compatible mode"
+#~ msgstr "Suoritetaan Vi-yhteensopivuustilaa"
-#~ msgid "E253: Fontset name: %s\n"
-#~ msgstr "E253: Fontsetin nimi: %s\n"
+#~ msgid "type :help version8<Enter> for version info"
+#~ msgstr "kirjoita :help version8<Enter> versiotietoja varten "
-#~ msgid "Font0: %s\n"
-#~ msgstr "Fontti0: %s\n"
+#~ msgid "type :help<Enter> or <F1> for on-line help"
+#~ msgstr "kirjoita :help<Enter> tai <F1> ohjetta varten "
-#~ msgid "Font1: %s\n"
-#~ msgstr "Fontti1: %s\n"
+#~ msgid "version "
+#~ msgstr "versio "
-#~ msgid "Font%<PRId64> width is not twice that of font0\n"
-#~ msgstr "Fontti%<PRId64>:n leveys ei ole kaksi kertaa fontti0:n\n"
+#~ msgid "VIM - Vi IMproved"
+#~ msgstr "VIM - Vi IMproved"
-#~ msgid "Font0 width: %<PRId64>\n"
-#~ msgstr "Fontti0:n leveys: %<PRId64>\n"
+#~ msgid " DEBUG BUILD"
+#~ msgstr " DEBUG-versio"
-#~ msgid ""
-#~ "Font1 width: %<PRId64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "Fontti1:n leveys: %<PRId64>\n"
-#~ "\n"
+#~ msgid "Linking: "
+#~ msgstr "Linkitys: "
-#~ msgid "Invalid font specification"
-#~ msgstr "Virheellinen fonttimääritys"
+#~ msgid "Compiler: "
+#~ msgstr "Käännin: "
-#~ msgid "&Dismiss"
-#~ msgstr "&Ohita"
+#~ msgid "Compilation: "
+#~ msgstr "Käännös: "
-#~ msgid "no specific match"
-#~ msgstr "ei tarkkaa täsmäystä"
+#~ msgid " system menu file: \""
+#~ msgstr " järjestelmävalikko: \""
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - fonttivalitsin"
+#~ msgid " defaults file: \""
+#~ msgstr " defaults-tiedosto: \""
-#~ msgid "Name:"
-#~ msgstr "Nimi:"
+#~ msgid "3rd user gvimrc file: \""
+#~ msgstr "3. käyttäjän gvimrc: \""
-#~ msgid "Show size in Points"
-#~ msgstr "Näytä koko pisteinä"
+#~ msgid "2nd user gvimrc file: \""
+#~ msgstr "2. käyttäjän gvimrc: \""
-#~ msgid "Encoding:"
-#~ msgstr "Koodaus:"
+#~ msgid " user gvimrc file: \""
+#~ msgstr " käyttäjän gvimrc: \""
-#~ msgid "Font:"
-#~ msgstr "Fontti:"
+#~ msgid " system gvimrc file: \""
+#~ msgstr " järjestelmän gvimrc: \""
-#~ msgid "Style:"
-#~ msgstr "Tyyli:"
+#~ msgid " 2nd user exrc file: \""
+#~ msgstr " 2. käyttäjän exrc: \""
-#~ msgid "Size:"
-#~ msgstr "Koko:"
+#~ msgid " user exrc file: \""
+#~ msgstr " käyttäjän exrc: \""
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: Hangu-automaattivirhe"
+#~ msgid " 3rd user vimrc file: \""
+#~ msgstr " 3. käyttäjän vimrc: \""
-#~ msgid "E563: stat error"
-#~ msgstr "E563: stat-virhe"
+#~ msgid " 2nd user vimrc file: \""
+#~ msgstr " 2. käyttäjän vimrc: \""
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: ei voi avata cscope-tietokantaa: %s"
+#~ msgid " user vimrc file: \""
+#~ msgstr " käyttäjän vimrc: \""
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: ei voi hakea cscope-tietokannan tietoja"
+#~ msgid "with (classic) GUI."
+#~ msgstr "perinteisellä GUIlla."
-#~ msgid "Lua library cannot be loaded."
-#~ msgstr "Luan kirjastoa ei voitu ladata."
+#~ msgid "with Cocoa GUI."
+#~ msgstr "Cocoa-GUIlla."
-#~ msgid "cannot save undo information"
-#~ msgstr "ei voitu tallentaa kumoustietoja"
+#~ msgid "with Carbon GUI."
+#~ msgstr "Carbon-GUIlla."
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr "E815: Sori, komento ei toimi, MzScheme-kirjastoa ei voitu ladata."
+#~ msgid "with GUI."
+#~ msgstr "GUIlla."
-#~ msgid "invalid expression"
-#~ msgstr "virheellinen ilmaus"
+#~ msgid "with Photon GUI."
+#~ msgstr "Photon-GUIlla."
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "ilmaukset poistettu käytöstä käännösaikana"
+#~ msgid "with X11-Athena GUI."
+#~ msgstr "X11-Athena-GUIlla."
-#~ msgid "hidden option"
-#~ msgstr "piilotettu asetus"
+#~ msgid "with X11-neXtaw GUI."
+#~ msgstr "X11-neXtaw-GUIlla."
-#~ msgid "unknown option"
-#~ msgstr "tuntematon asetus"
+#~ msgid "with X11-Motif GUI."
+#~ msgstr "X11-Motif-GUIlla."
-#~ msgid "window index is out of range"
-#~ msgstr "ikkunan indeksi alueen ulkopuolella"
+#~ msgid "with GTK2 GUI."
+#~ msgstr "GTK2-GUIlla."
-#~ msgid "couldn't open buffer"
-#~ msgstr "ei voitu avata puskuria"
+#~ msgid "with GTK2-GNOME GUI."
+#~ msgstr "GTK2-Gnome-GUIlla."
-#~ msgid "cannot delete line"
-#~ msgstr "ei voitu poistaa riviä"
+#~ msgid "with GTK3 GUI."
+#~ msgstr "GTK3-GUIlla."
-#~ msgid "cannot replace line"
-#~ msgstr "ei voitu korvata riviä"
+#~ msgid "without GUI."
+#~ msgstr "ilman GUIta."
-#~ msgid "cannot insert line"
-#~ msgstr "ei voitu lisätä riviä"
+#~ msgid ""
+#~ "\n"
+#~ "Tiny version "
+#~ msgstr ""
+#~ "\n"
+#~ "Tiny-versio "
-#~ msgid "string cannot contain newlines"
-#~ msgstr "merkkijono ei saa sisältää rivinvaihtoja"
+#~ msgid ""
+#~ "\n"
+#~ "Small version "
+#~ msgstr ""
+#~ "\n"
+#~ "Small-versio "
-#~ msgid "Vim error: ~a"
-#~ msgstr "Vim-virhe: ~a"
+#~ msgid ""
+#~ "\n"
+#~ "Normal version "
+#~ msgstr ""
+#~ "\n"
+#~ "Normal-versio "
-#~ msgid "Vim error"
-#~ msgstr "Vim-virhe"
+#~ msgid ""
+#~ "\n"
+#~ "Big version "
+#~ msgstr ""
+#~ "\n"
+#~ "Big-version "
-#~ msgid "buffer is invalid"
-#~ msgstr "puskuri on virheellinen"
+#~ msgid ""
+#~ "\n"
+#~ "Huge version "
+#~ msgstr ""
+#~ "\n"
+#~ "Huge-versio "
-#~ msgid "window is invalid"
-#~ msgstr "ikkuna on virheellinen"
+#~ msgid "Modified by "
+#~ msgstr "Muokannut "
-#~ msgid "linenr out of range"
-#~ msgstr "rivinumero arvoalueen ulkopuolelta"
+#~ msgid ""
+#~ "\n"
+#~ "Included patches: "
+#~ msgstr ""
+#~ "\n"
+#~ "Pätsit: "
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "ei sallittu Vimin hiekkalaatikossa"
+#~ msgid ""
+#~ "\n"
+#~ "OpenVMS version"
+#~ msgstr ""
+#~ "\n"
+#~ "OpenVMS-version"
-#~ msgid "E836: This Vim cannot execute :python after using :py3"
+#~ msgid ""
+#~ "\n"
+#~ "MacOS version"
#~ msgstr ""
-#~ "E836: Python: Ei voi käyttää komentoja :py ja :py3 samassa istunnossa"
+#~ "\n"
+#~ "MacOS-version"
-#~ msgid "E837: This Vim cannot execute :py3 after using :python"
+#~ msgid ""
+#~ "\n"
+#~ "MacOS X version"
#~ msgstr ""
-#~ "E837: Python: Ei voi käyttää komentoja :py ja :py3 samassa istunnossa"
+#~ "\n"
+#~ "MacOS X-version"
#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
+#~ "\n"
+#~ "MacOS X (unix) version"
#~ msgstr ""
-#~ "E263: Sori, komento ei toimi, Python-kirjaston lataaminen ei onnistunut."
+#~ "\n"
+#~ "MacOS X-version (unix)"
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "ei voi poistaa OutputObject-attribuutteja"
+#~ msgid ""
+#~ "\n"
+#~ "MS-Windows 32-bit console version"
+#~ msgstr ""
+#~ "\n"
+#~ "MS-Windows 32-bittinen konsoliversio"
-#~ msgid "softspace must be an integer"
-#~ msgstr "softspacen pitää olla kokonaisluku"
+#~ msgid ""
+#~ "\n"
+#~ "MS-Windows 64-bit console version"
+#~ msgstr ""
+#~ "\n"
+#~ "MS-Windows 32-bittinen konsoliversio"
-#~ msgid "invalid attribute"
-#~ msgstr "virheellinen attribuutti"
+#~ msgid " with OLE support"
+#~ msgstr " OLE-tuella"
-#~ msgid "<buffer object (deleted) at %p>"
-#~ msgstr "<puskuriolio (poistettu) kohdassa %p>"
+#~ msgid " in Win32s mode"
+#~ msgstr " Win32s-tilassa"
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Pythonia ei voi kutsua rekursiivisesti"
+#~ msgid ""
+#~ "\n"
+#~ "MS-Windows 32-bit GUI version"
+#~ msgstr ""
+#~ "\n"
+#~ "MS-Windows 32-bittinen GUI-version"
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: muuttujan $_ pitää olla Stringin instanssi"
+#~ msgid ""
+#~ "\n"
+#~ "MS-Windows 64-bit GUI version"
+#~ msgstr ""
+#~ "\n"
+#~ "MS-Windows 64-bittinen GUI-versio"
#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr "E266: Sori, komento ei toimi, Ruby-kirjastoa ei voitu ladata."
+#~ "\n"
+#~ "MS-Windows 16/32-bit GUI version"
+#~ msgstr ""
+#~ "\n"
+#~ "MS-Windows 16- t. 32-bittinen GUI-versio"
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: odotuksenvastainen return"
+#~ msgid "E827: Undo file is encrypted: %s"
+#~ msgstr "E827: Kumoustiedosto on salattu: %s"
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: Odotuksenvastainen next"
+#~ msgid "E826: Undo file decryption failed: %s"
+#~ msgstr "E826: Kumoustiedoston purku epäonnistui: %s"
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: Odotuksenvastainen break"
+#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
+#~ msgstr "E832: Salaamattomalla tiedostolla on salattu kumoustiedosto: %s"
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: odotuksenvastainen redo"
+#~ msgid "No undo possible; continue anyway"
+#~ msgstr "Ei voi kumota, jatketaan silti"
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: retry rescuen ulkopuolella"
+#~ msgid "Used CUT_BUFFER0 instead of empty selection"
+#~ msgstr "Käytettiin CUT_BUFFER0:aa tyhjän valinnan sijaan"
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: käsittelemätön poikkeus"
+#~ msgid "new shell started\n"
+#~ msgstr "uusi kuori avattu\n"
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: tuntematon longjmp-tila %d"
+#~ msgid "Cannot open $VIMRUNTIME/rgb.txt"
+#~ msgstr "Ei voida avata tiedostoa $VIMRUNTIME/rgb.txt"
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "Vaihda toteutuksen ja määritelmän välillä"
+#~ msgid ""
+#~ "\n"
+#~ "--- Terminal keys ---"
+#~ msgstr ""
+#~ "\n"
+#~ "--- Terminaalinäppäimet ---"
-#~ msgid "Show base class of"
-#~ msgstr "Näytä kantaluokka kohteelle"
+#~ msgid "E437: terminal capability \"cm\" required"
+#~ msgstr "E437: terminaalilla pitää olla cm kyvyissään"
-#~ msgid "Show overridden member function"
-#~ msgstr "Näytä korvattu jäsenfunktio"
+#~ msgid "E436: No \"%s\" entry in termcap"
+#~ msgstr "E436: %s ei löytynyt termcapista"
-#~ msgid "Retrieve from file"
-#~ msgstr "Jäljitä tiedostosta"
+#~ msgid "E559: Terminal entry not found in termcap"
+#~ msgstr "E559: Terminaalia ei löytynyt termcapista"
-#~ msgid "Retrieve from project"
-#~ msgstr "Jäljitä projektista"
+#~ msgid "E558: Terminal entry not found in terminfo"
+#~ msgstr "E558: Terminaalia ei löytynyt terminfosta"
-#~ msgid "Retrieve from all projects"
-#~ msgstr "Jäljitä kaikista projekteista"
+#~ msgid "E557: Cannot open termcap file"
+#~ msgstr "E557: Ei voi avata termcap-tiedostoa"
-#~ msgid "Retrieve"
-#~ msgstr "Jäljitä"
+#~ msgid "defaulting to '"
+#~ msgstr "oletusarvona "
-#~ msgid "Show source of"
-#~ msgstr "Näytä lähdekoodi kohteelle"
+#~ msgid "' not known. Available builtin terminals are:"
+#~ msgstr " ei tunnettu. Tuetut terminaalit:"
-#~ msgid "Find symbol"
-#~ msgstr "Etsi symboli"
+#~ msgid "E430: Tag file path truncated for %s\n"
+#~ msgstr "E430: Tägitiedoston polku katkaistu kohdassa %s\n"
-#~ msgid "Browse class"
-#~ msgstr "Selaa luokkaa"
+#~ msgid "E422: terminal code too long: %s"
+#~ msgstr "E422: terminaalikoodi liian pitkä: %s"
-#~ msgid "Show class in hierarchy"
-#~ msgstr "Näytä luokka hierarkiassa"
+#~ msgid "E845: Insufficient memory, word list will be incomplete"
+#~ msgstr "E845: Muisti ei riitä, sanalista jää keskeneräiseksi"
+
+#~ msgid "Conversion in %s not supported"
+#~ msgstr "Muutosta kohteessa %s ei tueta"
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "Näytä luokka rajoitetussa hierarkiassa"
+#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
+#~ msgstr "Varoitus: Ei löydetty sanalistaa %s_%s.spl tai %s_ascii.spl"
-#~ msgid "Xref refers to"
-#~ msgstr "Xref viittaa kohteeseen"
+#~ msgid ""
+#~ "\n"
+#~ "# Last %sSearch Pattern:\n"
+#~ "~"
+#~ msgstr ""
+#~ "\n"
+#~ "# Edellinen %sHakulauseke:\n"
+#~ "~"
-#~ msgid "Xref referred by"
-#~ msgstr "Xref viitattu kohteesta"
+#~ msgid "Substitute "
+#~ msgstr "Korvaa "
-#~ msgid "Xref has a"
-#~ msgstr "Xref sisältää kohteen"
+#~ msgid "(NFA) COULD NOT OPEN %s !"
+#~ msgstr "(NFA) EI VOI AVATA KOHDETTA %s"
-#~ msgid "Xref used by"
-#~ msgstr "Xrefiä käyttää"
+#~ msgid ""
+#~ "Could not open temporary log file for writing, displaying on stderr ... "
+#~ msgstr ""
+#~ "Ei voitu avata väliaikaislokitiedosta kirjoittamista varten, joten "
+#~ "virheet näytetään vakiovirhevirrassa. "
-#~ msgid "Show docu of"
-#~ msgstr "Näytä dokumentti kohteelle"
+#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!"
+#~ msgstr "E878: (NFA) Ei voitu allokoida muistia polkujen läpikäyntiin"
-#~ msgid "Generate docu for"
-#~ msgstr "Luo dokumentti kohteelle"
+#~ msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
+#~ msgstr "E876: (NFA regexp) Tila ei riitä NFA:n tallentamiseen"
#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
+#~ "E875: (NFA regexp) (While converting from postfix to NFA), too many "
+#~ "states left on stack"
#~ msgstr ""
-#~ "Ei voida yhdistää SNiFF+:aan. Tarkista ympäristömuuttujat (sniffemacsin "
-#~ "löytyä polkumuuttujasta $PATH).\n"
+#~ "E875: (NFA regexp) (Muunnettaessa postfixistä NFA:ksi), liikaa tiloja "
+#~ "jäljellä pinossa"
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: Virhe luettaessa, yhteys katkaistu"
+#~ msgid "E874: (NFA) Could not pop the stack !"
+#~ msgstr "E874: (NFA) Ei voida poistaa pinosta"
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "SNiFF+ "
+#~ msgid "E873: (NFA regexp) proper termination error"
+#~ msgstr "E873: (NFA regexp) oikea lopetusvirhe"
-#~ msgid "not "
-#~ msgstr "ei ole "
+#~ msgid "E879: (NFA regexp) Too many \\z("
+#~ msgstr "E879: (NFA regexp) Liikaa merkkejä \\z("
-#~ msgid "connected"
-#~ msgstr "yhdistetty"
+#~ msgid "E872: (NFA regexp) Too many '('"
+#~ msgstr "E872: (NFA regexp) Liian monta suljetta '('"
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: Tuntematon SNiFF+-pyyntö: %s"
+#~ msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
+#~ msgstr "E871: (NFA regexp) Multi ei voi seurata multia"
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: Virhe yhdistettäessä SNiFF+:aan"
+#~ msgid "E870: (NFA regexp) Error reading repetition limits"
+#~ msgstr "E870: (NFA regexp) Virhe luettaessa toiston määriä"
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SNiFF+ ei ole yhdistetty"
+#~ msgid "E869: (NFA) Unknown operator '\\@%c'"
+#~ msgstr "E869: (NFA) Tuntematon operaattori '\\@%c'"
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: Ei ole SNiFF+-puskuri"
+#~ msgid "E868: Error building NFA with equivalence class!"
+#~ msgstr "E868: Virhe NFA:n ekvivalenssiluokkia tekemisessä"
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: Virhe kirjoituksessa, yhteys katkaistu"
+#~ msgid "E867: (NFA) Unknown operator '\\%%%c'"
+#~ msgstr "E867: (NFA) Tuntematon operaattori '\\%%%c'"
-#~ msgid "invalid buffer number"
-#~ msgstr "virheellinen puskurinumero"
+#~ msgid "E867: (NFA) Unknown operator '\\z%c'"
+#~ msgstr "E867: (NFA) Tuntematon operaattori '\\z%c'"
-#~ msgid "not implemented yet"
-#~ msgstr "ei toteutettu"
+#~ msgid "E877: (NFA regexp) Invalid character class: %ld"
+#~ msgstr "E877: (NFA regexp) Virheellinen merkkiluokka: %ld"
-#~ msgid "cannot set line(s)"
-#~ msgstr "ei voi asettaa rivejä"
+#~ msgid "E866: (NFA regexp) Misplaced %c"
+#~ msgstr "E866: (NFA-regexp) %c väärässä paikassa"
-#~ msgid "invalid mark name"
-#~ msgstr "virheellinen merkin nimi"
+#~ msgid "E865: (NFA) Regexp end encountered prematurely"
+#~ msgstr "E865: (NFA) Säännöllisen ilmauksen ennenaikainen loppu"
-#~ msgid "mark not set"
-#~ msgstr "merkko ei ole asetettu"
+#~ msgid "Error file"
+#~ msgstr "Virhetiedosto"
-#~ msgid "row %d column %d"
-#~ msgstr "rivi %d sarake %d"
+#~ msgid "shell returned %d"
+#~ msgstr "kuori palautti arvon %d"
-#~ msgid "cannot insert/append line"
-#~ msgstr "rivin lisäys ei onnistu"
+#~ msgid "Vim Warning"
+#~ msgstr "Vim-varoitus"
-#~ msgid "line number out of range"
-#~ msgstr "rivinumero arvoalueen ulkopuolella"
+#~ msgid ""
+#~ "VIMRUN.EXE not found in your $PATH.\n"
+#~ "External commands will not pause after completion.\n"
+#~ "See :help win32-vimrun for more information."
+#~ msgstr ""
+#~ "VIMRUN.EXEä ei löydy muuttujasta $PATH.\n"
+#~ "Ulkoiset komennot eivät pysähdy suorituksen lopussa.\n"
+#~ "Lisätietoja komennolla :help win32-vimrun"
-#~ msgid "unknown flag: "
-#~ msgstr "tuntematon asetus: "
+#~ msgid "E371: Command not found"
+#~ msgstr "E371: Komentoa ei löydy"
-#~ msgid "unknown vimOption"
-#~ msgstr "tuntematon vimOption"
+#~ msgid "shutdown"
+#~ msgstr "sammutus"
-#~ msgid "keyboard interrupt"
-#~ msgstr "näppäimistökeskeytys"
+#~ msgid "logoff"
+#~ msgstr "uloskirjautuminen"
-#~ msgid "vim error"
-#~ msgstr "vim-virhe"
+#~ msgid "close"
+#~ msgstr "sulkeminen"
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr "ei voi luoda puskuri- tai ikkunakomentoa, olio on poistumassa"
+#~ msgid "Vim: Caught %s event\n"
+#~ msgstr "Vim: Napattiin %s\n"
+
+#~ msgid "Could not fix up function pointers to the DLL!"
+#~ msgstr "Ei voitu korjata funktio-osoittimia DLL:ssä"
+
+#~ msgid "VIM Error"
+#~ msgstr "VIM-virhe"
+
+#~ msgid "Could not load vim32.dll!"
+#~ msgstr "Vim32.dll:ää ei voitu ladata"
+
+#~ msgid "At line"
+#~ msgstr "Rivillä"
+
+#~ msgid "XSMP SmcOpenConnection failed: %s"
+#~ msgstr "XSMP SmcOpenConnection epäonnistui: %s"
+
+#~ msgid "XSMP ICE connection watch failed"
+#~ msgstr "XSMP:n ICE-yhteyden tarkkailu epäonnistui"
+
+#~ msgid "XSMP opening connection"
+#~ msgstr "XSMP avaa yhteyttä"
+
+#~ msgid "XSMP handling save-yourself request"
+#~ msgstr "XSMP käsittelee save-yourself-pyyntöä"
+
+#~ msgid "Opening the X display failed"
+#~ msgstr "X-näytön avaus epäonnistui"
+
+#~ msgid "XSMP lost ICE connection"
+#~ msgstr "XSMP kadotti ICE-yhteyden"
#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr "callbackia ei voi rekisteröidä: puskuri tai ikkuna on poistettu"
+#~ "\n"
+#~ "Command terminated\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Komento loppui\n"
#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
+#~ "\n"
+#~ "Cannot execute shell "
#~ msgstr ""
-#~ "E280: kriittinen TCL-virhe: reflist hajalla? Ilmoita asiasta "
-#~ "postituslistalle vim-dev@vim.org"
+#~ "\n"
+#~ "Kuoren suoritus ei onnistu "
-#~ msgid "cannot register callback command: buffer/window reference not found"
+#~ msgid ""
+#~ "\n"
+#~ "Cannot fork\n"
#~ msgstr ""
-#~ "callbackia ei voi rekisteröidä: puskurin tai ikkunan viitettä ei löydy"
+#~ "\n"
+#~ "Ei voi haarauttaa\n"
#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr "E571: Sori, komento ei toimi, Tcl-kirjastoa ei voitu ladata."
+#~ "\n"
+#~ "Cannot create pipes\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Putkia ei voi tehdä\n"
#~ msgid ""
-#~ "E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim."
-#~ "org"
+#~ "\n"
+#~ "Cannot execute shell sh\n"
#~ msgstr ""
-#~ "E281: TCL-virhe: lopetuskoodi ei ole kokonaisluku? Ilmoita asiasta "
-#~ "postituslistalle vim-dev@vim.org"
+#~ "\n"
+#~ "Kuoren sh suoritus ei onnistu\n"
-#~ msgid "E572: exit code %d"
-#~ msgstr "E572: palautusarvo %d"
+# mikä security context?
+#~ msgid "Could not get security context %s for %s. Removing it!"
+#~ msgstr "Ei saatu turvallisuuskontekstia %s kohteelle %s ja se poistetaan"
-#~ msgid "cannot get line"
-#~ msgstr "ei voida hakea riviä"
+#~ msgid "Could not set security context %s for %s"
+#~ msgstr "Ei voitu asettaa turvallisuuskontekstia %s kohteelle %s"
-#~ msgid "Unable to register a command server name"
-#~ msgstr "Komentopalvelimen nimen rekisteröinti ei onnistu"
+#~ msgid "Opening the X display timed out"
+#~ msgstr "X-näytön avaus aikakatkaistiin"
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: Komennon lähetys kohdeohjelmalle ei onnistu"
+#~ msgid "Testing the X display failed"
+#~ msgstr "X-näytön testaus epäonnistui"
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: Virheellinen palvelimen tunniste: %s"
+#~ msgid ""
+#~ "\n"
+#~ "Vim: Got X error\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Vim: X-virhe\n"
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr "E251: VIMin instanssin rekisteriarvo on virheellinen, poistettiin."
+#~ msgid "Opening the X display took %ld msec"
+#~ msgstr "X-näytön avaus vei %ld millisekuntia"
-#~ msgid "netbeans is not supported with this GUI\n"
-#~ msgstr "netbeans ei toimi tässä käyttöliittymässä\n"
+#~ msgid "E245: Illegal char '%c' in font name \"%s\""
+#~ msgstr "E245: Virheellinen merkki %c fontin nimessä %s"
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "Tähän Vimiin ei ole käännetty diff-toimintoja mukaan."
+#~ msgid "E244: Illegal quality name \"%s\" in font name \"%s\""
+#~ msgstr "E244: Virheellinen laatunimi %s fontin nimessä %s"
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "-nb:tä ei voi käyttää, koska sitä ei käännetty mukaan\n"
+#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+#~ msgstr "E244: Virheellinen merkistön nimi %s fontin nimessä %s"
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: Virhe: Gvimin käynnistys NetBeansistä ei onnistu\n"
+#~ msgid "Printing '%s'"
+#~ msgstr "Tulostetaan %s"
+
+#~ msgid "E238: Print error: %s"
+#~ msgstr "E238: Tulostinvirhe: %s"
+
+#~ msgid "E613: Unknown printer font: %s"
+#~ msgstr "E613: Tuntematon tulostimen fontti: %s"
+
+#~ msgid "to %s on %s"
+#~ msgstr "tulostimelle %s kohteessa %s"
+
+#~ msgid "E237: Printer selection failed"
+#~ msgstr "E237: Tulostimen valinta epäonnistui"
+
+#~ msgid "'columns' is not 80, cannot execute external commands"
+#~ msgstr "columns ei ole 80, ei voi suorittaa ulkoista komentoa"
+
+#~ msgid "I/O ERROR"
+#~ msgstr "IO-virhe"
+
+#~ msgid "ANCHOR_BUF_SIZE too small."
+#~ msgstr "ANCHOR_BUF_SIZE liian pieni."
+
+#~ msgid " returned\n"
+#~ msgstr " palautti\n"
+
+#~ msgid "shell "
+#~ msgstr "kuori "
+
+#~ msgid "Cannot execute "
+#~ msgstr "Ei voi suorittaa "
+
+#~ msgid "E360: Cannot execute shell with -f option"
+#~ msgstr "E360: Kuorta ei voi avata asetuksella -f"
+
+#~ msgid "mch_get_shellsize: not a console??\n"
+#~ msgstr "mch_get_shellsize: ei ole konsoli?\n"
+
+#~ msgid "cannot change console mode ?!\n"
+#~ msgstr "ei voi vaihtaa konsolitilaa?\n"
+
+#~ msgid "Vim exiting with %d\n"
+#~ msgstr "Vim sulkeutuu koodilla %d\n"
+
+#~ msgid "Cannot create "
+#~ msgstr "Ei voi luoda "
+
+#~ msgid "Cannot open NIL:\n"
+#~ msgstr "Ei voi avata NILiä:\n"
+
+#~ msgid "Need %s version %ld\n"
+#~ msgstr "Tarvitaan %s versio %ld\n"
+
+#~ msgid "Need Amigados version 2.04 or later\n"
+#~ msgstr "Amigados 2.04 tai uudempi tarvitaan\n"
+
+#~ msgid "VIM: Can't open window!\n"
+#~ msgstr "VIM: Ei voi avata ikkunaa\n"
+
+#~ msgid "cannot open "
+#~ msgstr "ei voi avata "
+
+#~ msgid "E538: No mouse support"
+#~ msgstr "E538: Hiirtä ei tueta"
+
+#~ msgid "E533: can't select wide font"
+#~ msgstr "E533: Leveän fontin valinta ei onnistu"
+
+#~ msgid "E598: Invalid fontset"
+#~ msgstr "E598: Viallinen fontset"
+
+#~ msgid "E597: can't select fontset"
+#~ msgstr "E597: Fontsetin valinta ei onnistu"
+
+#~ msgid "E596: Invalid font(s)"
+#~ msgstr "E596: Viallisia fontteja"
+
+#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+#~ msgstr "E617: Ei voi muuttaa GTK+2-GUIssa"
+
+#~ msgid "E531: Use \":gui\" to start the GUI"
+#~ msgstr "E531: Käytä komentoa :gui GUIn käynnistämiseen"
+
+#~ msgid "E530: Cannot change term in GUI"
+#~ msgstr "E530: Ei voi vaihtaa termiä GUIssa"
+
+#~ msgid "E522: Not found in termcap"
+#~ msgstr "E522: Puuttuu termcapista"
+
+#~ msgid "Thanks for flying Vim"
+#~ msgstr "Kiitos että ajoit Vimiä"
+
+#~ msgid "%<%f%h%m%=Page %N"
+#~ msgstr "%<%f%h%m%=Sivu %N"
#~ msgid ""
#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
+#~ "# Registers:\n"
#~ msgstr ""
#~ "\n"
-#~ "Jos aakkoslaji on ohitettu, lisää alkuun / tehdäksesi asetuksesta "
-#~ "suuraakkosia"
+#~ "# Rekisterit:\n"
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\trekisteröi gvim OLEa varten"
+#~ msgid "Illegal register name"
+#~ msgstr "Virheellinen rekisterin nimi"
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tPoista gvim OLE-rekisteristä"
+#~ msgid "freeing %ld lines"
+#~ msgstr "vapautetaan %ld riviä"
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tAvaa GUI (kuten gvimillä)"
+#~ msgid "cannot yank; delete anyway"
+#~ msgstr "Ei voi kopioida; poista joka tapauksessa"
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f tai --nofork\tEdustalle: Älä haarauta GUIn käynnistyksessä"
+#~ msgid "E775: Eval feature not available"
+#~ msgstr "E775: Eval ei ole käytettävissä"
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\tÄlä käytä newcli:tä ikkunan avaamiseen"
+#~ msgid "E505: %s is read-only (add ! to override)"
+#~ msgstr "E505: %s on kirjoitussuojattu (lisää komentoon ! ohittaaksesi)"
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <laite>\t\tKäytä <laitetta> IO:hon"
+#~ msgid "E511: netbeans already connected"
+#~ msgstr "E511: netbeans on yhdistetty jo"
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\tKäytä <gvimrc>-tiedostoa .gvimrc:iden sijasta"
+#~ msgid "E838: netbeans is not supported with this GUI"
+#~ msgstr "E838: netbeans ei toimi tässä käyttöliittymässä"
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\tMuokkaa salattua tiedostoa"
+#~ msgid "E658: NetBeans connection lost for buffer %ld"
+#~ msgstr "E658: NetBeans-yhteys katkesi puskurille %ld"
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <näyttö>\tYhdistä vim tiettyyn X-palvelimeen"
+#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+#~ msgstr "E668: Väärä avaustila NetBeans-yhteyden infotiedostolle: %s"
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tÄlä yhdistä X-palvelimeen"
+#~ msgid "E547: Illegal mouseshape"
+#~ msgstr "E547: Virheellinen hiiren muoto"
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr ""
-#~ "--remote <tiedostoja>\tMuokkaa <tiedostoja> Vim-palvelimessa, jos "
-#~ "mahdollista"
+#~ msgid "E341: Internal error: lalloc(%ld, )"
+#~ msgstr "E341: Sisäinen virhe: lalloc(%ld, )"
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-silent <tiedostoja>\tSama, mutta älä ilmoita puuttuvasta "
-#~ "palvelimesta"
+#~ msgid "E340: Line is becoming too long"
+#~ msgstr "E340: Rivistä tulee liian pitkä"
#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
+#~ "[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+#~ "\n"
#~ msgstr ""
-#~ "--remote-wait <tiedostoja> kuten --remote, mutta odota tiedostojen "
-#~ "muokkaamista"
+#~ "[kutsut] yht. re/malloc() %lu, yht. free() %lu\n"
+#~ "\n"
#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
+#~ "\n"
+#~ "[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
#~ msgstr ""
-#~ "--remote-wait-silent <tiedostoja> sama, mutta älä ilmoita puuttuvasta "
-#~ "palvelimesta"
+#~ "\n"
+#~ "[tavua] yht. alloc-free %lu-%lu, käytössä %lu, käyttöhuippu %lu\n"
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <tiedostoja> kuten --remote, mutta avaa "
-#~ "välilehti joka tiedostolle"
+#~ msgid "ERROR: "
+#~ msgstr "VIRHE: "
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr ""
-#~ "--remote-send <näppäimiä>\tLähetä <näppäimiä> painalluksina Vimille ja "
-#~ "lopeta"
+#~ msgid "E338: Sorry, no file browser in console mode"
+#~ msgstr "E338: tiedostonselain puuttuu konsolitilasta"
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr ""
-#~ "--remote-expr <ilmaus>\tKäsittele <ilmaus> Vim-palvelimella ja tulosta "
-#~ "tulos"
+#~ msgid "Open File dialog"
+#~ msgstr "Avausikkuna"
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr "--serverlist\t\tLuettele Vim-palvelinten nimet ja lopeta"
+#~ msgid "Save File dialog"
+#~ msgstr "Tallennusikkuna"
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <nimi>\tLähetä Vim-palvelimelle <nimi> tai luo se"
+#~ msgid "Select Directory dialog"
+#~ msgstr "Hakemiston valintaikkuna"
+
+#~ msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+#~ msgstr "Käännöksen ylläpitäjä: Flammie Pirinen <flammie@iki.fi>"
+
+#~ msgid "E337: Menu not found - check menu names"
+#~ msgstr "E337: Valikkoa ei löytynyt - tarkista valikkojen nimet"
+
+#~ msgid "E336: Menu path must lead to a sub-menu"
+#~ msgstr "E336: Valikkopolun pitää johtaa alivalikkoon"
+
+#~ msgid "Tear off this menu"
+#~ msgstr "Repäise valikko irti"
+
+#~ msgid "Swap file already exists!"
+#~ msgstr "Swap-tiedosto on jo olemassa"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
+#~ " [not usable with this version of Vim]"
#~ msgstr ""
#~ "\n"
-#~ "Gvimin (Motif-version) tuntemat argumentit:\n"
+#~ " [ei toimi tämän Vim-version kanssa]"
+
+#~ msgid "Using crypt key from swap file for the text file.\n"
+#~ msgstr "Käytetään swäpin salausavainta tekstitiedostolle\n"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
+#~ "to use the same key for text file and swap file"
#~ msgstr ""
#~ "\n"
-#~ "Gvimin (neXtaw-version) tuntemat argumentit:\n"
+#~ "käyttääksesi samaa avainta teksti- ja swäppitiedostoille"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
+#~ "If you wrote the text file after changing the crypt key press enter"
#~ msgstr ""
#~ "\n"
-#~ "Gvimin (Athena-version) tuntemat argumentit:\n"
+#~ "Jos kirjoitit tekstitiedoston salausavaimen vaihdon jälkeen paina enteriä"
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <näyttö>\tSuorita vim <näytössä>"
+#~ msgid ""
+#~ "\n"
+#~ "enter the new crypt key."
+#~ msgstr ""
+#~ "\n"
+#~ "anna uusi salausavain."
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tKäynnistä pienennettynä"
+#~ msgid ""
+#~ "\n"
+#~ "If you entered a new crypt key but did not write the text file,"
+#~ msgstr ""
+#~ "\n"
+#~ "Jos käytit uutta salausavainta muttet kirjoittanut tekstitiedostoa,"
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <väri>\tKäytä <väriä> taustavärinä (myös: -bg)"
+#~ msgid "Swap file is encrypted: \"%s\""
+#~ msgstr "Swap-tiedosto on salattu: %s"
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr "-foreground <väri>\tKäytä <väriä> tekstin värinä (myös: -fg)"
+#~ msgid ""
+#~ "E833: %s is encrypted and this version of Vim does not support encryption"
+#~ msgstr "E833: %s on salattu eikä tämä Vim tue salausta"
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <fontti>\t\tKäytä <fonttia> tekstissä (myös: -fn)"
+#~ msgid "E843: Error while updating swap file crypt"
+#~ msgstr "E843: Virhe päivitettäessä swapin kryptausta"
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <fontti>\tKäytä <fonttia> lihavoidussa tekstissä"
+#~ msgid "E289: input method doesn't support my preedit type"
+#~ msgstr "E289: syötemetodi ei tue tätä preedit-tyyppiä"
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <fontti>\tKäytä <fonttia> kursivoidussa tekstissä"
+#~ msgid "E288: input method doesn't support any style"
+#~ msgstr "E288: syötemetodi ei tue tyylejä"
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+#~ msgid "E287: Warning: Could not set destroy callback to IM"
#~ msgstr ""
-#~ "-geometry <geom>\tKäytä mittoja <geom> ikkunan asetteluun (myös: -geom)"
+#~ "E287: Varoitus: Ei voitu asettaa destroy-kutsua syötemetodipalvelimelle"
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidt <leveys>\tKäytä <leveyttä> reunuksissa (myös: -bw) "
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <leveys> Käytä <leveyttä> vierityspalkissa (myös: -sw)"
+#~ msgid "E286: Failed to open input method"
+#~ msgstr "E286: Syötemetodin avaus ei onnistu"
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr "-menuheight <korkeus>\tKäytä <korkeutta> valikossa (myös: -mh)"
+#~ msgid "E285: Failed to create input context"
+#~ msgstr "E285: Syötekontekstin luonti ei onnistu"
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tKäytä käänteisvärejä (myös: -rv) "
+#~ msgid "E284: Cannot set IC values"
+#~ msgstr "E284: Ei voi asettaa IC-arvoja"
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tÄlä käytä käänteisvärejä (myös: +rv)"
+#~ msgid "E543: Not a valid codepage"
+#~ msgstr "E543: Koodisivu ei ole käypä"
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <resurssi>\tAseta resurssi"
+#~ msgid "Missing '>'"
+#~ msgstr "> puuttuu"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (RISC OS version):\n"
+#~ "# History of marks within files (newest to oldest):\n"
#~ msgstr ""
#~ "\n"
-#~ "Gvimin (RISC OS -version) tuntemat argumentit:\n"
-
-#~ msgid "--columns <number>\tInitial width of window in columns"
-#~ msgstr "--columns <luku>\tIkkunan alkuleveys sarakkeina"
+#~ "# Tiedostojen merkkien historia (uusimmasta vanhimpaan):\n"
-#~ msgid "--rows <number>\tInitial height of window in rows"
-#~ msgstr "--rows <luku>\tIkkunan alkukorkeus riveinä"
+#~ msgid ""
+#~ "\n"
+#~ "# Jumplist (newest first):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# Hyppylista (uusin ensiksi):\n"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
+#~ "# File marks:\n"
#~ msgstr ""
#~ "\n"
-#~ "Gvimin (GTK+-version) tuntemat argumentit:\n"
+#~ "# Tiedoston merkit:\n"
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <näyttö>\tSuorita vim näytöllä <näyttö> (myös: --display)"
+#~ msgid ": Send expression failed.\n"
+#~ msgstr ": Ilmauksen lähetys epäonnistui.\n"
-# X-ikkunointijärjestelmässä saman sovelluksen saman luokan ikkunat
-# tunnistetaan rooliresursseista
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr ""
-#~ "--role <rooli>\tAseta pääikkunalle ainutlaatuinen rooli tunnisteeksi"
+#~ msgid "No display: Send expression failed.\n"
+#~ msgstr "Ei näyttöä: Ilmauksen lähetys epäonnistui.\n"
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tAvaa Vim annettuun GTK-olioon "
+#~ msgid "%d of %d edited"
+#~ msgstr "%d/%d muokattu"
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <otsikko>\tAvaa Vim isäntäohjelman sisään"
+#~ msgid ": Send failed. Trying to execute locally\n"
+#~ msgstr ": Lähetys epäonnistui. Yritetään suorittaa paikallisena\n"
+
+#~ msgid ": Send failed.\n"
+#~ msgstr ": Lähetys epäonnistui.\n"
+
+#~ msgid "No display"
+#~ msgstr "Ei näyttöä"
#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
#~ msgstr "--windowid <HWND>\tAvaa Vim annettuun win32-olioon "
-#~ msgid "No display"
-#~ msgstr "Ei näyttöä"
+#~ msgid "-P <parent title>\tOpen Vim inside parent application"
+#~ msgstr "-P <otsikko>\tAvaa Vim isäntäohjelman sisään"
-#~ msgid ": Send failed.\n"
-#~ msgstr ": Lähetys epäonnistui.\n"
+#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
+#~ msgstr "--echo-wid\t\tTulosta gvimin Window ID vakiotulosteeseen"
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": Lähetys epäonnistui. Yritetään suorittaa paikallisena\n"
+#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+#~ msgstr "--socketid <xid>\tAvaa Vim annettuun GTK-olioon "
-#~ msgid "%d of %d edited"
-#~ msgstr "%d/%d muokattu"
+# X-ikkunointijärjestelmässä saman sovelluksen saman luokan ikkunat
+# tunnistetaan rooliresursseista
+#~ msgid "--role <role>\tSet a unique role to identify the main window"
+#~ msgstr ""
+#~ "--role <rooli>\tAseta pääikkunalle ainutlaatuinen rooli tunnisteeksi"
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "Ei näyttöä: Ilmauksen lähetys epäonnistui.\n"
+#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
+#~ msgstr "-display <näyttö>\tSuorita vim näytöllä <näyttö> (myös: --display)"
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": Ilmauksen lähetys epäonnistui.\n"
+#~ msgid ""
+#~ "\n"
+#~ "Arguments recognised by gvim (GTK+ version):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Gvimin (GTK+-version) tuntemat argumentit:\n"
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: Koodisivu ei ole käypä"
+#~ msgid "-xrm <resource>\tSet the specified resource"
+#~ msgstr "-xrm <resurssi>\tAseta resurssi"
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: Syötekontekstin luonti ei onnistu"
+#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+#~ msgstr "+reverse\t\tÄlä käytä käänteisvärejä (myös: +rv)"
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: Syötemetodin avaus ei onnistu"
+#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
+#~ msgstr "-reverse\t\tKäytä käänteisvärejä (myös: -rv) "
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
+#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+#~ msgstr "-menuheight <korkeus>\tKäytä <korkeutta> valikossa (myös: -mh)"
+
+#~ msgid ""
+#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
#~ msgstr ""
-#~ "E287: Varoitus: Ei voitu asettaa destroy-kutsua syötemetodipalvelimelle"
+#~ "-scrollbarwidth <leveys> Käytä <leveyttä> vierityspalkissa (myös: -sw)"
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: syötemetodi ei tue tyylejä"
+#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+#~ msgstr "-borderwidt <leveys>\tKäytä <leveyttä> reunuksissa (myös: -bw) "
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr "E289: syötemetodi ei tue tätä preedit-tyyppiä"
+#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+#~ msgstr ""
+#~ "-geometry <geom>\tKäytä mittoja <geom> ikkunan asetteluun (myös: -geom)"
-#~ msgid ""
-#~ "E833: %s is encrypted and this version of Vim does not support encryption"
-#~ msgstr "E833: %s on salattu eikä tämä Vim tue salausta"
+#~ msgid "-italicfont <font>\tUse <font> for italic text"
+#~ msgstr "-italicfont <fontti>\tKäytä <fonttia> kursivoidussa tekstissä"
-#~ msgid "Swap file is encrypted: \"%s\""
-#~ msgstr "Swap-tiedosto on salattu: %s"
+#~ msgid "-boldfont <font>\tUse <font> for bold text"
+#~ msgstr "-boldfont <fontti>\tKäytä <fonttia> lihavoidussa tekstissä"
+
+#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+#~ msgstr "-font <fontti>\t\tKäytä <fonttia> tekstissä (myös: -fn)"
+
+#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+#~ msgstr "-foreground <väri>\tKäytä <väriä> tekstin värinä (myös: -fg)"
+
+#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
+#~ msgstr "-background <väri>\tKäytä <väriä> taustavärinä (myös: -bg)"
+
+#~ msgid "-iconic\t\tStart vim iconified"
+#~ msgstr "-iconic\t\tKäynnistä pienennettynä"
+
+#~ msgid "-display <display>\tRun vim on <display>"
+#~ msgstr "-display <näyttö>\tSuorita vim <näytössä>"
#~ msgid ""
#~ "\n"
-#~ "If you entered a new crypt key but did not write the text file,"
+#~ "Arguments recognised by gvim (Athena version):\n"
#~ msgstr ""
#~ "\n"
-#~ "Jos käytit uutta salausavainta muttet kirjoittanut tekstitiedostoa,"
+#~ "Gvimin (Athena-version) tuntemat argumentit:\n"
#~ msgid ""
#~ "\n"
-#~ "enter the new crypt key."
+#~ "Arguments recognised by gvim (neXtaw version):\n"
#~ msgstr ""
#~ "\n"
-#~ "anna uusi salausavain."
+#~ "Gvimin (neXtaw-version) tuntemat argumentit:\n"
#~ msgid ""
#~ "\n"
-#~ "If you wrote the text file after changing the crypt key press enter"
+#~ "Arguments recognised by gvim (Motif version):\n"
#~ msgstr ""
#~ "\n"
-#~ "Jos kirjoitit tekstitiedoston salausavaimen vaihdon jälkeen paina enteriä"
+#~ "Gvimin (Motif-version) tuntemat argumentit:\n"
+
+#~ msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+#~ msgstr "-i <viminfo>\t\tKäytä <viminfo>-tiedostoa .viminfon sijaan"
+
+#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
+#~ msgstr "--servername <nimi>\tLähetä Vim-palvelimelle <nimi> tai luo se"
+
+#~ msgid "--serverlist\t\tList available Vim server names and exit"
+#~ msgstr "--serverlist\t\tLuettele Vim-palvelinten nimet ja lopeta"
#~ msgid ""
-#~ "\n"
-#~ "to use the same key for text file and swap file"
+#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
#~ msgstr ""
-#~ "\n"
-#~ "käyttääksesi samaa avainta teksti- ja swäppitiedostoille"
+#~ "--remote-expr <ilmaus>\tKäsittele <ilmaus> Vim-palvelimella ja tulosta "
+#~ "tulos"
-#~ msgid "Using crypt key from swap file for the text file.\n"
-#~ msgstr "Käytetään swäpin salausavainta tekstitiedostolle\n"
+#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+#~ msgstr ""
+#~ "--remote-send <näppäimiä>\tLähetä <näppäimiä> painalluksina Vimille ja "
+#~ "lopeta"
#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
+#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
+#~ "file"
#~ msgstr ""
-#~ "\n"
-#~ " [ei toimi tämän Vim-version kanssa]"
+#~ "--remote-tab[-wait][-silent] <tiedostoja> kuten --remote, mutta avaa "
+#~ "välilehti joka tiedostolle"
-#~ msgid "Tear off this menu"
-#~ msgstr "Repäise valikko irti"
+#~ msgid ""
+#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
+#~ msgstr ""
+#~ "--remote-wait-silent <tiedostoja> sama, mutta älä ilmoita puuttuvasta "
+#~ "palvelimesta"
-#~ msgid "Select Directory dialog"
-#~ msgstr "Hakemiston valintaikkuna"
+#~ msgid ""
+#~ "--remote-wait <files> As --remote but wait for files to have been edited"
+#~ msgstr ""
+#~ "--remote-wait <tiedostoja> kuten --remote, mutta odota tiedostojen "
+#~ "muokkaamista"
-#~ msgid "Save File dialog"
-#~ msgstr "Tallennusikkuna"
+#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
+#~ msgstr ""
+#~ "--remote-silent <tiedostoja>\tSama, mutta älä ilmoita puuttuvasta "
+#~ "palvelimesta"
-#~ msgid "Open File dialog"
-#~ msgstr "Avausikkuna"
+#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+#~ msgstr ""
+#~ "--remote <tiedostoja>\tMuokkaa <tiedostoja> Vim-palvelimessa, jos "
+#~ "mahdollista"
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: Sori, tiedostonselain puuttuu konsolitilasta"
+#~ msgid "-X\t\t\tDo not connect to X server"
+#~ msgstr "-X\t\t\tÄlä yhdistä X-palvelimeen"
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "Vim: säästetään tiedostoja...\n"
+#~ msgid "-display <display>\tConnect vim to this particular X-server"
+#~ msgstr "-display <näyttö>\tYhdistä vim tiettyyn X-palvelimeen"
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "Vim: Valmis.\n"
+#~ msgid "-x\t\t\tEdit encrypted files"
+#~ msgstr "-x\t\t\tMuokkaa salattua tiedostoa"
-#~ msgid "ERROR: "
-#~ msgstr "VIRHE: "
+#~ msgid "+\t\t\tStart at end of file"
+#~ msgstr "+\t\t\tAloita tiedoston lopusta"
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[tavua] yht. alloc-free %<PRIu64>-%<PRIu64>, käytössä %<PRIu64>, "
-#~ "käyttöhuippu %<PRIu64>\n"
+#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+#~ msgstr "-U <gvimrc>\t\tKäytä <gvimrc>-tiedostoa .gvimrc:iden sijasta"
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[kutsut] yht. re/malloc() %<PRIu64>, yht. free() %<PRIu64>\n"
-#~ "\n"
+#~ msgid "--not-a-term\t\tSkip warning for input/output not being a terminal"
+#~ msgstr "--not-a-term\t\tOhita varoitus siitä että i/o ei ole terminaali"
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: Rivistä tulee liian pitkä"
+#~ msgid "-T <terminal>\tSet terminal type to <terminal>"
+#~ msgstr "-T <terminaali>\tAseta terminaalin tyypiksi <terminaali>"
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: Sisäinen virhe: lalloc(%<PRId64>, )"
+#~ msgid "-F\t\t\tStart in Farsi mode"
+#~ msgstr "-F\t\t\tkäynnistä farsi-tilassa"
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: Virheellinen hiiren muoto"
+#~ msgid "-H\t\t\tStart in Hebrew mode"
+#~ msgstr "-H\t\t\tkäynnistä heprea-tilassa"
-#~ msgid "Enter encryption key: "
-#~ msgstr "Anna salausavain: "
+#~ msgid "-A\t\t\tstart in Arabic mode"
+#~ msgstr "-A\t\t\tkäynnistä arabia-tilassa"
-#~ msgid "Enter same key again: "
-#~ msgstr "Anna sama avain uudestaan: "
+#~ msgid "-dev <device>\t\tUse <device> for I/O"
+#~ msgstr "-dev <laite>\t\tKäytä <laitetta> IO:hon"
-#~ msgid "Keys don't match!"
-#~ msgstr "Avaimet eivät täsmää!"
+#~ msgid "-f\t\t\tDon't use newcli to open window"
+#~ msgstr "-f\t\t\tÄlä käytä newcli:tä ikkunan avaamiseen"
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Ei voi yhdistää Netbeans #2:een"
+#~ msgid "-L\t\t\tSame as -r"
+#~ msgstr "-L\t\t\tkuten -r"
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Ei voi yhdistää Netbeansiin"
+#~ msgid "-D\t\t\tDebugging mode"
+#~ msgstr "-D\t\t\tVianetsintätila"
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr "E668: Väärä avaustila NetBeans-yhteyden infotiedostolle: %s"
+#~ msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+#~ msgstr "-N\t\t\tEi Vi-yhteensopivuutta: nocompatible"
-#~ msgid "read from Netbeans socket"
-#~ msgstr "luettu Netbeans-soketista"
+#~ msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+#~ msgstr "-C\t\t\tVi-yhteensopivuustila: compatible"
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: NetBeans-yhteys katkesi puskurille %<PRId64>"
+#~ msgid "-l\t\t\tLisp mode"
+#~ msgstr "-l\t\t\tLisp-tila"
-#~ msgid "E511: netbeans already connected"
-#~ msgstr "E511: netbeans on yhdistetty jo"
+#~ msgid "-b\t\t\tBinary mode"
+#~ msgstr "-b\t\t\tBinääritila"
-#~ msgid "E505: "
-#~ msgstr "E505: "
+#~ msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+#~ msgstr "-Z\t\t\tRajoitettu tila (kuten rvimillä)"
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: Eval ei ole käytettävissä"
+#~ msgid "-R\t\t\tReadonly mode (like \"view\")"
+#~ msgstr "-R\t\t\tKirjoitussuojattu tila (kuten view'lla)"
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "vapautetaan %<PRId64> riviä"
+#~ msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+#~ msgstr "-y\t\t\tHelppokäyttötila (kuten evimissä, ilman tiloja)"
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: Ei voi vaihtaa termiä GUIssa"
+#~ msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+#~ msgstr "-d\t\t\tDiff-tila (kuten vimdiffillä)"
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: Käytä komentoa :gui GUIn käynnistämiseen"
+#~ msgid "-E\t\t\tImproved Ex mode"
+#~ msgstr "-E\t\t\tParanneltu Ex-tila"
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: Ei voi muuttaa GTK+2-GUIssa"
+#~ msgid "-e\t\t\tEx mode (like \"ex\")"
+#~ msgstr "-e\t\t\tEx-tila (kute exillä)"
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: Viallisia fontteja"
+#~ msgid "-v\t\t\tVi mode (like \"vi\")"
+#~ msgstr "-v\t\t\tVi-tila (kuten villä)"
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: Fontsetin valinta ei onnistu"
+#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+#~ msgstr "-f tai --nofork\tEdustalle: Älä haarauta GUIn käynnistyksessä"
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: Viallinen fontset"
+#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+#~ msgstr "-g\t\t\tAvaa GUI (kuten gvimillä)"
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: Leveän fontin valinta ei onnistu"
+#~ msgid "-unregister\t\tUnregister gvim for OLE"
+#~ msgstr "-unregister\t\tPoista gvim OLE-rekisteristä"
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: Viallinen leveä fontti"
+#~ msgid "-register\t\tRegister this gvim for OLE"
+#~ msgstr "-register\t\trekisteröi gvim OLEa varten"
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: Hiirtä ei tueta"
+#~ msgid ""
+#~ "\n"
+#~ "Where case is ignored prepend / to make flag upper case"
+#~ msgstr ""
+#~ "\n"
+#~ "Jos aakkoslaji on ohitettu, lisää alkuun / tehdäksesi asetuksesta "
+#~ "suuraakkosia"
-#~ msgid "cannot open "
-#~ msgstr "ei voi avata "
+#~ msgid ""
+#~ "\n"
+#~ " or:"
+#~ msgstr ""
+#~ "\n"
+#~ " tai:"
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: Ei voi avata ikkunaa\n"
+#~ msgid " vim [arguments] "
+#~ msgstr " vim [argumentit] "
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Amigados 2.04 tai uudempi tarvitaan\n"
+#~ msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n"
+#~ msgstr "Vim: Virhe: Tämä versio Vimistä ei toimi Cygwinin terminaalissa\n"
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "Tarvitaan %s versio %<PRId64>\n"
+#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+#~ msgstr "Vim: Virhe: Gvimin käynnistys NetBeansistä ei onnistu\n"
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "Ei voi avata NILiä:\n"
+#~ msgid "This Vim was not compiled with the diff feature."
+#~ msgstr "Tähän Vimiin ei ole käännetty diff-toimintoja mukaan."
-#~ msgid "Cannot create "
-#~ msgstr "Ei voi luoda "
+#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
+#~ msgstr "-nb:tä ei voi käyttää, koska sitä ei käännetty mukaan\n"
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim sulkeutuu koodilla %d\n"
+#~ msgid "netbeans is not supported with this GUI\n"
+#~ msgstr "netbeans ei toimi tässä käyttöliittymässä\n"
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "ei voi vaihtaa konsolitilaa?\n"
+#~ msgid "%d files to edit\n"
+#~ msgstr "%d tiedostoa muokattavana\n"
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: ei ole konsoli?\n"
+#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
+#~ msgstr "E251: VIMin instanssin rekisteriarvo on virheellinen, poistettiin."
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: Kuorta ei voi avata asetuksella -f"
+#~ msgid "E573: Invalid server id used: %s"
+#~ msgstr "E573: Virheellinen palvelimen tunniste: %s"
-#~ msgid "Cannot execute "
-#~ msgstr "Ei voi suorittaa "
+#~ msgid "E248: Failed to send command to the destination program"
+#~ msgstr "E248: Komennon lähetys kohdeohjelmalle ei onnistu"
-#~ msgid "shell "
-#~ msgstr "kuori "
+#~ msgid "Unable to register a command server name"
+#~ msgstr "Komentopalvelimen nimen rekisteröinti ei onnistu"
-#~ msgid " returned\n"
-#~ msgstr " palautti\n"
+#~ msgid "cannot get line"
+#~ msgstr "ei voida hakea riviä"
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE liian pieni."
+#~ msgid "E572: exit code %d"
+#~ msgstr "E572: palautusarvo %d"
-#~ msgid "I/O ERROR"
-#~ msgstr "IO-virhe"
+#~ msgid ""
+#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
+#~ "loaded."
+#~ msgstr "E571: komento ei toimi, Tcl-kirjastoa ei voitu ladata."
-#~ msgid "Message"
-#~ msgstr "Viesti"
+#~ msgid "cannot register callback command: buffer/window reference not found"
+#~ msgstr ""
+#~ "callbackia ei voi rekisteröidä: puskurin tai ikkunan viitettä ei löydy"
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "columns ei ole 80, ei voi suorittaa ulkoista komentoa"
+#~ msgid ""
+#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
+#~ "dev@vim.org"
+#~ msgstr ""
+#~ "E280: kriittinen TCL-virhe: reflist hajalla? Ilmoita asiasta "
+#~ "postituslistalle vim-dev@vim.org"
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: Tulostimen valinta epäonnistui"
+#~ msgid ""
+#~ "cannot register callback command: buffer/window is already being deleted"
+#~ msgstr "callbackia ei voi rekisteröidä: puskuri tai ikkuna on poistettu"
-#~ msgid "to %s on %s"
-#~ msgstr "tulostimelle %s kohteessa %s"
+#~ msgid "cannot create buffer/window command: object is being deleted"
+#~ msgstr "ei voi luoda puskuri- tai ikkunakomentoa, olio on poistumassa"
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: Tuntematon tulostimen fontti: %s"
+#~ msgid "vim error"
+#~ msgstr "vim-virhe"
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: Tulostinvirhe: %s"
+#~ msgid "unknown vimOption"
+#~ msgstr "tuntematon vimOption"
-#~ msgid "Printing '%s'"
-#~ msgstr "Tulostetaan %s"
+#~ msgid "unknown flag: "
+#~ msgstr "tuntematon asetus: "
-#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
-#~ msgstr "E244: Virheellinen merkistön nimi %s fontin nimessä %s"
+#~ msgid "cannot insert/append line"
+#~ msgstr "rivin lisäys ei onnistu"
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: Virheellinen merkki %c fontin nimessä %s"
+#~ msgid "row %d column %d"
+#~ msgstr "rivi %d sarake %d"
+
+#~ msgid "mark not set"
+#~ msgstr "merkko ei ole asetettu"
+
+#~ msgid "cannot set line(s)"
+#~ msgstr "ei voi asettaa rivejä"
-#~ msgid "Vim: Double signal, exiting\n"
-#~ msgstr "Vim: Kaksoissignaali, lopetetaan\n"
+#~ msgid "not implemented yet"
+#~ msgstr "ei toteutettu"
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "Vim: Tappava signaali %s\n"
+#~ msgid "E273: unknown longjmp status %d"
+#~ msgstr "E273: tuntematon longjmp-tila %d"
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "Vim: Tappava signaali\n"
+#~ msgid "E272: unhandled exception"
+#~ msgstr "E272: käsittelemätön poikkeus"
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "X-näytön avaus vei %<PRId64> millisekuntia"
+#~ msgid "E271: retry outside of rescue clause"
+#~ msgstr "E271: retry rescuen ulkopuolella"
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim: X-virhe\n"
+#~ msgid "E269: unexpected break"
+#~ msgstr "E269: Odotuksenvastainen break"
-#~ msgid "Testing the X display failed"
-#~ msgstr "X-näytön testaus epäonnistui"
+#~ msgid "E268: unexpected next"
+#~ msgstr "E268: Odotuksenvastainen next"
-#~ msgid "Opening the X display timed out"
-#~ msgstr "X-näytön avaus aikakatkaistiin"
+#~ msgid "E267: unexpected return"
+#~ msgstr "E267: odotuksenvastainen return"
#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
+#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
+#~ "loaded."
+#~ msgstr "E266: komento ei toimi, Ruby-kirjastoa ei voitu ladata."
+
+#~ msgid "E265: $_ must be an instance of String"
+#~ msgstr "E265: muuttujan $_ pitää olla Stringin instanssi"
+
+#~ msgid "E837: This Vim cannot execute :py3 after using :python"
#~ msgstr ""
-#~ "\n"
-#~ "Kuoren sh suoritus ei onnistu\n"
+#~ "E837: Python: Ei voi käyttää komentoja :py ja :py3 samassa istunnossa"
+
+#~ msgid "E659: Cannot invoke Python recursively"
+#~ msgstr "E659: Pythonia ei voi kutsua rekursiivisesti"
#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
+#~ "E887: Sorry, this command is disabled, the Python's site module could not "
+#~ "be loaded."
#~ msgstr ""
-#~ "\n"
-#~ "Putkia ei voi tehdä\n"
+#~ "E887: Komento ei toimi, Pythonin site-moduulien lataaminen ei onnistunut."
#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
+#~ "E263: Sorry, this command is disabled, the Python library could not be "
+#~ "loaded."
+#~ msgstr "E263: komento ei toimi, Python-kirjaston lataaminen ei onnistunut."
+
+#~ msgid "E836: This Vim cannot execute :python after using :py3"
#~ msgstr ""
-#~ "\n"
-#~ "Ei voi haarauttaa\n"
+#~ "E836: Python: Ei voi käyttää komentoja :py ja :py3 samassa istunnossa"
+
+#~ msgid "not allowed in the Vim sandbox"
+#~ msgstr "ei sallittu Vimin hiekkalaatikossa"
+
+#~ msgid "linenr out of range"
+#~ msgstr "rivinumero arvoalueen ulkopuolelta"
+
+#~ msgid "window is invalid"
+#~ msgstr "ikkuna on virheellinen"
+
+#~ msgid "buffer is invalid"
+#~ msgstr "puskuri on virheellinen"
+
+#~ msgid "Vim error"
+#~ msgstr "Vim-virhe"
+
+#~ msgid "Vim error: ~a"
+#~ msgstr "Vim-virhe: ~a"
+
+#~ msgid "couldn't open buffer"
+#~ msgstr "ei voitu avata puskuria"
+
+#~ msgid "unknown option"
+#~ msgstr "tuntematon asetus"
+
+#~ msgid "hidden option"
+#~ msgstr "piilotettu asetus"
+
+#~ msgid "expressions disabled at compile time"
+#~ msgstr "ilmaukset poistettu käytöstä käännösaikana"
+
+#~ msgid "invalid expression"
+#~ msgstr "virheellinen ilmaus"
#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
+#~ "E895: Sorry, this command is disabled, the MzScheme's racket/base module "
+#~ "could not be loaded."
#~ msgstr ""
-#~ "\n"
-#~ "Komento loppui\n"
+#~ "E895: Komento ei toimi, MzScheme-moduulia racket/base ei voitu ladata."
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP kadotti ICE-yhteyden"
+#~ msgid ""
+#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
+#~ "be loaded."
+#~ msgstr "E815: komento ei toimi, MzScheme-kirjastoa ei voitu ladata."
-#~ msgid "Opening the X display failed"
-#~ msgstr "X-näytön avaus epäonnistui"
+#~ msgid "Lua library cannot be loaded."
+#~ msgstr "Luan kirjastoa ei voitu ladata."
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP käsittelee save-yourself-pyyntöä"
+#~ msgid "E626: cannot get cscope database information"
+#~ msgstr "E626: ei voi hakea cscope-tietokannan tietoja"
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP avaa yhteyttä"
+#~ msgid "E625: cannot open cscope database: %s"
+#~ msgstr "E625: ei voi avata cscope-tietokantaa: %s"
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP:n ICE-yhteyden tarkkailu epäonnistui"
+#~ msgid "E563: stat error"
+#~ msgstr "E563: stat-virhe"
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP SmcOpenConnection epäonnistui: %s"
+#~ msgid "E256: Hangul automata ERROR"
+#~ msgstr "E256: Hangu-automaattivirhe"
-#~ msgid "At line"
-#~ msgstr "Rivillä"
+#~ msgid "Size:"
+#~ msgstr "Koko:"
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "Vim32.dll:ää ei voitu ladata"
+#~ msgid "Style:"
+#~ msgstr "Tyyli:"
-#~ msgid "VIM Error"
-#~ msgstr "VIM-virhe"
+#~ msgid "Font:"
+#~ msgstr "Fontti:"
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "Ei voitu korjata funktio-osoittimia DLL:ssä"
+#~ msgid "Encoding:"
+#~ msgstr "Koodaus:"
-#~ msgid "shell returned %d"
-#~ msgstr "kuori palautti arvon %d"
+#~ msgid "Show size in Points"
+#~ msgstr "Näytä koko pisteinä"
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: Napattiin %s\n"
+#~ msgid "Name:"
+#~ msgstr "Nimi:"
-#~ msgid "close"
-#~ msgstr "sulkeminen"
+#~ msgid "Vim - Font Selector"
+#~ msgstr "Vim - fonttivalitsin"
-#~ msgid "logoff"
-#~ msgstr "uloskirjautuminen"
+#~ msgid "no specific match"
+#~ msgstr "ei tarkkaa täsmäystä"
-#~ msgid "shutdown"
-#~ msgstr "sammutus"
+#~ msgid "&Dismiss"
+#~ msgstr "&Ohita"
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: Komentoa ei löydy"
+#~ msgid "Invalid font specification"
+#~ msgstr "Virheellinen fonttimääritys"
+
+#~ msgid "Font1 width: %ld"
+#~ msgstr "Fontti1:n leveys: %ld"
+
+#~ msgid "Font0 width: %ld"
+#~ msgstr "Fontti0:n leveys: %ld"
+
+#~ msgid "Font%ld width is not twice that of font0"
+#~ msgstr "Fontti%ld:n leveys ei ole kaksi kertaa fontti0:n"
+
+#~ msgid "Font1: %s"
+#~ msgstr "Fontti1: %s"
+
+#~ msgid "Font0: %s"
+#~ msgstr "Fontti0: %s"
+
+#~ msgid "E253: Fontset name: %s"
+#~ msgstr "E253: Fontsetin nimi: %s"
+
+#~ msgid "Font '%s' is not fixed-width"
+#~ msgstr "Fontti %s ei ole tasavälinen"
+
+#~ msgid "E252: Fontset name: %s"
+#~ msgstr "E252: Fontsetin nimi: %s"
+
+#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+#~ msgstr "E250: Seuraavien merkistöjoukkojen fontit puuttuvat fontsetistä %s:"
#~ msgid ""
-#~ "VIMRUN.EXE not found in your $PATH.\n"
-#~ "External commands will not pause after completion.\n"
-#~ "See :help win32-vimrun for more information."
+#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
#~ msgstr ""
-#~ "VIMRUN.EXEä ei löydy muuttujasta $PATH.\n"
-#~ "Ulkoiset komennot eivät pysähdy suorituksen lopussa.\n"
-#~ "Lisätietoja komennolla :help win32-vimrun"
+#~ "Vim E458: Ei voi varata värikartan alkiota, värit voivat mennä väärin"
-#~ msgid "Vim Warning"
-#~ msgstr "Vim-varoitus"
+# MDI eli windowsin moni-ikkunasovellus
+#~ msgid "E672: Unable to open window inside MDI application"
+#~ msgstr "E672: Ikkunaa ei voitu avata MDI-sovellukseen"
-#~ msgid "Error file"
-#~ msgstr "Virhetiedosto"
+# OLE on object linking and embedding på windowska
+#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+#~ msgstr "E243: Argumenttia ei tueta: -%s, käytä OLE-versiota"
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "Muutosta kohteessa %s ei tueta"
+#~ msgid "Directory\t*.nothing\n"
+#~ msgstr "Hakemisto\t*.nothing\n"
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: Tägitiedoston polku katkaistu kohdassa %s\n"
+#~ msgid "Not Used"
+#~ msgstr "Ei käytössä"
-#~ msgid "new shell started\n"
-#~ msgstr "uusi kuori avattu\n"
+#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
+#~ msgstr "Etsi ja korvaa (\\\\:llä löytää \\:t)"
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "Käytettiin CUT_BUFFER0:aa tyhjän valinnan sijaan"
+#~ msgid "Find string (use '\\\\' to find a '\\')"
+#~ msgstr "Etsi merkkijonoa (\\\\:llä löytää \\:t)"
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "Ei voi kumota, jatketaan silti"
+#~ msgid "Open tab..."
+#~ msgstr "Avaa välilehti..."
-#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
-#~ msgstr "E832: Salaamattomalla tiedostolla on salattu kumoustiedosto: %s"
+#~ msgid "&Undo"
+#~ msgstr "&Kumoa"
-#~ msgid "E826: Undo file decryption failed: %s"
-#~ msgstr "E826: Kumoustiedoston purku epäonnistui: %s"
+#~ msgid "Replace &All"
+#~ msgstr "Korvaa k&aikki"
-#~ msgid "E827: Undo file is encrypted: %s"
-#~ msgstr "E827: Kumoustiedosto on salattu: %s"
+#~ msgid "&Replace"
+#~ msgstr "Ko&rvaa"
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16- t. 32-bittinen GUI-versio"
+#~ msgid "Find &Next"
+#~ msgstr "Hae &seuraava"
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 64-bittinen GUI-versio"
+#~ msgid "Selection"
+#~ msgstr "Valinta"
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32-bittinen GUI-version"
+#~ msgid "&OK"
+#~ msgstr "&Ok"
-#~ msgid " in Win32s mode"
-#~ msgstr " Win32s-tilassa"
+#~ msgid "Files"
+#~ msgstr "Tiedostot"
-#~ msgid " with OLE support"
-#~ msgstr " OLE-tuella"
+#~ msgid "&Help"
+#~ msgstr "O&hje"
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32-bittinen konsoliversio"
+#~ msgid "Filter"
+#~ msgstr "Suodatus"
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32-bittinen konsoliversio"
+#~ msgid "Directories"
+#~ msgstr "Hakemistot"
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16-bittinen versio"
+#~ msgid "&Cancel"
+#~ msgstr "&Peru"
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "32-bittinen MS-DOS-versio"
+#~ msgid "&Filter"
+#~ msgstr "&Suodata"
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "16-bittinen MS-DOS-versio"
+#~ msgid "Vim: Main window unexpectedly destroyed\n"
+#~ msgstr "Vim: Pääikkuna tuhoutui odottamatta\n"
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X-version (unix)"
+#~ msgid "Open Tab..."
+#~ msgstr "Avaa välilehti..."
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X-version"
+#~ msgid "New tab"
+#~ msgstr "Uusi välilehti"
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS-version"
+#~ msgid "Close tab"
+#~ msgstr "Sulje välilehti"
-#~ msgid ""
-#~ "\n"
-#~ "RISC OS version"
-#~ msgstr ""
-#~ "\n"
-#~ "RISC OS-version"
+#~ msgid "Vim: Received \"die\" request from session manager\n"
+#~ msgstr "Vim: sessiomanageri lähetti die-pyynnön\n"
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "OpenVMS-version"
+#~ msgid "_Close"
+#~ msgstr "_Sulje"
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Big-version "
+#~ msgid "Replace All"
+#~ msgstr "Korvaa kaikki"
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Normal-versio "
+#~ msgid "Replace"
+#~ msgstr "Korvaa"
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Small-versio "
+#~ msgid "Find Next"
+#~ msgstr "Etsi seuraava"
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Tiny-versio "
+#~ msgid "Down"
+#~ msgstr "Alas"
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "GTK2-Gnome-GUIlla."
+#~ msgid "Up"
+#~ msgstr "Ylös"
-#~ msgid "with GTK2 GUI."
-#~ msgstr "GTK2-GUIlla."
+#~ msgid "Direction"
+#~ msgstr "Suunta"
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "X11-Motif-GUIlla."
+#~ msgid "Match case"
+#~ msgstr "Kirjaintaso"
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "X11-neXtaw-GUIlla."
+#~ msgid "Match whole word only"
+#~ msgstr "Korvaa kokonaisia sanoja"
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "X11-Athena-GUIlla."
+#~ msgid "Replace with:"
+#~ msgstr "Korvaa:"
-#~ msgid "with Photon GUI."
-#~ msgstr "Photon-GUIlla."
+#~ msgid "Find what:"
+#~ msgstr "Etsi:"
-#~ msgid "with GUI."
-#~ msgstr "GUIlla."
+#~ msgid "VIM - Search..."
+#~ msgstr "VIM - Etsi..."
-#~ msgid "with Carbon GUI."
-#~ msgstr "Carbon-GUIlla."
+#~ msgid "VIM - Search and Replace..."
+#~ msgstr "VIM - Etsi ja korvaa..."
-#~ msgid "with Cocoa GUI."
-#~ msgstr "Cocoa-GUIlla."
+#~ msgid "Input _Methods"
+#~ msgstr "Syöte_menetelmät"
-#~ msgid "with (classic) GUI."
-#~ msgstr "perinteisellä GUIlla."
+#~ msgid "No"
+#~ msgstr "Ei"
-#~ msgid " system gvimrc file: \""
-#~ msgstr " järjestelmän gvimrc: \""
+#~ msgid "Yes"
+#~ msgstr "Kyllä"
-#~ msgid " user gvimrc file: \""
-#~ msgstr " käyttäjän gvimrc: \""
+#~ msgid "_OK"
+#~ msgstr "_OK"
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr "2. käyttäjän gvimrc: \""
+#~ msgid "_Open"
+#~ msgstr "_Avaa"
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr "3. käyttäjän gvimrc: \""
+#~ msgid "_Save"
+#~ msgstr "_Tallenna"
-#~ msgid " system menu file: \""
-#~ msgstr " järjestelmävalikko: \""
+#~ msgid "_Cancel"
+#~ msgstr "_Peru"
-#~ msgid "Compiler: "
-#~ msgstr "Käännin: "
+#~ msgid "E232: Cannot create BalloonEval with both message and callback"
+#~ msgstr "E232: Ei voi luoda BalloonEvalia viestille ja callbackille"
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "valikko Ohje->Orvot lisätietoja varten "
+#~ msgid "Vim dialog"
+#~ msgstr "Vim-ikkuna"
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "Suoritetaan tilattomana, kirjoitettu teksti syötetään"
+#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+#~ msgstr "Vierityspalkki: Pixmapin geometria ei selviä"
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "valikko Muokkaa->Yleiset asetukset->Vaihda syötetilaa"
+#~ msgid "Cancel"
+#~ msgstr "Peru"
-#~ msgid " for two modes "
-#~ msgstr " kahta tilaa varten "
+#~ msgid "OK"
+#~ msgstr "OK"
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "valikko Muokkaa->Yleiset asetukset->Vaihda Vi-yhteensopivuutta"
+#~ msgid "E615: vim_SelFile: can't get current directory"
+#~ msgstr "E615: vim_SelFile: nykyistä hakemistoa ei saada selville"
-#~ msgid " for Vim defaults "
-#~ msgstr " Vim-oletuksia varten"
+#~ msgid "Pathname:"
+#~ msgstr "Polku:"
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "VAROITUS: Window 95/98/ME havaittu"
+#~ msgid "E614: vim_SelFile: can't return to current directory"
+#~ msgstr "E614: vim_SelFile: nykyiseen hakemistoon ei voi palata"
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr "kirjoita :help windows95<Enter> lisätietoja varten"
+#~ msgid "E616: vim_SelFile: can't get font %s"
+#~ msgstr "E616: vim_SelFile: ei saada fonttia %s"
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: Kirjaston %s lataaminen ei onnistu"
+#~ msgid "<cannot open> "
+#~ msgstr "<ei voi avata> "
+
+#~ msgid "No match at cursor, finding next"
+#~ msgstr "Ei täsmäystä kursorin alla, etsitään seuraava"
+
+#~ msgid "E599: Value of 'imactivatekey' is invalid"
+#~ msgstr "E599: imactivatekeyn arvo on virheellinen"
+
+#~ msgid "E231: 'guifontwide' invalid"
+#~ msgstr "E231: guifontwide virheellinen"
+
+#~ msgid "E665: Cannot start GUI, no valid font found"
+#~ msgstr "E665: Ei voi avata GUIta, sopivaa fonttia ei löydy"
+
+#~ msgid "E230: Cannot read from \"%s\""
+#~ msgstr "E230: Ei voi lukea kohteesta %s"
+
+#~ msgid "E229: Cannot start the GUI"
+#~ msgstr "E229: GUIn käynnistys ei onnistu"
+
+#~ msgid "E851: Failed to create a new process for the GUI"
+#~ msgstr "E851: Ei voitu luoda uutta prosessia käyttöliittymälle"
+
+# tietääkseni resurssiforkki on applen tiedostojärjestelmän tunnistejuttujuttu
+#~ msgid "E460: The resource fork would be lost (add ! to override)"
+#~ msgstr "E460: resurssiosa häviäisi (lisää komentoon ! ohittaaksesi)"
+
+#~ msgid "writing to device disabled with 'opendevice' option"
+#~ msgstr "laitteeseen kirjoittaminen pois käytöstä opendevice-asetuksella"
+
+#~ msgid "Partial writes disallowed for NetBeans buffers"
+#~ msgstr "Osittaiset kirjoitukset kielletty NetBeans-puskureissa"
+
+#~ msgid "NetBeans disallows writes of unmodified buffers"
+#~ msgstr "NetBeans ei salli kirjoittaa muokkaamattomiin puskureihin"
+
+#~ msgid "Reading from stdin..."
+#~ msgstr "Luetaan vakiosyötteestä"
+
+#~ msgid "Vim: Reading from stdin...\n"
+#~ msgstr "Vim: Luetaan vakiosyötteestä...\n"
+
+#~ msgid "is a device (disabled with 'opendevice' option)"
+#~ msgstr "on laite (ei käytössä opendevice-asetuksen takia)"
+
+#~ msgid "Debug Line"
+#~ msgstr "Vianetsintärivi"
+
+#~ msgid "Input Line"
+#~ msgstr "Syöterivi"
+
+#~ msgid "Expression"
+#~ msgstr "Ilmaus"
+
+#~ msgid "Search String"
+#~ msgstr "Hakujono"
+
+#~ msgid "Command Line"
+#~ msgstr "Komentorivi"
#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr "Sori, komento ei toimi, Perl kirjastoa ei voinut ladata."
+#~ "\n"
+#~ "# %s History (newest to oldest):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# %s Historia (uusimmasta alkaen):\n"
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr "E299: Perl-suoritus kielletty hiekkalaatikossa ilman Safe-moduulia"
+#~ msgid "E196: No digraphs in this version"
+#~ msgstr "E196: Digraafeja ei ole tässä versiossa"
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "&Muokkaa usealla Vimillä"
+#~ msgid "E195: Cannot open viminfo file for reading"
+#~ msgstr "E195: Viminfoa ei voi avata lukemista varten"
-#~ msgid "Edit with single &Vim"
-#~ msgstr "Muokkaa yhdellä &Vimillä"
+#~ msgid "E809: #< is not available without the +eval feature"
+#~ msgstr "E809: #< ei ole käytössä jollei +eval ole päällä"
-#~ msgid "Diff with Vim"
-#~ msgstr "Diffi Vimillä"
+#~ msgid "Save Setup"
+#~ msgstr "Tallenna asetukset"
-#~ msgid "Edit with &Vim"
-#~ msgstr "Muokkaa &Vimillä"
+#~ msgid "Save Session"
+#~ msgstr "Tallenna sessio"
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "Muokkaa olemassaolevalla Vimillä - "
+#~ msgid "Save View"
+#~ msgstr "Tallenna näkymä"
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "Muokkaa valittuja tiedostoja Vimillä"
+#~ msgid "Save Redirection"
+#~ msgstr "Tallenna uudelleenosoitus"
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "Virhe prosessin käynnistämisessä, varmista että gvim on polulla"
+#~ msgid "E930: Cannot use :redir inside execute()"
+#~ msgstr "E930: Komentoa :redir ei voi käyttää funktion execute() sisällä"
-#~ msgid "gvimext.dll error"
-#~ msgstr "gvimext.dll-virhe"
+#~ msgid "E466: :winpos requires two number arguments"
+#~ msgstr "E466: :winpos vaatii kaksi lukuargumenttia"
-#~ msgid "Path length too long!"
-#~ msgstr "Liian pitkä polku"
+#~ msgid "E188: Obtaining window position not implemented for this platform"
+#~ msgstr "E188: Ikkunan sijainnin selvitys ei toimi tällä alustalla"
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: Tuntematon fontset: %s"
+#~ msgid "Window position: X %d, Y %d"
+#~ msgstr "Ikkunan sijainti: X %d, Y %d"
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: Tuntematon fontti: %s"
+#~ msgid ""
+#~ "E747: Cannot change directory, buffer is modified (add ! to override)"
+#~ msgstr ""
+#~ "E747: Hakemistoa ei voida muuttaa, puskuria on muokattu (lisää "
+#~ "komentoon ! ohittaaksesi"
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: Fontti %s ei ole tasavälinen"
+#~ msgid "Append File"
+#~ msgstr "Lisää tiedostoon"
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: Ei voitu ladta kirjastofunktiota %s"
+#~ msgid "Edit File in new window"
+#~ msgstr "Muokkaa uudessa ikkunassa"
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr "E26: Hepreaa ei voi käyttää, koska sitä ei käännetty mukaan\n"
+#~ msgid "unknown"
+#~ msgstr "tuntematon"
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: Farsia ei voi käyttää, koska sitä ei käännetty mukaan\n"
+#~ msgid "E172: Only one file name allowed"
+#~ msgstr "E172: Vain yksi tiedostonimi sallitaan"
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr "E800: Arabiaa ei voi käyttää, koska sitä ei käännetty mukaan\n"
+#~ msgid "Source Vim script"
+#~ msgstr "Lataa vim-skripti"
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: palvelinta %s ei ole rekisteröitynä"
+#~ msgid " (NOT FOUND)"
+#~ msgstr " (EI LÖYTYNYT)"
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: näyttöä ei voi avata"
+#~ msgid ""
+#~ "\n"
+#~ "# Last Substitute String:\n"
+#~ "$"
+#~ msgstr ""
+#~ "\n"
+#~ "# Viimeisin korvausmerkkijono:\n"
+#~ "$"
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: Virheellinen ilmaus saatu"
+#~ msgid "Edit File"
+#~ msgstr "Muokkaa tiedostoa"
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: Alue on suojattu, muuttaminen ei onnistu"
+#~ msgid "Save As"
+#~ msgstr "Tallenna nimellä"
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans ei tue muutoksia kirjoitussuojattuihin tiedostoihin"
+#~ msgid ""
+#~ "\n"
+#~ "# Bar lines, copied verbatim:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# Bar-rivit, kopiotu sellaisenaan:\n"
-#~ msgid "Need encryption key for \"%s\""
-#~ msgstr "Tarvitaan salausavain kohteelle %s "
+#~ msgid "Illegal starting char"
+#~ msgstr "Virheellinen aloitusmerkki"
-#~ msgid "writelines() requires list of strings"
-#~ msgstr "writelines()-komennolle pitää antaa merkkijonolista"
+#~ msgid "# Value of 'encoding' when this file was written\n"
+#~ msgstr "# encoding-muuttujan arvo tiedostoa kirjoitettaessa\n"
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: Virhe IO-olioiden alustuksessa"
+#~ msgid ""
+#~ "# You may edit it if you're careful!\n"
+#~ "\n"
+#~ msgstr ""
+#~ "# Muokkaa varovasti!\n"
+#~ "\n"
-#~ msgid "no such buffer"
-#~ msgstr "puskuria ei ole"
+#~ msgid "# This viminfo file was generated by Vim %s.\n"
+#~ msgstr "# Vimin %s generoima viminfo-tiedosto.\n"
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "yritettiin viitata poistettuun ikkunaan"
+#~ msgid "E138: Can't write viminfo file %s!"
+#~ msgstr "E138: Viminfo-tiedoston kirjoittaminen ei onnistu %s"
-#~ msgid "readonly attribute"
-#~ msgstr "kirjoitussuojattu attribuutti"
+#~ msgid "E929: Too many viminfo temp files, like %s!"
+#~ msgstr "E929: liikaa viminfo-väliaikaistiedostoja, kuten %s."
-#~ msgid "cursor position outside buffer"
-#~ msgstr "kursorin sijainti puskurin ulkopuolella"
+#~ msgid "E136: viminfo: Too many errors, skipping rest of file"
+#~ msgstr "E136: viminfo: liikaa virheitä, ohitetaan lopputiedosto"
-#~ msgid "<window object (deleted) at %p>"
-#~ msgstr "<ikkunaolio (poistettu) kohdassa %p>"
+#~ msgid "%sviminfo: %s in line: "
+#~ msgstr "%sviminfo: %s rivillä: "
-#~ msgid "<window object (unknown) at %p>"
-#~ msgstr "<ikkunaolio (tuntematon) kohdassa %p>"
+#~ msgid "E258: Unable to send to client"
+#~ msgstr "E258: Asiakkaalle lähetys ei onnistunut"
-#~ msgid "<window %d>"
-#~ msgstr "<ikkuna %d>"
+#~ msgid "E277: Unable to read a server reply"
+#~ msgstr "E277: Palvelimen vastauksen lukeminen ei onnistunut"
-#~ msgid "no such window"
-#~ msgstr "ikkunaa ei ole"
+#~ msgid "E240: No connection to Vim server"
+#~ msgstr "E240: Ei yhteyttä vim-palvelimeen"
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "yritettiin viitata poistettuun puskuriin"
+#~ msgid ""
+#~ "&OK\n"
+#~ "&Cancel"
+#~ msgstr ""
+#~ "&OK\n"
+#~ "&Peru"
+
+#~ msgid ""
+#~ "\n"
+#~ "# global variables:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# globaalit muuttujat:\n"
+
+#~ msgid "E729: using Funcref as a String"
+#~ msgstr "E729: Funcref ei käy merkkijonosta"
+
+#~ msgid "E914: Using a Channel as a Float"
+#~ msgstr "E914: Käytettiin Channelia Floattina"
+
+#~ msgid "E911: Using a Job as a Float"
+#~ msgstr "E911: Job ei käy Floatista"
+
+#~ msgid "E913: Using a Channel as a Number"
+#~ msgstr "E913: Channel ei käy Numberista"
+
+#~ msgid "E910: Using a Job as a Number"
+#~ msgstr "E910: Job ei käy Numberista"
+
+#~ msgid "E703: Using a Funcref as a Number"
+#~ msgstr "E703: Funcref ei käy Numberista"
+
+#~ msgid "E724: variable nested too deep for displaying"
+#~ msgstr "E724: muuttuja on upotettu liian syvälle näytettäväksi"
+
+#~ msgid "Patch file"
+#~ msgstr "Patch-tiedosto"
+
+#~ msgid "[crypted]"
+#~ msgstr "[salattu]"
+
+#~ msgid "Keys don't match!"
+#~ msgstr "Avaimet eivät täsmää!"
-# New Line eli uusi rivinvaihtomerkki (ei CR, LF tai CR LF)
-#~ msgid "[NL found]"
-#~ msgstr "[NL puuttuu]"
+#~ msgid "Enter same key again: "
+#~ msgstr "Anna sama avain uudestaan: "
-#~ msgid "Vim dialog..."
-#~ msgstr "Vim-ikkuna..."
+#~ msgid "Enter encryption key: "
+#~ msgstr "Anna salausavain: "
-#~ msgid "Font Selection"
-#~ msgstr "Fontin valinta"
+#~ msgid "Warning: Using a weak encryption method; see :help 'cm'"
+#~ msgstr "Varoitus: Käytetään heikkoa salausmenetelmää, ks. :help 'cm'"
-#~ msgid "E569: maximum number of cscope connections reached"
-#~ msgstr "E569: enimmäismäärä cscope-yhteyksiä otettu"
+#~ msgid "E821: File is encrypted with unknown method"
+#~ msgstr "E821: Tiedoston salaus on tuntematon"
+
+#~ msgid "E918: buffer must be loaded: %s"
+#~ msgstr "E918: puskuria ei voi ladata: %s"
+
+#~ msgid "E915: in_io buffer requires in_buf or in_name to be set"
+#~ msgstr "E915: in_io-puskurilla pitää olla in_buf tai in_name asetettu"
-#~ msgid "-name <name>\t\tUse resource as if vim was <name>"
-#~ msgstr "-name <nimi>\t\tKäytä resurssia vim <nimenä>"
+#~ msgid "E920: _io file requires _name to be set"
+#~ msgstr "E920: _io-tiedostolla pitää olla _name asetettu"
-#~ msgid "\t\t\t (Unimplemented)\n"
-#~ msgstr "\t\t\t (toteuttamatta)\n"
+#~ msgid "E906: not an open channel"
+#~ msgstr "E906: ei ole avoin kanava"
+
+#~ msgid ""
+#~ "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel"
+#~ msgstr ""
+#~ "E912: ei voida käyttää funktioita ch_evalexpr(), ch_sendexpr() raa'an tai "
+#~ "nl-kanavan kanssa"
-#~ msgid "E290: over-the-spot style requires fontset"
-#~ msgstr "E290: over-the-spot-tyylissä pitää olla fontset"
+#~ msgid "E917: Cannot use a callback with %s()"
+#~ msgstr "E917: Ei voitu käyttää callbackia %s()"
-#~ msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
-#~ msgstr "E291: GTK+-versio vanhempi kuin 1.2.3: Tila-alue poistettu käytöstä"
+#~ msgid ""
+#~ "\n"
+#~ "# Buffer list:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# Puskuriluettelo:\n"
-#~ msgid "E292: Input Method Server is not running"
-#~ msgstr "E292: Syötemetodipalvelin ei ole käynnissä"
+#~ msgid "E931: Buffer cannot be registered"
+#~ msgstr "E931: Puskuria ei voi rekisteröidä"
-#~ msgid "E396: containedin argument not accepted here"
-#~ msgstr "E396: containedin ei sovi tähän"
+#~ msgid "E819: Blowfish test failed"
+#~ msgstr "E819: Blowfish-testi epäonnistui"
-#~ msgid "with GTK-GNOME GUI."
-#~ msgstr "GTK-Gnome-GUIlla."
+#~ msgid "E818: sha256 test failed"
+#~ msgstr "E818: sha256-testi epäonnistui failed"
-#~ msgid "with GTK GUI."
-#~ msgstr "GTK-GUIlla."
+#~ msgid "E817: Blowfish big/little endian use wrong"
+#~ msgstr "E817: Blowfishin tavujärjestys väärä"
-#~ msgid "-V[N]\t\tVerbose level"
-#~ msgstr "-V[N]\t\tMonisanaisuustaso"
+#~ msgid "E820: sizeof(uint32_t) != 4"
+#~ msgstr "E820: sizeof(uint32_t) != 4"
-#~ msgid "...(truncated)"
-#~ msgstr "...(katkaistu)"
+#~ msgid "E831: bf_key_init() called with empty password"
+#~ msgstr "E831: bf_key_init() tyhjällä salasanalla"
diff --git a/src/nvim/po/fr.po b/src/nvim/po/fr.po
index bf0610de02..c0df5f2170 100644
--- a/src/nvim/po/fr.po
+++ b/src/nvim/po/fr.po
@@ -1,3 +1,4 @@
+
# French Translation for Vim
#
# Do ":help uganda" in Vim to read copying and usage conditions.
@@ -6,7 +7,7 @@
# FIRST AUTHOR DindinX <David.Odin@bigfoot.com> 2000.
# SECOND AUTHOR Adrien Beau <version.francaise@free.fr> 2002, 2003.
# THIRD AUTHOR David Blanchet <david.blanchet@free.fr> 2006, 2008.
-# FOURTH AUTHOR Dominique Pellé <dominique.pelle@gmail.com> 2008, 2015.
+# FOURTH AUTHOR Dominique Pellé <dominique.pelle@gmail.com> 2008, 2017.
#
# Latest translation available at:
# http://dominique.pelle.free.fr/vim-fr.php
@@ -15,8 +16,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Vim(Français)\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-30 17:54+0200\n"
-"PO-Revision-Date: 2015-07-30 18:00+0200\n"
+"POT-Creation-Date: 2017-01-16 00:30+0100\n"
+"PO-Revision-Date: 2017-01-16 00:51+0100\n"
"Last-Translator: Dominique Pellé <dominique.pelle@gmail.com>\n"
"Language-Team: \n"
"Language: fr\n"
@@ -24,201 +25,172 @@ msgstr ""
"Content-Type: text/plain; charset=ISO_8859-15\n"
"Content-Transfer-Encoding: 8bit\n"
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "impossible d'obtenir la valeur d'une option"
+msgid "E831: bf_key_init() called with empty password"
+msgstr "E831: bf_key_init() appelée avec un mot de passe vide"
-#: ../api/private/helpers.c:204
-#, fuzzy
-msgid "internal error: unknown option type"
-msgstr "erreur interne : pas d'élément de liste vim"
+msgid "E820: sizeof(uint32_t) != 4"
+msgstr "E820: sizeof(uint32_t) != 4"
+
+msgid "E817: Blowfish big/little endian use wrong"
+msgstr "E817: petit/gros boutisme incorrect dans blowfish"
+
+msgid "E818: sha256 test failed"
+msgstr "E818: le test de sha256 a échoué"
+
+msgid "E819: Blowfish test failed"
+msgstr "E819: le test de blowfish a échoué"
# DB - TODO : Trouver une traduction valable et attestée pour "location".
-#: ../buffer.c:92
msgid "[Location List]"
msgstr "[Liste des emplacements]"
-#: ../buffer.c:93
msgid "[Quickfix List]"
msgstr "[Liste Quickfix]"
-#: ../buffer.c:94
msgid "E855: Autocommands caused command to abort"
msgstr "E855: Des autocommandes ont causé la terminaison de la commande"
# AB - Il faut respecter l'esprit plus que la lettre.
-#: ../buffer.c:135
msgid "E82: Cannot allocate any buffer, exiting..."
msgstr "E82: Aucun tampon ne peut être alloué, Vim doit s'arrêter"
# AB - La situation est probablement plus grave que la version anglaise ne le
# laisse entendre (voir l'aide en ligne). La version française est plus
# explicite.
-#: ../buffer.c:138
msgid "E83: Cannot allocate buffer, using other one..."
msgstr ""
"E83: L'allocation du tampon a échoué : arrêtez Vim, libérez de la mémoire"
-#: ../buffer.c:763
+msgid "E931: Buffer cannot be registered"
+msgstr "E931: Le tampon ne peut pas être enregistré"
+
+msgid "E937: Attempt to delete a buffer that is in use"
+msgstr "E937: Tentative de suppression d'un tampon en cours d'utilisation"
+
msgid "E515: No buffers were unloaded"
msgstr "E515: Aucun tampon n'a été déchargé"
-#: ../buffer.c:765
msgid "E516: No buffers were deleted"
msgstr "E516: Aucun tampon n'a été effacé"
-#: ../buffer.c:767
msgid "E517: No buffers were wiped out"
msgstr "E517: Aucun tampon n'a été détruit"
-#: ../buffer.c:772
msgid "1 buffer unloaded"
msgstr "1 tampon a été déchargé"
-#: ../buffer.c:774
#, c-format
msgid "%d buffers unloaded"
msgstr "%d tampons ont été déchargés"
-#: ../buffer.c:777
msgid "1 buffer deleted"
msgstr "1 tampon a été effacé"
-#: ../buffer.c:779
#, c-format
msgid "%d buffers deleted"
msgstr "%d tampons ont été effacés"
-#: ../buffer.c:782
msgid "1 buffer wiped out"
msgstr "1 tampon a été détruit"
-#: ../buffer.c:784
#, c-format
msgid "%d buffers wiped out"
msgstr "%d tampons ont été détruits"
-#: ../buffer.c:806
msgid "E90: Cannot unload last buffer"
msgstr "E90: Impossible de décharger le dernier tampon"
# AB - La version française est meilleure que la version anglaise.
-#: ../buffer.c:874
msgid "E84: No modified buffer found"
msgstr "E84: Aucun tampon n'est modifié"
#. back where we started, didn't find anything.
-#: ../buffer.c:903
msgid "E85: There is no listed buffer"
msgstr "E85: Aucun tampon n'est listé"
# AB - Je ne suis pas sûr que l'on puisse obtenir ce message.
-#: ../buffer.c:915
msgid "E87: Cannot go beyond last buffer"
msgstr "E87: Impossible d'aller après le dernier tampon"
# AB - Je ne suis pas sûr que l'on puisse obtenir ce message.
-#: ../buffer.c:917
msgid "E88: Cannot go before first buffer"
msgstr "E88: Impossible d'aller avant le premier tampon"
-#: ../buffer.c:945
#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
msgstr ""
-"E89: Le tampon %<PRId64> n'a pas été enregistré (ajoutez ! pour passer outre)"
+"E89: Le tampon %ld n'a pas été enregistré (ajoutez ! pour passer outre)"
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
msgid "W14: Warning: List of file names overflow"
msgstr "W14: Alerte : La liste des noms de fichier déborde"
# AB - Vu le code source, la version française est meilleure que la
# version anglaise. Ce message est similaire au message E86.
-#: ../buffer.c:1555 ../quickfix.c:3361
#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: Le tampon %<PRId64> n'existe pas"
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Le tampon %ld n'existe pas"
# AB - Il faut respecter l'esprit plus que la lettre.
-#: ../buffer.c:1798
#, c-format
msgid "E93: More than one match for %s"
msgstr "E93: Plusieurs tampons correspondent à %s"
-#: ../buffer.c:1800
#, c-format
msgid "E94: No matching buffer for %s"
msgstr "E94: Aucun tampon ne correspond à %s"
-#: ../buffer.c:2161
#, c-format
-msgid "line %<PRId64>"
-msgstr "ligne %<PRId64>"
+msgid "line %ld"
+msgstr "ligne %ld"
-#: ../buffer.c:2233
msgid "E95: Buffer with this name already exists"
msgstr "E95: Un tampon porte déjà ce nom"
-#: ../buffer.c:2498
msgid " [Modified]"
msgstr "[Modifié]"
# AB - "[Inédité]" est plus correct, mais sonne faux.
-#: ../buffer.c:2501
msgid "[Not edited]"
msgstr "[Non édité]"
-#: ../buffer.c:2504
msgid "[New file]"
msgstr "[Nouveau fichier]"
-#: ../buffer.c:2505
msgid "[Read errors]"
msgstr "[Erreurs de lecture]"
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
msgid "[RO]"
msgstr "[RO]"
# AB - La version courte, "[RO]", devrait-elle être traduite par "[LS]" ?
# Il faudrait faire un sondage auprès des utilisateurs francophones.
-#: ../buffer.c:2507 ../fileio.c:1807
msgid "[readonly]"
msgstr "[lecture-seule]"
-#: ../buffer.c:2524
#, c-format
msgid "1 line --%d%%--"
msgstr "1 ligne --%d%%--"
-#: ../buffer.c:2526
#, c-format
-msgid "%<PRId64> lines --%d%%--"
-msgstr "%<PRId64> lignes --%d%%--"
+msgid "%ld lines --%d%%--"
+msgstr "%ld lignes --%d%%--"
# AB - Faut-il remplacer "sur" par "de" ?
# DB - Mon avis : oui.
-#: ../buffer.c:2530
#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "ligne %<PRId64> sur %<PRId64> --%d%%-- col "
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "ligne %ld sur %ld --%d%%-- col "
# DB - Je trouvais [Aucun fichier] (VO : [No file]) plus naturel
# lors du lancement de Vim en mode graphique (ce message
# apparaît notamment dans le titre de la fenêtre).
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
msgid "[No Name]"
msgstr "[Aucun nom]"
#. must be a help buffer
-#: ../buffer.c:2667
msgid "help"
msgstr "aide"
-#: ../buffer.c:3225 ../screen.c:4883
msgid "[Help]"
msgstr "[Aide]"
@@ -226,24 +198,19 @@ msgstr "[Aide]"
# traduction littérale et brève, mais qui risque fort d'être mal comprise.
# J'ai finalement choisi d'utiliser une abréviation, mais cela ne me
# satisfait pas.
-#: ../buffer.c:3254 ../screen.c:4887
msgid "[Preview]"
msgstr "[Prévisu]"
-#: ../buffer.c:3528
msgid "All"
msgstr "Tout"
-#: ../buffer.c:3528
msgid "Bot"
msgstr "Bas"
# AB - Attention, on passe de trois à quatre lettres.
-#: ../buffer.c:3531
msgid "Top"
msgstr "Haut"
-#: ../buffer.c:4244
msgid ""
"\n"
"# Buffer list:\n"
@@ -251,11 +218,9 @@ msgstr ""
"\n"
"# Liste des tampons :\n"
-#: ../buffer.c:4289
msgid "[Scratch]"
msgstr "[Brouillon]"
-#: ../buffer.c:4529
msgid ""
"\n"
"--- Signs ---"
@@ -263,175 +228,220 @@ msgstr ""
"\n"
"--- Symboles ---"
-#: ../buffer.c:4538
#, c-format
msgid "Signs for %s:"
msgstr "Symboles dans %s :"
-#: ../buffer.c:4543
#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " ligne=%<PRId64> id=%d nom=%s"
+msgid " line=%ld id=%d name=%s"
+msgstr " ligne=%ld id=%d nom=%s"
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: ':' manquant"
+msgid "E902: Cannot connect to port"
+msgstr "E902: Impossible de se connecter au port"
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: Mode non autorisé"
+msgid "E901: gethostbyname() in channel_open()"
+msgstr "E901: gethostbyname() dans channel_open()"
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: chiffre attendu"
+msgid "E898: socket() in channel_open()"
+msgstr "E898: socket() dans channel_open()"
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: Pourcentage non autorisé"
+msgid "E903: received command with non-string argument"
+msgstr "E903: commande reçue avec un argument qui n'est pas une chaîne"
+
+msgid "E904: last argument for expr/call must be a number"
+msgstr "E904: le dernier argument de expr/call doit être un nombre"
+
+msgid "E904: third argument for call must be a list"
+msgstr "E904: le troisième argument de \"call\" doit être une liste"
+
+#, c-format
+msgid "E905: received unknown command: %s"
+msgstr "E905: commande inconnue reçue : %s"
+
+#, c-format
+msgid "E630: %s(): write while not connected"
+msgstr "E630: %s() : écriture sans être connecté"
+
+#, c-format
+msgid "E631: %s(): write failed"
+msgstr "E631: %s() : erreur d'écriture"
+
+#, c-format
+msgid "E917: Cannot use a callback with %s()"
+msgstr "E917: Impossible d'utiliser un callback avec %s()"
+
+msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel"
+msgstr ""
+"E912: Impossible d'utiliser ch_evalexpr()/ch_sendexpr() avec un canal brut "
+"ou nl"
+
+msgid "E906: not an open channel"
+msgstr "E906: pas un canal ouvert"
+
+msgid "E920: _io file requires _name to be set"
+msgstr "E920: fichier _io nécessite _name"
+
+msgid "E915: in_io buffer requires in_buf or in_name to be set"
+msgstr "E915: tampon in_io nécessite in_buf ou in_name "
+
+#, c-format
+msgid "E918: buffer must be loaded: %s"
+msgstr "E918: le tampon doit être chargé : %s"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: Le fichier est chiffré avec une méthode inconnue"
+
+msgid "Warning: Using a weak encryption method; see :help 'cm'"
+msgstr ""
+"Alerte : utilisation d'une méthode de chiffrage faible ; consultez :help 'cm'"
+
+msgid "Enter encryption key: "
+msgstr "Tapez la clé de chiffrement : "
+
+msgid "Enter same key again: "
+msgstr "Tapez la clé à nouveau : "
+
+msgid "Keys don't match!"
+msgstr "Les clés ne correspondent pas !"
+
+msgid "[crypted]"
+msgstr "[chiffré]"
-# AB - Je n'ai pas trouvé de traduction satisfaisante au verbe "diff". Comme
-# Vim fait en pratique appel au programme "diff" pour evaluer les
-# différences entre fichiers, "to diff" a été traduit par "utiliser diff"
-# et d'autres expressions appropriées.
-#: ../diff.c:146
#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: Impossible d'utiliser diff sur plus de %<PRId64> tampons"
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Il manque ':' dans le Dictionnaire %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Clé dupliquée dans le Dictionnaire : %s"
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Il manque une virgule dans le Dictionnaire : %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Il manque '}' à la fin du Dictionnaire : %s"
+
+msgid "extend() argument"
+msgstr "argument de extend()"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: La clé existe déjà : %s"
+
+#, c-format
+msgid "E96: Cannot diff more than %ld buffers"
+msgstr "E96: Impossible d'utiliser diff sur plus de %ld tampons"
-#: ../diff.c:753
msgid "E810: Cannot read or write temp files"
msgstr "E810: Impossible de lire ou écrire des fichiers temporaires"
# AB - La version française est meilleure que la version anglaise.
-#: ../diff.c:755
msgid "E97: Cannot create diffs"
msgstr "E97: diff ne fonctionne pas"
-#: ../diff.c:966
+msgid "Patch file"
+msgstr "Fichier rustine"
+
msgid "E816: Cannot read patch output"
msgstr "E816: Le fichier intermédiaire produit par patch n'a pu être lu"
-#: ../diff.c:1220
msgid "E98: Cannot read diff output"
msgstr "E98: Le fichier intermédiaire produit par diff n'a pu être lu"
-#: ../diff.c:2081
msgid "E99: Current buffer is not in diff mode"
msgstr "E99: Le tampon courant n'est pas en mode diff"
-#: ../diff.c:2100
msgid "E793: No other buffer in diff mode is modifiable"
msgstr "E793: Aucun autre tampon en mode diff n'est modifiable"
-#: ../diff.c:2102
msgid "E100: No other buffer in diff mode"
msgstr "E100: Aucun autre tampon n'est en mode diff"
# AB - La version française est meilleure que la version anglaise, mais elle
# peut être améliorée.
-#: ../diff.c:2112
msgid "E101: More than two buffers in diff mode, don't know which one to use"
msgstr "E101: Plus de deux tampons sont en mode diff, soyez plus précis"
-#: ../diff.c:2141
#, c-format
msgid "E102: Can't find buffer \"%s\""
msgstr "E102: Le tampon %s est introuvable"
-#: ../diff.c:2152
#, c-format
msgid "E103: Buffer \"%s\" is not in diff mode"
msgstr "E103: Le tampon %s n'est pas en mode diff"
-#: ../diff.c:2193
msgid "E787: Buffer changed unexpectedly"
msgstr "E787: Le tampon a été modifié inopinément"
# AB - Je cherche une traduction plus concise pour "escape".
-#: ../digraph.c:1598
msgid "E104: Escape not allowed in digraph"
msgstr "E104: Un digraphe ne peut contenir le caractère d'échappement"
# AB - La version française est trop verbeuse.
-#: ../digraph.c:1760
msgid "E544: Keymap file not found"
msgstr "E544: Le fichier descripteur de clavier est introuvable"
# AB - La version française est meilleure que la version anglaise.
-#: ../digraph.c:1785
msgid "E105: Using :loadkeymap not in a sourced file"
msgstr "E105: :loadkeymap ne peut être utilisé que dans un script Vim"
-#: ../digraph.c:1821
msgid "E791: Empty keymap entry"
msgstr "E791: Entrée du descripteur de clavier (keymap) vide"
# AB - Remplacer "complétion" par "complètement" ? Voir l'éthymologie
# d'"accrétion".
-#: ../edit.c:82
msgid " Keyword completion (^N^P)"
msgstr " Complètement de mot-clé (^N^P)"
# DB - todo : Faut-il une majuscule à "mode" ?
#. ctrl_x_mode == 0, ^P/^N compl.
-#: ../edit.c:83
msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
msgstr " mode ^X (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
-#: ../edit.c:85
msgid " Whole line completion (^L^N^P)"
msgstr " Complètement de ligne entière (^L^N^P)"
-#: ../edit.c:86
msgid " File name completion (^F^N^P)"
msgstr " Complètement de nom de fichier (^F^N^P)"
-#: ../edit.c:87
msgid " Tag completion (^]^N^P)"
msgstr " Complètement de marqueur (^]^N^P)"
# AB - J'ai dû avoir une bonne raison de faire une version française aussi
# différente de la version anglaise. Il me faut la retrouver.
# DB - TODO
-#: ../edit.c:88
msgid " Path pattern completion (^N^P)"
msgstr " Complètement global de mot-clé (^N^P)"
-#: ../edit.c:89
msgid " Definition completion (^D^N^P)"
msgstr " Complètement de définition (^D^N^P)"
# AB - Trouver une meilleure formulation que "selon le".
# DB : proposition : "avec"
-#: ../edit.c:91
msgid " Dictionary completion (^K^N^P)"
msgstr " Complètement avec le dictionnaire (^K^N^P)"
# AB - Trouver une meilleure formulation que "selon le".
-#: ../edit.c:92
msgid " Thesaurus completion (^T^N^P)"
msgstr " Complètement avec le thésaurus (^T^N^P)"
# AB - La version française est meilleure que la version anglaise.
# DB : Suggestion.
-#: ../edit.c:93
msgid " Command-line completion (^V^N^P)"
msgstr " Complètement de ligne de commande (^V^N^P)"
-#: ../edit.c:94
msgid " User defined completion (^U^N^P)"
msgstr " Complètement défini par l'utilisateur (^U^N^P)"
# DB : On doit pouvoir trouver nettement mieux que ça.
-#: ../edit.c:95
msgid " Omni completion (^O^N^P)"
msgstr " Complètement selon le type de fichier (Omni) (^O^N^P)"
-#: ../edit.c:96
msgid " Spelling suggestion (s^N^P)"
msgstr " Suggestion d'orthographe (s^N^P)"
-#: ../edit.c:97
msgid " Keyword Local completion (^N^P)"
msgstr " Complètement local de mot-clé (^N/^P)"
@@ -439,45 +449,35 @@ msgstr " Complètement local de mot-clé (^N/^P)"
# Il faut éviter de le faire trop long. Je pense que la version française
# est suffisamment compréhensible dans le contexte dans lequel elle est
# affichée.
-#: ../edit.c:100
msgid "Hit end of paragraph"
msgstr "Fin du paragraphe"
-#: ../edit.c:101
msgid "E839: Completion function changed window"
msgstr "E839: La fonction de complètement a changé la fenêtre"
-#: ../edit.c:102
msgid "E840: Completion function deleted text"
msgstr "E840: La fonction de complètement a effacé du texte"
-#: ../edit.c:1847
msgid "'dictionary' option is empty"
msgstr "L'option 'dictionary' est vide"
-#: ../edit.c:1848
msgid "'thesaurus' option is empty"
msgstr "L'option 'thesaurus' est vide"
-#: ../edit.c:2655
#, c-format
msgid "Scanning dictionary: %s"
msgstr "Examen du dictionnaire : %s"
-#: ../edit.c:3079
msgid " (insert) Scroll (^E/^Y)"
msgstr " (insertion) Défilement (^E/^Y)"
-#: ../edit.c:3081
msgid " (replace) Scroll (^E/^Y)"
msgstr " (remplacement) Défilement (^E/^Y)"
-#: ../edit.c:3587
#, c-format
msgid "Scanning: %s"
msgstr "Examen : %s"
-#: ../edit.c:3614
msgid "Scanning tags."
msgstr "Examen des marqueurs."
@@ -485,7 +485,6 @@ msgstr "Examen des marqueurs."
# opération de complétion est répétée (typiquement avec CTRL-X CTRL-N).
# Que ce soit en anglais ou en français, il y a un problème de majuscules.
# Bien qu'insatisfaisante, cette traduction semble optimale.
-#: ../edit.c:4519
msgid " Adding"
msgstr " Ajout"
@@ -493,236 +492,138 @@ msgstr " Ajout"
#. * be called before line = ml_get(), or when this address is no
#. * longer needed. -- Acevedo.
#.
-#: ../edit.c:4562
msgid "-- Searching..."
msgstr "-- Recherche en cours..."
# AB - Ce texte s'ajoute à la fin d'un des messages de complétion ci-dessus.
# AB - Faut-il utiliser "origine" ou "originel" au lieu d'"original" ?
# DB : Suggestion.
-#: ../edit.c:4618
msgid "Back at original"
msgstr "Retour au point de départ"
# AB - Ce texte s'ajoute à la fin d'un des messages de complétion ci-dessus.
-#: ../edit.c:4621
msgid "Word from other line"
msgstr "Mot d'une autre ligne"
# AB - Ce texte s'ajoute à la fin d'un des messages de complétion ci-dessus.
-#: ../edit.c:4624
msgid "The only match"
msgstr "La seule correspondance"
# AB - Ce texte s'ajoute à la fin d'un des messages de complétion ci-dessus.
# AB - Faut-il remplacer "sur" par "de" ?
# DB : Pour moi, non.
-#: ../edit.c:4680
#, c-format
msgid "match %d of %d"
msgstr "Correspondance %d sur %d"
# AB - Ce texte s'ajoute à la fin d'un des messages de complétion ci-dessus.
# DB - todo : la VO n'a pas de majuscule.
-#: ../edit.c:4684
#, c-format
msgid "match %d"
msgstr "Correspondance %d"
-#: ../eval.c:137
+#. maximum nesting of lists and dicts
msgid "E18: Unexpected characters in :let"
msgstr "E18: Caractères inattendus avant '='"
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: index de Liste hors limites : %<PRId64> au-delà de la fin"
-
-#: ../eval.c:139
#, c-format
msgid "E121: Undefined variable: %s"
msgstr "E121: Variable non définie : %s"
-#: ../eval.c:140
msgid "E111: Missing ']'"
msgstr "E111: ']' manquant"
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: L'argument de %s doit être une Liste"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: L'argument de %s doit être une Liste ou un Dictionnaire"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Impossible d'utiliser une clé vide dans un Dictionnaire"
-
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: Liste requise"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: Dictionnaire requis"
-
-# DB : Suggestion
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: La fonction %s a reçu trop d'arguments"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: La clé %s n'existe pas dans le Dictionnaire"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: La fonction %s existe déjà (ajoutez ! pour la remplacer)"
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: Une entrée du Dictionnaire porte déjà ce nom"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: Référence de fonction (Funcref) requise"
-
-#: ../eval.c:153
msgid "E719: Cannot use [:] with a Dictionary"
msgstr "E719: Utilisation de [:] impossible avec un Dictionnaire"
-#: ../eval.c:154
#, c-format
msgid "E734: Wrong variable type for %s="
msgstr "E734: Type de variable erroné avec %s="
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: Fonction inconnue : %s"
-
-#: ../eval.c:156
#, c-format
msgid "E461: Illegal variable name: %s"
msgstr "E461: Nom de variable invalide : %s"
-#: ../eval.c:157
msgid "E806: using Float as a String"
msgstr "E806: Utilisation d'un Flottant comme une Chaîne"
# DB - todo : trouver mieux que "destinations".
-#: ../eval.c:1830
msgid "E687: Less targets than List items"
msgstr "E687: Moins de destinations que d'éléments dans la Liste"
# DB - todo : trouver mieux que "destinations".
-#: ../eval.c:1834
msgid "E688: More targets than List items"
msgstr "E688: Plus de destinations que d'éléments dans la Liste"
-#: ../eval.c:1906
msgid "Double ; in list of variables"
msgstr "Double ; dans une liste de variables"
-#: ../eval.c:2078
#, c-format
msgid "E738: Can't list variables for %s"
msgstr "E738: Impossible de lister les variables de %s"
-#: ../eval.c:2391
msgid "E689: Can only index a List or Dictionary"
msgstr "E689: Seul une Liste ou un Dictionnaire peut être indexé"
-#: ../eval.c:2396
msgid "E708: [:] must come last"
msgstr "E708: [:] ne peut être spécifié qu'en dernier"
-#: ../eval.c:2439
msgid "E709: [:] requires a List value"
-msgstr "E709: [:] n?cessite une Liste"
+msgstr "E709: [:] nécessite une Liste"
-#: ../eval.c:2674
msgid "E710: List value has more items than target"
msgstr "E710: La Liste a plus d'éléments que la destination"
-#: ../eval.c:2678
msgid "E711: List value has not enough items"
msgstr "E711: La Liste n'a pas assez d'éléments"
-#: ../eval.c:2867
msgid "E690: Missing \"in\" after :for"
msgstr "E690: \"in\" manquant après :for"
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: Parenthèses manquantes : %s"
-
-#: ../eval.c:3263
#, c-format
msgid "E108: No such variable: \"%s\""
msgstr "E108: Variable inexistante : %s"
-#: ../eval.c:3333
msgid "E743: variable nested too deep for (un)lock"
msgstr "E743: variable trop imbriquée pour la (dé)verrouiller"
# AB - Je suis partagé entre la concision d'une traduction assez littérale et
# la lourdeur d'une traduction plus correcte.
-#: ../eval.c:3630
msgid "E109: Missing ':' after '?'"
msgstr "E109: Il manque ':' après '?'"
-#: ../eval.c:3893
msgid "E691: Can only compare List with List"
msgstr "E691: Une Liste ne peut être comparée qu'avec une Liste"
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
-msgstr "E692: Opération invalide avec les Listes"
+msgid "E692: Invalid operation for List"
+msgstr "E692: Opération invalide avec les Liste"
-#: ../eval.c:3915
msgid "E735: Can only compare Dictionary with Dictionary"
msgstr "E735: Un Dictionnaire ne peut être comparé qu'avec un Dictionnaire"
-#: ../eval.c:3917
msgid "E736: Invalid operation for Dictionary"
msgstr "E736: Opération invalide avec les Dictionnaires"
-# DB - todo : Traduction valable (et courte) pour Funcref ?
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: Une Funcref ne peut être comparée qu'à une Funcref"
-
-#: ../eval.c:3934
msgid "E694: Invalid operation for Funcrefs"
msgstr "E694: Opération invalide avec les Funcrefs"
-#: ../eval.c:4277
msgid "E804: Cannot use '%' with Float"
msgstr "E804: Impossible d'utiliser '%' avec un Flottant"
-#: ../eval.c:4478
msgid "E110: Missing ')'"
msgstr "E110: ')' manquant"
-#: ../eval.c:4609
msgid "E695: Cannot index a Funcref"
msgstr "E695: Impossible d'indexer une Funcref"
+msgid "E909: Cannot index a special variable"
+msgstr "E909: Impossible d'indexer une variable spéciale"
+
# AB - La version française est meilleure que la version anglaise.
-#: ../eval.c:4839
#, c-format
msgid "E112: Option name missing: %s"
msgstr "E112: Il manque un nom d'option après %s"
-#: ../eval.c:4855
#, c-format
msgid "E113: Unknown option: %s"
msgstr "E113: Option inconnue : %s"
@@ -730,464 +631,307 @@ msgstr "E113: Option inconnue : %s"
# AB - La version française est meilleure que la version anglaise, qui est
# erronée, d'ailleurs : il s'agit d'une "double quote" et non d'une
# "quote".
-#: ../eval.c:4904
#, c-format
msgid "E114: Missing quote: %s"
msgstr "E114: Il manque \" à la fin de %s"
# AB - La version française est meilleure que la version anglaise.
-#: ../eval.c:5020
#, c-format
msgid "E115: Missing quote: %s"
msgstr "E115: Il manque ' à la fin de %s"
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: Il manque une virgule dans la Liste %s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: Il manque ']' à la fin de la Liste %s"
-
-#: ../eval.c:5750
msgid "Not enough memory to set references, garbage collection aborted!"
msgstr ""
"Pas assez de mémoire pour les références, arrêt du ramassage de miètes !"
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: Il manque ':' dans le Dictionnaire %s"
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: variable trop imbriquée pour être affichée"
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: Clé \"%s\" dupliquée dans le Dictionnaire"
+msgid "E805: Using a Float as a Number"
+msgstr "E805: Utilisation d'un Flottant comme un Nombre"
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: Il manque une virgule dans le Dictionnaire %s"
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Utilisation d'une Funcref comme un Nombre"
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: Il manque '}' à la fin du Dictionnaire %s"
+msgid "E745: Using a List as a Number"
+msgstr "E745: Utilisation d'une Liste comme un Nombre"
-#: ../eval.c:6555
-msgid "E724: variable nested too deep for displaying"
-msgstr "E724: variable trop imbriquée pour être affichée"
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Utilisation d'un Dictionnaire comme un Nombre"
+
+msgid "E910: Using a Job as a Number"
+msgstr "E910: Utilisation d'une Tâche comme un Nombre"
+
+msgid "E913: Using a Channel as a Number"
+msgstr "E913: Utilisation d'un Canal comme un Nombre"
+
+msgid "E891: Using a Funcref as a Float"
+msgstr "E891: Utilisation d'une Funcref comme un Flottant"
+
+msgid "E892: Using a String as a Float"
+msgstr "E892: Utilisation d'une Chaîne comme un Flottant"
+
+msgid "E893: Using a List as a Float"
+msgstr "E893: Utilisation d'une Liste comme un Flottant"
+
+msgid "E894: Using a Dictionary as a Float"
+msgstr "E894: Utilisation d'un Dictionnaire comme un Flottant"
+
+msgid "E907: Using a special value as a Float"
+msgstr "E907: Utilisation d'une valeur spéciale comme un Flottant"
+
+msgid "E911: Using a Job as a Float"
+msgstr "E911: Utilisation d'une Tâche comme un Flottant"
+
+msgid "E914: Using a Channel as a Float"
+msgstr "E914: Utilisation d'un Canal comme un Flottant"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: Utilisation d'une Funcref comme une Chaîne"
+
+msgid "E730: using List as a String"
+msgstr "E730: Utilisation d'une Liste comme une Chaîne"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Utilisation d'un Dictionnaire comme une Chaîne"
+
+msgid "E908: using an invalid value as a String"
+msgstr "E908: Utilisation d'une valeur invalide comme une Chaîne"
-#: ../eval.c:7188
#, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E740: Trop d'arguments pour la fonction %s"
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: Impossible de supprimer la variable %s"
-#: ../eval.c:7190
#, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E116: Arguments invalides pour la fonction %s"
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: Le nom d'une Funcref doit commencer par une majuscule : %s"
-#: ../eval.c:7377
#, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E117: Fonction inconnue : %s"
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Le nom d'une variable entre en conflit avec la fonction %s"
-#: ../eval.c:7383
#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: La fonction %s n'a pas reçu assez d'arguments"
+msgid "E741: Value is locked: %s"
+msgstr "E741: La valeur de %s est verrouillée"
+
+msgid "Unknown"
+msgstr "Inconnu"
-#: ../eval.c:7387
#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: <SID> utilisé en dehors d'un script : %s"
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Impossible de modifier la valeur de %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: variable trop imbriquée pour en faire une copie"
+
+# AB - La version française est capitalisée pour être en accord avec les autres
+# commentaires enregistrés dans le fichier viminfo.
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# Variables globales:\n"
+
+# DB - Plus précis ("la dernière fois") ?
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tModifié la dernière fois dans "
+
+msgid "map() argument"
+msgstr "argument de map()"
+
+msgid "filter() argument"
+msgstr "argument de filter()"
-#: ../eval.c:7391
#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E725: Appel d'une fonction « dict » sans Dictionnaire : %s"
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: L'argument de %s doit être une Liste"
+
+msgid "E928: String required"
+msgstr "E928: Chaîne requis"
-#: ../eval.c:7453
msgid "E808: Number or Float required"
msgstr "E808: Nombre ou Flottant requis"
-#: ../eval.c:7503
msgid "add() argument"
msgstr "argument de add()"
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: Trop d'arguments"
-
-#: ../eval.c:8073
msgid "E785: complete() can only be used in Insert mode"
msgstr "E785: complete() n'est utilisable que dans le mode Insertion"
# AB - Texte par défaut du bouton de la boîte de dialogue affichée par la
# fonction confirm().
-#: ../eval.c:8156
+#.
+#. * Yes this is ugly, I don't particularly like it either. But doing it
+#. * this way has the compelling advantage that translations need not to
+#. * be touched at all. See below what 'ok' and 'ync' are used for.
+#.
msgid "&Ok"
msgstr "&Ok"
-#: ../eval.c:8692
-msgid "extend() argument"
-msgstr "argument de extend()"
-
-#: ../eval.c:9345
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: un mappage existe déjà pour %s"
-
-#: ../eval.c:8915
-msgid "map() argument"
-msgstr "argument de map()"
-
-#: ../eval.c:8916
-msgid "filter() argument"
-msgstr "argument de filter()"
-
-#: ../eval.c:9229
#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld lignes : "
+msgid "+-%s%3ld line: "
+msgid_plural "+-%s%3ld lines: "
+msgstr[0] "+-%s%3ld ligne : "
+msgstr[1] "+-%s%3ld lignes : "
-#: ../eval.c:9291
#, c-format
msgid "E700: Unknown function: %s"
msgstr "E700: Fonction inconnue : %s"
+msgid "E922: expected a dict"
+msgstr "E922: dictionnaire attendu"
+
+msgid "E923: Second argument of function() must be a list or a dict"
+msgstr ""
+"E923: Le second argument de function() doit être une liste ou un dictionnaire"
+
+# AB - Textes des boutons de la boîte de dialogue affichée par inputdialog().
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&Ok\n"
+"&Annuler"
+
# AB - La version française est meilleure que la version anglaise.
-#: ../eval.c:10729
msgid "called inputrestore() more often than inputsave()"
msgstr "inputrestore() a été appelé plus de fois qu'inputsave()"
-#: ../eval.c:10771
msgid "insert() argument"
msgstr "argument de insert()"
-#: ../eval.c:10841
msgid "E786: Range not allowed"
msgstr "E786: Les plages ne sont pas autorisées"
-#: ../eval.c:11140
+msgid "E916: not a valid job"
+msgstr "E916: tâche invalide"
+
msgid "E701: Invalid type for len()"
msgstr "E701: Type invalide avec len()"
-#: ../eval.c:11980
+#, c-format
+msgid "E798: ID is reserved for \":match\": %ld"
+msgstr "E798: ID est réservé pour \":match\": %ld"
+
msgid "E726: Stride is zero"
msgstr "E726: Le pas est nul"
-#: ../eval.c:11982
msgid "E727: Start past end"
msgstr "E727: Début au-delà de la fin"
-#: ../eval.c:12024 ../eval.c:15297
msgid "<empty>"
msgstr "<vide>"
-#: ../eval.c:12282
+# 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 a é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()"
-#: ../eval.c:12466
msgid "E655: Too many symbolic links (cycle?)"
msgstr "E655: Trop de liens symboliques (cycle ?)"
-#: ../eval.c:12593
msgid "reverse() argument"
msgstr "argument de reverse()"
-#: ../eval.c:13721
+# AB - La version française est meilleure que la version anglaise.
+msgid "E258: Unable to send to client"
+msgstr "E258: La réponse n'a pas pu être envoyée au client"
+
+#, c-format
+msgid "E927: Invalid action: '%s'"
+msgstr "E927: Action invalide : « %s »"
+
msgid "sort() argument"
msgstr "argument de sort()"
-#: ../eval.c:13721
-#, fuzzy
msgid "uniq() argument"
-msgstr "argument de add()"
+msgstr "argument de uniq()"
-#: ../eval.c:13776
msgid "E702: Sort compare function failed"
msgstr "E702: La fonction de comparaison de sort() a échoué"
-#: ../eval.c:13806
-#, fuzzy
msgid "E882: Uniq compare function failed"
-msgstr "E702: La fonction de comparaison de sort() a échoué"
+msgstr "E882: La fonction de comparaison de uniq() a échoué"
-#: ../eval.c:14085
msgid "(Invalid)"
msgstr "(Invalide)"
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: Erreur lors de l'écriture du fichier temporaire"
-
-#: ../eval.c:16159
-msgid "E805: Using a Float as a Number"
-msgstr "E805: Utilisation d'un Flottant comme un Nombre"
-
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr "E703: Utilisation d'une Funcref comme un Nombre"
-
-#: ../eval.c:16170
-msgid "E745: Using a List as a Number"
-msgstr "E745: Utilisation d'une Liste comme un Nombre"
-
-#: ../eval.c:16173
-msgid "E728: Using a Dictionary as a Number"
-msgstr "E728: Utilisation d'un Dictionnaire comme un Nombre"
-
-#: ../eval.c:16259
-msgid "E729: using Funcref as a String"
-msgstr "E729: Utilisation d'une Funcref comme une Chaîne"
-
-#: ../eval.c:16262
-msgid "E730: using List as a String"
-msgstr "E730: Utilisation d'une Liste comme une Chaîne"
-
-#: ../eval.c:16265
-msgid "E731: using Dictionary as a String"
-msgstr "E731: Utilisation d'un Dictionnaire comme une Chaîne"
-
-# DB : On doit pouvoir trouver nettement mieux que ça.
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: Type de variable incohérent pour %s"
-
-#: ../eval.c:16705
-#, c-format
-msgid "E795: Cannot delete variable %s"
-msgstr "E795: Impossible de supprimer la variable %s"
-
-#: ../eval.c:16724
-#, c-format
-msgid "E704: Funcref variable name must start with a capital: %s"
-msgstr "E704: Le nom d'une Funcref doit commencer par une majuscule : %s"
-
-#: ../eval.c:16732
-#, c-format
-msgid "E705: Variable name conflicts with existing function: %s"
-msgstr "E705: Le nom d'une variable entre en conflit avec la fonction %s"
-
-#: ../eval.c:16763
-#, c-format
-msgid "E741: Value is locked: %s"
-msgstr "E741: La valeur de %s est verrouillée"
-
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
-msgid "Unknown"
-msgstr "Inconnu"
-
-#: ../eval.c:16768
-#, c-format
-msgid "E742: Cannot change value of %s"
-msgstr "E742: Impossible de modifier la valeur de %s"
-
-#: ../eval.c:16838
-msgid "E698: variable nested too deep for making a copy"
-msgstr "E698: variable trop imbriquée pour en faire une copie"
-
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: Fonction non définie : %s"
-
-# AB - La version française est plus consistante que la version anglaise.
-# AB - Je suis partagé entre la concision d'une traduction assez littérale et
-# la lourdeur d'une traduction plus correcte.
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: Il manque '(' après %s"
-
-#: ../eval.c:17293
-msgid "E862: Cannot use g: here"
-msgstr "E862: Impossible d'utiliser g: ici"
-
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: Argument invalide : %s"
-
-#: ../eval.c:17323
-#, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E853: Nom d'argument dupliqué : %s"
-
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: Il manque :endfunction"
-
-#: ../eval.c:17537
-#, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E707: Le nom de fonction entre en conflit avec la variable : %s"
-
-#: ../eval.c:17549
-#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: Impossible de redéfinir fonction %s : déjà utilisée"
-
-# DB - Le contenu du "c-format" est le nom de la fonction.
-#: ../eval.c:17604
-#, c-format
-msgid "E746: Function name does not match script file name: %s"
-msgstr "E746: Le nom de la fonction %s ne correspond pas le nom du script"
-
-#: ../eval.c:17716
-msgid "E129: Function name required"
-msgstr "E129: Nom de fonction requis"
-
-#: ../eval.c:17824
-#, fuzzy, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr "E128: La fonction %s ne commence pas par une majuscule ou contient ':'"
-
-#: ../eval.c:17833
-#, fuzzy, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr "E128: La fonction %s ne commence pas par une majuscule ou contient ':'"
-
-# AB - Il est difficile de créer une version française qui fasse moins de 80
-# caractères de long, nom de la fonction compris : "It is in use" est une
-# expression très dense. Traductions possibles : "elle est utilisée",
-# "elle s'exécute" ou "elle est occupée".
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: Impossible d'effacer %s : cette fonction est utilisée"
-
-# AB - Vérifier dans la littérature technique s'il n'existe pas une meilleure
-# traduction pour "function call depth".
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr ""
-"E132: La profondeur d'appel de fonction est supérieure à 'maxfuncdepth'"
-
-# AB - Ce texte fait partie d'un message de débogage.
-#: ../eval.c:18568
#, c-format
-msgid "calling %s"
-msgstr "appel de %s"
+msgid "E935: invalid submatch number: %d"
+msgstr "E935: numéro de submatch invalide : %d"
-# AB - Vérifier.
-#: ../eval.c:18651
-#, c-format
-msgid "%s aborted"
-msgstr "%s annulée"
-
-# AB - Ce texte fait partie d'un message de débogage.
-#: ../eval.c:18653
-#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s a retourné #%<PRId64>"
-
-# AB - Ce texte fait partie d'un message de débogage.
-#: ../eval.c:18670
-#, c-format
-msgid "%s returning %s"
-msgstr "%s a retourné \"%s\""
-
-# AB - Ce texte fait partie d'un message de débogage.
-#: ../eval.c:18691 ../ex_cmds2.c:2695
-#, c-format
-msgid "continuing in %s"
-msgstr "de retour dans %s"
-
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: :return en dehors d'une fonction"
-
-# AB - La version française est capitalisée pour être en accord avec les autres
-# commentaires enregistrés dans le fichier viminfo.
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# Variables globales:\n"
-
-# DB - Plus précis ("la dernière fois") ?
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\tModifié la dernière fois dans "
+msgid "E677: Error writing temp file"
+msgstr "E677: Erreur lors de l'écriture du fichier temporaire"
-#: ../eval.c:19272
-msgid "No old files"
-msgstr "Aucun vieux fichier"
+msgid "E921: Invalid callback argument"
+msgstr "E921: Argument de callback invalide"
-#: ../ex_cmds.c:122
#, c-format
msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
msgstr "<%s>%s%s %d, Hexa %02x, Octal %03o"
-#: ../ex_cmds.c:145
#, c-format
msgid "> %d, Hex %04x, Octal %o"
msgstr "> %d, Hexa %04x, Octal %o"
-#: ../ex_cmds.c:146
#, c-format
msgid "> %d, Hex %08x, Octal %o"
msgstr "> %d, Hexa %08x, Octal %o"
# AB - La version anglaise est très mauvaise, ce qui m'oblige a inventer une
# version française.
-#: ../ex_cmds.c:684
msgid "E134: Move lines into themselves"
msgstr "E134: La destination est dans la plage d'origine"
-#: ../ex_cmds.c:747
msgid "1 line moved"
msgstr "1 ligne déplacée"
-#: ../ex_cmds.c:749
#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "%<PRId64> lignes déplacées"
+msgid "%ld lines moved"
+msgstr "%ld lignes déplacées"
-#: ../ex_cmds.c:1175
#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "%<PRId64> lignes filtrées"
+msgid "%ld lines filtered"
+msgstr "%ld lignes filtrées"
# AB - J'ai volontairement omis l'astérisque initiale car je pense que le
# motif "Filter*" décrit plus clairement les quatre autocommandes liées
# au filtrage (FilterReadPre, FilterReadPost, FilterWritePre et
# FilterWritePost) que "*Filter*" que l'on confond avec une tentative de
# mise en valeur.
-#: ../ex_cmds.c:1194
msgid "E135: *Filter* Autocommands must not change current buffer"
msgstr ""
"E135: Les autocommandes Filter* ne doivent pas changer le tampon courant"
# AB - Il faut respecter l'esprit plus que la lettre. Dans le cas présent,
# nettement plus.
-#: ../ex_cmds.c:1244
msgid "[No write since last change]\n"
msgstr "[Attention : tout n'est pas enregistré]\n"
# AB - Le numéro et le message d'erreur (%s ci-dessous) et le "numéro" de ligne
# sont des chaînes de caractères dont le contenu est à la discrétion de
# l'appelant de la fonction viminfo_error().
-#: ../ex_cmds.c:1424
#, c-format
msgid "%sviminfo: %s in line: "
msgstr "%sviminfo : %s à la ligne "
# AB - La version française est meilleure que la version anglaise.
-#: ../ex_cmds.c:1431
msgid "E136: viminfo: Too many errors, skipping rest of file"
msgstr ""
"E136: Il y a trop d'erreurs ; interruption de la lecture du fichier viminfo"
@@ -1195,30 +939,25 @@ msgstr ""
# AB - Ce texte fait partie d'un message de débogage.
# DB - ... dont les valeurs possibles sont les messages
# qui suivent.
-#: ../ex_cmds.c:1458
#, c-format
msgid "Reading viminfo file \"%s\"%s%s%s"
msgstr "Lecture du fichier viminfo \"%s\"%s%s%s"
# AB - Ce texte fait partie d'un message de débogage.
# DB - Voir ci-dessus.
-#: ../ex_cmds.c:1460
msgid " info"
msgstr " info"
# AB - Ce texte fait partie d'un message de débogage.
# DB - Voir ci-dessus.
-#: ../ex_cmds.c:1461
msgid " marks"
msgstr " marques"
-#: ../ex_cmds.c:1462
msgid " oldfiles"
msgstr " vieux fichiers"
# AB - Ce texte fait partie d'un message de débogage.
# DB - Voir ci-dessus.
-#: ../ex_cmds.c:1463
msgid " FAILED"
msgstr " ÉCHEC"
@@ -1227,33 +966,36 @@ msgstr " ÉCHEC"
# AB - Le mot "viminfo" a été retiré pour que le message ne dépasse pas 80
# caractères dans le cas courant où %s = /home/12345678/.viminfo
#. avoid a wait_return for this message, it's annoying
-#: ../ex_cmds.c:1541
#, c-format
msgid "E137: Viminfo file is not writable: %s"
msgstr "E137: L'écriture dans le fichier %s est interdite"
+#, c-format
+msgid "E929: Too many viminfo temp files, like %s!"
+msgstr "E929: Trop de fichiers temporaires viminfo, comme %s!"
+
# AB - Le point d'exclamation est superflu.
# AB - Le mot "viminfo" a été retiré pour que le message ne dépasse pas 80
# caractères dans le cas courant où %s = /home/12345678/.viminfo
-#: ../ex_cmds.c:1626
#, c-format
msgid "E138: Can't write viminfo file %s!"
msgstr "E138: Impossible d'écrire le fichier %s"
# AB - Ce texte est un message de débogage.
-#: ../ex_cmds.c:1635
#, c-format
msgid "Writing viminfo file \"%s\""
msgstr "Écriture du fichier viminfo \"%s\""
+#, c-format
+msgid "E886: Can't rename viminfo file to %s!"
+msgstr "E886: Impossible de renommer viminfo en %s"
+
#. Write the info:
-#: ../ex_cmds.c:1720
#, c-format
msgid "# This viminfo file was generated by Vim %s.\n"
msgstr "# Ce fichier viminfo a été généré par Vim %s.\n"
# AB - Les deux versions, bien que différentes, se valent.
-#: ../ex_cmds.c:1722
msgid ""
"# You may edit it if you're careful!\n"
"\n"
@@ -1261,58 +1003,61 @@ msgstr ""
"# Vous pouvez l'éditer, mais soyez prudent.\n"
"\n"
-#: ../ex_cmds.c:1723
msgid "# Value of 'encoding' when this file was written\n"
msgstr "# 'encoding' dans lequel ce fichier a été écrit\n"
# AB - Ce texte est passé en argument à la fonction viminfo_error().
# AB - "illégal" est un terme trop fort à mon goût.
-#: ../ex_cmds.c:1800
msgid "Illegal starting char"
msgstr "Caractère initial non valide"
+msgid ""
+"\n"
+"# Bar lines, copied verbatim:\n"
+msgstr ""
+"\n"
+"# Lignes commençant par |, copiées littéralement :\n"
+
+# AB - Ceci est un titre de boîte de dialogue. Vérifier que la version
+# française est correcte pour les trois références ; j'ai un doute quant
+# à la troisième.
+msgid "Save As"
+msgstr "Enregistrer sous - Vim"
+
# AB - Ceci est un contenu de boîte de dialogue (éventuellement en mode texte).
# AB - La version française est meilleure que la version anglaise.
-#: ../ex_cmds.c:2162
msgid "Write partial file?"
msgstr "Perdre une partie du fichier ?"
# AB - La version française est nettement meilleure que la version anglaise.
-#: ../ex_cmds.c:2166
msgid "E140: Use ! to write partial buffer"
msgstr ""
"E140: Une partie du fichier serait perdue (ajoutez ! pour passer outre)"
-#: ../ex_cmds.c:2281
#, c-format
msgid "Overwrite existing file \"%s\"?"
msgstr "Écraser le fichier %s existant ?"
-#: ../ex_cmds.c:2317
#, c-format
msgid "Swap file \"%s\" exists, overwrite anyway?"
msgstr "Le fichier d'échange \"%s\" existe déjà, l'écraser ?"
# DB - Un peu long à mon avis.
-#: ../ex_cmds.c:2326
#, c-format
msgid "E768: Swap file exists: %s (:silent! overrides)"
msgstr "E768: Le fichier d'échange %s existe déjà (:silent! pour passer outre)"
-#: ../ex_cmds.c:2381
#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: Pas de nom de fichier pour le tampon %<PRId64>"
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Pas de nom de fichier pour le tampon %ld"
# AB - Il faut respecter l'esprit plus que la lettre.
-#: ../ex_cmds.c:2412
msgid "E142: File not written: Writing is disabled by 'write' option"
msgstr ""
"E142: L'option 'nowrite' est activée et empêche toute écriture du fichier"
# AB - Ceci est un contenu de boîte de dialogue (éventuellement en mode texte).
# AB - "activée pour" n'est pas une formulation très heureuse.
-#: ../ex_cmds.c:2434
#, c-format
msgid ""
"'readonly' option is set for \"%s\".\n"
@@ -1321,7 +1066,6 @@ msgstr ""
"L'option 'readonly' est activée pour \"%s\".\n"
"Voulez-vous tout de même enregistrer ?"
-#: ../ex_cmds.c:2439
#, c-format
msgid ""
"File permissions of \"%s\" are read-only.\n"
@@ -1332,94 +1076,81 @@ msgstr ""
"Il peut être possible de l'écrire tout de même.\n"
"Tenter ?"
-#: ../ex_cmds.c:2451
#, c-format
msgid "E505: \"%s\" is read-only (add ! to override)"
msgstr "E505: \"%s\" est en lecture seule (ajoutez ! pour passer outre)"
+# AB - Ceci est un titre de boîte de dialogue.
+msgid "Edit File"
+msgstr "Ouvrir un fichier - Vim"
+
# AB - Il faut respecter l'esprit plus que la lettre.
# AB - J'hésite à ajouter "à sa création" après le nom du tampon. Ce message
# devrait n'être affiché qu'après une tentative d'ouverture de fichier,
# la version actuelle devrait donc suffire.
# DB - Suggestion : "nouveau tampon" ?
-#: ../ex_cmds.c:3120
#, c-format
msgid "E143: Autocommands unexpectedly deleted new buffer %s"
msgstr "E143: Une autocommande a effacé le nouveau tampon %s"
-#: ../ex_cmds.c:3313
msgid "E144: non-numeric argument to :z"
msgstr "E144: L'argument de :z n'est pas numérique"
# AB - La version française fera peut-être mieux passer l'amère pilule.
# La consultation de l'aide donnera l'explication complète à ceux qui
# ne comprendraient pas à quoi ce message est dû.
-#: ../ex_cmds.c:3404
msgid "E145: Shell commands not allowed in rvim"
msgstr "E145: Les commandes externes sont indisponibles dans rvim"
-#: ../ex_cmds.c:3498
msgid "E146: Regular expressions can't be delimited by letters"
msgstr ""
"E146: Les expressions régulières ne peuvent pas être délimitées par des "
"lettres"
-#: ../ex_cmds.c:3964
#, c-format
msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
msgstr "remplacer par %s (y/n/a/q/l/^E/^Y)?"
-#: ../ex_cmds.c:4379
msgid "(Interrupted) "
msgstr "(Interrompu) "
-#: ../ex_cmds.c:4384
msgid "1 match"
msgstr "1 correspondance"
-#: ../ex_cmds.c:4384
msgid "1 substitution"
msgstr "1 substitution"
-#: ../ex_cmds.c:4387
#, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> correspondances"
+msgid "%ld matches"
+msgstr "%ld correspondances"
-#: ../ex_cmds.c:4388
#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> substitutions"
+msgid "%ld substitutions"
+msgstr "%ld substitutions"
-#: ../ex_cmds.c:4392
msgid " on 1 line"
msgstr " sur 1 ligne"
-#: ../ex_cmds.c:4395
#, c-format
-msgid " on %<PRId64> lines"
-msgstr " sur %<PRId64> lignes"
+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.
-#: ../ex_cmds.c:4438
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.
-#: ../ex_cmds.c:4467
msgid "E148: Regular expression missing from global"
msgstr "E148: :global doit être suivi par une expression régulière"
# AB - Ce message est utilisé lorsque :vglobal ne trouve rien. Lorsque :global
# ne trouve rien, c'est "Pattern not found: %s" / "Motif introuvable: %s"
# qui est utilisé.
-#: ../ex_cmds.c:4508
#, c-format
msgid "Pattern found in every line: %s"
msgstr "Motif trouvé dans toutes les lignes : %s"
-#: ../ex_cmds.c:4510
#, c-format
msgid "Pattern not found: %s"
msgstr "Motif introuvable: %s"
@@ -1430,7 +1161,6 @@ msgstr "Motif introuvable: %s"
# à internationalisation. J'attends que les deux autres messages soient
# traduisibles pour traduire celui-ci.
# DB - TODO : Qu'en est-il à présent ?
-#: ../ex_cmds.c:4587
msgid ""
"\n"
"# Last Substitute String:\n"
@@ -1441,43 +1171,33 @@ msgstr ""
"$"
# This message should *so* be E42!
-#: ../ex_cmds.c:4679
msgid "E478: Don't panic!"
msgstr "E478: Pas de panique !"
-#: ../ex_cmds.c:4717
#, c-format
msgid "E661: Sorry, no '%s' help for %s"
msgstr "E661: Désolé, aucune aide en langue '%s' pour %s"
-#: ../ex_cmds.c:4719
#, c-format
msgid "E149: Sorry, no help for %s"
msgstr "E149: Désolé, aucune aide pour %s"
-#: ../ex_cmds.c:4751
#, c-format
msgid "Sorry, help file \"%s\" not found"
msgstr "Désolé, le fichier d'aide \"%s\" est introuvable"
-#: ../ex_cmds.c:5323
#, c-format
-msgid "E150: Not a directory: %s"
-msgstr "E150: %s n'est pas un répertoire"
+msgid "E151: No match: %s"
+msgstr "E151: Aucune correspondance : %s"
-# AB - La version anglaise est plus précise, mais trop technique.
-#: ../ex_cmds.c:5446
#, c-format
msgid "E152: Cannot open %s for writing"
-msgstr "E152: Impossible d'écrire %s"
+msgstr "E152: Impossible d'ouvrir %s en écriture"
-# AB - La version anglaise est plus précise, mais trop technique.
-#: ../ex_cmds.c:5471
#, c-format
msgid "E153: Unable to open %s for reading"
-msgstr "E153: Impossible de lire %s"
+msgstr "E153: Impossible d'ouvrir %s en lecture"
-#: ../ex_cmds.c:5500
#, c-format
msgid "E670: Mix of help file encodings within a language: %s"
msgstr "E670: Encodages différents dans les fichiers d'aide en langue %s"
@@ -1487,315 +1207,279 @@ msgstr "E670: Encodages différents dans les fichiers d'aide en langue %s"
# traduction de 40 caractères ou moins. Ce qui est loin d'être le cas
# présent.
# DB - Suggestion.
-#: ../ex_cmds.c:5565
#, c-format
msgid "E154: Duplicate tag \"%s\" in file %s/%s"
msgstr "E154: Marqueur \"%s\" dupliqué dans le fichier %s/%s"
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: %s n'est pas un répertoire"
+
# AB - Il faut respecter l'esprit plus que la lettre.
-#: ../ex_cmds.c:5687
#, c-format
msgid "E160: Unknown sign command: %s"
msgstr "E160: Commande inconnue : :sign %s"
# AB - La version française est meilleure que la version anglaise.
-#: ../ex_cmds.c:5704
msgid "E156: Missing sign name"
msgstr "E156: Il manque le nom du symbole"
-#: ../ex_cmds.c:5746
msgid "E612: Too many signs defined"
msgstr "E612: Trop de symboles sont définis"
# AB - Cette traduction ne me satisfait pas.
# DB - Suggestion.
-#: ../ex_cmds.c:5813
#, c-format
msgid "E239: Invalid sign text: %s"
msgstr "E239: Le texte du symbole est invalide : %s"
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
#, c-format
msgid "E155: Unknown sign: %s"
msgstr "E155: Symbole inconnu : %s"
# AB - La version française est meilleure que la version anglaise.
-#: ../ex_cmds.c:5877
msgid "E159: Missing sign number"
msgstr "E159: Il manque l'ID du symbole"
# AB - Vu le code source, la version française est meilleure que la
# version anglaise. Ce message est similaire au message E102.
-#: ../ex_cmds.c:5971
#, c-format
msgid "E158: Invalid buffer name: %s"
msgstr "E158: Le tampon %s est introuvable"
+msgid "E934: Cannot jump to a buffer that does not have a name"
+msgstr "E934: Impossible de sauter à un tampon sans nom"
+
# AB - Vu le code source, la version française est meilleure que la
# version anglaise.
-#: ../ex_cmds.c:6008
#, c-format
-msgid "E157: Invalid sign ID: %<PRId64>"
-msgstr "E157: Le symbole %<PRId64> est introuvable"
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Le symbole %ld est introuvable"
+
+#, c-format
+msgid "E885: Not possible to change sign %s"
+msgstr "E885: Impossible de changer le symbole %s"
+
+msgid " (NOT FOUND)"
+msgstr " (INTROUVABLE)"
-#: ../ex_cmds.c:6066
msgid " (not supported)"
msgstr " (non supporté)"
-#: ../ex_cmds.c:6169
msgid "[Deleted]"
msgstr "[Effacé]"
+msgid "No old files"
+msgstr "Aucun vieux fichier"
+
# AB - La version française de la première phrase ne me satisfait pas.
# DB - Suggestion.
-#: ../ex_cmds2.c:139
msgid "Entering Debug mode. Type \"cont\" to continue."
msgstr "Mode débogage activé. Tapez \"cont\" pour continuer."
-#: ../ex_cmds2.c:143 ../ex_docmd.c:759
#, c-format
-msgid "line %<PRId64>: %s"
-msgstr "ligne %<PRId64> : %s"
+msgid "line %ld: %s"
+msgstr "ligne %ld : %s"
-#: ../ex_cmds2.c:145
#, c-format
msgid "cmd: %s"
msgstr "cmde : %s"
-#: ../ex_cmds2.c:322
+msgid "frame is zero"
+msgstr "le cadre de pile est zéro"
+
+#, c-format
+msgid "frame at highest level: %d"
+msgstr "cadre de pile au niveau le plus haut : %d"
+
#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "Point d'arrêt dans %s%s ligne %<PRId64>"
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Point d'arrêt dans %s%s ligne %ld"
-#: ../ex_cmds2.c:581
#, c-format
msgid "E161: Breakpoint not found: %s"
msgstr "E161: Le point d'arrêt %s est introuvable"
-#: ../ex_cmds2.c:611
msgid "No breakpoints defined"
msgstr "Aucun point d'arrêt n'est défini"
# AB - Le deuxième %s est remplacé par "func" ou "file" sans que l'on puisse
# traduire ces mots.
-#: ../ex_cmds2.c:617
#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s ligne %<PRId64>"
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s ligne %ld"
-#: ../ex_cmds2.c:942
msgid "E750: First use \":profile start {fname}\""
msgstr "E750: Utilisez d'abord \":profile start {nomfichier}\""
# AB - "changes to" est redondant et a été omis de la version française.
-#: ../ex_cmds2.c:1269
#, c-format
msgid "Save changes to \"%s\"?"
msgstr "Enregistrer \"%s\" ?"
# AB - Si les parenthèses posent problème, il faudra remettre les guillemets
# ci-dessus.
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
msgid "Untitled"
msgstr "(sans titre)"
# AB - Il faut respecter l'esprit plus que la lettre.
# AB - Ce message est similaire au message E89.
-#: ../ex_cmds2.c:1421
#, c-format
msgid "E162: No write since last change for buffer \"%s\""
msgstr "E162: Le tampon %s n'a pas été enregistré"
-#: ../ex_cmds2.c:1480
msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
-msgstr "Alerte : Entrée inattendue dans un autre tampon (vérifier autocmdes)"
+msgstr ""
+"Alerte : Entrée inattendue dans un autre tampon (vérifier autocommandes)"
-#: ../ex_cmds2.c:1826
msgid "E163: There is only one file to edit"
msgstr "E163: Il n'y a qu'un seul fichier à éditer"
-#: ../ex_cmds2.c:1828
msgid "E164: Cannot go before first file"
msgstr "E164: Impossible d'aller avant le premier fichier"
-#: ../ex_cmds2.c:1830
msgid "E165: Cannot go beyond last file"
msgstr "E165: Impossible d'aller au-delà du dernier fichier"
-#: ../ex_cmds2.c:2175
#, c-format
msgid "E666: compiler not supported: %s"
msgstr "E666: Compilateur %s non supporté"
-#: ../ex_cmds2.c:2257
#, c-format
msgid "Searching for \"%s\" in \"%s\""
msgstr "Recherche de \"%s\" dans \"%s\""
-#: ../ex_cmds2.c:2284
#, c-format
msgid "Searching for \"%s\""
msgstr "Recherche de \"%s\""
-#: ../ex_cmds2.c:2307
#, c-format
msgid "not found in '%s': \"%s\""
msgstr "introuvable dans '%s' : \"%s\""
-#: ../ex_cmds2.c:2472
+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\""
-#: ../ex_cmds2.c:2518
#, c-format
msgid "could not source \"%s\""
msgstr "impossible de sourcer \"%s\""
-#: ../ex_cmds2.c:2520
#, c-format
-msgid "line %<PRId64>: could not source \"%s\""
-msgstr "ligne %<PRId64> : impossible de sourcer \"%s\""
+msgid "line %ld: could not source \"%s\""
+msgstr "ligne %ld : impossible de sourcer \"%s\""
-#: ../ex_cmds2.c:2535
#, c-format
msgid "sourcing \"%s\""
msgstr "sourcement \"%s\""
-#: ../ex_cmds2.c:2537
#, c-format
-msgid "line %<PRId64>: sourcing \"%s\""
-msgstr "ligne %<PRId64> : sourcement de \"%s\""
+msgid "line %ld: sourcing \"%s\""
+msgstr "ligne %ld : sourcement de \"%s\""
-#: ../ex_cmds2.c:2693
#, c-format
msgid "finished sourcing %s"
msgstr "fin du sourcement de %s"
-#: ../ex_cmds2.c:2765
+# AB - Ce texte fait partie d'un message de débogage.
+#, c-format
+msgid "continuing in %s"
+msgstr "de retour dans %s"
+
msgid "modeline"
msgstr "ligne de mode"
-#: ../ex_cmds2.c:2767
msgid "--cmd argument"
msgstr "argument --cmd"
-#: ../ex_cmds2.c:2769
msgid "-c argument"
msgstr "argument -c"
-#: ../ex_cmds2.c:2771
msgid "environment variable"
msgstr "variable d'environnement"
-#: ../ex_cmds2.c:2773
msgid "error handler"
msgstr "gestionnaire d'erreur"
-#: ../ex_cmds2.c:3020
msgid "W15: Warning: Wrong line separator, ^M may be missing"
msgstr "W15: Alerte : Séparateur de ligne erroné, ^M possiblement manquant"
-#: ../ex_cmds2.c:3139
msgid "E167: :scriptencoding used outside of a sourced file"
msgstr "E167: :scriptencoding utilisé en dehors d'un fichier sourcé"
-#: ../ex_cmds2.c:3166
msgid "E168: :finish used outside of a sourced file"
msgstr "E168: :finish utilisé en dehors d'un fichier sourcé"
# DB - Le premier %s est, au choix : "time ", "ctype " ou "messages ",
# sans qu'il soit possible de les traduire.
-#: ../ex_cmds2.c:3389
#, c-format
msgid "Current %slanguage: \"%s\""
msgstr "Langue courante pour %s : \"%s\""
-#: ../ex_cmds2.c:3404
#, c-format
msgid "E197: Cannot set language to \"%s\""
msgstr "E197: Impossible de choisir la langue \"%s\""
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
msgstr "Mode Ex activé. Tapez \"visual\" pour passer en mode Normal."
-#: ../ex_docmd.c:428
msgid "E501: At end-of-file"
msgstr "E501: À la fin du fichier"
-#: ../ex_docmd.c:513
msgid "E169: Command too recursive"
msgstr "E169: Commande trop récursive"
-#: ../ex_docmd.c:1006
#, c-format
msgid "E605: Exception not caught: %s"
msgstr "E605: Exception non interceptée : %s"
-#: ../ex_docmd.c:1085
msgid "End of sourced file"
msgstr "Fin du fichier sourcé"
-#: ../ex_docmd.c:1086
msgid "End of function"
msgstr "Fin de la fonction"
-#: ../ex_docmd.c:1628
msgid "E464: Ambiguous use of user-defined command"
msgstr "E464: Utilisation ambiguë d'une commande définie par l'utilisateur"
-#: ../ex_docmd.c:1638
msgid "E492: Not an editor command"
msgstr "E492: Commande inconnue"
-#: ../ex_docmd.c:1729
msgid "E493: Backwards range given"
msgstr "E493: La plage spécifiée est inversée"
-#: ../ex_docmd.c:1733
msgid "Backwards range given, OK to swap"
msgstr "La plage spécifiée est inversée, OK pour l'inverser"
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
msgid "E494: Use w or w>>"
msgstr "E494: Utilisez w ou w>>"
-#: ../ex_docmd.c:3454
-msgid "E319: The command is not available in this version"
+msgid "E319: Sorry, the command is not available in this version"
msgstr "E319: Désolé, cette commande n'est pas disponible dans cette version"
-#: ../ex_docmd.c:3752
msgid "E172: Only one file name allowed"
msgstr "E172: Un seul nom de fichier autorisé"
-#: ../ex_docmd.c:4238
msgid "1 more file to edit. Quit anyway?"
msgstr "Encore 1 fichier à éditer. Quitter tout de même ?"
-#: ../ex_docmd.c:4242
#, c-format
msgid "%d more files to edit. Quit anyway?"
msgstr "Encore %d fichiers à éditer. Quitter tout de même ?"
-#: ../ex_docmd.c:4248
msgid "E173: 1 more file to edit"
msgstr "E173: encore 1 fichier à éditer"
-#: ../ex_docmd.c:4250
#, c-format
-msgid "E173: %<PRId64> more files to edit"
-msgstr "E173: encore %<PRId64> fichiers à éditer"
+msgid "E173: %ld more files to edit"
+msgstr "E173: encore %ld fichiers à éditer"
-#: ../ex_docmd.c:4320
msgid "E174: Command already exists: add ! to replace it"
msgstr "E174: La commande existe déjà : ajoutez ! pour la redéfinir"
-#: ../ex_docmd.c:4432
msgid ""
"\n"
" Name Args Address Complete Definition"
@@ -1803,356 +1487,311 @@ msgstr ""
"\n"
" Nom Args Adresse Complet. Définition"
-#: ../ex_docmd.c:4516
msgid "No user-defined commands found"
msgstr "Aucune commande définie par l'utilisateur trouvée"
-#: ../ex_docmd.c:4538
msgid "E175: No attribute specified"
msgstr "E175: Pas d'attribut spécifié"
-#: ../ex_docmd.c:4583
msgid "E176: Invalid number of arguments"
msgstr "E176: Nombre d'arguments invalide"
-#: ../ex_docmd.c:4594
msgid "E177: Count cannot be specified twice"
msgstr "E177: Le quantificateur ne peut être spécifié deux fois"
-#: ../ex_docmd.c:4603
msgid "E178: Invalid default value for count"
msgstr "E178: La valeur par défaut du quantificateur est invalide"
-#: ../ex_docmd.c:4625
msgid "E179: argument required for -complete"
msgstr "E179: argument requis avec -complete"
-#: ../ex_docmd.c:4933
msgid "E179: argument required for -addr"
msgstr "E179: argument requis avec -addr"
-#: ../ex_docmd.c:4635
#, c-format
msgid "E181: Invalid attribute: %s"
msgstr "E181: Attribut invalide : %s"
-#: ../ex_docmd.c:4678
msgid "E182: Invalid command name"
msgstr "E182: Nom de commande invalide"
-#: ../ex_docmd.c:4691
msgid "E183: User defined commands must start with an uppercase letter"
msgstr "E183: Les commandes utilisateur doivent commencer par une majuscule"
-#: ../ex_docmd.c:4696
msgid "E841: Reserved name, cannot be used for user defined command"
msgstr ""
"E841: Nom réservé, ne peux pas être utilisé pour une commande utilisateur"
-#: ../ex_docmd.c:4751
#, c-format
msgid "E184: No such user-defined command: %s"
msgstr "E184: Aucune commande %s définie par l'utilisateur"
-#: ../ex_docmd.c:5516
#, c-format
msgid "E180: Invalid address type value: %s"
msgstr "E180: Valeur de type d'adresse invalide : %s"
-#: ../ex_docmd.c:5219
#, c-format
msgid "E180: Invalid complete value: %s"
msgstr "E180: Valeur invalide pour \"-complete=\" : %s"
-#: ../ex_docmd.c:5225
msgid "E468: Completion argument only allowed for custom completion"
msgstr "E468: Seul le complètement personnalisé accepte un argument"
-#: ../ex_docmd.c:5231
msgid "E467: Custom completion requires a function argument"
-msgstr "E467: Le complètement personnalisé requiert une fonction en argument"
+msgstr "E467: Le complètement personnalisé nécessite une fonction en argument"
+
+msgid "unknown"
+msgstr "inconnu"
-#: ../ex_docmd.c:5257
#, c-format
msgid "E185: Cannot find color scheme '%s'"
msgstr "E185: Impossible de trouver le jeu de couleurs '%s'"
-#: ../ex_docmd.c:5263
msgid "Greetings, Vim user!"
msgstr "Bienvenue, utilisateur de Vim !"
-#: ../ex_docmd.c:5431
msgid "E784: Cannot close last tab page"
msgstr "E784: Impossible de fermer le dernier onglet"
-#: ../ex_docmd.c:5462
msgid "Already only one tab page"
msgstr "Il ne reste déjà plus qu'un seul onglet"
-#: ../ex_docmd.c:6004
+msgid "Edit File in new window"
+msgstr "Ouvrir un fichier dans une nouvelle fenêtre - Vim"
+
#, c-format
msgid "Tab page %d"
msgstr "Onglet %d"
-#: ../ex_docmd.c:6295
msgid "No swap file"
msgstr "Pas de fichier d'échange"
-#: ../ex_docmd.c:6478
+msgid "Append File"
+msgstr "Ajouter fichier"
+
msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
msgstr ""
"E747: Tampon modifié : impossible de changer de répertoire (ajoutez ! pour "
"passer outre)"
-#: ../ex_docmd.c:6485
msgid "E186: No previous directory"
msgstr "E186: Pas de répertoire précédent"
-#: ../ex_docmd.c:6530
msgid "E187: Unknown"
msgstr "E187: Inconnu"
-#: ../ex_docmd.c:6610
msgid "E465: :winsize requires two number arguments"
-msgstr "E465: :winsize requiert deux arguments numériques"
+msgstr "E465: :winsize nécessite deux arguments numériques"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Position de la fenêtre : X %d, Y %d"
# DB : Suggestion, sans doute perfectible.
-#: ../ex_docmd.c:6655
msgid "E188: Obtaining window position not implemented for this platform"
msgstr ""
"E188: Récupérer la position de la fenêtre non implémenté dans cette version"
-#: ../ex_docmd.c:6662
msgid "E466: :winpos requires two number arguments"
-msgstr "E466: :winpos requiert deux arguments numériques"
+msgstr "E466: :winpos nécessite deux arguments numériques"
+
+msgid "E930: Cannot use :redir inside execute()"
+msgstr "E930: Impossible d'utiliser :redir dans execute()"
+
+msgid "Save Redirection"
+msgstr "Enregistrer la redirection"
+
+msgid "Save View"
+msgstr "Enregistrer la vue - Vim"
+
+msgid "Save Session"
+msgstr "Enregistrer la session - Vim"
+
+msgid "Save Setup"
+msgstr "Enregistrer les réglages - Vim"
-#: ../ex_docmd.c:7241
#, c-format
msgid "E739: Cannot create directory: %s"
msgstr "E739: Impossible de créer le répertoire \"%s\""
-#: ../ex_docmd.c:7268
#, c-format
msgid "E189: \"%s\" exists (add ! to override)"
msgstr "E189: \"%s\" existe (ajoutez ! pour passer outre)"
-#: ../ex_docmd.c:7273
#, c-format
msgid "E190: Cannot open \"%s\" for writing"
msgstr "E190: Impossible d'ouvrir \"%s\" pour y écrire"
#. set mark
-#: ../ex_docmd.c:7294
msgid "E191: Argument must be a letter or forward/backward quote"
msgstr "E191: L'argument doit être une lettre ou une (contre-)apostrophe"
-#: ../ex_docmd.c:7333
msgid "E192: Recursive use of :normal too deep"
msgstr "E192: Appel récursif de :normal trop important"
-#: ../ex_docmd.c:7807
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< n'est pas disponible sans la fonctionnalité +eval"
+
msgid "E194: No alternate file name to substitute for '#'"
msgstr "E194: Aucun nom de fichier alternatif à substituer à '#'"
-#: ../ex_docmd.c:7841
msgid "E495: no autocommand file name to substitute for \"<afile>\""
msgstr "E495: Aucun nom de ficher d'autocommande à substituer à \"<afile>\""
-#: ../ex_docmd.c:7850
msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
msgstr "E496: Aucun numéro de tampon d'autocommande à substituer à \"<abuf>\""
-#: ../ex_docmd.c:7861
msgid "E497: no autocommand match name to substitute for \"<amatch>\""
msgstr "E497: Aucune correspondance d'autocommande à substituer à \"<amatch>\""
-#: ../ex_docmd.c:7870
msgid "E498: no :source file name to substitute for \"<sfile>\""
msgstr "E498: Aucun nom de fichier :source à substituer à \"<sfile>\""
-#: ../ex_docmd.c:7876
msgid "E842: no line number to use for \"<slnum>\""
msgstr "E842: aucun numéro de ligne à utiliser pour \"<slnum>\""
-#: ../ex_docmd.c:7903
-#, c-format
+#, no-c-format
msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
msgstr "E499: Nom de fichier vide pour '%' ou '#', ne marche qu'avec \":p:h\""
-#: ../ex_docmd.c:7905
msgid "E500: Evaluates to an empty string"
msgstr "E500: Évalué en une chaîne vide"
-#: ../ex_docmd.c:8838
msgid "E195: Cannot open viminfo file for reading"
msgstr "E195: Impossible d'ouvrir le viminfo en lecture"
-#: ../ex_eval.c:464
+msgid "E196: No digraphs in this version"
+msgstr "E196: Pas de digraphes dans cette version"
+
msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
msgstr "E608: Impossible d'émettre des exceptions avec 'Vim' comme préfixe"
#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
#, c-format
msgid "Exception thrown: %s"
msgstr "Exception émise : %s"
-#: ../ex_eval.c:545
#, c-format
msgid "Exception finished: %s"
msgstr "Exception terminée : %s"
-#: ../ex_eval.c:546
#, c-format
msgid "Exception discarded: %s"
msgstr "Exception éliminée : %s"
-#: ../ex_eval.c:588 ../ex_eval.c:634
#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, ligne %<PRId64>"
+msgid "%s, line %ld"
+msgstr "%s, ligne %ld"
#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
#, c-format
msgid "Exception caught: %s"
msgstr "Exception interceptée : %s"
# DB - Le c-format est féminin, singulier ou pluriel (cf. 3 messages plus bas).
-#: ../ex_eval.c:676
#, c-format
msgid "%s made pending"
msgstr "%s mise(s) en attente"
-#: ../ex_eval.c:679
#, c-format
msgid "%s resumed"
msgstr "%s ré-émise(s)"
-#: ../ex_eval.c:683
#, c-format
msgid "%s discarded"
msgstr "%s éliminée(s)"
-#: ../ex_eval.c:708
msgid "Exception"
msgstr "Exception"
-#: ../ex_eval.c:713
msgid "Error and interrupt"
msgstr "Erreur et interruption"
-#: ../ex_eval.c:715
msgid "Error"
msgstr "Erreur"
#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
msgid "Interrupt"
msgstr "Interruption"
-#: ../ex_eval.c:795
msgid "E579: :if nesting too deep"
msgstr "E579: Imbrication de :if trop importante"
-#: ../ex_eval.c:830
msgid "E580: :endif without :if"
msgstr "E580: :endif sans :if"
-#: ../ex_eval.c:873
msgid "E581: :else without :if"
msgstr "E581: :else sans :if"
-#: ../ex_eval.c:876
msgid "E582: :elseif without :if"
msgstr "E582: :elseif sans :if"
-#: ../ex_eval.c:880
msgid "E583: multiple :else"
msgstr "E583: Il ne peut y avoir qu'un seul :else"
-#: ../ex_eval.c:883
msgid "E584: :elseif after :else"
msgstr "E584: :elseif après :else"
-#: ../ex_eval.c:941
msgid "E585: :while/:for nesting too deep"
msgstr "E585: Imbrication de :while ou :for trop importante"
-#: ../ex_eval.c:1028
msgid "E586: :continue without :while or :for"
msgstr "E586: :continue sans :while ou :for"
-#: ../ex_eval.c:1061
msgid "E587: :break without :while or :for"
msgstr "E587: :break sans :while ou :for"
-#: ../ex_eval.c:1102
msgid "E732: Using :endfor with :while"
msgstr "E732: Utilisation de :endfor avec :while"
-#: ../ex_eval.c:1104
msgid "E733: Using :endwhile with :for"
msgstr "E733: Utilisation de :endwhile avec :for"
-#: ../ex_eval.c:1247
msgid "E601: :try nesting too deep"
msgstr "E601: Imbrication de :try trop importante"
-#: ../ex_eval.c:1317
msgid "E603: :catch without :try"
msgstr "E603: :catch sans :try"
#. Give up for a ":catch" after ":finally" and ignore it.
#. * Just parse.
-#: ../ex_eval.c:1332
msgid "E604: :catch after :finally"
msgstr "E604: :catch après :finally"
-#: ../ex_eval.c:1451
msgid "E606: :finally without :try"
msgstr "E606: :finally sans :try"
#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
msgid "E607: multiple :finally"
msgstr "E607: Il ne peut y avoir qu'un seul :finally"
-#: ../ex_eval.c:1571
msgid "E602: :endtry without :try"
msgstr "E602: :endtry sans :try"
-#: ../ex_eval.c:2026
msgid "E193: :endfunction not inside a function"
msgstr "E193: :endfunction en dehors d'une fonction"
-#: ../ex_getln.c:1643
msgid "E788: Not allowed to edit another buffer now"
msgstr "E788: L'édition d'un autre tampon n'est plus permise"
-#: ../ex_getln.c:1656
msgid "E811: Not allowed to change buffer information now"
msgstr ""
"E811: Changement des informations du tampon n'est pas permise maintenant"
# DB - TODO : Pas compris le message ni comment le déclencher malgré une visite
# dans le code.
-#: ../ex_getln.c:3178
msgid "tagname"
msgstr "nom du marqueur"
# DB - TODO : Idem précédent.
-#: ../ex_getln.c:3181
msgid " kind file\n"
msgstr " type de fichier\n"
-#: ../ex_getln.c:4799
msgid "'history' option is zero"
msgstr "l'option 'history' vaut zéro"
# DB - Messages et les suivants : fichier .viminfo.
# Pas de majuscule nécessaire pour les messages d'après.
-#: ../ex_getln.c:5046
#, c-format
msgid ""
"\n"
@@ -2161,311 +1800,232 @@ msgstr ""
"\n"
"# Historique %s (chronologie décroissante) :\n"
-#: ../ex_getln.c:5047
msgid "Command Line"
msgstr "ligne de commande"
-#: ../ex_getln.c:5048
msgid "Search String"
msgstr "chaîne de recherche"
-#: ../ex_getln.c:5049
msgid "Expression"
msgstr "expression"
-#: ../ex_getln.c:5050
msgid "Input Line"
msgstr "ligne de saisie"
-#: ../ex_getln.c:5117
+msgid "Debug Line"
+msgstr "Ligne de débogage"
+
msgid "E198: cmd_pchar beyond the command length"
msgstr "E198: cmd_pchar au-delà de la longueur de la commande"
-#: ../ex_getln.c:5279
msgid "E199: Active window or buffer deleted"
msgstr "E199: Fenêtre ou tampon actif effacé"
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr "E854: chemin trop long pour complètement"
-
-#: ../file_search.c:446
-#, c-format
-msgid ""
-"E343: Invalid path: '**[number]' must be at the end of the path or be "
-"followed by '%s'."
-msgstr ""
-"E343: Chemin invalide : '**[nombre]' doit être à la fin du chemin ou être "
-"suivi de '%s'."
-
-#: ../file_search.c:1505
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: Répertoire \"%s\" introuvable dans 'cdpath'"
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: Fichier \"%s\" introuvable dans 'path'"
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: Plus de répertoire \"%s\" dans 'cdpath'"
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: Plus de fichier \"%s\" dans 'path'"
-
-#: ../fileio.c:137
msgid "E812: Autocommands changed buffer or buffer name"
msgstr "E812: Des autocommandes ont changé le tampon ou le nom du tampon"
-#: ../fileio.c:368
msgid "Illegal file name"
msgstr "Nom de fichier invalide"
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
msgid "is a directory"
msgstr "est un répertoire"
-#: ../fileio.c:397
msgid "is not a file"
msgstr "n'est pas un fichier"
-#: ../fileio.c:508 ../fileio.c:3522
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "est un périphérique (désactivé par l'option 'opendevice')"
+
msgid "[New File]"
msgstr "[Nouveau fichier]"
-#: ../fileio.c:511
msgid "[New DIRECTORY]"
msgstr "[Nouveau RÉPERTOIRE]"
-#: ../fileio.c:529 ../fileio.c:532
msgid "[File too big]"
msgstr "[Fichier trop volumineux]"
-#: ../fileio.c:534
msgid "[Permission Denied]"
msgstr "[Permission refusée]"
-#: ../fileio.c:653
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr "E200: Les autocommandes *ReadPre ont rendu le fichier illisible"
-#: ../fileio.c:655
msgid "E201: *ReadPre autocommands must not change current buffer"
msgstr ""
"E201: Autocommandes *ReadPre ne doivent pas modifier le contenu du tampon "
"courant"
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
+msgid "Vim: Reading from stdin...\n"
msgstr "Vim : Lecture de stdin...\n"
+msgid "Reading from stdin..."
+msgstr "Lecture de stdin..."
+
#. Re-opening the original file failed!
-#: ../fileio.c:909
msgid "E202: Conversion made file unreadable!"
msgstr "E202: La conversion a rendu le fichier illisible !"
-#. fifo or socket
-#: ../fileio.c:1782
msgid "[fifo/socket]"
msgstr "[fifo/socket]"
-#. fifo
-#: ../fileio.c:1788
msgid "[fifo]"
msgstr "[fifo]"
-#. or socket
-#: ../fileio.c:1794
msgid "[socket]"
msgstr "[socket]"
-#. or character special
-#: ../fileio.c:1801
msgid "[character special]"
msgstr "[caractère spécial]"
-#: ../fileio.c:1815
msgid "[CR missing]"
msgstr "[CR manquant]"
-#: ../fileio.c:1819
msgid "[long lines split]"
msgstr "[lignes longues coupées]"
-#: ../fileio.c:1823 ../fileio.c:3512
msgid "[NOT converted]"
msgstr "[NON converti]"
-#: ../fileio.c:1826 ../fileio.c:3515
msgid "[converted]"
msgstr "[converti]"
-#: ../fileio.c:1831
#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[ERREUR DE CONVERSION à la ligne %<PRId64>]"
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[ERREUR DE CONVERSION à la ligne %ld]"
-#: ../fileio.c:1835
#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[OCTET INVALIDE à la ligne %<PRId64>]"
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[OCTET INVALIDE à la ligne %ld]"
-#: ../fileio.c:1838
msgid "[READ ERRORS]"
msgstr "[ERREURS DE LECTURE]"
-#: ../fileio.c:2104
msgid "Can't find temp file for conversion"
msgstr "Impossible de générer un fichier temporaire pour la conversion"
-#: ../fileio.c:2110
msgid "Conversion with 'charconvert' failed"
msgstr "La conversion avec 'charconvert' a échoué"
# DB : Pas de majuscule ?
-#: ../fileio.c:2113
msgid "can't read output of 'charconvert'"
msgstr "Impossible de lire la sortie de 'charconvert'"
-#: ../fileio.c:2437
msgid "E676: No matching autocommands for acwrite buffer"
msgstr "E676: Pas d'autocommande correspondante pour le tampon acwrite"
-#: ../fileio.c:2466
msgid "E203: Autocommands deleted or unloaded buffer to be written"
msgstr "E203: Des autocommandes ont effacé ou déchargé le tampon à écrire"
-#: ../fileio.c:2486
msgid "E204: Autocommand changed number of lines in unexpected way"
msgstr ""
"E204: L'autocommande a modifié le nombre de lignes de manière inattendue"
-#: ../fileio.c:2548 ../fileio.c:2565
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans interdit l'écriture des tampons non modifiés"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Netbeans interdit l'écriture partielle de ses tampons"
+
msgid "is not a file or writable device"
msgstr "n'est pas un fichier ou un périphérique inscriptible"
-#: ../fileio.c:2601
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "écriture vers un périphérique désactivé par l'option 'opendevice'"
+
msgid "is read-only (add ! to override)"
msgstr "est en lecture seule (ajoutez ! pour passer outre)"
-#: ../fileio.c:2886
msgid "E506: Can't write to backup file (add ! to override)"
msgstr "E506: Impossible d'écrire la copie de secours (! pour passer outre)"
-#: ../fileio.c:2898
msgid "E507: Close error for backup file (add ! to override)"
msgstr "E507: Erreur de fermeture de la copie de secours (! pour passer outre)"
-#: ../fileio.c:2901
msgid "E508: Can't read file for backup (add ! to override)"
msgstr ""
"E508: Impossible de lire le fichier pour la copie de secours (ajoutez ! pour "
"passer outre)"
-#: ../fileio.c:2923
msgid "E509: Cannot create backup file (add ! to override)"
msgstr ""
"E509: Impossible de créer la copie de secours (ajoutez ! pour passer outre)"
-#: ../fileio.c:3008
msgid "E510: Can't make backup file (add ! to override)"
msgstr ""
"E510: Impossible de générer la copie de secours (ajoutez ! pour passer outre)"
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
+msgid "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"
-#: ../fileio.c:3134
msgid "E213: Cannot convert (add ! to write without conversion)"
msgstr "E213: Impossible de convertir (ajoutez ! pour écrire sans convertir)"
-#: ../fileio.c:3169
msgid "E166: Can't open linked file for writing"
msgstr "E166: Impossible d'ouvrir le lien pour y écrire"
-#: ../fileio.c:3173
msgid "E212: Can't open file for writing"
msgstr "E212: Impossible d'ouvrir le fichier pour y écrire"
-#: ../fileio.c:3363
msgid "E667: Fsync failed"
msgstr "E667: Fsynch a échoué"
-#: ../fileio.c:3398
msgid "E512: Close failed"
msgstr "E512: Erreur de fermeture de fichier"
-#: ../fileio.c:3436
msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
msgstr ""
"E513: Erreur d'écriture, échec de conversion (videz 'fenc' pour passer outre)"
-#: ../fileio.c:3441
#, c-format
msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
"override)"
msgstr ""
-"E513: Erreur d'écriture, échec de conversion à la ligne %<PRId64> (videz "
-"'fenc' pour passer outre)"
+"E513: Erreur d'écriture, échec de conversion à la ligne %ld (videz 'fenc' "
+"pour passer outre)"
-#: ../fileio.c:3448
msgid "E514: write error (file system full?)"
msgstr "E514: erreur d'écriture (système de fichiers plein ?)"
-#: ../fileio.c:3506
msgid " CONVERSION ERROR"
msgstr " ERREUR DE CONVERSION"
-#: ../fileio.c:3509
#, c-format
-msgid " in line %<PRId64>;"
-msgstr " à la ligne %<PRId64>"
+msgid " in line %ld;"
+msgstr " à la ligne %ld"
-#: ../fileio.c:3519
msgid "[Device]"
msgstr "[Périph.]"
-#: ../fileio.c:3522
msgid "[New]"
msgstr "[Nouveau]"
-#: ../fileio.c:3535
msgid " [a]"
msgstr " [a]"
-#: ../fileio.c:3535
msgid " appended"
msgstr " ajouté(s)"
-#: ../fileio.c:3537
msgid " [w]"
msgstr " [e]"
-#: ../fileio.c:3537
msgid " written"
msgstr " écrit(s)"
-#: ../fileio.c:3579
msgid "E205: Patchmode: can't save original file"
msgstr "E205: Patchmode : impossible d'enregistrer le fichier original"
-#: ../fileio.c:3602
msgid "E206: patchmode: can't touch empty original file"
msgstr "E206: patchmode : impossible de créer le fichier original vide"
-#: ../fileio.c:3616
msgid "E207: Can't delete backup file"
msgstr "E207: Impossible d'effacer la copie de secours"
-#: ../fileio.c:3672
msgid ""
"\n"
"WARNING: Original file may be lost or damaged\n"
@@ -2474,99 +2034,78 @@ msgstr ""
"ALERTE: Le fichier original est peut-être perdu ou endommagé\n"
# DB - todo : un peu long...
-#: ../fileio.c:3675
msgid "don't quit the editor until the file is successfully written!"
msgstr ""
"ne quittez pas l'éditeur tant que le fichier n'est pas correctement "
"enregistré !"
-#: ../fileio.c:3795
msgid "[dos]"
msgstr "[dos]"
-#: ../fileio.c:3795
msgid "[dos format]"
msgstr "[format dos]"
-#: ../fileio.c:3801
msgid "[mac]"
msgstr "[mac]"
-#: ../fileio.c:3801
msgid "[mac format]"
msgstr "[format mac]"
-#: ../fileio.c:3807
msgid "[unix]"
msgstr "[unix]"
-#: ../fileio.c:3807
msgid "[unix format]"
msgstr "[format unix]"
-#: ../fileio.c:3831
msgid "1 line, "
msgstr "1 ligne, "
-#: ../fileio.c:3833
#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> lignes, "
+msgid "%ld lines, "
+msgstr "%ld lignes, "
-#: ../fileio.c:3836
msgid "1 character"
msgstr "1 caractère"
-#: ../fileio.c:3838
#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> caractères"
+msgid "%lld characters"
+msgstr "%lld caractères"
-#: ../fileio.c:3849
msgid "[noeol]"
msgstr "[noeol]"
-#: ../fileio.c:3849
msgid "[Incomplete last line]"
msgstr "[Dernière ligne incomplète]"
#. don't overwrite messages here
#. must give this prompt
#. don't use emsg() here, don't want to flush the buffers
-#: ../fileio.c:3865
msgid "WARNING: The file has been changed since reading it!!!"
msgstr "ALERTE : Le fichier a été modifié depuis que Vim l'a lu !"
-#: ../fileio.c:3867
msgid "Do you really want to write to it"
msgstr "Voulez-vous vraiment écrire dedans"
-#: ../fileio.c:4648
#, c-format
msgid "E208: Error writing to \"%s\""
msgstr "E208: Erreur lors de l'écriture dans \"%s\""
-#: ../fileio.c:4655
#, c-format
msgid "E209: Error closing \"%s\""
msgstr "E209: Erreur lors de la fermeture de \"%s\""
-#: ../fileio.c:4657
#, c-format
msgid "E210: Error reading \"%s\""
msgstr "E210: Erreur lors de la lecture de \"%s\""
-#: ../fileio.c:4883
msgid "E246: FileChangedShell autocommand deleted buffer"
msgstr "E246: L'autocommande FileChangedShell a effacé le tampon"
-#: ../fileio.c:4894
#, c-format
msgid "E211: File \"%s\" no longer available"
msgstr "E211: Le fichier \"%s\" n'est plus disponible"
# DB - todo : Suggestion. Bof bof, à améliorer.
-#: ../fileio.c:4906
#, c-format
msgid ""
"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
@@ -2574,40 +2113,32 @@ msgid ""
msgstr ""
"W12: Alerte : Le fichier \"%s\" a été modifié, ainsi que le tampon dans Vim"
-#: ../fileio.c:4907
msgid "See \":help W12\" for more info."
msgstr "Consultez \":help W12\" pour plus d'information."
-#: ../fileio.c:4910
#, c-format
msgid "W11: Warning: File \"%s\" has changed since editing started"
msgstr "W11: Alerte : Le fichier \"%s\" a changé depuis le début de l'édition"
-#: ../fileio.c:4911
msgid "See \":help W11\" for more info."
msgstr "Consultez \":help W11\" pour plus d'information."
-#: ../fileio.c:4914
#, c-format
msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
msgstr ""
"W16: Alerte : Les permissions de \"%s\" ont changé depuis le début de "
"l'édition"
-#: ../fileio.c:4915
msgid "See \":help W16\" for more info."
msgstr "Consultez \":help W16\" pour plus d'information."
-#: ../fileio.c:4927
#, c-format
msgid "W13: Warning: File \"%s\" has been created after editing started"
msgstr "W13: Alerte : Le fichier \"%s\" a été créé après le début de l'édition"
-#: ../fileio.c:4947
msgid "Warning"
msgstr "Alerte"
-#: ../fileio.c:4948
msgid ""
"&OK\n"
"&Load File"
@@ -2615,48 +2146,45 @@ msgstr ""
"&Ok\n"
"&Charger le fichier"
-#: ../fileio.c:5065
#, c-format
msgid "E462: Could not prepare for reloading \"%s\""
msgstr "E462: Impossible de préparer le rechargement de \"%s\""
-#: ../fileio.c:5078
#, c-format
msgid "E321: Could not reload \"%s\""
msgstr "E321: Impossible de recharger \"%s\""
-#: ../fileio.c:5601
msgid "--Deleted--"
msgstr "--Effacé--"
-#: ../fileio.c:5732
#, c-format
msgid "auto-removing autocommand: %s <buffer=%d>"
msgstr "Autocommandes marquées pour auto-suppression : %s <tampon=%d>"
#. the group doesn't exist
-#: ../fileio.c:5772
#, c-format
msgid "E367: No such group: \"%s\""
msgstr "E367: Aucun groupe \"%s\""
-#: ../fileio.c:5897
+msgid "E936: Cannot delete the current group"
+msgstr "E936: Impossible de supprimer le groupe courant"
+
+msgid "W19: Deleting augroup that is still in use"
+msgstr "W19: Effacement d'augroup toujours en usage"
+
#, c-format
msgid "E215: Illegal character after *: %s"
msgstr "E215: Caractère non valide après * : %s"
-#: ../fileio.c:5905
#, c-format
msgid "E216: No such event: %s"
msgstr "E216: Aucun événement %s"
-#: ../fileio.c:5907
#, c-format
msgid "E216: No such group or event: %s"
msgstr "E216: Aucun événement ou groupe %s"
#. Highlight title
-#: ../fileio.c:6090
msgid ""
"\n"
"--- Auto-Commands ---"
@@ -2664,776 +2192,580 @@ msgstr ""
"\n"
"--- Auto-commandes ---"
-#: ../fileio.c:6293
#, c-format
msgid "E680: <buffer=%d>: invalid buffer number "
msgstr "E680: <buffer=%d> : numéro de tampon invalide"
-#: ../fileio.c:6370
msgid "E217: Can't execute autocommands for ALL events"
msgstr ""
"E217: Impossible d'exécuter les autocommandes pour TOUS les événements (ALL)"
-#: ../fileio.c:6393
msgid "No matching autocommands"
msgstr "Aucune autocommande correspondante"
-#: ../fileio.c:6831
msgid "E218: autocommand nesting too deep"
msgstr "E218: autocommandes trop imbriquées"
-#: ../fileio.c:7143
#, c-format
msgid "%s Auto commands for \"%s\""
msgstr "Autocommandes %s pour \"%s\""
-#: ../fileio.c:7149
#, c-format
msgid "Executing %s"
msgstr "Exécution de %s"
-#: ../fileio.c:7211
#, c-format
msgid "autocommand %s"
msgstr "autocommande %s"
-#: ../fileio.c:7795
msgid "E219: Missing {."
msgstr "E219: { manquant."
-#: ../fileio.c:7797
msgid "E220: Missing }."
msgstr "E220: } manquant."
-#: ../fold.c:93
msgid "E490: No fold found"
msgstr "E490: Aucun repli trouvé"
-#: ../fold.c:544
msgid "E350: Cannot create fold with current 'foldmethod'"
msgstr "E350: Impossible de créer un repli avec la 'foldmethod'e actuelle"
-#: ../fold.c:546
msgid "E351: Cannot delete fold with current 'foldmethod'"
msgstr "E351: Impossible de supprimer un repli avec la 'foldmethod'e actuelle"
-#: ../fold.c:1784
#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld lignes repliées "
+msgid "+--%3ld line folded "
+msgid_plural "+--%3ld lines folded "
+msgstr[0] "+--%3ld ligne repliée "
+msgstr[1] "+--%3ld lignes repliées "
-#. buffer has already been read
-#: ../getchar.c:273
msgid "E222: Add to read buffer"
msgstr "E222: Ajout au tampon de lecture"
-#: ../getchar.c:2040
msgid "E223: recursive mapping"
msgstr "E223: mappage récursif"
-#: ../getchar.c:2849
#, c-format
msgid "E224: global abbreviation already exists for %s"
msgstr "E224: une abréviation globale existe déjà pour %s"
-#: ../getchar.c:2852
#, c-format
msgid "E225: global mapping already exists for %s"
msgstr "E225: un mappage global existe déjà pour %s"
-#: ../getchar.c:2952
#, c-format
msgid "E226: abbreviation already exists for %s"
msgstr "E226: une abréviation existe déjà pour %s"
-#: ../getchar.c:2955
#, c-format
msgid "E227: mapping already exists for %s"
msgstr "E227: un mappage existe déjà pour %s"
-#: ../getchar.c:3008
msgid "No abbreviation found"
msgstr "Aucune abréviation trouvée"
-#: ../getchar.c:3010
msgid "No mapping found"
msgstr "Aucun mappage trouvé"
-#: ../getchar.c:3974
msgid "E228: makemap: Illegal mode"
msgstr "E228: makemap : mode invalide"
-# msgstr "--Pas de lignes dans le tampon--"
-# DB - todo : ou encore : msgstr "--Aucune ligne dans le tampon--"
-#. key value of 'cedit' option
-#. type of cmdline window or 0
-#. result of cmdline window or 0
-#: ../globals.h:924
-msgid "--No lines in buffer--"
-msgstr "--Le tampon est vide--"
-
-#.
-#. * The error messages that can be shared are included here.
-#. * Excluded are errors that are only used once and debugging messages.
-#.
-#: ../globals.h:996
-msgid "E470: Command aborted"
-msgstr "E470: Commande annulée"
-
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: Argument requis"
-
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: \\ devrait être suivi de /, ? ou &"
-
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgid "E851: Failed to create a new process for the GUI"
msgstr ""
-"E11: Invalide dans la fenêtre ligne-de-commande ; <CR> exécute, CTRL-C quitte"
+"E851: Échec lors de la création d'un nouveau processus pour l'interface "
+"graphique"
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgid "E852: The child process failed to start the GUI"
msgstr ""
-"E12: commande non autorisée depuis un exrc/vimrc dans répertoire courant ou "
-"une recherche de marqueur"
-
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: :endif manquant"
+"E852: Le processus fils n'a pas réussi à démarrer l'interface graphique"
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: :endtry manquant"
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Impossible de démarrer l'interface graphique"
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: :endwhile manquant"
-
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: :endfor manquant"
-
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: :endwhile sans :while"
-
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: :endfor sans :for"
-
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: Le fichier existe déjà (ajoutez ! pour passer outre)"
-
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: La commande a échoué"
-
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: Erreur interne"
-
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "Interrompu"
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Impossible de lire \"%s\""
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: Adresse invalide"
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr ""
+"E665: Impossible de démarrer l'IHM graphique, aucune police valide trouvée"
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: Argument invalide"
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' est invalide"
-#: ../globals.h:1015
-#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: Argument invalide : %s"
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Valeur de 'imactivatekey' invalide"
-#: ../globals.h:1016
#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: Expression invalide : %s"
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Impossible d'allouer la couleur %s"
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: Plage invalide"
+msgid "No match at cursor, finding next"
+msgstr "Aucune correspondance sous le curseur, recherche de la suivante"
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: Commande invalide"
+msgid "<cannot open> "
+msgstr "<impossible d'ouvrir> "
-#: ../globals.h:1019
#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: \"%s\" est un répertoire"
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile : impossible d'obtenir la police %s"
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: Valeur de défilement invalide"
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile : impossible de revenir dans le répertoire courant"
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
+msgid "Pathname:"
+msgstr "Chemin :"
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: L'appel à la bibliothèque a échoué pour \"%s()\""
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile : impossible d'obtenir le répertoire courant"
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: La marque a un numéro de ligne invalide"
+msgid "OK"
+msgstr "Ok"
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: Marque non positionnée"
+msgid "Cancel"
+msgstr "Annuler"
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: Impossible de modifier, 'modifiable' est désactivé"
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Widget scrollbar : Impossible d'obtenir la géométrie du pixmap 'thumb'"
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: Trop de récursion dans les scripts"
+msgid "Vim dialog"
+msgstr "Vim"
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: Pas de fichier alternatif"
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: Impossible de créer un BalloonEval avec message ET callback"
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: Cette abréviation n'existe pas"
+msgid "_Cancel"
+msgstr "_Annuler"
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: Le ! n'est pas autorisé"
+msgid "_Save"
+msgstr "_Enregistrer"
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: L'interface graphique n'a pas été compilée dans cette version"
+msgid "_Open"
+msgstr "_Ouvrir"
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: Aucun nom de groupe de surbrillance %s"
+msgid "_OK"
+msgstr "_Ok"
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: Pas encore de texte inséré"
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Oui\n"
+"&Non\n"
+"&Annuler"
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: Aucune ligne de commande précédente"
+msgid "Yes"
+msgstr "Oui"
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: Mappage inexistant"
+msgid "No"
+msgstr "Non"
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: Aucune correspondance"
+# todo '_' is for hotkey, i guess?
+msgid "Input _Methods"
+msgstr "_Méthodes de saisie"
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: Aucune correspondance : %s"
+msgid "VIM - Search and Replace..."
+msgstr "Remplacer - Vim"
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: Aucun nom de fichier"
+msgid "VIM - Search..."
+msgstr "Rechercher - Vim"
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: Aucune expression régulière de substitution précédente"
+msgid "Find what:"
+msgstr "Rechercher :"
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: Aucune commande précédente"
+msgid "Replace with:"
+msgstr "Remplacer par :"
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: Aucune expression régulière précédente"
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Mots entiers seulement"
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: Les plages ne sont pas autorisées"
+#. match case button
+msgid "Match case"
+msgstr "Respecter la casse"
-#: ../globals.h:1048
-msgid "E36: Not enough room"
-msgstr "E36: Pas assez de place"
+msgid "Direction"
+msgstr "Direction"
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: Impossible de créer le fichier %s"
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Haut"
-#: ../globals.h:1050
-msgid "E483: Can't get temp file name"
-msgstr "E483: Impossible d'obtenir un nom de fichier temporaire"
+msgid "Down"
+msgstr "Bas"
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: Impossible d'ouvrir le fichier \"%s\""
+msgid "Find Next"
+msgstr "Suivant"
-#: ../globals.h:1052
-#, c-format
-msgid "E485: Can't read file %s"
-msgstr "E485: Impossible de lire le fichier %s"
+msgid "Replace"
+msgstr "Remplacer"
-#: ../globals.h:1054
-msgid "E37: No write since last change (add ! to override)"
-msgstr "E37: Modifications non enregistrées (ajoutez ! pour passer outre)"
+msgid "Replace All"
+msgstr "Remplacer tout"
-# AB - Il faut respecter l'esprit plus que la lettre. Dans le cas présent,
-# nettement plus.
-#: ../globals.h:1055
-#, fuzzy
-msgid "E37: No write since last change"
-msgstr "[Attention : tout n'est pas enregistré]\n"
+msgid "_Close"
+msgstr "_Fermer"
-#: ../globals.h:1056
-msgid "E38: Null argument"
-msgstr "E38: Argument null"
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim : Une requête \"die\" a été reçue par le gestionnaire de session\n"
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: Nombre attendu"
+msgid "Close tab"
+msgstr "Fermer l'onglet"
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: Impossible d'ouvrir le fichier d'erreurs %s"
+msgid "New tab"
+msgstr "Nouvel onglet"
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: Mémoire épuisée"
+# DB - todo : un peu long. Cet entrée de menu permet d'ouvrir un fichier
+# dans un nouvel onglet via le sélecteur de fichiers graphique.
+msgid "Open Tab..."
+msgstr "Ouvrir dans un onglet..."
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "Motif introuvable"
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim : Fenêtre principale détruite inopinément\n"
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: Motif introuvable : %s"
+msgid "&Filter"
+msgstr "&Filtrer"
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: L'argument doit être positif"
+msgid "&Cancel"
+msgstr "&Annuler"
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: Impossible de retourner au répertoire précédent"
+msgid "Directories"
+msgstr "Répertoires"
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: Aucune erreur"
+msgid "Filter"
+msgstr "Filtre"
-# DB - TODO : trouver une traduction valable et attestée pour "location".
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: Aucune liste d'emplacements"
+msgid "&Help"
+msgstr "&Aide"
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: La chaîne de recherche est endommagée"
+msgid "Files"
+msgstr "Fichiers"
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: L'automate de regexp est corrompu"
+msgid "&OK"
+msgstr "&Ok"
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: L'option 'readonly' est activée (ajoutez ! pour passer outre)"
+msgid "Selection"
+msgstr "Sélection"
-#: ../globals.h:1073
-#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: La variable \"%s\" est en lecture seule"
+msgid "Find &Next"
+msgstr "Suiva&nt"
-#: ../globals.h:1075
-#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr ""
-"E794: Impossible de modifier une variable depuis le bac à sable : \"%s\""
+msgid "&Replace"
+msgstr "&Remplacer"
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: Erreur lors de la lecture du fichier d'erreurs"
+msgid "Replace &All"
+msgstr "Rempl&acer tout"
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: Opération interdite dans le bac à sable"
+msgid "&Undo"
+msgstr "Ann&uler"
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: Interdit à cet endroit"
+msgid "Open tab..."
+msgstr "Ouvrir dans un onglet..."
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: Choix du mode d'écran non supporté"
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Chercher une chaîne (utilisez '\\\\' pour chercher un '\\')"
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: Valeur de défilement invalide"
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Chercher et remplacer (utilisez '\\\\' pour trouver un '\\')"
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: L'option 'shell' est vide"
+# DB - Traduction non indispensable puisque le code indique qu'il s'agit d'un
+# paramétrage bidon afin de sélectionner un répertoire plutôt qu'un
+# fichier.
+#. 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é"
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: Impossible de lire les données du symbole !"
+# DB - Traduction non indispensable puisque le code indique qu'il s'agit d'un
+# paramétrage bidon afin de sélectionner un répertoire plutôt qu'un
+# fichier.
+msgid "Directory\t*.nothing\n"
+msgstr "Répertoire\t*.rien\n"
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: Erreur lors de la fermeture du fichier d'échange"
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Titre de fenêtre \"%s\" introuvable"
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: La pile des marqueurs est vide"
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Argument non supporté : \"-%s\" ; Utilisez la version OLE."
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: Commande trop complexe"
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Impossible d'ouvrir une fenêtre dans une application MDI"
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: Nom trop long"
+# DB - todo : perfectible.
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: Erreur d'allocation de couleurs, couleurs possiblement incorrectes"
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: Trop de ["
+# DB - todo : La VF est-elle compréhensible ?
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr ""
+"E250: Des polices manquent dans %s pour les jeux de caractères suivants :"
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: Trop de noms de fichiers"
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Nom du jeu de polices : %s"
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: Caractères surnuméraires"
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "La police '%s' n'a pas une largeur fixe"
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: Marque inconnue"
+#, c-format
+msgid "E253: Fontset name: %s"
+msgstr "E253: Nom du jeu de polices : %s"
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: Impossible de développer les métacaractères"
+#, c-format
+msgid "Font0: %s"
+msgstr "Font0: %s"
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: 'winheight' ne peut pas être plus petit que 'winminheight'"
+#, c-format
+msgid "Font1: %s"
+msgstr "Font1: %s"
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: 'winwidth' ne peut pas être plus petit que 'winminwidth'"
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "La largeur de Font%ld n'est pas le double de celle de Font0"
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: Erreur lors de l'écriture"
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "Largeur de Font0 : %ld"
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "Le quantificateur est nul"
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "Largeur de Font1 : %ld"
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: <SID> utilisé en dehors d'un script"
+# DB - todo : Pas certain de mon coup, ici...
+msgid "Invalid font specification"
+msgstr "La spécification de la police est invalide"
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: Erreur interne : %s"
+msgid "&Dismiss"
+msgstr "Aban&donner"
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: le motif utilise plus de mémoire que 'maxmempattern'"
+# DB - todo : Pas certain de mon coup, ici...
+msgid "no specific match"
+msgstr "aucune correspondance particulière"
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: tampon vide"
+msgid "Vim - Font Selector"
+msgstr "Choisir une police - Vim"
-#: ../buffer.c:1587
-#, c-format
-msgid "E86: Buffer %<PRId64> does not exist"
-msgstr "E86: Le tampon %<PRId64> n'existe pas"
+msgid "Name:"
+msgstr "Nom :"
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: Délimiteur ou motif de recherche invalide"
+#. create toggle button
+msgid "Show size in Points"
+msgstr "Afficher la taille en Points"
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: Le fichier est chargé dans un autre tampon"
+msgid "Encoding:"
+msgstr "Encodage :"
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: L'option '%s' n'est pas activée"
+msgid "Font:"
+msgstr "Police :"
-#: ../globals.h:1111
-msgid "E850: Invalid register name"
-msgstr "E850: Nom de registre invalide"
+msgid "Style:"
+msgstr "Style :"
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "La recherche a atteint le HAUT, et continue en BAS"
+msgid "Size:"
+msgstr "Taille :"
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "La recherche a atteint le BAS, et continue en HAUT"
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: ERREUR dans l'automate Hangul"
-#: ../hardcopy.c:240
msgid "E550: Missing colon"
msgstr "E550: ':' manquant"
# DB - Il s'agit ici d'un problème lors du parsing d'une option dont le contenu
# est une liste d'éléments séparés par des virgules.
-#: ../hardcopy.c:252
msgid "E551: Illegal component"
msgstr "E551: élément invalide"
-#: ../hardcopy.c:259
msgid "E552: digit expected"
msgstr "E552: chiffre attendu"
-#: ../hardcopy.c:473
#, c-format
msgid "Page %d"
msgstr "Page %d"
-#: ../hardcopy.c:597
msgid "No text to be printed"
msgstr "Aucun texte à imprimer"
-#: ../hardcopy.c:668
#, c-format
msgid "Printing page %d (%d%%)"
msgstr "Impression de la page %d (%d%%)"
-#: ../hardcopy.c:680
#, c-format
msgid " Copy %d of %d"
msgstr " Copie %d sur %d"
-#: ../hardcopy.c:733
#, c-format
msgid "Printed: %s"
msgstr "Imprimé : %s"
-#: ../hardcopy.c:740
msgid "Printing aborted"
msgstr "Impression interrompue"
-#: ../hardcopy.c:1365
msgid "E455: Error writing to PostScript output file"
msgstr "E455: Erreur lors de l'écriture du fichier PostScript"
-#: ../hardcopy.c:1747
#, c-format
msgid "E624: Can't open file \"%s\""
msgstr "E624: Impossible d'ouvrir le fichier \"%s\""
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
#, c-format
msgid "E457: Can't read PostScript resource file \"%s\""
msgstr "E457: Impossible de lire le fichier de ressource PostScript \"%s\""
-#: ../hardcopy.c:1772
#, c-format
msgid "E618: file \"%s\" is not a PostScript resource file"
msgstr "E618: \"%s\" n'est pas un fichier de ressource PostScript"
-#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844
#, c-format
msgid "E619: file \"%s\" is not a supported PostScript resource file"
msgstr "E619: \"%s\" n'est pas un fichier de ressource PostScript supporté"
-#: ../hardcopy.c:1856
#, c-format
msgid "E621: \"%s\" resource file has wrong version"
msgstr "E621: La version du fichier de ressource \"%s\" est erronée"
-#: ../hardcopy.c:2225
msgid "E673: Incompatible multi-byte encoding and character set."
msgstr "E673: Jeu de caractères et encodage multi-octets incompatibles"
-#: ../hardcopy.c:2238
msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
msgstr ""
"E674: 'printmbcharset' ne peut pas être vide avec un encodage multi-octets"
-#: ../hardcopy.c:2254
msgid "E675: No default font specified for multi-byte printing."
msgstr "E675: Aucune police par défaut pour l'impression multi-octets"
-#: ../hardcopy.c:2426
msgid "E324: Can't open PostScript output file"
msgstr "E324: Impossible d'ouvrir le fichier PostScript de sortie"
-#: ../hardcopy.c:2458
#, c-format
msgid "E456: Can't open file \"%s\""
msgstr "E456: Impossible d'ouvrir le fichier \"%s\""
-#: ../hardcopy.c:2583
msgid "E456: Can't find PostScript resource file \"prolog.ps\""
msgstr "E456: Le fichier de ressource PostScript \"prolog.ps\" est introuvable"
-#: ../hardcopy.c:2593
msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
msgstr ""
"E456: Le fichier de ressource PostScript \"cidfont.ps\" est introuvable"
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
#, c-format
msgid "E456: Can't find PostScript resource file \"%s.ps\""
msgstr "E456: Le fichier de ressource PostScript \"%s.ps\" est introuvable"
-#: ../hardcopy.c:2654
#, c-format
msgid "E620: Unable to convert to print encoding \"%s\""
msgstr "E620: La conversion pour imprimer dans l'encodage \"%s\" a échoué"
-#: ../hardcopy.c:2877
msgid "Sending to printer..."
msgstr "Envoi à l'imprimante..."
-#: ../hardcopy.c:2881
msgid "E365: Failed to print PostScript file"
msgstr "E365: L'impression du fichier PostScript a échoué"
-#: ../hardcopy.c:2883
msgid "Print job sent."
msgstr "Tâche d'impression envoyée."
-#: ../if_cscope.c:85
msgid "Add a new database"
msgstr "Ajouter une base de données"
-#: ../if_cscope.c:87
msgid "Query for a pattern"
msgstr "Rechercher un motif"
-#: ../if_cscope.c:89
msgid "Show this message"
msgstr "Afficher ce message"
-#: ../if_cscope.c:91
msgid "Kill a connection"
msgstr "Fermer une connexion"
-#: ../if_cscope.c:93
msgid "Reinit all connections"
msgstr "Réinitialiser toutes les connexions"
-#: ../if_cscope.c:95
msgid "Show connections"
msgstr "Afficher les connexions"
-#: ../if_cscope.c:101
#, c-format
msgid "E560: Usage: cs[cope] %s"
msgstr "E560: Utilisation : cs[cope] %s"
-#: ../if_cscope.c:225
msgid "This cscope command does not support splitting the window.\n"
msgstr "Cette commande cscope ne supporte pas le partage de la fenêtre.\n"
-#: ../if_cscope.c:266
msgid "E562: Usage: cstag <ident>"
msgstr "E562: Utilisation : cstag <ident>"
-#: ../if_cscope.c:313
msgid "E257: cstag: tag not found"
msgstr "E257: cstag : marqueur introuvable"
-#: ../if_cscope.c:461
#, c-format
msgid "E563: stat(%s) error: %d"
msgstr "E563: Erreur stat(%s) : %d"
-#: ../if_cscope.c:551
+msgid "E563: stat error"
+msgstr "E563: Erreur stat"
+
#, c-format
msgid "E564: %s is not a directory or a valid cscope database"
msgstr "E564: %s n'est pas un répertoire ou une base de données cscope valide"
-#: ../if_cscope.c:566
#, c-format
msgid "Added cscope database %s"
msgstr "Base de données cscope %s ajoutée"
-#: ../if_cscope.c:616
#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: erreur lors de la lecture de la connexion cscope %<PRId64>"
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: erreur lors de la lecture de la connexion cscope %ld"
-#: ../if_cscope.c:711
msgid "E561: unknown cscope search type"
msgstr "E561: type de recherche cscope inconnu"
-#: ../if_cscope.c:752 ../if_cscope.c:789
msgid "E566: Could not create cscope pipes"
msgstr "E566: Impossible de créer les tuyaux (pipes) cscope"
-#: ../if_cscope.c:767
msgid "E622: Could not fork for cscope"
msgstr "E622: Impossible de forker pour cscope"
-#: ../if_cscope.c:849
-#, fuzzy
msgid "cs_create_connection setpgid failed"
-msgstr "exec de cs_create_connection a échoué"
+msgstr "cs_create_connection setpgid a échoué"
-#: ../if_cscope.c:853 ../if_cscope.c:889
msgid "cs_create_connection exec failed"
msgstr "exec de cs_create_connection a échoué"
-#: ../if_cscope.c:863 ../if_cscope.c:902
msgid "cs_create_connection: fdopen for to_fp failed"
msgstr "cs_create_connection : fdopen pour to_fp a échoué"
-#: ../if_cscope.c:865 ../if_cscope.c:906
msgid "cs_create_connection: fdopen for fr_fp failed"
msgstr "cs_create_connection : fdopen pour fr_fp a échoué"
-#: ../if_cscope.c:890
msgid "E623: Could not spawn cscope process"
msgstr "E623: Impossible d'engendrer le processus cscope"
-#: ../if_cscope.c:932
msgid "E567: no cscope connections"
msgstr "E567: Aucune connexion cscope"
-#: ../if_cscope.c:1009
#, c-format
msgid "E469: invalid cscopequickfix flag %c for %c"
msgstr "E469: Drapeau cscopequickfix %c invalide pour %c"
# DB - todo
-#: ../if_cscope.c:1058
#, c-format
msgid "E259: no matches found for cscope query %s of %s"
msgstr "E259: aucune correspondance trouvée pour la requête cscope %s de %s"
-#: ../if_cscope.c:1142
msgid "cscope commands:\n"
msgstr "commandes cscope :\n"
-#: ../if_cscope.c:1150
#, c-format
msgid "%-5s: %s%*s (Usage: %s)"
msgstr "%-5s: %s%*s (Utilisation : %s)"
-#: ../if_cscope.c:1155
msgid ""
"\n"
+" a: Find assignments to this symbol\n"
" c: Find functions calling this function\n"
" d: Find functions called by this function\n"
" e: Find this egrep pattern\n"
@@ -3444,6 +2776,7 @@ msgid ""
" t: Find this text string\n"
msgstr ""
"\n"
+" a: Trouver les affectations à ce symbole\n"
" c: Trouver les fonctions appelant cette fonction\n"
" d: Trouver les fonctions appelées par cette fonction\n"
" e: Trouver ce motif egrep\n"
@@ -3453,31 +2786,33 @@ msgstr ""
" s: Trouver ce symbole C\n"
" t: Trouver cette chaîne\n"
-#: ../if_cscope.c:1226
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: impossible d'ouvrir la base de données cscope %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr ""
+"E626: impossible d'obtenir des informations sur la base de données cscope"
+
msgid "E568: duplicate cscope database not added"
msgstr "E568: base de données cscope redondante non ajoutée"
-#: ../if_cscope.c:1335
#, c-format
msgid "E261: cscope connection %s not found"
msgstr "E261: Connexion cscope %s introuvable"
-#: ../if_cscope.c:1364
#, c-format
msgid "cscope connection %s closed"
msgstr "connexion cscope %s fermée"
#. should not reach here
-#: ../if_cscope.c:1486
msgid "E570: fatal error in cs_manage_matches"
msgstr "E570: erreur fatale dans cs_manage_matches"
-#: ../if_cscope.c:1693
#, c-format
msgid "Cscope tag: %s"
msgstr "Marqueur cscope : %s"
-#: ../if_cscope.c:1711
msgid ""
"\n"
" # line"
@@ -3486,87 +2821,307 @@ msgstr ""
" # ligne"
# DB - todo : Faut-il respecter l'alignement ici ?
-#: ../if_cscope.c:1713
msgid "filename / context / line\n"
msgstr "nom / contexte/ ligne\n"
-#: ../if_cscope.c:1809
#, c-format
msgid "E609: Cscope error: %s"
msgstr "E609: Erreur cscope : %s"
-#: ../if_cscope.c:2053
msgid "All cscope databases reset"
msgstr "Toutes les bases de données cscope ont été réinitialisées"
-#: ../if_cscope.c:2123
msgid "no cscope connections\n"
msgstr "aucune connexion cscope\n"
-#: ../if_cscope.c:2126
msgid " # pid database name prepend path\n"
msgstr " # pid nom de la base de données chemin\n"
-#: ../main.c:144
+msgid "Lua library cannot be loaded."
+msgstr "La bibliothèque Lua n'a pas pu être chargée."
+
+msgid "cannot save undo information"
+msgstr "impossible d'enregistrer les informations d'annulation"
+
+msgid ""
+"E815: Sorry, this command is disabled, the MzScheme libraries could not be "
+"loaded."
+msgstr ""
+"E815: Désolé, cette commande est désactivée : les bibliothèques MzScheme "
+"n'ont pas pu être chargées."
+
+msgid ""
+"E895: Sorry, this command is disabled, the MzScheme's racket/base module "
+"could not be loaded."
+msgstr ""
+"E895: Désolé, cette commande est désactivée : le module MzScheme racket/base "
+"ne peut pas être chargé."
+
+msgid "invalid expression"
+msgstr "expression invalide"
+
+msgid "expressions disabled at compile time"
+msgstr "expressions désactivées lors de la compilation"
+
+msgid "hidden option"
+msgstr "option cachée"
+
+msgid "unknown option"
+msgstr "option inconnue"
+
+msgid "window index is out of range"
+msgstr "numéro de fenêtre hors limites"
+
+msgid "couldn't open buffer"
+msgstr "impossible d'ouvrir le tampon"
+
+msgid "cannot delete line"
+msgstr "impossible d'effacer la ligne"
+
+msgid "cannot replace line"
+msgstr "impossible de remplacer la ligne"
+
+msgid "cannot insert line"
+msgstr "impossible d'insérer la ligne"
+
+msgid "string cannot contain newlines"
+msgstr "une chaîne ne peut pas contenir de saut-de-ligne"
+
+msgid "error converting Scheme values to Vim"
+msgstr "erreur lors de la conversion d'une valeur de Scheme à Vim"
+
+msgid "Vim error: ~a"
+msgstr "Erreur Vim : ~a"
+
+msgid "Vim error"
+msgstr "Erreur Vim"
+
+msgid "buffer is invalid"
+msgstr "tampon invalide"
+
+msgid "window is invalid"
+msgstr "fenêtre invalide"
+
+msgid "linenr out of range"
+msgstr "numéro de ligne hors limites"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "non autorisé dans le bac à sable"
+
+msgid "E836: This Vim cannot execute :python after using :py3"
+msgstr "E836: Vim ne peut pas exécuter :python après avoir utilisé :py3"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: Désolé, commande désactivée : la bibliothèque Python n'a pas pu être "
+"chargée."
+
+msgid ""
+"E887: Sorry, this command is disabled, the Python's site module could not be "
+"loaded."
+msgstr ""
+"E887: Désolé, commande désactivée : la bibliothèque Python n'a pas pu être "
+"chargée."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Impossible d'invoquer Python récursivement"
+
+msgid "E837: This Vim cannot execute :py3 after using :python"
+msgstr "E837: Vim ne peut pas exécuter :py3 après avoir utilisé :python"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: $_ doit être une instance de chaîne (String)"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: Désolé, commande désactivée : la bibliothèque Ruby n'a pas pu être "
+"chargée."
+
+msgid "E267: unexpected return"
+msgstr "E267: « return » inattendu"
+
+msgid "E268: unexpected next"
+msgstr "E268: « next » inattendu"
+
+msgid "E269: unexpected break"
+msgstr "E269: « break » inattendu"
+
+msgid "E270: unexpected redo"
+msgstr "E270: « redo » inattendu"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: « retry » hors d'une clause « rescue »"
+
+msgid "E272: unhandled exception"
+msgstr "E272: Exception non prise en charge"
+
+# DB - todo
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: contexte de longjmp inconnu : %d"
+
+msgid "invalid buffer number"
+msgstr "numéro de tampon invalide"
+
+msgid "not implemented yet"
+msgstr "pas encore implémenté"
+
+# DB - TODO : le contexte est celui d'une annulation.
+#. ???
+msgid "cannot set line(s)"
+msgstr "Impossible de remettre la/les ligne(s)"
+
+msgid "invalid mark name"
+msgstr "nom de marque invalide"
+
+msgid "mark not set"
+msgstr "marque non positionnée"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "ligne %d colonne %d"
+
+msgid "cannot insert/append line"
+msgstr "Impossible d'insérer/ajouter de lignes"
+
+msgid "line number out of range"
+msgstr "numéro de ligne hors limites"
+
+msgid "unknown flag: "
+msgstr "drapeau inconnu : "
+
+msgid "unknown vimOption"
+msgstr "vimOption inconnue"
+
+msgid "keyboard interrupt"
+msgstr "interruption clavier"
+
+msgid "vim error"
+msgstr "erreur Vim"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr ""
+"Impossible de créer commande de tampon/fenêtre : objet en cours d'effacement"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"Impossible d'inscrire la commande de rappel : tampon/fenêtre en effacement"
+
+#. 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 !"
+
+#, c-format
+msgid "E938: Duplicate key in JSON: \"%s\""
+msgstr "E938: Clé dupliquée dans le document JSON : \"%s\""
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Il manque une virgule dans la Liste %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Il manque ']' à la fin de la Liste %s"
+
msgid "Unknown option argument"
msgstr "Option inconnue"
-#: ../main.c:146
msgid "Too many edit arguments"
msgstr "Trop d'arguments d'édition"
-#: ../main.c:148
msgid "Argument missing after"
msgstr "Argument manquant après"
-#: ../main.c:150
msgid "Garbage after option argument"
msgstr "arguments en trop après l'option"
-#: ../main.c:152
msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
msgstr "Trop d'arguments \"+command\", \"-c command\" ou \"--cmd command\""
-#: ../main.c:154
msgid "Invalid argument for"
msgstr "Argument invalide pour"
-#: ../main.c:294
#, c-format
msgid "%d files to edit\n"
msgstr "%d fichiers à éditer\n"
-#: ../main.c:1342
+msgid "netbeans is not supported with this GUI\n"
+msgstr "netbeans n'est pas supporté avec cette interface graphique\n"
+
+msgid "'-nb' cannot be used: not enabled at compile time\n"
+msgstr "'-nb' ne peut pas être utilisé : désactivé à la compilation\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Ce Vim n'a pas été compilé avec la fonctionnalité diff"
+
msgid "Attempt to open script file again: \""
msgstr "Nouvelle tentative pour ouvrir le script : \""
-#: ../main.c:1350
msgid "Cannot open for reading: \""
msgstr "Impossible d'ouvrir en lecture : \""
-#: ../main.c:1393
msgid "Cannot open for script output: \""
msgstr "Impossible d'ouvrir pour la sortie script : \""
-#: ../main.c:1622
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim : Erreur : Impossible de démarrer gvim depuis NetBeans\n"
+
+msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n"
+msgstr ""
+"Vim : Erreur : Cette version de Vim ne fonctionne pas dans un terminal "
+"Cygwin\n"
+
msgid "Vim: Warning: Output is not to a terminal\n"
msgstr "Vim : Alerte : La sortie ne s'effectue pas sur un terminal\n"
-#: ../main.c:1624
msgid "Vim: Warning: Input is not from a terminal\n"
msgstr "Vim : Alerte : L'entrée ne se fait pas sur un terminal\n"
#. just in case..
-#: ../main.c:1891
msgid "pre-vimrc command line"
msgstr "ligne de commande pre-vimrc"
-#: ../main.c:1964
#, c-format
msgid "E282: Cannot read from \"%s\""
msgstr "E282: Impossible de lire \"%s\""
-#: ../main.c:2149
msgid ""
"\n"
"More info with: \"vim -h\"\n"
@@ -3574,23 +3129,18 @@ msgstr ""
"\n"
"Plus d'info avec : \"vim -h\"\n"
-#: ../main.c:2178
msgid "[file ..] edit specified file(s)"
msgstr "[fichier ...] ouvrir le ou les fichiers spécifiés"
-#: ../main.c:2179
msgid "- read text from stdin"
msgstr "- lire le texte à partir de stdin"
-#: ../main.c:2180
msgid "-t tag edit file where tag is defined"
msgstr "-t marqueur ouvrir le fichier qui contient le marqueur"
-#: ../main.c:2181
msgid "-q [errorfile] edit file with first error"
msgstr "-q [fichErr] ouvrir à l'endroit de la première erreur"
-#: ../main.c:2187
msgid ""
"\n"
"\n"
@@ -3600,11 +3150,9 @@ msgstr ""
"\n"
"utilisation :"
-#: ../main.c:2189
msgid " vim [arguments] "
msgstr " vim [args] "
-#: ../main.c:2193
msgid ""
"\n"
" or:"
@@ -3612,7 +3160,15 @@ msgstr ""
"\n"
" ou :"
-#: ../main.c:2196
+# DB - todo (VMS uniquement).
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"pour lesquels la casse est indifférente (/ pour que le drapeau soit "
+"majuscule)"
+
msgid ""
"\n"
"\n"
@@ -3622,192 +3178,338 @@ msgstr ""
"\n"
"Arguments :\n"
-#: ../main.c:2197
msgid "--\t\t\tOnly file names after this"
msgstr "--\t\tSeuls des noms de fichier sont spécifiés après ceci"
-#: ../main.c:2199
msgid "--literal\t\tDon't expand wildcards"
msgstr "--literal\tNe pas développer les métacaractères"
-#: ../main.c:2201
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\tInscrire ce gvim pour OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\tDésinscrire gvim de OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\tLancer l'interface graphique (comme \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr ""
+"-f, --nofork\tPremier-plan : ne pas détacher l'interface graphique du "
+"terminal"
+
msgid "-v\t\t\tVi mode (like \"vi\")"
msgstr "-v\t\tMode Vi (comme \"vi\")"
-#: ../main.c:2202
msgid "-e\t\t\tEx mode (like \"ex\")"
msgstr "-e\t\tMode Ex (comme \"ex\")"
-#: ../main.c:2203
msgid "-E\t\t\tImproved Ex mode"
msgstr "-E\t\t\tMode Ex amélioré"
-#: ../main.c:2204
msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
msgstr "-s\t\tMode silencieux (batch) (seulement pour \"ex\")"
-#: ../main.c:2205
msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
msgstr "-d\t\tMode diff (comme \"vimdiff\")"
-#: ../main.c:2206
msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
msgstr "-y\t\tMode facile (comme \"evim\", vim sans modes)"
-#: ../main.c:2207
msgid "-R\t\t\tReadonly mode (like \"view\")"
msgstr "-R\t\tMode lecture seule (comme \"view\")"
-#: ../main.c:2208
msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
msgstr "-Z\t\tMode restreint (comme \"rvim\")"
-#: ../main.c:2209
msgid "-m\t\t\tModifications (writing files) not allowed"
msgstr "-m\t\tInterdire l'enregistrement des fichiers"
-#: ../main.c:2210
msgid "-M\t\t\tModifications in text not allowed"
msgstr "-M\t\tInterdire toute modification de texte"
-#: ../main.c:2211
msgid "-b\t\t\tBinary mode"
msgstr "-b\t\tMode binaire"
-#: ../main.c:2212
msgid "-l\t\t\tLisp mode"
msgstr "-l\t\tMode lisp"
-#: ../main.c:2213
msgid "-C\t\t\tCompatible with Vi: 'compatible'"
msgstr "-C\t\tCompatible avec Vi : 'compatible'"
-#: ../main.c:2214
msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
msgstr "-N\t\tPas totalement compatible avec Vi : 'nocompatible'"
-#: ../main.c:2215
msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
msgstr "-V[N][<fichier>]\tMode verbeux [niveau N] [dans <fichier>]"
-#: ../main.c:2216
msgid "-D\t\t\tDebugging mode"
msgstr "-D\t\tMode débogage"
-#: ../main.c:2217
msgid "-n\t\t\tNo swap file, use memory only"
msgstr "-n\t\tNe pas utiliser de fichier d'échange, seulement la mémoire"
-#: ../main.c:2218
msgid "-r\t\t\tList swap files and exit"
msgstr "-r\t\tLister les fichiers d'échange et quitter"
-#: ../main.c:2219
msgid "-r (with file name)\tRecover crashed session"
msgstr "-r <fichier>\tRécupérer une session plantée"
-#: ../main.c:2220
msgid "-L\t\t\tSame as -r"
msgstr "-L\t\tComme -r"
-#: ../main.c:2221
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\tNe pas utiliser newcli pour l'ouverture des fenêtres"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <périph>\tUtiliser <périphérique> pour les E/S"
+
msgid "-A\t\t\tstart in Arabic mode"
msgstr "-A\t\tDémarrer en mode arabe"
-#: ../main.c:2222
msgid "-H\t\t\tStart in Hebrew mode"
msgstr "-H\t\tDémarrer en mode hébreu"
-#: ../main.c:2223
msgid "-F\t\t\tStart in Farsi mode"
msgstr "-F\t\tDémarrer en mode farsi"
-#: ../main.c:2224
msgid "-T <terminal>\tSet terminal type to <terminal>"
msgstr "-T <term>\tRégler le type du terminal sur <terminal>"
-#: ../main.c:2225
+msgid "--not-a-term\t\tSkip warning for input/output not being a terminal"
+msgstr ""
+"--no-a-term\t\tAucun avertissement si l'entrée/sortie n'est pas un terminal"
+
+msgid "--ttyfail\t\tExit if input or output is not a terminal"
+msgstr ""
+"--ttyfail\t\tQuitte si l'entrée ou la sortie ne sont pas un terminal"
+
msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
msgstr "-u <vimrc>\tUtiliser <vimrc> au lieu du vimrc habituel"
-#: ../main.c:2226
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\tUtiliser <gvimrc> au lieu du gvimrc habituel"
+
msgid "--noplugin\t\tDon't load plugin scripts"
msgstr "--noplugin\tNe charger aucun greffon"
-#: ../main.c:2227
msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
msgstr "-p[N]\tOuvrir N onglets (défaut : un pour chaque fichier)"
-#: ../main.c:2228
msgid "-o[N]\t\tOpen N windows (default: one for each file)"
msgstr "-o[N]\tOuvrir N fenêtres (défaut : une pour chaque fichier)"
-#: ../main.c:2229
msgid "-O[N]\t\tLike -o but split vertically"
msgstr "-O[N]\tComme -o, mais partager verticalement"
-#: ../main.c:2230
msgid "+\t\t\tStart at end of file"
msgstr "+\t\tOuvrir à la fin du fichier"
-#: ../main.c:2231
msgid "+<lnum>\t\tStart at line <lnum>"
msgstr "+<numL>\tOuvrir le fichier à la ligne <numL>"
-#: ../main.c:2232
msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
msgstr "--cmd <cmde>\tExécuter <commande> avant de charger les fichiers vimrc"
-#: ../main.c:2233
msgid "-c <command>\t\tExecute <command> after loading the first file"
msgstr "-c <cmde>\tExécuter <commande> une fois le 1er fichier chargé"
-#: ../main.c:2235
msgid "-S <session>\t\tSource file <session> after loading the first file"
msgstr ""
"-S <session>\tSourcer le fichier <session> une fois le 1er fichier chargé"
-#: ../main.c:2236
msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
msgstr "-s <src>\tLire les commandes du mode Normal à partir du fichier <src>"
-#: ../main.c:2237
msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
msgstr "-w <dest>\tAjouter toutes les commandes tapées dans le fichier <dest>"
-#: ../main.c:2238
msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
msgstr "-W <dest>\tÉcrire toutes les commandes tapées dans le fichier <dest>"
-#: ../main.c:2240
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tÉditer des fichiers chiffrés"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <display>\tConnecter Vim au serveur X spécifié"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tNe pas se connecter à un serveur X"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <fich>\tÉditer les <fichiers> dans un serveur Vim si possible"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-silent ...\tPareil, mais pas d'erreur s'il n'y a aucun serveur"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr ""
+"--remote-wait <fich>\tComme --remote mais ne quitter qu'à la fin de l'édition"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-wait-silent\tPareil, mais pas d'erreur s'il n'y a aucun serveur"
+
+msgid ""
+"--remote-tab[-wait][-silent] <files> As --remote but use tab page per file"
+msgstr ""
+"--remote-tab[-wait][-silent] <fich>\tComme --remote mais ouvrir un onglet "
+"pour chaque fichier"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <tche>\tEnvoyer <touches> à un serveur Vim puis quitter"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr ""
+"--remote-expr <expr>\tÉvaluer <expr> dans un serveur Vim, afficher le "
+"résultat"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr ""
+"--serverlist\t\tLister les noms des serveurs Vim disponibles et quitter"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <nom>\tEnvoyer au/devenir le serveur Vim nommé <nom>"
+
msgid "--startuptime <file>\tWrite startup timing messages to <file>"
msgstr ""
"--startuptime <fich>\tÉcrire les messages d'horodatage au démarrage dans "
"<fich>"
-#: ../main.c:2242
msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
msgstr "-i <viminfo>\t\tUtiliser <viminfo> au lieu du viminfo habituel"
-#: ../main.c:2243
msgid "-h or --help\tPrint Help (this message) and exit"
msgstr "-h ou --help\t\tAfficher l'aide (ce message) puis quitter"
-#: ../main.c:2244
msgid "--version\t\tPrint version information and exit"
msgstr "--version\t\tAfficher les informations de version et quitter"
-#: ../mark.c:676
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Arguments reconnus par gvim (version Motif) :\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Arguments reconnus par gvim (version neXtaw) :\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Arguments reconnus par gvim (version Athena) :\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <écran>\tLancer Vim sur ce <display>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tIconifier Vim au démarrage"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr ""
+"-background <coul>\tUtiliser <couleur> pour l'arrière-plan\t (abrv : -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr ""
+"-foreground <coul>\tUtiliser <couleur> pour le texte normal\t (abrv : -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <fonte>\tUtiliser <fonte> pour le texte normal\t (abrv : -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <fonte>\tUtiliser <fonte> pour le texte gras"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <fonte>\tUtiliser <fonte> pour le texte italique"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <géom>\tUtiliser cette <géométrie> initiale\t (abrv : -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr ""
+"-borderwidth <épais>\tUtiliser cette <épaisseur> de bordure\t (abrv : -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <lg>\tUtiliser cette <largeur> de barre de défil. (abrv: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr "-menuheight <haut>\tUtiliser cette <hauteur> de menu\t (abrv : -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tUtiliser la vidéo inverse\t\t (abrv : -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tNe pas utiliser de vidéo inverse\t (abrv : +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <ressource>\tConfigurer la <ressource> spécifiée"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Arguments reconnus par gvim (version GTK+) :\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr ""
+"-display <display>\tLancer Vim sur ce <display>\t(également : --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "--role <rôle>\tDonner un rôle pour identifier la fenêtre principale"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tOuvrir Vim dans un autre widget GTK"
+
+msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
+msgstr "--echo-wid\t\tGvim affiche l'ID de la fenêtre sur stdout"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <titre parent>\tOuvrir Vim dans une application parente"
+
+msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
+msgstr "--windowid <HWND>\tOuvrir Vim dans un autre widget win32"
+
+msgid "No display"
+msgstr "Aucun display"
+
+#. 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"
-#: ../mark.c:678
#, c-format
msgid "E283: No marks matching \"%s\""
msgstr "E283: Aucune marque ne correspond à \"%s\""
#. Highlight title
-#: ../mark.c:687
msgid ""
"\n"
"mark line col file/text"
@@ -3816,7 +3518,6 @@ msgstr ""
"marq ligne col fichier/texte"
#. Highlight title
-#: ../mark.c:789
msgid ""
"\n"
" jump line col file/text"
@@ -3825,7 +3526,6 @@ msgstr ""
" saut ligne col fichier/texte"
#. Highlight title
-#: ../mark.c:831
msgid ""
"\n"
"change line col text"
@@ -3833,7 +3533,6 @@ msgstr ""
"\n"
"modif ligne col fichier/texte"
-#: ../mark.c:1238
msgid ""
"\n"
"# File marks:\n"
@@ -3842,7 +3541,6 @@ msgstr ""
"# Marques dans le fichier :\n"
#. Write the jumplist with -'
-#: ../mark.c:1271
msgid ""
"\n"
"# Jumplist (newest first):\n"
@@ -3850,7 +3548,6 @@ msgstr ""
"\n"
"# Liste de sauts (le plus récent en premier) :\n"
-#: ../mark.c:1352
msgid ""
"\n"
"# History of marks within files (newest to oldest):\n"
@@ -3858,84 +3555,91 @@ msgstr ""
"\n"
"# Historique des marques dans les fichiers (les plus récentes en premier) :\n"
-#: ../mark.c:1431
msgid "Missing '>'"
msgstr "'>' manquant"
-#: ../memfile.c:426
+msgid "E543: Not a valid codepage"
+msgstr "E543: Page de codes non valide"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Impossible de régler les valeurs IC"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Échec de la création du contexte de saisie"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Échec de l'ouverture de la méthode de saisie"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr ""
+"E287: Alerte : Impossible d'inscrire le callback de destruction dans la MS"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: la méthode de saisie ne supporte aucun style"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr ""
+"E289: le type de préédition de Vim n'est pas supporté par la méthode de "
+"saisie"
+
msgid "E293: block was not locked"
msgstr "E293: le bloc n'était pas verrouillé"
-#: ../memfile.c:799
msgid "E294: Seek error in swap file read"
msgstr "E294: Erreur de positionnement lors de la lecture du fichier d'échange"
-#: ../memfile.c:803
msgid "E295: Read error in swap file"
msgstr "E295: Erreur de lecture dans le fichier d'échange"
-#: ../memfile.c:849
msgid "E296: Seek error in swap file write"
msgstr "E296: Erreur de positionnement lors de l'écriture du fichier d'échange"
-#: ../memfile.c:865
msgid "E297: Write error in swap file"
msgstr "E297: Erreur d'écriture dans le fichier d'échange"
-#: ../memfile.c:1036
msgid "E300: Swap file already exists (symlink attack?)"
msgstr "E300: Le fichier d'échange existe déjà (attaque par symlink ?)"
-#: ../memline.c:318
msgid "E298: Didn't get block nr 0?"
msgstr "E298: Bloc n°0 non récupéré ?"
-#: ../memline.c:361
msgid "E298: Didn't get block nr 1?"
msgstr "E298: Bloc n°1 non récupéré ?"
-#: ../memline.c:377
msgid "E298: Didn't get block nr 2?"
msgstr "E298: Bloc n°2 non récupéré ?"
+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????
-#: ../memline.c:465
msgid "E301: Oops, lost the swap file!!!"
msgstr "E301: Oups, le fichier d'échange a disparu !"
-#: ../memline.c:477
msgid "E302: Could not rename swap file"
msgstr "E302: Impossible de renommer le fichier d'échange"
-#: ../memline.c:554
#, c-format
msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
msgstr "E303: Impossible d'ouvrir fichier .swp pour \"%s\", récup. impossible"
-#: ../memline.c:666
msgid "E304: ml_upd_block0(): Didn't get block 0??"
msgstr "E304: ml_upd_block0() : bloc 0 non récupéré ?!"
-#. no swap files found
-#: ../memline.c:830
#, c-format
msgid "E305: No swap file found for %s"
msgstr "E305: Aucun fichier d'échange trouvé pour %s"
-#: ../memline.c:839
msgid "Enter number of swap file to use (0 to quit): "
msgstr "Entrez le numéro du fichier d'échange à utiliser (0 pour quitter) : "
-#: ../memline.c:879
#, c-format
msgid "E306: Cannot open %s"
msgstr "E306: Impossible d'ouvrir %s"
-#: ../memline.c:897
msgid "Unable to read block 0 from "
msgstr "Impossible de lire le bloc 0 de "
-#: ../memline.c:900
msgid ""
"\n"
"Maybe no changes were made or Vim did not update the swap file."
@@ -3944,28 +3648,22 @@ msgstr ""
"Il est possible qu'aucune modification n'a été faite ou que Vim n'a pas mis "
"à jour le fichier d'échange."
-#: ../memline.c:909
msgid " cannot be used with this version of Vim.\n"
msgstr " ne peut pas être utilisé avec cette version de Vim.\n"
-#: ../memline.c:911
msgid "Use Vim version 3.0.\n"
msgstr "Utilisez Vim version 3.0.\n"
-#: ../memline.c:916
#, c-format
msgid "E307: %s does not look like a Vim swap file"
msgstr "E307: %s ne semble pas être un fichier d'échange de Vim"
-#: ../memline.c:922
msgid " cannot be used on this computer.\n"
msgstr " ne peut pas être utilisé sur cet ordinateur.\n"
-#: ../memline.c:924
msgid "The file was created on "
msgstr "Le fichier a été créé le "
-#: ../memline.c:928
msgid ""
",\n"
"or the file has been damaged."
@@ -3973,86 +3671,107 @@ msgstr ""
",\n"
"ou le fichier a été endommagé."
-#: ../memline.c:945
+#, c-format
+msgid ""
+"E833: %s is encrypted and this version of Vim does not support encryption"
+msgstr ""
+"E833: %s est chiffré et cette version de Vim ne supporte pas le chiffrement"
+
msgid " has been damaged (page size is smaller than minimum value).\n"
msgstr " a été endommagé (taille de page inférieure à la valeur minimale).\n"
-#: ../memline.c:974
#, c-format
msgid "Using swap file \"%s\""
msgstr "Utilisation du fichier d'échange \"%s\""
-#: ../memline.c:980
#, c-format
msgid "Original file \"%s\""
msgstr "Fichier original \"%s\""
-#: ../memline.c:995
msgid "E308: Warning: Original file may have been changed"
msgstr "E308: Alerte : Le fichier original a pu être modifié"
-#: ../memline.c:1061
+#, c-format
+msgid "Swap file is encrypted: \"%s\""
+msgstr "Fichier d'échange chiffré : \"%s\""
+
+msgid ""
+"\n"
+"If you entered a new crypt key but did not write the text file,"
+msgstr ""
+"\n"
+"Si vous avez tapé une nouvelle clé de chiffrement mais n'avez pas enregistré "
+"le fichier texte,"
+
+msgid ""
+"\n"
+"enter the new crypt key."
+msgstr ""
+"\n"
+"tapez la nouvelle clé de chiffrement."
+
+msgid ""
+"\n"
+"If you wrote the text file after changing the crypt key press enter"
+msgstr ""
+"\n"
+"Si vous avez écrit le fichier texte après avoir changé la clé de "
+"chiffrement, appuyez sur entrée"
+
+msgid ""
+"\n"
+"to use the same key for text file and swap file"
+msgstr ""
+"\n"
+"afin d'utiliser la même clé pour le fichier texte et le fichier d'échange"
+
#, c-format
msgid "E309: Unable to read block 1 from %s"
msgstr "E309: Impossible de lire le bloc 1 de %s"
-#: ../memline.c:1065
msgid "???MANY LINES MISSING"
msgstr "???DE NOMBREUSES LIGNES MANQUENT"
-#: ../memline.c:1076
msgid "???LINE COUNT WRONG"
msgstr "???NOMBRE DE LIGNES ERRONÉ"
-#: ../memline.c:1082
msgid "???EMPTY BLOCK"
msgstr "???BLOC VIDE"
-#: ../memline.c:1103
msgid "???LINES MISSING"
msgstr "???LIGNES MANQUANTES"
-#: ../memline.c:1128
#, c-format
msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
msgstr "E310: ID du bloc 1 erroné (%s n'est pas un fichier d'échange ?)"
-#: ../memline.c:1133
msgid "???BLOCK MISSING"
msgstr "???BLOC MANQUANT"
-#: ../memline.c:1147
msgid "??? from here until ???END lines may be messed up"
msgstr "??? d'ici jusqu'à ???FIN des lignes peuvent être corrompues"
-#: ../memline.c:1164
msgid "??? from here until ???END lines may have been inserted/deleted"
msgstr "??? d'ici jusqu'à ???FIN des lignes ont pu être insérées/effacées"
-#: ../memline.c:1181
msgid "???END"
msgstr "???FIN"
-#: ../memline.c:1238
msgid "E311: Recovery Interrupted"
msgstr "E311: Récupération interrompue"
-#: ../memline.c:1243
msgid ""
"E312: Errors detected while recovering; look for lines starting with ???"
msgstr ""
"E312: Erreurs lors de la récupération ; examinez les lignes commençant "
"par ???"
-#: ../memline.c:1245
msgid "See \":help E312\" for more information."
msgstr "Consultez \":help E312\" pour plus d'information."
-#: ../memline.c:1249
msgid "Recovery completed. You should check if everything is OK."
msgstr "Récupération achevée. Vérifiez que tout est correct."
-#: ../memline.c:1251
msgid ""
"\n"
"(You might want to write out this file under another name\n"
@@ -4060,17 +3779,14 @@ msgstr ""
"\n"
"(Vous voudrez peut-être enregistrer ce fichier sous un autre nom\n"
-#: ../memline.c:1252
msgid "and run diff with the original file to check for changes)"
msgstr "et lancer diff avec le fichier original pour repérer les changements)"
-#: ../memline.c:1254
msgid "Recovery completed. Buffer contents equals file contents."
msgstr ""
"Récupération achevée. Le contenu du tampon est identique au contenu du "
"fichier."
-#: ../memline.c:1255
msgid ""
"\n"
"You may want to delete the .swp file now.\n"
@@ -4080,52 +3796,45 @@ msgstr ""
"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
-#: ../memline.c:1327
msgid "Swap files found:"
msgstr "Fichiers d'échange trouvés :"
-#: ../memline.c:1446
msgid " In current directory:\n"
msgstr " Dans le répertoire courant :\n"
-#: ../memline.c:1448
msgid " Using specified name:\n"
msgstr "Utilisant le nom indiqué :\n"
-#: ../memline.c:1450
msgid " In directory "
msgstr " Dans le répertoire "
-#: ../memline.c:1465
msgid " -- none --\n"
msgstr " -- aucun --\n"
-#: ../memline.c:1527
msgid " owned by: "
msgstr " propriété de : "
-#: ../memline.c:1529
msgid " dated: "
msgstr " daté : "
-#: ../memline.c:1532 ../memline.c:3231
msgid " dated: "
msgstr " daté : "
-#: ../memline.c:1548
msgid " [from Vim version 3.0]"
msgstr " [de Vim version 3.0]"
-#: ../memline.c:1550
msgid " [does not look like a Vim swap file]"
msgstr " [ne semble pas être un fichier d'échange Vim]"
-#: ../memline.c:1552
msgid " file name: "
msgstr " nom de fichier : "
-#: ../memline.c:1558
msgid ""
"\n"
" modified: "
@@ -4133,15 +3842,12 @@ msgstr ""
"\n"
" modifié : "
-#: ../memline.c:1559
msgid "YES"
msgstr "OUI"
-#: ../memline.c:1559
msgid "no"
msgstr "non"
-#: ../memline.c:1562
msgid ""
"\n"
" user name: "
@@ -4149,11 +3855,9 @@ msgstr ""
"\n"
" nom d'utilisateur : "
-#: ../memline.c:1568
msgid " host name: "
msgstr " nom d'hôte : "
-#: ../memline.c:1570
msgid ""
"\n"
" host name: "
@@ -4161,7 +3865,6 @@ msgstr ""
"\n"
" nom d'hôte : "
-#: ../memline.c:1575
msgid ""
"\n"
" process ID: "
@@ -4169,11 +3872,16 @@ msgstr ""
"\n"
" processus n° : "
-#: ../memline.c:1579
msgid " (still running)"
msgstr " (en cours d'exécution)"
-#: ../memline.c:1586
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [inutilisable avec cette version de Vim]"
+
msgid ""
"\n"
" [not usable on this computer]"
@@ -4181,97 +3889,75 @@ msgstr ""
"\n"
" [inutilisable sur cet ordinateur]"
-#: ../memline.c:1590
msgid " [cannot be read]"
msgstr " [ne peut être lu]"
-#: ../memline.c:1593
msgid " [cannot be opened]"
msgstr " [ne peut être ouvert]"
-#: ../memline.c:1698
msgid "E313: Cannot preserve, there is no swap file"
msgstr "E313: Préservation impossible, il n'y a pas de fichier d'échange"
-#: ../memline.c:1747
msgid "File preserved"
msgstr "Fichier préservé"
-#: ../memline.c:1749
msgid "E314: Preserve failed"
msgstr "E314: Échec de la préservation"
-#: ../memline.c:1819
#, c-format
-msgid "E315: ml_get: invalid lnum: %<PRId64>"
-msgstr "E315: ml_get : numéro de ligne invalide : %<PRId64>"
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get : numéro de ligne invalide : %ld"
-#: ../memline.c:1851
#, c-format
-msgid "E316: ml_get: cannot find line %<PRId64>"
-msgstr "E316: ml_get : ligne %<PRId64> introuvable"
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get : ligne %ld introuvable"
-#: ../memline.c:2236
msgid "E317: pointer block id wrong 3"
msgstr "E317: mauvais id de pointeur de bloc 3"
-#: ../memline.c:2311
msgid "stack_idx should be 0"
msgstr "stack_idx devrait être 0"
-#: ../memline.c:2369
msgid "E318: Updated too many blocks?"
msgstr "E318: Trop de blocs mis à jour ?"
-#: ../memline.c:2511
msgid "E317: pointer block id wrong 4"
msgstr "E317: mauvais id de pointeur de bloc 4"
-#: ../memline.c:2536
msgid "deleted block 1?"
msgstr "bloc 1 effacé ?"
-#: ../memline.c:2707
#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: Ligne %<PRId64> introuvable"
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Ligne %ld introuvable"
-#: ../memline.c:2916
msgid "E317: pointer block id wrong"
msgstr "E317: mauvais id de pointeur de bloc"
-#: ../memline.c:2930
msgid "pe_line_count is zero"
msgstr "pe_line_count vaut zéro"
-#: ../memline.c:2955
#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: numéro de ligne hors limites : %<PRId64> au-delà de la fin"
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: numéro de ligne hors limites : %ld au-delà de la fin"
-#: ../memline.c:2959
#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: nombre de lignes erroné dans le bloc %<PRId64>"
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: nombre de lignes erroné dans le bloc %ld"
-#: ../memline.c:2999
msgid "Stack size increases"
msgstr "La taille de la pile s'accroît"
-#: ../memline.c:3038
msgid "E317: pointer block id wrong 2"
msgstr "E317: mauvais id de pointeur de block 2"
-#: ../memline.c:3070
#, c-format
msgid "E773: Symlink loop for \"%s\""
msgstr "E773: cycle de liens symboliques avec \"%s\""
-#: ../memline.c:3221
msgid "E325: ATTENTION"
msgstr "E325: ATTENTION"
-#: ../memline.c:3222
msgid ""
"\n"
"Found a swap file by the name \""
@@ -4279,39 +3965,32 @@ msgstr ""
"\n"
"Trouvé un fichier d'échange nommé \""
-#: ../memline.c:3226
msgid "While opening file \""
msgstr "Lors de l'ouverture du fichier \""
-#: ../memline.c:3239
msgid " NEWER than swap file!\n"
msgstr " PLUS RÉCENT que le fichier d'échange !\n"
-#: ../memline.c:3244
+#. Some of these messages are long to allow translation to
+#. * other languages.
msgid ""
"\n"
"(1) Another program may be editing the same file. If this is the case,\n"
" be careful not to end up with two different instances of the same\n"
-" file when making changes."
+" file when making changes. Quit, or continue with caution.\n"
msgstr ""
"\n"
"(1) 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."
-
-#: ../memline.c:3245
-msgid " Quit, or continue with caution.\n"
-msgstr " Quittez, ou continuez prudemment.\n"
+" deux versions différentes du même fichier en faisant des modifications.\n"
+" Quitter ou continuer avec attention.\n"
-#: ../memline.c:3246
msgid "(2) An edit session for this file crashed.\n"
msgstr "(2) Une session d'édition de ce fichier a planté.\n"
-#: ../memline.c:3247
msgid " If this is the case, use \":recover\" or \"vim -r "
msgstr " Si c'est le cas, utilisez \":recover\" ou \"vim -r "
-#: ../memline.c:3249
msgid ""
"\"\n"
" to recover the changes (see \":help recovery\").\n"
@@ -4319,11 +3998,9 @@ msgstr ""
"\"\n"
" pour récupérer le fichier (consultez \":help recovery\").\n"
-#: ../memline.c:3250
msgid " If you did this already, delete the swap file \""
msgstr " Si vous l'avez déjà fait, effacez le fichier d'échange \""
-#: ../memline.c:3252
msgid ""
"\"\n"
" to avoid this message.\n"
@@ -4331,23 +4008,18 @@ msgstr ""
"\"\n"
" pour éviter ce message.\n"
-#: ../memline.c:3450 ../memline.c:3452
msgid "Swap file \""
msgstr "Le fichier d'échange \""
-#: ../memline.c:3451 ../memline.c:3455
msgid "\" already exists!"
msgstr "\" existe déjà !"
-#: ../memline.c:3457
msgid "VIM - ATTENTION"
msgstr "VIM - ATTENTION"
-#: ../memline.c:3459
msgid "Swap file already exists!"
msgstr "Un fichier d'échange existe déjà !"
-#: ../memline.c:3464
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4361,7 +4033,6 @@ msgstr ""
"&Quitter\n"
"&Abandonner"
-#: ../memline.c:3467
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4377,58 +4048,36 @@ msgstr ""
"&Quitter\n"
"&Abandonner"
-#.
-#. * Change the ".swp" extension to find another file that can be used.
-#. * First decrement the last char: ".swo", ".swn", etc.
-#. * If that still isn't enough decrement the last but one char: ".svz"
-#. * Can happen when editing many "No Name" buffers.
-#.
-#. ".s?a"
-#. ".saa": tried enough, give up
-#: ../memline.c:3528
msgid "E326: Too many swap files found"
msgstr "E326: Trop de fichiers d'échange trouvés"
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: Mémoire épuisée ! (allocation de %<PRIu64> octets)"
-
-#: ../menu.c:62
msgid "E327: Part of menu-item path is not sub-menu"
msgstr "E327: Une partie du chemin de l'élément de menu n'est pas un sous-menu"
# DB - todo : J'hésite avec
# msgstr "E328: Le menu n'existe pas dans ce mode"
-#: ../menu.c:63
msgid "E328: Menu only exists in another mode"
msgstr "E328: Le menu n'existe que dans un autre mode"
-#: ../menu.c:64
#, c-format
msgid "E329: No menu \"%s\""
msgstr "E329: Aucun menu \"%s\""
#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
msgid "E792: Empty menu name"
msgstr "E792: Nom de menu vide"
-#: ../menu.c:340
msgid "E330: Menu path must not lead to a sub-menu"
msgstr "E330: Le chemin de menu ne doit pas conduire à un sous-menu"
-#: ../menu.c:365
msgid "E331: Must not add menu items directly to menu bar"
msgstr "E331: Ajout d'éléments de menu directement dans barre de menu interdit"
-#: ../menu.c:370
msgid "E332: Separator cannot be part of a menu path"
msgstr "E332: Un séparateur ne peut faire partie d'un chemin de menu"
#. Now we have found the matching menu, and we list the mappings
#. Highlight title
-#: ../menu.c:762
msgid ""
"\n"
"--- Menus ---"
@@ -4436,71 +4085,62 @@ msgstr ""
"\n"
"--- Menus ---"
-#: ../menu.c:1313
+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"
-#: ../menu.c:1330
#, c-format
msgid "E334: Menu not found: %s"
msgstr "E334: Menu introuvable : %s"
-#: ../menu.c:1396
#, c-format
msgid "E335: Menu not defined for %s mode"
msgstr "E335: Le menu n'est pas défini pour le mode %s"
-#: ../menu.c:1426
msgid "E336: Menu path must lead to a sub-menu"
msgstr "E336: Le chemin du menu doit conduire à un sous-menu"
-#: ../menu.c:1447
msgid "E337: Menu not found - check menu names"
msgstr "E337: Menu introuvable - vérifiez les noms des menus"
-#: ../message.c:423
#, c-format
msgid "Error detected while processing %s:"
msgstr "Erreur détectée en traitant %s :"
-#: ../message.c:445
#, c-format
msgid "line %4ld:"
msgstr "ligne %4ld :"
-#: ../message.c:617
#, c-format
msgid "E354: Invalid register name: '%s'"
msgstr "E354: Nom de registre invalide : '%s'"
# DB - todo : mettre à jour ?
-#: ../message.c:986
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Maintenance des messages : Dominique Pellé <dominique.pelle@gmail.com>"
+
msgid "Interrupt: "
msgstr "Interruption : "
-#: ../message.c:988
msgid "Press ENTER or type command to continue"
msgstr "Appuyez sur ENTRÉE ou tapez une commande pour continuer"
-#: ../message.c:1843
#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s, ligne %<PRId64>"
+msgid "%s line %ld"
+msgstr "%s, ligne %ld"
-#: ../message.c:2392
msgid "-- More --"
msgstr "-- Plus --"
-#: ../message.c:2398
msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
msgstr ""
"ESPACE/d/j : écran/page/ligne vers le bas, b/u/k : vers le haut, q : quitter"
-#: ../message.c:3021 ../message.c:3031
msgid "Question"
msgstr "Question"
-#: ../message.c:3023
msgid ""
"&Yes\n"
"&No"
@@ -4508,17 +4148,6 @@ msgstr ""
"&Oui\n"
"&Non"
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"&Oui\n"
-"&Non\n"
-"&Annuler"
-
-#: ../message.c:3045
msgid ""
"&Yes\n"
"&No\n"
@@ -4532,176 +4161,251 @@ msgstr ""
"Tout aban&donner\n"
"&Annuler"
-#: ../message.c:3058
+# DB : Les trois messages qui suivent sont des titres de boîtes
+# de dialogue par défaut.
+msgid "Select Directory dialog"
+msgstr "Sélecteur de répertoire"
+
+msgid "Save File dialog"
+msgstr "Enregistrer un fichier"
+
+msgid "Open File dialog"
+msgstr "Ouvrir un fichier"
+
+#. 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()"
-#: ../message.c:3119
msgid "E807: Expected Float argument for printf()"
msgstr "E807: printf() attend un argument de type Flottant"
-#: ../message.c:3873
msgid "E767: Too many arguments to printf()"
msgstr "E767: Trop d'arguments pour printf()"
-#: ../misc1.c:2256
msgid "W10: Warning: Changing a readonly file"
msgstr "W10: Alerte : Modification d'un fichier en lecture seule"
-#: ../misc1.c:2537
msgid "Type number and <Enter> or click with mouse (empty cancels): "
msgstr "Tapez un nombre et <Entrée> ou cliquez avec la souris (rien annule) :"
-#: ../misc1.c:2539
msgid "Type number and <Enter> (empty cancels): "
msgstr "Tapez un nombre et <Entrée> (rien annule) :"
-#: ../misc1.c:2585
msgid "1 more line"
msgstr "1 ligne en plus"
-#: ../misc1.c:2588
msgid "1 line less"
msgstr "1 ligne en moins"
-#: ../misc1.c:2593
#, c-format
-msgid "%<PRId64> more lines"
-msgstr "%<PRId64> lignes en plus"
+msgid "%ld more lines"
+msgstr "%ld lignes en plus"
-#: ../misc1.c:2596
#, c-format
-msgid "%<PRId64> fewer lines"
-msgstr "%<PRId64> lignes en moins"
+msgid "%ld fewer lines"
+msgstr "%ld lignes en moins"
-#: ../misc1.c:2599
msgid " (Interrupted)"
msgstr " (Interrompu)"
-#: ../misc1.c:2635
msgid "Beep!"
msgstr "Bip !"
-#: ../misc2.c:738
+msgid "ERROR: "
+msgstr "ERREUR : "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[octets] total alloué-libéré %lu-%lu, utilisé %lu, pic %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[appels] total re/malloc() %lu, total free() %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: La ligne devient trop longue"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Erreur interne : lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Mémoire épuisée ! (allocation de %lu octets)"
+
#, c-format
msgid "Calling shell to execute: \"%s\""
msgstr "Appel du shell pour exécuter : \"%s\""
-#: ../normal.c:183
+msgid "E545: Missing colon"
+msgstr "E545: ':' manquant"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Mode non autorisé"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Forme de curseur invalide"
+
+msgid "E548: digit expected"
+msgstr "E548: chiffre attendu"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Pourcentage non autorisé"
+
+msgid "E854: path too long for completion"
+msgstr "E854: chemin trop long pour complètement"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: Chemin invalide : '**[nombre]' doit être à la fin du chemin ou être "
+"suivi de '%s'."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Répertoire \"%s\" introuvable dans 'cdpath'"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Fichier \"%s\" introuvable dans 'path'"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Plus de répertoire \"%s\" dans 'cdpath'"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Plus de fichier \"%s\" dans 'path'"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: Mode d'accès incorrect au fichier d'infos de connexion NetBeans : \"%s"
+"\""
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Connexion NetBeans perdue pour le tampon %ld"
+
+msgid "E838: netbeans is not supported with this GUI"
+msgstr "E838: netbeans n'est pas supporté avec cette interface graphique"
+
+msgid "E511: netbeans already connected"
+msgstr "E511: netbeans déjà connecté"
+
+#, c-format
+msgid "E505: %s is read-only (add ! to override)"
+msgstr "E505: %s est en lecture seule (ajoutez ! pour passer outre)"
+
msgid "E349: No identifier under cursor"
msgstr "E349: Aucun identifiant sous le curseur"
-#: ../normal.c:1866
msgid "E774: 'operatorfunc' is empty"
msgstr "E774: 'operatorfunc' est vide"
+msgid "E775: Eval feature not available"
+msgstr "E775: La fonctionnalité d'évaluation n'est pas disponible"
+
# DB : Il est ici question du mode Visuel.
-#: ../normal.c:2637
msgid "Warning: terminal cannot highlight"
msgstr "Alerte : le terminal ne peut pas surligner"
-#: ../normal.c:2807
msgid "E348: No string under cursor"
msgstr "E348: Aucune chaîne sous le curseur"
-#: ../normal.c:3937
msgid "E352: Cannot erase folds with current 'foldmethod'"
msgstr "E352: Impossible d'effacer des replis avec la 'foldmethod'e actuelle"
-#: ../normal.c:5897
msgid "E664: changelist is empty"
msgstr "E664: La liste des modifications (changelist) est vide"
-#: ../normal.c:5899
msgid "E662: At start of changelist"
msgstr "E662: Au début de la liste des modifications"
-#: ../normal.c:5901
msgid "E663: At end of changelist"
msgstr "E663: À la fin de la liste des modifications"
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
+msgid "Type :quit<Enter> to exit Vim"
msgstr "tapez :q<Entrée> pour quitter Vim"
-#: ../ops.c:248
#, c-format
msgid "1 line %sed 1 time"
msgstr "1 ligne %sée 1 fois"
-#: ../ops.c:250
#, c-format
msgid "1 line %sed %d times"
msgstr "1 ligne %sée %d fois"
-#: ../ops.c:253
#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> lignes %sées 1 fois"
+msgid "%ld lines %sed 1 time"
+msgstr "%ld lignes %sées 1 fois"
-#: ../ops.c:256
#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> lignes %sées %d fois"
+msgid "%ld lines %sed %d times"
+msgstr "%ld lignes %sées %d fois"
-#: ../ops.c:592
#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "%<PRId64> lignes à indenter... "
+msgid "%ld lines to indent... "
+msgstr "%ld lignes à indenter... "
-#: ../ops.c:634
msgid "1 line indented "
msgstr "1 ligne indentée "
-#: ../ops.c:636
#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "%<PRId64> lignes indentées "
+msgid "%ld lines indented "
+msgstr "%ld lignes indentées "
-#: ../ops.c:938
msgid "E748: No previously used register"
msgstr "E748: Aucun registre n'a été précédemment utilisé"
# DB - Question O/N.
#. must display the prompt
-#: ../ops.c:1433
msgid "cannot yank; delete anyway"
msgstr "impossible de réaliser une copie ; effacer tout de même"
-#: ../ops.c:1929
msgid "1 line changed"
msgstr "1 ligne modifiée"
-#: ../ops.c:1931
#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "%<PRId64> lignes modifiées"
+msgid "%ld lines changed"
+msgstr "%ld lignes modifiées"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "libération de %ld lignes"
-#: ../ops.c:2521
msgid "block of 1 line yanked"
msgstr "bloc de 1 ligne copié"
-#: ../ops.c:2523
msgid "1 line yanked"
msgstr "1 ligne copiée"
-#: ../ops.c:2525
#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "bloc de %<PRId64> lignes copié"
+msgid "block of %ld lines yanked"
+msgstr "bloc de %ld lignes copié"
-#: ../ops.c:2528
#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "%<PRId64> lignes copiées"
+msgid "%ld lines yanked"
+msgstr "%ld lignes copiées"
-#: ../ops.c:2710
#, c-format
msgid "E353: Nothing in register %s"
msgstr "E353: Le registre %s est vide"
#. Highlight title
-#: ../ops.c:3185
msgid ""
"\n"
"--- Registers ---"
@@ -4709,11 +4413,9 @@ msgstr ""
"\n"
"--- Registres ---"
-#: ../ops.c:4455
msgid "Illegal register name"
msgstr "Nom de registre invalide"
-#: ../ops.c:4533
msgid ""
"\n"
"# Registers:\n"
@@ -4721,189 +4423,179 @@ msgstr ""
"\n"
"# Registres :\n"
-#: ../ops.c:4575
#, c-format
msgid "E574: Unknown register type %d"
msgstr "E574: Type de registre %d inconnu"
-#: ../ops.c:5089
+msgid ""
+"E883: search pattern and expression register may not contain two or more "
+"lines"
+msgstr ""
+"E883: le motif de recherche et le registre d'expression ne peuvent pas "
+"contenir deux lignes ou plus"
+
#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> Colonnes ; "
+msgid "%ld Cols; "
+msgstr "%ld Colonnes ; "
-#: ../ops.c:5097
#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
+msgid "Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes"
msgstr ""
-"%s%<PRId64> sur %<PRId64> Lignes ; %<PRId64> sur %<PRId64> Mots ; %<PRId64> "
-"sur %<PRId64> Octets sélectionnés"
+"%s%ld sur %ld Lignes ; %lld sur %lld Mots ; %lld sur %lld Octets sélectionnés"
-#: ../ops.c:5105
#, c-format
msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
+"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of "
+"%lld Bytes"
msgstr ""
-"%s%<PRId64> sur %<PRId64> Lignes ; %<PRId64> sur %<PRId64> Mots ; %<PRId64> "
-"sur %<PRId64> Caractères ; %<PRId64> sur %<PRId64> octets sélectionnés"
+"%s%ld sur %ld Lignes ; %lld sur %lld Mots ; %lld sur %lld Caractères ; %lld "
+"sur %lld octets sélectionnés"
-#: ../ops.c:5123
#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
+msgid "Col %s of %s; Line %ld of %ld; Word %lld of %lld; Byte %lld of %lld"
msgstr ""
-"Colonne %s sur %s ; Ligne %<PRId64> sur %<PRId64> ; Mot %<PRId64> sur "
-"%<PRId64> ; Octet %<PRId64> sur %<PRId64>"
+"Colonne %s sur %s ; Ligne %ld sur %ld ; Mot %lld sur %lld ; Octet %lld sur "
+"%lld"
-#: ../ops.c:5133
#, c-format
msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
+"Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte "
+"%lld of %lld"
msgstr ""
-"Colonne %s sur %s ; Ligne %<PRId64> sur %<PRId64> ; Mot %<PRId64> sur "
-"%<PRId64> ; Caractère %<PRId64> sur %<PRId64> ; Octet %<PRId64> sur %<PRId64>"
+"Colonne %s sur %s ; Ligne %ld sur %ld ; Mot %lld sur %lld ; Caractère %lld "
+"sur %lld ; Octet %lld sur %lld"
-#: ../ops.c:5146
#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> pour le BOM)"
+msgid "(+%ld for BOM)"
+msgstr "(+%ld pour le BOM)"
-#: ../option.c:1238
msgid "%<%f%h%m%=Page %N"
msgstr "%<%f%h%m%=Page %N"
-#: ../option.c:1574
msgid "Thanks for flying Vim"
msgstr "Merci d'avoir choisi Vim"
-#. found a mismatch: skip
-#: ../option.c:2698
msgid "E518: Unknown option"
msgstr "E518: Option inconnue"
-#: ../option.c:2709
msgid "E519: Option not supported"
msgstr "E519: Option non supportée"
-#: ../option.c:2740
msgid "E520: Not allowed in a modeline"
msgstr "E520: Non autorisé dans une ligne de mode"
-#: ../option.c:2815
msgid "E846: Key code not set"
msgstr "E846: Le code de touche n'est pas configuré"
-#: ../option.c:2924
msgid "E521: Number required after ="
msgstr "E521: Nombre requis après ="
-#: ../option.c:3226 ../option.c:3864
msgid "E522: Not found in termcap"
msgstr "E522: Introuvable dans termcap"
-#: ../option.c:3335
#, c-format
msgid "E539: Illegal character <%s>"
msgstr "E539: Caractère <%s> invalide"
-#: ../option.c:2253
#, c-format
msgid "For option %s"
msgstr "Pour l'option %s"
-#: ../option.c:3862
msgid "E529: Cannot set 'term' to empty string"
msgstr "E529: 'term' ne doit pas être une chaîne vide"
-#: ../option.c:3885
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: Impossible de modifier term dans l'interface graphique"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Utilisez \":gui\" pour démarrer l'interface graphique"
+
msgid "E589: 'backupext' and 'patchmode' are equal"
msgstr "E589: 'backupext' et 'patchmode' sont égaux"
-#: ../option.c:3964
msgid "E834: Conflicts with value of 'listchars'"
msgstr "E834: Conflits avec la valeur de 'listchars'"
-#: ../option.c:3966
msgid "E835: Conflicts with value of 'fillchars'"
msgstr "E835: Conflits avec la valeur de 'fillchars'"
-#: ../option.c:4163
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Non modifiable dans l'interface graphique GTK+ 2"
+
msgid "E524: Missing colon"
msgstr "E524: ':' manquant"
-#: ../option.c:4165
msgid "E525: Zero length string"
msgstr "E525: Chaîne de longueur nulle"
-#: ../option.c:4220
#, c-format
msgid "E526: Missing number after <%s>"
msgstr "E526: Nombre manquant après <%s>"
-#: ../option.c:4232
msgid "E527: Missing comma"
msgstr "E527: Virgule manquante"
-#: ../option.c:4239
msgid "E528: Must specify a ' value"
msgstr "E528: Une valeur ' doit être spécifiée"
-#: ../option.c:4271
msgid "E595: contains unprintable or wide character"
msgstr "E595: contient des caractères à largeur double non-imprimables"
-#: ../option.c:4469
+msgid "E596: Invalid font(s)"
+msgstr "E596: Police(s) invalide(s)"
+
+msgid "E597: can't select fontset"
+msgstr "E597: Impossible de sélectionner un jeu de polices"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Jeu de polices invalide"
+
+msgid "E533: can't select wide font"
+msgstr "E533: Impossible de sélectionner une police à largeur double"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Police à largeur double invalide"
+
#, c-format
msgid "E535: Illegal character after <%c>"
msgstr "E535: Caractère invalide après <%c>"
-#: ../option.c:4534
msgid "E536: comma required"
msgstr "E536: virgule requise"
-#: ../option.c:4543
#, c-format
msgid "E537: 'commentstring' must be empty or contain %s"
msgstr "E537: 'commentstring' doit être vide ou contenir %s"
+msgid "E538: No mouse support"
+msgstr "E538: La souris n'est pas supportée"
+
# DB - Le code est sans ambiguïté sur le caractère manquant.
# À défaut d'une traduction valable, au moins comprend-on
# ce qui se passe.
-#: ../option.c:4928
msgid "E540: Unclosed expression sequence"
msgstr "E540: '}' manquant"
-#: ../option.c:4932
msgid "E541: too many items"
msgstr "E541: trop d'éléments"
-#: ../option.c:4934
msgid "E542: unbalanced groups"
msgstr "E542: parenthèses non équilibrées"
-#: ../option.c:5148
msgid "E590: A preview window already exists"
msgstr "E590: Il existe déjà une fenêtre de prévisualisation"
-#: ../option.c:5311
msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
-msgstr "W17: L'arabe requiert l'UTF-8, tapez ':set encoding=utf-8'"
+msgstr "W17: L'arabe nécessite l'UTF-8, tapez ':set encoding=utf-8'"
-#: ../option.c:5623
#, c-format
msgid "E593: Need at least %d lines"
msgstr "E593: Au moins %d lignes sont nécessaires"
-#: ../option.c:5631
#, c-format
msgid "E594: Need at least %d columns"
msgstr "E594: Au moins %d colonnes sont nécessaires"
-#: ../option.c:6011
#, c-format
msgid "E355: Unknown option: %s"
msgstr "E355: Option inconnue : %s"
@@ -4911,12 +4603,10 @@ msgstr "E355: Option inconnue : %s"
#. There's another character after zeros or the string
#. * is empty. In both cases, we are trying to set a
#. * num option using a string.
-#: ../option.c:6037
#, c-format
msgid "E521: Number required: &%s = '%s'"
msgstr "E521: Nombre requis : &%s = '%s'"
-#: ../option.c:6149
msgid ""
"\n"
"--- Terminal codes ---"
@@ -4924,7 +4614,6 @@ msgstr ""
"\n"
"--- Codes de terminal ---"
-#: ../option.c:6151
msgid ""
"\n"
"--- Global option values ---"
@@ -4932,7 +4621,6 @@ msgstr ""
"\n"
"--- Valeur des options globales ---"
-#: ../option.c:6153
msgid ""
"\n"
"--- Local option values ---"
@@ -4940,7 +4628,6 @@ msgstr ""
"\n"
"--- Valeur des options locales ---"
-#: ../option.c:6155
msgid ""
"\n"
"--- Options ---"
@@ -4948,29 +4635,147 @@ msgstr ""
"\n"
"--- Options ---"
-#: ../option.c:6816
msgid "E356: get_varp ERROR"
msgstr "E356: ERREUR get_varp"
-#: ../option.c:7696
#, c-format
msgid "E357: 'langmap': Matching character missing for %s"
msgstr "E357: 'langmap' : Aucun caractère correspondant pour %s"
-#: ../option.c:7715
#, c-format
msgid "E358: 'langmap': Extra characters after semicolon: %s"
msgstr "E358: 'langmap' : Caractères surnuméraires après point-virgule : %s"
-#: ../os/shell.c:194
+msgid "cannot open "
+msgstr "impossible d'ouvrir "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM : Impossible d'ouvrir la fenêtre !\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Amigados version 2.04 ou ultérieure est nécessaire\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "%s version %ld est nécessaire\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Impossible d'ouvrir NIL :\n"
+
+msgid "Cannot create "
+msgstr "Impossible de créer "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim quitte avec %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "Impossible de modifier le mode de la console ?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize : pas une console ?!\n"
+
+#. 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 "E237: Printer selection failed"
+msgstr "E237: La sélection de l'imprimante a échoué"
+
+# DB - Contenu des c-formats : Imprimante puis Port.
+#, c-format
+msgid "to %s on %s"
+msgstr "vers %s sur %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Police d'imprimante inconnue : %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Erreur d'impression : %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Impression de '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Jeu de caractères \"%s\" invalide dans le nom de fonte \"%s\""
+
+#, c-format
+msgid "E244: Illegal quality name \"%s\" in font name \"%s\""
+msgstr "E244: Nom de qualité \"%s\" invalide dans le nom de fonte \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Caractère '%c' invalide dans le nom de fonte \"%s\""
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "L'ouverture du display X a pris %ld ms"
+
msgid ""
"\n"
-"Cannot execute shell "
+"Vim: Got X error\n"
msgstr ""
"\n"
-"Impossible d'exécuter le shell "
+"Vim : Réception d'une erreur X\n"
+
+msgid "Testing the X display failed"
+msgstr "Le test du display X a échoué"
+
+msgid "Opening the X display timed out"
+msgstr "L'ouverture du display X a dépassé le délai d'attente"
+
+msgid ""
+"\n"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Impossible d'obtenir le contexte de sécurité pour "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Impossible de modifier le contexte de sécurité pour "
+
+#, c-format
+msgid "Could not set security context %s for %s"
+msgstr "Impossible d'initialiser le contexte de sécurité %s pour %s"
+
+#, c-format
+msgid "Could not get security context %s for %s. Removing it!"
+msgstr ""
+"Impossible d'obtenir le contexte de sécurité %s pour %s. Il sera supprimé !"
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Impossible d'exécuter le shell sh\n"
-#: ../os/shell.c:439
msgid ""
"\n"
"shell returned "
@@ -4978,234 +4783,278 @@ msgstr ""
"\n"
"le shell a retourné "
-#: ../os_unix.c:465 ../os_unix.c:471
msgid ""
"\n"
-"Could not get security context for "
+"Cannot create pipes\n"
msgstr ""
"\n"
-"Impossible d'obtenir le contexte de sécurité pour "
+"Impossible de créer des tuyaux (pipes)\n"
-#: ../os_unix.c:479
msgid ""
"\n"
-"Could not set security context for "
+"Cannot fork\n"
msgstr ""
"\n"
-"Impossible de modifier le contexte de sécurité pour "
+"Impossible de forker\n"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Impossible d'exécuter le shell "
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Commande interrompue\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP a perdu la connexion ICE"
-#: ../os_unix.c:1558 ../os_unix.c:1647
#, c-format
msgid "dlerror = \"%s\""
msgstr "dlerror = \"%s\""
-#: ../path.c:1449
+msgid "Opening the X display failed"
+msgstr "L'ouverture du display X a échoué"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP : prise en charge d'une requête save-yourself"
+
+msgid "XSMP opening connection"
+msgstr "XSMP : ouverture de la connexion"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP : échec de la surveillance de connexion ICE"
+
#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: Le fichier \"%s\" est introuvable dans 'path'"
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP : SmcOpenConnection a échoué : %s"
+
+msgid "At line"
+msgstr "À la ligne"
+
+msgid "Could not load vim32.dll!"
+msgstr "Impossible de charger vim32.dll !"
+
+msgid "VIM Error"
+msgstr "Erreur VIM"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Impossible d'initialiser les pointeurs de fonction vers la DLL !"
+
+# DB - Les événements en question sont ceux des messages qui suivent.
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim : Événement %s intercepté\n"
+
+msgid "close"
+msgstr "de fermeture"
+
+msgid "logoff"
+msgstr "de déconnexion"
+
+msgid "shutdown"
+msgstr "d'arrêt"
+
+msgid "E371: Command not found"
+msgstr "E371: Commande introuvable"
+
+msgid ""
+"VIMRUN.EXE not found in your $PATH.\n"
+"External commands will not pause after completion.\n"
+"See :help win32-vimrun for more information."
+msgstr ""
+"VIMRUN.EXE est introuvable votre $PATH.\n"
+"Les commandes externes ne feront pas de pause une fois terminées.\n"
+"Consultez :help win32-vimrun pour plus d'informations."
+
+msgid "Vim Warning"
+msgstr "Alerte Vim"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "le shell a retourné %d"
-#: ../quickfix.c:359
#, c-format
msgid "E372: Too many %%%c in format string"
msgstr "E372: Trop de %%%c dans la chaîne de format"
-#: ../quickfix.c:371
#, c-format
msgid "E373: Unexpected %%%c in format string"
msgstr "E373: %%%c inattendu dans la chaîne de format"
-#: ../quickfix.c:420
msgid "E374: Missing ] in format string"
msgstr "E374: ] manquant dans la chaîne de format"
-#: ../quickfix.c:431
#, c-format
msgid "E375: Unsupported %%%c in format string"
msgstr "E375: %%%c non supporté dans la chaîne de format"
-#: ../quickfix.c:448
#, c-format
msgid "E376: Invalid %%%c in format string prefix"
msgstr "E376: %%%c invalide dans le préfixe de la chaîne de format"
-#: ../quickfix.c:454
#, c-format
msgid "E377: Invalid %%%c in format string"
msgstr "E377: %%%c invalide dans la chaîne de format"
#. nothing found
-#: ../quickfix.c:477
msgid "E378: 'errorformat' contains no pattern"
msgstr "E378: 'errorformat' ne contient aucun motif"
-#: ../quickfix.c:695
msgid "E379: Missing or empty directory name"
msgstr "E379: Nom de répertoire vide ou absent"
-#: ../quickfix.c:1305
msgid "E553: No more items"
msgstr "E553: Plus d'éléments"
-#: ../quickfix.c:1674
+msgid "E924: Current window was closed"
+msgstr "E924: La fenêtre courante doit être fermée"
+
+msgid "E925: Current quickfix was changed"
+msgstr "E925: Le quickfix courant a changé"
+
+msgid "E926: Current location list was changed"
+msgstr "E926: La liste d'emplacements courante a changé"
+
#, c-format
msgid "(%d of %d)%s%s: "
msgstr "(%d sur %d)%s%s : "
-#: ../quickfix.c:1676
msgid " (line deleted)"
msgstr " (ligne effacée)"
-#: ../quickfix.c:1863
+#, c-format
+msgid "%serror list %d of %d; %d errors "
+msgstr "%sliste d'erreurs %d sur %d ; %d erreurs"
+
msgid "E380: At bottom of quickfix stack"
msgstr "E380: En bas de la pile quickfix"
-#: ../quickfix.c:1869
msgid "E381: At top of quickfix stack"
msgstr "E381: Au sommet de la pile quickfix"
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "liste d'erreurs %d sur %d ; %d erreurs"
+msgid "No entries"
+msgstr "Aucune entrée"
-#: ../quickfix.c:2427
msgid "E382: Cannot write, 'buftype' option is set"
msgstr "E382: Écriture impossible, l'option 'buftype' est activée"
-#: ../quickfix.c:2812
+msgid "Error file"
+msgstr "Fichier d'erreurs"
+
msgid "E683: File name missing or invalid pattern"
msgstr "E683: Nom de fichier manquant ou motif invalide"
-#: ../quickfix.c:2911
#, c-format
msgid "Cannot open file \"%s\""
msgstr "Impossible d'ouvrir le fichier \"%s\""
-#: ../quickfix.c:3429
msgid "E681: Buffer is not loaded"
msgstr "E681: le tampon n'est pas chargé"
-#: ../quickfix.c:3487
msgid "E777: String or List expected"
msgstr "E777: Chaîne ou Liste attendue"
-#: ../regexp.c:359
#, c-format
msgid "E369: invalid item in %s%%[]"
msgstr "E369: élément invalide dans %s%%[]"
-#: ../regexp.c:374
#, c-format
msgid "E769: Missing ] after %s["
msgstr "E769: ']' manquant après %s["
-#: ../regexp.c:375
#, c-format
msgid "E53: Unmatched %s%%("
msgstr "E53: Pas de correspondance pour %s%%("
-#: ../regexp.c:376
#, c-format
msgid "E54: Unmatched %s("
msgstr "E54: %s( ouvrante non fermée"
-#: ../regexp.c:377
#, c-format
msgid "E55: Unmatched %s)"
msgstr "E55: %s) fermante non ouverte"
-#: ../regexp.c:378
msgid "E66: \\z( not allowed here"
msgstr "E66: \\z( n'est pas autorisé ici"
-#: ../regexp.c:379
msgid "E67: \\z1 et al. not allowed here"
msgstr "E67: \\z1 et co. ne sont pas autorisés ici"
-#: ../regexp.c:380
#, c-format
msgid "E69: Missing ] after %s%%["
msgstr "E69: ']' manquant après %s%%["
-#: ../regexp.c:381
#, c-format
msgid "E70: Empty %s%%[]"
msgstr "E70: %s%%[] vide"
-#: ../regexp.c:1209 ../regexp.c:1224
msgid "E339: Pattern too long"
msgstr "E339: Motif trop long"
-#: ../regexp.c:1371
msgid "E50: Too many \\z("
msgstr "E50: Trop de \\z("
-#: ../regexp.c:1378
#, c-format
msgid "E51: Too many %s("
msgstr "E51: Trop de %s("
-#: ../regexp.c:1427
msgid "E52: Unmatched \\z("
msgstr "E52: Pas de correspondance pour \\z("
-#: ../regexp.c:1637
#, c-format
msgid "E59: invalid character after %s@"
msgstr "E59: caractère invalide après %s@"
-#: ../regexp.c:1672
#, c-format
msgid "E60: Too many complex %s{...}s"
msgstr "E60: Trop de %s{...}s complexes"
-#: ../regexp.c:1687
#, c-format
msgid "E61: Nested %s*"
msgstr "E61: %s* imbriqués"
-#: ../regexp.c:1690
#, c-format
msgid "E62: Nested %s%c"
msgstr "E62: %s%c imbriqués"
-#: ../regexp.c:1800
msgid "E63: invalid use of \\_"
msgstr "E63: utilisation invalide de \\_"
-#: ../regexp.c:1850
#, c-format
msgid "E64: %s%c follows nothing"
msgstr "E64: %s%c ne suit aucun atome"
-#: ../regexp.c:1902
msgid "E65: Illegal back reference"
msgstr "E65: post-référence invalide"
-#: ../regexp.c:1943
msgid "E68: Invalid character after \\z"
msgstr "E68: Caractère invalide après \\z"
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
#, c-format
msgid "E678: Invalid character after %s%%[dxouU]"
msgstr "E678: Caractère invalide après %s%%[dxouU]"
-#: ../regexp.c:2107
#, c-format
msgid "E71: Invalid character after %s%%"
msgstr "E71: Caractère invalide après %s%%"
-#: ../regexp.c:3017
#, c-format
msgid "E554: Syntax error in %s{...}"
msgstr "E554: Erreur de syntaxe dans %s{...}"
-#: ../regexp.c:3805
msgid "External submatches:\n"
msgstr "Sous-correspondances externes :\n"
-#: ../regexp.c:7022
+#, c-format
+msgid "E888: (NFA regexp) cannot repeat %s"
+msgstr "E888: (regexp NFA) %s ne peut pas être répété"
+
msgid ""
"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
"used "
@@ -5213,63 +5062,56 @@ msgstr ""
"E864: \\%#= peut être suivi uniquement de 0, 1 ou 2. Le moteur automatique "
"sera utilisé "
-#: ../regexp_nfa.c:239
+msgid "Switching to backtracking RE engine for pattern: "
+msgstr "Moteur RE avec backtracking utilisé pour le motif : "
+
msgid "E865: (NFA) Regexp end encountered prematurely"
msgstr "E865: (NFA) Fin de regexp rencontrée prématurément"
-#: ../regexp_nfa.c:240
#, c-format
msgid "E866: (NFA regexp) Misplaced %c"
msgstr "E866: (regexp NFA) %c au mauvais endroit"
-#: ../regexp_nfa.c:242
-#, fuzzy, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr "E877: (regexp NFA) Classe de caractère invalide "
+#, c-format
+msgid "E877: (NFA regexp) Invalid character class: %ld"
+msgstr "E877: (regexp NFA) Classe de caractère invalide : %ld"
-#: ../regexp_nfa.c:1261
#, c-format
msgid "E867: (NFA) Unknown operator '\\z%c'"
msgstr "E867: (NFA) Opérateur inconnu '\\z%c'"
-#: ../regexp_nfa.c:1387
-#, fuzzy, c-format
+#, c-format
msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr "E867: (NFA) Opérateur inconnu '\\z%c'"
+msgstr "E867: (NFA) Opérateur inconnu '\\%%%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"
-#: ../regexp_nfa.c:1802
#, c-format
msgid "E869: (NFA) Unknown operator '\\@%c'"
msgstr "E869: (NFA) Opérateur inconnu '\\@%c'"
-#: ../regexp_nfa.c:1831
msgid "E870: (NFA regexp) Error reading repetition limits"
msgstr "E870: (regexp NFA) Erreur à la lecture des limites de répétition"
#. Can't have a multi follow a multi.
-#: ../regexp_nfa.c:1895
msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
msgstr "E871: (regexp NFA) Un multi ne peut pas suivre un multi !"
#. Too many `('
-#: ../regexp_nfa.c:2037
msgid "E872: (NFA regexp) Too many '('"
msgstr "E872: (regexp NFA) Trop de '('"
-#: ../regexp_nfa.c:2042
-#, fuzzy
msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E872: (regexp NFA) Trop de '('"
+msgstr "E879: (regexp NFA) Trop de \\z("
-#: ../regexp_nfa.c:2066
msgid "E873: (NFA regexp) proper termination error"
msgstr "E873: (NFA regexp) erreur de terminaison"
-#: ../regexp_nfa.c:2599
msgid "E874: (NFA) Could not pop the stack !"
msgstr "E874: (NFA) Impossible de dépiler !"
-#: ../regexp_nfa.c:3298
msgid ""
"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
"left on stack"
@@ -5277,178 +5119,138 @@ msgstr ""
"E875: (regexp NFA) (lors de la conversion de postfix à NFA), il reste trop "
"d'états sur la pile"
-#: ../regexp_nfa.c:3302
msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
msgstr "E876: (regexp NFA) Pas assez de mémoire pour stocker le NFA"
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
+msgid "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, displaying on stderr ... "
msgstr ""
"Impossible d'ouvrir le fichier de log temporaire en écriture, affichage sur "
"stderr ... "
-#: ../regexp_nfa.c:4840
#, c-format
msgid "(NFA) COULD NOT OPEN %s !"
msgstr "(NFA) IMPOSSIBLE D'OUVRIR %s !"
-#: ../regexp_nfa.c:6049
msgid "Could not open temporary log file for writing "
msgstr "Impossible d'ouvrir le fichier de log en écriture"
-#: ../screen.c:7435
msgid " VREPLACE"
msgstr " VREMPLACEMENT"
-#: ../screen.c:7437
msgid " REPLACE"
msgstr " REMPLACEMENT"
# DB - todo
-#: ../screen.c:7440
msgid " REVERSE"
msgstr " REVERSE"
-#: ../screen.c:7441
msgid " INSERT"
msgstr " INSERTION"
-#: ../screen.c:7443
msgid " (insert)"
msgstr " (insertion)"
-#: ../screen.c:7445
msgid " (replace)"
msgstr " (remplacement)"
-#: ../screen.c:7447
msgid " (vreplace)"
msgstr " (vremplacement)"
-#: ../screen.c:7449
msgid " Hebrew"
msgstr " hébreu"
-#: ../screen.c:7454
msgid " Arabic"
msgstr " arabe"
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (langue)"
-
-#: ../screen.c:7459
msgid " (paste)"
msgstr " (collage)"
-#: ../screen.c:7469
msgid " VISUAL"
msgstr " VISUEL"
-#: ../screen.c:7470
msgid " VISUAL LINE"
msgstr " VISUEL LIGNE"
-#: ../screen.c:7471
msgid " VISUAL BLOCK"
msgstr " VISUEL BLOC"
-#: ../screen.c:7472
msgid " SELECT"
msgstr " SÉLECTION"
-#: ../screen.c:7473
msgid " SELECT LINE"
msgstr " SÉLECTION LIGNE"
-#: ../screen.c:7474
msgid " SELECT BLOCK"
msgstr " SÉLECTION BLOC"
-#: ../screen.c:7486 ../screen.c:7541
msgid "recording"
msgstr "Enregistrement"
-#: ../search.c:487
#, c-format
msgid "E383: Invalid search string: %s"
msgstr "E383: Chaîne de recherche invalide : %s"
-#: ../search.c:832
#, c-format
msgid "E384: search hit TOP without match for: %s"
msgstr "E384: la recherche a atteint le HAUT sans trouver : %s"
-#: ../search.c:835
#, c-format
msgid "E385: search hit BOTTOM without match for: %s"
msgstr "E385: la recherche a atteint le BAS sans trouver : %s"
-#: ../search.c:1200
msgid "E386: Expected '?' or '/' after ';'"
msgstr "E386: '?' ou '/' attendu après ';'"
-#: ../search.c:4085
msgid " (includes previously listed match)"
msgstr " (inclut des correspondances listées précédemment)"
#. cursor at status line
-#: ../search.c:4104
msgid "--- Included files "
msgstr "--- Fichiers inclus "
-#: ../search.c:4106
msgid "not found "
msgstr "introuvables "
-#: ../search.c:4107
msgid "in path ---\n"
msgstr "dans le chemin ---\n"
-#: ../search.c:4168
msgid " (Already listed)"
msgstr " (Déjà listé)"
-#: ../search.c:4170
msgid " NOT FOUND"
msgstr " INTROUVABLE"
-#: ../search.c:4211
#, c-format
msgid "Scanning included file: %s"
msgstr "Examen des fichiers inclus : %s"
-#: ../search.c:4216
#, c-format
msgid "Searching included file %s"
msgstr "Recherche du fichier inclus %s"
-#: ../search.c:4405
msgid "E387: Match is on current line"
msgstr "E387: La correspondance est sur la ligne courante"
-#: ../search.c:4517
msgid "All included files were found"
msgstr "Tous les fichiers inclus ont été trouvés"
-#: ../search.c:4519
msgid "No included files"
msgstr "Aucun fichier inclus"
-#: ../search.c:4527
msgid "E388: Couldn't find definition"
msgstr "E388: Impossible de trouver la définition"
-#: ../search.c:4529
msgid "E389: Couldn't find pattern"
msgstr "E389: Impossible de trouver le motif"
-#: ../search.c:4668
msgid "Substitute "
msgstr "Substitue "
-#: ../search.c:4681
#, c-format
msgid ""
"\n"
@@ -5459,97 +5261,129 @@ msgstr ""
"# Dernier motif de recherche %s :\n"
"~"
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: Erreur de format du fichier orthographique"
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: La vérification orthographique n'est pas activée"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
+msgstr "Alerte : Liste de mots \"%s_%s.spl\" ou \"%s_ascii.spl\" introuvable"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr "Alerte : Liste de mots \"%s.%s.spl\" ou \"%s.ascii.spl\" introuvable"
+
+msgid "E797: SpellFileMissing autocommand deleted buffer"
+msgstr "E797: L'autocommande SpellFileMissing a effacé le tampon"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Alerte : région %s non supportée"
+
+msgid "Sorry, no suggestions"
+msgstr "Désolé, aucune suggestion"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Désolé, seulement %ld suggestions"
+
+#. 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"
-#: ../spell.c:952
msgid "E758: Truncated spell file"
msgstr "E758: Fichier orthographique tronqué"
-#: ../spell.c:953
#, c-format
msgid "Trailing text in %s line %d: %s"
msgstr "Texte en trop dans %s ligne %d : %s"
-#: ../spell.c:954
#, c-format
msgid "Affix name too long in %s line %d: %s"
msgstr "Nom d'affixe trop long dans %s ligne %d : %s"
-#: ../spell.c:955
msgid "E761: Format error in affix file FOL, LOW or UPP"
msgstr "E761: Erreur de format dans le fichier d'affixe FOL, LOW et UPP"
-#: ../spell.c:957
msgid "E762: Character in FOL, LOW or UPP is out of range"
msgstr "E762: Un caractère dans FOL, LOW ou UPP est hors-limites"
-#: ../spell.c:958
msgid "Compressing word tree..."
msgstr "Compression de l'arbre des mots"
-#: ../spell.c:1951
-msgid "E756: Spell checking is not enabled"
-msgstr "E756: La vérification orthographique n'est pas activée"
-
-#: ../spell.c:2249
-#, c-format
-msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
-msgstr "Alerte : Liste de mots \"%s.%s.spl\" ou \"%s.ascii.spl\" introuvable"
-
-#: ../spell.c:2473
#, c-format
msgid "Reading spell file \"%s\""
msgstr "Lecture du fichier orthographique \"%s\""
-#: ../spell.c:2496
msgid "E757: This does not look like a spell file"
msgstr "E757: Le fichier ne ressemble pas à un fichier orthographique"
-#: ../spell.c:2501
msgid "E771: Old spell file, needs to be updated"
msgstr "E771: Fichier orthographique obsolète, sa mise à jour est nécessaire"
-#: ../spell.c:2504
msgid "E772: Spell file is for newer version of Vim"
msgstr "E772: Le fichier est prévu pour une version de Vim plus récente"
-#: ../spell.c:2602
msgid "E770: Unsupported section in spell file"
msgstr "E770: Section non supportée dans le fichier orthographique"
-#: ../spell.c:3762
#, c-format
-msgid "Warning: region %s not supported"
-msgstr "Alerte : région %s non supportée"
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: %s ne semble pas être un fichier .sug"
+
+#, 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"
-#: ../spell.c:4550
#, c-format
msgid "Reading affix file %s ..."
msgstr "Lecture du fichier d'affixes %s..."
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
msgid "Conversion failure for word in %s line %d: %s"
msgstr "Échec de conversion du mot dans %s ligne %d : %s"
-#: ../spell.c:4630 ../spell.c:6170
#, c-format
msgid "Conversion in %s not supported: from %s to %s"
msgstr "La conversion dans %s non supportée : de %s vers %s"
-#: ../spell.c:4642
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "La conversion dans %s non supportée"
+
#, c-format
msgid "Invalid value for FLAG in %s line %d: %s"
msgstr "Valeur de FLAG invalide dans %s ligne %d : %s"
-#: ../spell.c:4655
#, c-format
msgid "FLAG after using flags in %s line %d: %s"
msgstr "FLAG trouvé après des drapeaux dans %s ligne %d : %s"
-#: ../spell.c:4723
#, c-format
msgid ""
"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
@@ -5558,7 +5392,6 @@ msgstr ""
"Définir COMPOUNDFORBIDFLAG après des PFX peut donner des résultats erronés "
"dans %s ligne %d"
-#: ../spell.c:4731
#, c-format
msgid ""
"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
@@ -5567,45 +5400,37 @@ msgstr ""
"Définir COMPOUNDPERMITFLAG après des PFX peut donner des résultats erronés "
"dans %s ligne %d"
-#: ../spell.c:4747
#, c-format
msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
msgstr "Valeur de COMPOUNDRULES erronée dans %s ligne %d : %s"
-#: ../spell.c:4771
#, c-format
msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
msgstr "Valeur de COMPOUNDWORDMAX erronée dans %s ligne %d : %s"
-#: ../spell.c:4777
#, c-format
msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
msgstr "Valeur de COMPOUNDMIN erronée dans %s ligne %d : %s"
-#: ../spell.c:4783
#, c-format
msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
msgstr "Valeur de COMPOUNDSYLMAX erronée dans %s ligne %d : %s"
-#: ../spell.c:4795
#, c-format
msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
msgstr "Valeur de CHECKCOMPOUNDPATTERN erronée dans %s ligne %d : %s"
# DB - TODO
-#: ../spell.c:4847
#, c-format
msgid "Different combining flag in continued affix block in %s line %d: %s"
msgstr ""
"Drapeaux de composition différents dans un bloc d'affixes continu dans %s "
"ligne %d : %s"
-#: ../spell.c:4850
#, c-format
msgid "Duplicate affix in %s line %d: %s"
msgstr "Affixe dupliqué dans %s ligne %d : %s"
-#: ../spell.c:4871
#, c-format
msgid ""
"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
@@ -5614,339 +5439,233 @@ msgstr ""
"Affixe aussi utilisée pour BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/"
"NOSUGGEST dans %s ligne %d : %s"
-#: ../spell.c:4893
#, c-format
msgid "Expected Y or N in %s line %d: %s"
msgstr "Y ou N attendu dans %s ligne %d : %s"
# DB - todo (regexp impossible à compiler...)
-#: ../spell.c:4968
#, c-format
msgid "Broken condition in %s line %d: %s"
msgstr "Condition non valide dans %s ligne %d : %s"
-#: ../spell.c:5091
#, c-format
msgid "Expected REP(SAL) count in %s line %d"
msgstr "Nombre de REP(SAL) attendu dans %s ligne %d"
-#: ../spell.c:5120
#, c-format
msgid "Expected MAP count in %s line %d"
msgstr "Nombre de MAP attendu dans %s ligne %d"
-#: ../spell.c:5132
#, c-format
msgid "Duplicate character in MAP in %s line %d"
msgstr "Caractère dupliqué dans MAP dans %s ligne %d"
-#: ../spell.c:5176
#, c-format
msgid "Unrecognized or duplicate item in %s line %d: %s"
msgstr "Élément non reconnu ou dupliqué dans %s ligne %d : %s"
-#: ../spell.c:5197
#, c-format
msgid "Missing FOL/LOW/UPP line in %s"
msgstr "Ligne FOL/LOW/UPP manquante dans %s"
-#: ../spell.c:5220
msgid "COMPOUNDSYLMAX used without SYLLABLE"
msgstr "Utilisation de COMPOUNDSYLMAX sans SYLLABLE"
-#: ../spell.c:5236
msgid "Too many postponed prefixes"
msgstr "Trop de préfixes reportés (PFXPOSTPONE)"
-#: ../spell.c:5238
msgid "Too many compound flags"
msgstr "Trop de drapeaux de composition"
-#: ../spell.c:5240
msgid "Too many postponed prefixes and/or compound flags"
msgstr "Trop de préfixes reportés et/ou de drapeaux de composition"
-#: ../spell.c:5250
#, c-format
msgid "Missing SOFO%s line in %s"
msgstr "Ligne SOFO%s manquante dans %s"
-#: ../spell.c:5253
#, c-format
msgid "Both SAL and SOFO lines in %s"
msgstr "Lignes SAL et lignes SOFO présentes dans %s"
-#: ../spell.c:5331
#, c-format
msgid "Flag is not a number in %s line %d: %s"
msgstr "Le drapeau n'est pas un nombre dans %s ligne %d : %s"
-#: ../spell.c:5334
#, c-format
msgid "Illegal flag in %s line %d: %s"
msgstr "Drapeau non autorisé dans %s ligne %d : %s"
-#: ../spell.c:5493 ../spell.c:5501
#, c-format
msgid "%s value differs from what is used in another .aff file"
msgstr "La valeur de %s est différente de celle d'un autre fichier .aff"
-#: ../spell.c:5602
#, c-format
msgid "Reading dictionary file %s ..."
msgstr "Lecture du fichier orthographique %s..."
-#: ../spell.c:5611
#, c-format
msgid "E760: No word count in %s"
msgstr "E760: Nombre de mots non indiqué dans %s"
-#: ../spell.c:5669
#, c-format
msgid "line %6d, word %6d - %s"
msgstr "ligne %6d, mot %6d - %s"
-#: ../spell.c:5691
#, c-format
msgid "Duplicate word in %s line %d: %s"
msgstr "Mot dupliqué dans %s ligne %d : %s"
-#: ../spell.c:5694
#, c-format
msgid "First duplicate word in %s line %d: %s"
msgstr "Premier mot dupliqué dans %s ligne %d : %s"
-#: ../spell.c:5746
#, c-format
msgid "%d duplicate word(s) in %s"
msgstr "%d mot(s) dupliqué(s) dans %s"
-#: ../spell.c:5748
#, c-format
msgid "Ignored %d word(s) with non-ASCII characters in %s"
msgstr "%d mot(s) ignoré(s) avec des caractères non-ASCII dans %s"
-#: ../spell.c:6115
#, c-format
msgid "Reading word file %s ..."
msgstr "Lecture de la liste de mots %s..."
-#: ../spell.c:6155
#, c-format
msgid "Duplicate /encoding= line ignored in %s line %d: %s"
msgstr "Ligne /encoding= en double ignorée dans %s ligne %d : %s"
-#: ../spell.c:6159
#, c-format
msgid "/encoding= line after word ignored in %s line %d: %s"
msgstr "Ligne /encoding= après des mots ignorée dans %s ligne %d : %s"
-#: ../spell.c:6180
#, c-format
msgid "Duplicate /regions= line ignored in %s line %d: %s"
msgstr "Ligne /regions= en double ignorée dans %s ligne %d : %s"
-#: ../spell.c:6185
#, c-format
msgid "Too many regions in %s line %d: %s"
msgstr "Trop de régions dans %s ligne %d : %s"
-#: ../spell.c:6198
#, c-format
msgid "/ line ignored in %s line %d: %s"
msgstr "Ligne / ignorée dans %s ligne %d : %s"
-#: ../spell.c:6224
#, c-format
msgid "Invalid region nr in %s line %d: %s"
msgstr "Numéro de région invalide dans %s ligne %d : %s"
-#: ../spell.c:6230
#, c-format
msgid "Unrecognized flags in %s line %d: %s"
msgstr "Drapeaux non reconnus dans %s ligne %d : %s"
-#: ../spell.c:6257
#, c-format
msgid "Ignored %d words with non-ASCII characters"
msgstr "%d mot(s) ignoré(s) avec des caractères non-ASCII"
-#: ../spell.c:6656
+msgid "E845: Insufficient memory, word list will be incomplete"
+msgstr "E845: mémoire insuffisante, liste de mots peut-être incomplète"
+
#, c-format
msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
msgstr "%d noeuds compressés sur %d ; %d (%d%%) restants "
-#: ../spell.c:7340
msgid "Reading back spell file..."
msgstr "Relecture du fichier orthographique"
-#. Go through the trie of good words, soundfold each word and add it to
-#. the soundfold trie.
-#: ../spell.c:7357
+#.
+#. * 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..."
-#: ../spell.c:7368
#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "Nombre de mots après l'analyse phonétique : %<PRId64>"
+msgid "Number of words after soundfolding: %ld"
+msgstr "Nombre de mots après l'analyse phonétique : %ld"
-#: ../spell.c:7476
#, c-format
msgid "Total number of words: %d"
msgstr "Nombre total de mots : %d"
-#: ../spell.c:7655
#, c-format
msgid "Writing suggestion file %s ..."
msgstr "Écriture du fichier de suggestions %s..."
-#: ../spell.c:7707 ../spell.c:7927
#, c-format
msgid "Estimated runtime memory use: %d bytes"
msgstr "Estimation de mémoire consommée : %d octets"
-#: ../spell.c:7820
msgid "E751: Output file name must not have region name"
msgstr "E751: Le nom du fichier ne doit pas contenir de nom de région"
-#: ../spell.c:7822
msgid "E754: Only up to 8 regions supported"
msgstr "E754: 8 régions au maximum sont supportées"
-#: ../spell.c:7846
#, c-format
msgid "E755: Invalid region in %s"
msgstr "E755: Région invalide dans %s"
-#: ../spell.c:7907
msgid "Warning: both compounding and NOBREAK specified"
msgstr "Alerte : la composition et NOBREAK sont tous les deux spécifiés"
-#: ../spell.c:7920
#, c-format
msgid "Writing spell file %s ..."
msgstr "Écriture du fichier orthographique %s..."
-#: ../spell.c:7925
msgid "Done!"
msgstr "Terminé !"
# DB - todo : perfectible.
-#: ../spell.c:8034
#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: 'spellfile' n'a pas %<PRId64> entrées"
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' n'a pas %ld entrées"
-#: ../spell.c:8074
-#, fuzzy, c-format
+#, c-format
msgid "Word '%.*s' removed from %s"
-msgstr "Mot retiré de %s"
+msgstr "Mot '%.*s' retiré de %s"
-#: ../spell.c:8117
-#, fuzzy, c-format
+#, c-format
msgid "Word '%.*s' added to %s"
-msgstr "Mot ajouté dans %s"
+msgstr "Mot '%.*s' ajouté dans %s"
-#: ../spell.c:8381
msgid "E763: Word characters differ between spell files"
msgstr ""
"E763: Les caractères de mots diffèrent entre les fichiers orthographiques"
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "Désolé, aucune suggestion"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "Désolé, seulement %<PRId64> suggestions"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "Remplacer \"%.*s\" par :"
-
-# DB - todo : l'intérêt de traduire ce message m'échappe.
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < \"%.*s\""
-
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: Pas de suggestion orthographique précédente"
-
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: Introuvable : %s"
-
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: %s ne semble pas être un fichier .sug"
-
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: Fichier de suggestions obsolète, mise à jour nécessaire : %s"
-
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: Fichier .sug prévu pour une version de Vim plus récente : %s"
-
-#: ../spell.c:9295
-#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr "E781: Le fichier .sug ne correspond pas au fichier .spl : %s"
-
-#: ../spell.c:9305
-#, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E782: Erreur lors de la lecture de fichier de suggestions : %s"
-
#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
+#. * file.
msgid "E783: duplicate char in MAP entry"
-msgstr "E783: caractères dupliqué dans l'entrée MAP"
+msgstr "E783: caractère dupliqué dans l'entrée MAP"
-#: ../syntax.c:266
msgid "No Syntax items defined for this buffer"
msgstr "Aucun élément de syntaxe défini pour ce tampon"
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
#, c-format
msgid "E390: Illegal argument: %s"
msgstr "E390: Argument invalide : %s"
-#: ../syntax.c:3299
+msgid "syntax iskeyword "
+msgstr "syntaxe iskeyword "
+
#, c-format
msgid "E391: No such syntax cluster: %s"
msgstr "E391: Aucune grappe de syntaxe %s"
-#: ../syntax.c:3433
msgid "syncing on C-style comments"
msgstr "synchronisation sur les commentaires de type C"
-#: ../syntax.c:3439
msgid "no syncing"
msgstr "Aucune synchronisation"
# DB - Les deux messages qui suivent vont ensemble.
-#: ../syntax.c:3441
msgid "syncing starts "
msgstr "La synchronisation débute "
-#: ../syntax.c:3443 ../syntax.c:3506
msgid " lines before top line"
msgstr " lignes avant la ligne du haut"
-#: ../syntax.c:3448
msgid ""
"\n"
"--- Syntax sync items ---"
@@ -5954,7 +5673,6 @@ msgstr ""
"\n"
"--- Éléments de synchronisation syntaxique ---"
-#: ../syntax.c:3452
msgid ""
"\n"
"syncing on items"
@@ -5962,7 +5680,6 @@ msgstr ""
"\n"
"synchronisation sur éléments"
-#: ../syntax.c:3457
msgid ""
"\n"
"--- Syntax items ---"
@@ -5970,275 +5687,220 @@ msgstr ""
"\n"
"--- Éléments de syntaxe ---"
-#: ../syntax.c:3475
#, c-format
msgid "E392: No such syntax cluster: %s"
msgstr "E392: Aucune grappe de syntaxe %s"
-#: ../syntax.c:3497
msgid "minimal "
msgstr "minimum "
-#: ../syntax.c:3503
msgid "maximal "
msgstr "maximum "
# DB - todo
-#: ../syntax.c:3513
msgid "; match "
msgstr "; correspond avec "
# DB - todo
-#: ../syntax.c:3515
msgid " line breaks"
msgstr " coupures de ligne"
-#: ../syntax.c:4076
msgid "E395: contains argument not accepted here"
msgstr "E395: L'argument « contains » n'est pas accepté ici"
-#: ../syntax.c:4096
msgid "E844: invalid cchar value"
msgstr "E844: valeur de cchar invalide"
-#: ../syntax.c:4107
msgid "E393: group[t]here not accepted here"
msgstr "E393: L'argument « group[t]here » n'est pas accepté ici"
-#: ../syntax.c:4126
#, c-format
msgid "E394: Didn't find region item for %s"
msgstr "E394: Aucun élément de type région trouvé pour %s"
-#: ../syntax.c:4188
msgid "E397: Filename required"
msgstr "E397: Nom de fichier requis"
-#: ../syntax.c:4221
msgid "E847: Too many syntax includes"
msgstr "E847: Trop d'inclusions de syntaxe"
-#: ../syntax.c:4303
#, c-format
msgid "E789: Missing ']': %s"
msgstr "E789: ']' manquant : %s"
-#: ../syntax.c:4531
+#, c-format
+msgid "E890: trailing char after ']': %s]%s"
+msgstr "E890: Caractère surnuméraire après ']': %s]%s"
+
#, c-format
msgid "E398: Missing '=': %s"
msgstr "E398: '=' manquant : %s"
-#: ../syntax.c:4666
#, c-format
msgid "E399: Not enough arguments: syntax region %s"
msgstr "E399: Pas assez d'arguments : syntax region %s"
-#: ../syntax.c:4870
msgid "E848: Too many syntax clusters"
msgstr "E848: Trop de grappes de syntaxe"
-#: ../syntax.c:4954
msgid "E400: No cluster specified"
msgstr "E400: Aucune grappe spécifiée"
-#. end delimiter not found
-#: ../syntax.c:4986
#, c-format
msgid "E401: Pattern delimiter not found: %s"
msgstr "E401: Délimiteur de motif introuvable : %s"
-#: ../syntax.c:5049
#, c-format
msgid "E402: Garbage after pattern: %s"
msgstr "E402: caractères en trop après le motif : %s"
-#: ../syntax.c:5120
msgid "E403: syntax sync: line continuations pattern specified twice"
msgstr ""
"E403: synchro syntax : motif de continuation de ligne présent deux fois"
-#: ../syntax.c:5169
#, c-format
msgid "E404: Illegal arguments: %s"
msgstr "E404: Arguments invalides : %s"
-#: ../syntax.c:5217
#, c-format
msgid "E405: Missing equal sign: %s"
msgstr "E405: '=' manquant : %s"
-#: ../syntax.c:5222
#, c-format
msgid "E406: Empty argument: %s"
msgstr "E406: Argument vide : %s"
-#: ../syntax.c:5240
#, c-format
msgid "E407: %s not allowed here"
msgstr "E407: %s n'est pas autorisé ici"
-#: ../syntax.c:5246
#, c-format
msgid "E408: %s must be first in contains list"
msgstr "E408: %s doit être le premier élément d'une liste « contains »"
-#: ../syntax.c:5304
#, c-format
msgid "E409: Unknown group name: %s"
msgstr "E409: Nom de groupe inconnu : %s"
-#: ../syntax.c:5512
#, c-format
msgid "E410: Invalid :syntax subcommand: %s"
msgstr "E410: Sous-commande de :syntax invalide : %s"
-#: ../syntax.c:5854
msgid ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
msgstr ""
+" TOTAL NOMBRE MATCH PLUS LENT MOYEN NOM MOTIF"
-#: ../syntax.c:6146
msgid "E679: recursive loop loading syncolor.vim"
msgstr "E679: boucle récursive lors du chargement de syncolor.vim"
-#: ../syntax.c:6256
#, c-format
msgid "E411: highlight group not found: %s"
msgstr "E411: groupe de surbrillance introuvable : %s"
-#: ../syntax.c:6278
#, c-format
msgid "E412: Not enough arguments: \":highlight link %s\""
msgstr "E412: Trop peu d'arguments : \":highlight link %s\""
-#: ../syntax.c:6284
#, c-format
msgid "E413: Too many arguments: \":highlight link %s\""
msgstr "E413: Trop d'arguments : \":highlight link %s\""
-#: ../syntax.c:6302
msgid "E414: group has settings, highlight link ignored"
msgstr "E414: le groupe a déjà des attributs, lien de surbrillance ignoré"
-#: ../syntax.c:6367
#, c-format
msgid "E415: unexpected equal sign: %s"
msgstr "E415: signe égal inattendu : %s"
-#: ../syntax.c:6395
#, c-format
msgid "E416: missing equal sign: %s"
msgstr "E416: '=' manquant : %s"
-#: ../syntax.c:6418
#, c-format
msgid "E417: missing argument: %s"
msgstr "E417: argument manquant : %s"
-#: ../syntax.c:6446
#, c-format
msgid "E418: Illegal value: %s"
msgstr "E418: Valeur invalide : %s"
-#: ../syntax.c:6496
msgid "E419: FG color unknown"
msgstr "E419: Couleur de premier plan inconnue"
-#: ../syntax.c:6504
msgid "E420: BG color unknown"
msgstr "E420: Couleur d'arrière-plan inconnue"
-#: ../syntax.c:6564
#, c-format
msgid "E421: Color name or number not recognized: %s"
msgstr "E421: Nom ou numéro de couleur non reconnu : %s"
-#: ../syntax.c:6714
#, c-format
msgid "E422: terminal code too long: %s"
msgstr "E422: le code de terminal est trop long : %s"
-#: ../syntax.c:6753
#, c-format
msgid "E423: Illegal argument: %s"
msgstr "E423: Argument invalide : %s"
-#: ../syntax.c:6925
msgid "E424: Too many different highlighting attributes in use"
msgstr ""
"E424: Trop d'attributs de surbrillance différents en cours d'utilisation"
-#: ../syntax.c:7427
msgid "E669: Unprintable character in group name"
msgstr "E669: Caractère non-imprimable dans un nom de groupe"
-#: ../syntax.c:7434
msgid "W18: Invalid character in group name"
msgstr "W18: Caractère invalide dans un nom de groupe"
-#: ../syntax.c:7448
msgid "E849: Too many highlight and syntax groups"
msgstr "E849: Trop de groupes de surbrillance et de syntaxe"
-#: ../tag.c:104
msgid "E555: at bottom of tag stack"
msgstr "E555: En bas de la pile de marqueurs"
-#: ../tag.c:105
msgid "E556: at top of tag stack"
msgstr "E556: Au sommet de la pile de marqueurs"
-#: ../tag.c:380
msgid "E425: Cannot go before first matching tag"
msgstr "E425: Impossible d'aller avant le premier marqueur correspondant"
-#: ../tag.c:504
#, c-format
msgid "E426: tag not found: %s"
msgstr "E426: Marqueur introuvable : %s"
-#: ../tag.c:528
msgid " # pri kind tag"
msgstr " # pri type marqueur"
-#: ../tag.c:531
msgid "file\n"
msgstr "fichier\n"
-#: ../tag.c:829
msgid "E427: There is only one matching tag"
msgstr "E427: Il n'y a qu'un marqueur correspondant"
-#: ../tag.c:831
msgid "E428: Cannot go beyond last matching tag"
msgstr "E428: Impossible d'aller au-delà du dernier marqueur correspondant"
-#: ../tag.c:850
#, c-format
msgid "File \"%s\" does not exist"
msgstr "Le fichier \"%s\" n'existe pas"
#. Give an indication of the number of matching tags
-#: ../tag.c:859
#, c-format
msgid "tag %d of %d%s"
msgstr "marqueur %d sur %d%s"
-#: ../tag.c:862
msgid " or more"
msgstr " ou plus"
-#: ../tag.c:864
msgid " Using tag with different case!"
msgstr " Utilisation d'un marqueur avec une casse différente !"
-#: ../tag.c:909
#, c-format
msgid "E429: File \"%s\" does not exist"
msgstr "E429: Le fichier \"%s\" n'existe pas"
#. Highlight title
-#: ../tag.c:960
msgid ""
"\n"
" # TO tag FROM line in file/text"
@@ -6246,80 +5908,67 @@ msgstr ""
"\n"
" # VERS marqueur DE ligne dans le fichier/texte"
-#: ../tag.c:1303
#, c-format
msgid "Searching tags file %s"
msgstr "Examen du fichier de marqueurs %s"
-#: ../tag.c:1545
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Chemin de fichiers de marqueurs tronqué pour %s\n"
+
msgid "Ignoring long line in tags file"
msgstr "Ignore longue ligne dans le fichier de marqueurs"
-#: ../tag.c:1915
#, c-format
msgid "E431: Format error in tags file \"%s\""
msgstr "E431: Erreur de format dans le fichier de marqueurs \"%s\""
-#: ../tag.c:1917
#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "Avant l'octet %<PRId64>"
+msgid "Before byte %ld"
+msgstr "Avant l'octet %ld"
-#: ../tag.c:1929
#, c-format
msgid "E432: Tags file not sorted: %s"
msgstr "E432: Le fichier de marqueurs %s n'est pas ordonné"
#. never opened any tags file
-#: ../tag.c:1960
msgid "E433: No tags file"
msgstr "E433: Aucun fichier de marqueurs"
-#: ../tag.c:2536
msgid "E434: Can't find tag pattern"
msgstr "E434: Le motif de marqueur est introuvable"
-#: ../tag.c:2544
msgid "E435: Couldn't find tag, just guessing!"
msgstr "E435: Marqueur introuvable, tentative pour deviner !"
-#: ../tag.c:2797
#, c-format
msgid "Duplicate field name: %s"
msgstr "Nom de champ dupliqué : %s"
-#: ../term.c:1442
msgid "' not known. Available builtin terminals are:"
msgstr "' inconnu. Les terminaux intégrés sont :"
-#: ../term.c:1463
msgid "defaulting to '"
msgstr "utilisation par défaut de '"
-#: ../term.c:1731
msgid "E557: Cannot open termcap file"
msgstr "E557: Impossible d'ouvrir le fichier termcap"
-#: ../term.c:1735
msgid "E558: Terminal entry not found in terminfo"
msgstr "E558: La description du terminal est introuvable dans terminfo"
-#: ../term.c:1737
msgid "E559: Terminal entry not found in termcap"
msgstr "E559: La description du terminal est introuvable dans termcap"
-#: ../term.c:1878
#, c-format
msgid "E436: No \"%s\" entry in termcap"
msgstr "E436: Aucune entrée \"%s\" dans termcap"
# DB - todo : Comment améliorer ?
-#: ../term.c:2249
msgid "E437: terminal capability \"cm\" required"
msgstr "E437: capacité de terminal \"cm\" requise"
#. Highlight title
-#: ../term.c:4376
msgid ""
"\n"
"--- Terminal keys ---"
@@ -6327,174 +5976,365 @@ msgstr ""
"\n"
"--- Touches du terminal ---"
-#: ../ui.c:481
+msgid "Cannot open $VIMRUNTIME/rgb.txt"
+msgstr "Impossible d'ouvrir $VIMRUNTIME/rgb.txt"
+
+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.
-#: ../undo.c:379
-#, fuzzy
msgid "E881: Line count changed unexpectedly"
-msgstr "E834: Le nombre de lignes a été changé inopinément"
+msgstr "E881: Le nombre de lignes a été changé inopinément"
+
+# DB - Question O/N.
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Annulation impossible ; continuer"
-#: ../undo.c:627
#, c-format
msgid "E828: Cannot open undo file for writing: %s"
msgstr "E828: Impossible d'ouvrir le fichier d'annulations en écriture : %s"
-#: ../undo.c:717
#, c-format
msgid "E825: Corrupted undo file (%s): %s"
msgstr "E825: Fichier d'annulations corrompu (%s) : %s"
-#: ../undo.c:1039
msgid "Cannot write undo file in any directory in 'undodir'"
msgstr ""
"Impossible d'écrire le fichier d'annulations dans n'importe quel répertoire "
"de 'undodir'"
-#: ../undo.c:1074
#, c-format
msgid "Will not overwrite with undo file, cannot read: %s"
msgstr "Le fichier d'annulations ne sera pas écrasé, impossible de lire : %s"
-#: ../undo.c:1092
#, c-format
msgid "Will not overwrite, this is not an undo file: %s"
msgstr "Fichier ne sera pas écrasé, ce n'est pas un fichier d'annulations : %s"
-#: ../undo.c:1108
msgid "Skipping undo file write, nothing to undo"
msgstr "Le fichier d'annulations n'est pas écrit, rien à annuler"
-#: ../undo.c:1121
#, c-format
msgid "Writing undo file: %s"
msgstr "Écriture du fichier d'annulations : %s"
-#: ../undo.c:1213
#, c-format
msgid "E829: write error in undo file: %s"
msgstr "E829: Erreur d'écriture dans le fichier d'annulations : %s"
-#: ../undo.c:1280
#, c-format
msgid "Not reading undo file, owner differs: %s"
msgstr "Le fichier d'annulations n'est pas lu, propriétaire différent : %s"
-#: ../undo.c:1292
#, c-format
msgid "Reading undo file: %s"
msgstr "Lecture du fichier d'annulations : %s..."
-#: ../undo.c:1299
#, c-format
msgid "E822: Cannot open undo file for reading: %s"
msgstr "E822: Impossible d'ouvrir le fichier d'annulations en lecture : %s"
-#: ../undo.c:1308
#, c-format
msgid "E823: Not an undo file: %s"
msgstr "E823: Ce n'est pas un fichier d'annulations : %s"
-#: ../undo.c:1313
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: Fichier non-chiffré a un fichier d'annulations chiffré : %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: Déchiffrage du fichier d'annulation a échoué : %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: Le fichier d'annulations est chiffré : %s"
+
#, c-format
msgid "E824: Incompatible undo file: %s"
msgstr "E824: Fichier d'annulations incompatible : %s"
-#: ../undo.c:1328
msgid "File contents changed, cannot use undo info"
msgstr ""
"Le contenu du fichier a changé, impossible d'utiliser les informations "
"d'annulation"
-#: ../undo.c:1497
#, c-format
msgid "Finished reading undo file %s"
msgstr "Fin de lecture du fichier d'annulations %s"
-#: ../undo.c:1586 ../undo.c:1812
msgid "Already at oldest change"
msgstr "Déjà à la modification la plus ancienne"
-#: ../undo.c:1597 ../undo.c:1814
msgid "Already at newest change"
msgstr "Déjà à la modification la plus récente"
-#: ../undo.c:1806
#, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E830: Annulation n° %<PRId64> introuvable"
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Annulation n° %ld introuvable"
-#: ../undo.c:1979
msgid "E438: u_undo: line numbers wrong"
msgstr "E438: u_undo : numéros de ligne erronés"
-#: ../undo.c:2183
msgid "more line"
msgstr "ligne en plus"
-#: ../undo.c:2185
msgid "more lines"
msgstr "lignes en plus"
-#: ../undo.c:2187
msgid "line less"
msgstr "ligne en moins"
-#: ../undo.c:2189
msgid "fewer lines"
msgstr "lignes en moins"
-#: ../undo.c:2193
msgid "change"
msgstr "modification"
-#: ../undo.c:2195
msgid "changes"
msgstr "modifications"
-#: ../undo.c:2225
#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s ; %s #%<PRId64> ; %s"
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s ; %s #%ld ; %s"
-#: ../undo.c:2228
msgid "before"
msgstr "avant"
-#: ../undo.c:2228
msgid "after"
msgstr "après"
-#: ../undo.c:2325
msgid "Nothing to undo"
msgstr "Rien à annuler"
# DB - Les deux premières colonnes sont alignées à droite.
-#: ../undo.c:2330
msgid "number changes when saved"
msgstr "numéro modif. instant enregistré"
-#: ../undo.c:2360
#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "il y a %<PRId64> secondes"
+msgid "%ld seconds ago"
+msgstr "il y a %ld secondes"
-#: ../undo.c:2372
msgid "E790: undojoin is not allowed after undo"
msgstr "E790: undojoin n'est pas autorisé après une annulation"
-#: ../undo.c:2466
msgid "E439: undo list corrupt"
msgstr "E439: la liste d'annulation est corrompue"
-#: ../undo.c:2495
msgid "E440: undo line missing"
msgstr "E440: ligne d'annulation manquante"
-#: ../version.c:600
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: La fonction %s existe déjà (ajoutez ! pour la remplacer)"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Une entrée du Dictionnaire porte déjà ce nom"
+
+msgid "E718: Funcref required"
+msgstr "E718: Référence de fonction (Funcref) requise"
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Fonction inconnue : %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Argument invalide : %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Nom d'argument dupliqué : %s"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: Trop d'arguments pour la fonction %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Arguments invalides pour la fonction %s"
+
+# AB - Vérifier dans la littérature technique s'il n'existe pas une meilleure
+# traduction pour "function call depth".
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr ""
+"E132: La profondeur d'appel de fonction est supérieure à 'maxfuncdepth'"
+
+# AB - Ce texte fait partie d'un message de débogage.
+#, c-format
+msgid "calling %s"
+msgstr "appel de %s"
+
+# AB - Vérifier.
+#, c-format
+msgid "%s aborted"
+msgstr "%s annulée"
+
+# AB - Ce texte fait partie d'un message de débogage.
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s a retourné #%ld"
+
+# AB - Ce texte fait partie d'un message de débogage.
+#, c-format
+msgid "%s returning %s"
+msgstr "%s a retourné \"%s\""
+
+msgid "E699: Too many arguments"
+msgstr "E699: Trop d'arguments"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Fonction inconnue : %s"
+
+#, c-format
+msgid "E933: Function was deleted: %s"
+msgstr "E933: La fonction a été effacée: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: La fonction %s n'a pas reçu assez d'arguments"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: <SID> utilisé en dehors d'un script : %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Appel d'une fonction « dict » sans Dictionnaire : %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Nom de fonction requis"
+
+#, c-format
+msgid "E128: Function name must start with a capital or \"s:\": %s"
+msgstr ""
+"E128: Le nom de la fonction doit commencer par une majuscule ou \"s:\": %s"
+
+#, c-format
+msgid "E884: Function name cannot contain a colon: %s"
+msgstr ""
+"E884: Le nom de la fonction ne peut pas contenir le caractère deux-points : "
+"%s"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Fonction non définie : %s"
+
+# AB - La version française est plus consistante que la version anglaise.
+# AB - Je suis partagé entre la concision d'une traduction assez littérale et
+# la lourdeur d'une traduction plus correcte.
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Il manque '(' après %s"
+
+msgid "E862: Cannot use g: here"
+msgstr "E862: Impossible d'utiliser g: ici"
+
+#, c-format
+msgid "E932: Closure function should not be at top level: %s"
+msgstr ""
+"E932: une fonction fermeture ne devrait pas être au niveau principal : %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Il manque :endfunction"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: Le nom de fonction entre en conflit avec la variable : %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: Impossible de redéfinir fonction %s : déjà utilisée"
+
+# DB - Le contenu du "c-format" est le nom de la fonction.
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Le nom de la fonction %s ne correspond pas le nom du script"
+
+# AB - Il est difficile de créer une version française qui fasse moins de 80
+# caractères de long, nom de la fonction compris : "It is in use" est une
+# expression très dense. Traductions possibles : "elle est utilisée",
+# "elle s'exécute" ou "elle est occupée".
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Impossible d'effacer %s : cette fonction est utilisée"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return en dehors d'une fonction"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Parenthèses manquantes : %s"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"Version graphique MS-Windows 64 bits"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"Version graphique MS-Windows 32 bits"
+
+msgid " with OLE support"
+msgstr " supportant l'OLE"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit console version"
+msgstr ""
+"\n"
+"Version console MS-Windows 64 bits"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"Version console MS-Windows 32 bits"
+
+msgid ""
+"\n"
+"MacOS 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: "
@@ -6502,7 +6342,6 @@ msgstr ""
"\n"
"Rustines incluses : "
-#: ../version.c:627
msgid ""
"\n"
"Extra patches: "
@@ -6510,11 +6349,9 @@ msgstr ""
"\n"
"Rustines extra : "
-#: ../version.c:639 ../version.c:864
msgid "Modified by "
msgstr "Modifié par "
-#: ../version.c:646
msgid ""
"\n"
"Compiled "
@@ -6522,11 +6359,9 @@ msgstr ""
"\n"
"Compilé "
-#: ../version.c:649
msgid "by "
msgstr "par "
-#: ../version.c:660
msgid ""
"\n"
"Huge version "
@@ -6534,1872 +6369,949 @@ msgstr ""
"\n"
"Énorme version "
-#: ../version.c:661
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Grosse version "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Version normale "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Petite version "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Version minuscule "
+
msgid "without GUI."
msgstr "sans interface graphique."
-#: ../version.c:662
+msgid "with GTK3 GUI."
+msgstr "avec interface graphique GTK3."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "avec interface graphique GTK2-GNOME."
+
+msgid "with GTK2 GUI."
+msgstr "avec interface graphique GTK2."
+
+msgid "with X11-Motif GUI."
+msgstr "avec interface graphique X11-Motif."
+
+msgid "with X11-neXtaw GUI."
+msgstr "avec interface graphique X11-neXtaw."
+
+msgid "with X11-Athena GUI."
+msgstr "avec interface graphique X11-Athena."
+
+msgid "with Photon GUI."
+msgstr "avec interface graphique Photon."
+
+msgid "with GUI."
+msgstr "avec une interface graphique."
+
+msgid "with Carbon GUI."
+msgstr "avec interface graphique Carbon."
+
+msgid "with Cocoa GUI."
+msgstr "avec interface graphique Cocoa."
+
+msgid "with (classic) GUI."
+msgstr "avec interface graphique (classic)."
+
msgid " Features included (+) or not (-):\n"
msgstr " Fonctionnalités incluses (+) ou non (-) :\n"
-#: ../version.c:667
msgid " system vimrc file: \""
msgstr " fichier vimrc système : \""
-#: ../version.c:672
msgid " user vimrc file: \""
msgstr " fichier vimrc utilisateur : \""
-#: ../version.c:677
msgid " 2nd user vimrc file: \""
msgstr " 2me fichier vimrc utilisateur : \""
-#: ../version.c:682
msgid " 3rd user vimrc file: \""
msgstr " 3me fichier vimrc utilisateur : \""
-#: ../version.c:687
msgid " user exrc file: \""
msgstr " fichier exrc utilisateur : \""
-#: ../version.c:692
msgid " 2nd user exrc file: \""
msgstr " 2me fichier exrc utilisateur : \""
-#: ../version.c:699
+msgid " system gvimrc file: \""
+msgstr " fichier gvimrc système : \""
+
+msgid " user gvimrc file: \""
+msgstr " fichier gvimrc utilisateur : \""
+
+msgid "2nd user gvimrc file: \""
+msgstr "2me fichier gvimrc utilisateur : \""
+
+msgid "3rd user gvimrc file: \""
+msgstr "3me fichier gvimrc utilisateur : \""
+
+msgid " defaults file: \""
+msgstr " fichier de valeurs par défaut : \""
+
+msgid " system menu file: \""
+msgstr " fichier menu système : \""
+
msgid " fall-back for $VIM: \""
msgstr " $VIM par défaut : \""
-#: ../version.c:705
msgid " f-b for $VIMRUNTIME: \""
msgstr " $VIMRUNTIME par défaut : \""
-#: ../version.c:709
msgid "Compilation: "
msgstr "Compilation : "
-#: ../version.c:712
+msgid "Compiler: "
+msgstr "Compilateur : "
+
msgid "Linking: "
msgstr "Édition de liens : "
-#: ../version.c:717
msgid " DEBUG BUILD"
msgstr " VERSION DE DÉBOGAGE"
-#: ../version.c:767
msgid "VIM - Vi IMproved"
msgstr "VIM - Vi Amélioré"
-#: ../version.c:769
msgid "version "
msgstr "version "
-#: ../version.c:770
msgid "by Bram Moolenaar et al."
msgstr "par Bram Moolenaar et al."
-#: ../version.c:774
msgid "Vim is open source and freely distributable"
msgstr "Vim est un logiciel libre"
-#: ../version.c:776
msgid "Help poor children in Uganda!"
msgstr "Aidez les enfants pauvres d'Ouganda !"
-#: ../version.c:777
msgid "type :help iccf<Enter> for information "
msgstr "tapez :help iccf<Entrée> pour plus d'informations "
-#: ../version.c:779
msgid "type :q<Enter> to exit "
msgstr "tapez :q<Entrée> pour sortir du programme "
-#: ../version.c:780
msgid "type :help<Enter> or <F1> for on-line help"
msgstr "tapez :help<Entrée> ou <F1> pour accéder à l'aide en ligne "
-#: ../version.c:781
-msgid "type :help version7<Enter> for version info"
-msgstr "tapez :help version7<Entrée> pour lire les notes de mise à jour"
+msgid "type :help version8<Enter> for version info"
+msgstr "tapez :help version8<Entrée> pour lire les notes de mise à jour"
# DB - Pour les trois messages qui suivent :
# :set cp
# :intro
-#: ../version.c:784
msgid "Running in Vi compatible mode"
msgstr "Compatibilité avec Vi activée"
-#: ../version.c:785
msgid "type :set nocp<Enter> for Vim defaults"
msgstr "tapez :set nocp<Entrée> pour la désactiver"
-#: ../version.c:786
msgid "type :help cp-default<Enter> for info on this"
msgstr "tapez :help cp-default<Entrée> pour plus d'info"
-#: ../version.c:827
+msgid "menu Help->Orphans for information "
+msgstr "menu Aide->Orphelins pour plus d'info"
+
+msgid "Running modeless, typed text is inserted"
+msgstr "Les modes sont désactivés, le texte saisi est inséré"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "menu Édition->Réglages Globaux->Insertion Permanente"
+
+# DB - todo
+msgid " for two modes "
+msgstr " pour les modes "
+
+# DB - todo
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "menu Édition->Réglages Globaux->Compatibilité Vi"
+
+# DB - todo
+msgid " for Vim defaults "
+msgstr " pour déf. de Vim "
+
msgid "Sponsor Vim development!"
msgstr "Sponsorisez le développement de Vim !"
-#: ../version.c:828
msgid "Become a registered Vim user!"
msgstr "Devenez un utilisateur de Vim enregistré !"
-#: ../version.c:831
msgid "type :help sponsor<Enter> for information "
msgstr "tapez :help sponsor<Entrée> pour plus d'informations "
-#: ../version.c:832
msgid "type :help register<Enter> for information "
msgstr "tapez :help register<Entrée> pour plus d'informations "
-#: ../version.c:834
msgid "menu Help->Sponsor/Register for information "
msgstr "menu Aide->Sponsor/Enregistrement pour plus d'info"
-#: ../window.c:119
msgid "Already only one window"
msgstr "Il n'y a déjà plus qu'une fenêtre"
-#: ../window.c:224
msgid "E441: There is no preview window"
msgstr "E441: Il n'y a pas de fenêtre de prévisualisation"
-#: ../window.c:559
msgid "E442: Can't split topleft and botright at the same time"
msgstr "E442: Impossible de partager topleft et botright en même temps"
-#: ../window.c:1228
msgid "E443: Cannot rotate when another window is split"
msgstr "E443: Rotation impossible quand une autre fenêtre est partagée"
-#: ../window.c:1803
msgid "E444: Cannot close last window"
msgstr "E444: Impossible de fermer la dernière fenêtre"
-#: ../window.c:1810
msgid "E813: Cannot close autocmd window"
msgstr "E813: Impossible de fermer la fenêtre des autocommandes"
-#: ../window.c:1814
msgid "E814: Cannot close window, only autocmd window would remain"
msgstr ""
"E814: Impossible de fermer la fenêtre, seule la fenêtre des autocommandes "
"resterait"
-#: ../window.c:2717
msgid "E445: Other window contains changes"
msgstr "E445: Les modifications de l'autre fenêtre n'ont pas été enregistrées"
-#: ../window.c:4805
msgid "E446: No file name under cursor"
msgstr "E446: Aucun nom de fichier sous le curseur"
-#~ msgid "E831: bf_key_init() called with empty password"
-#~ msgstr "E831: bf_key_init() appelée avec un mot de passe vide"
-
-#~ msgid "E820: sizeof(uint32_t) != 4"
-#~ msgstr "E820: sizeof(uint32_t) != 4"
-
-#~ msgid "E817: Blowfish big/little endian use wrong"
-#~ msgstr "E817: petit/gros boutisme incorrect dans blowfish"
-
-#~ msgid "E818: sha256 test failed"
-#~ msgstr "E818: le test de sha256 a échoué"
-
-#~ msgid "E819: Blowfish test failed"
-#~ msgstr "E819: le test de blowfish a échoué"
-
-#~ msgid "Patch file"
-#~ msgstr "Fichier rustine"
-
-# AB - Textes des boutons de la boîte de dialogue affichée par inputdialog().
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "&Ok\n"
-#~ "&Annuler"
-
-# AB - À mon avis, la version anglaise est erronée.
-# DB : Vérifier
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Pas de connexion au serveur X"
-
-# AB - La version française est meilleure que la version anglaise.
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: L'envoi au serveur %s à échoué"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: Impossible de lire la réponse du serveur"
-
-# AB - La version française est meilleure que la version anglaise.
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: La réponse n'a pas pu être envoyée au client"
-
-# AB - Ceci est un titre de boîte de dialogue. Vérifier que la version
-# française est correcte pour les trois références ; j'ai un doute quant
-# à la troisième.
-#~ msgid "Save As"
-#~ msgstr "Enregistrer sous - Vim"
-
-# AB - Ceci est un titre de boîte de dialogue.
-#~ msgid "Edit File"
-#~ msgstr "Ouvrir un fichier - Vim"
-
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (INTROUVABLE)"
-
-#~ msgid "Source Vim script"
-#~ msgstr "Sourcer un script - Vim"
-
-#~ msgid "unknown"
-#~ msgstr "inconnu"
-
-#~ msgid "Edit File in new window"
-#~ msgstr "Ouvrir un fichier dans une nouvelle fenêtre - Vim"
-
-#~ msgid "Append File"
-#~ msgstr "Ajouter fichier"
-
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "Position de la fenêtre : X %d, Y %d"
-
-#~ msgid "Save Redirection"
-#~ msgstr "Enregistrer la redirection"
-
-#~ msgid "Save View"
-#~ msgstr "Enregistrer la vue - Vim"
-
-#~ msgid "Save Session"
-#~ msgstr "Enregistrer la session - Vim"
-
-#~ msgid "Save Setup"
-#~ msgstr "Enregistrer les réglages - Vim"
-
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: #< n'est pas disponible sans la fonctionnalité +eval"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: Pas de digraphes dans cette version"
-
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr "est un périphérique (désactivé par l'option 'opendevice')"
-
-#~ msgid "Reading from stdin..."
-#~ msgstr "Lecture de stdin..."
-
-#~ msgid "[crypted]"
-#~ msgstr "[chiffré]"
-
-#~ msgid "E821: File is encrypted with unknown method"
-#~ msgstr "E821: Le fichier est chiffré avec une méthode inconnue"
-
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans interdit l'écriture des tampons non modifiés"
-
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "Netbeans interdit l'écriture partielle de ses tampons"
-
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "écriture vers un périphérique désactivé par l'option 'opendevice'"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr ""
-#~ "E460: Les ressources partagées seraient perdues (ajoutez ! pour passer "
-#~ "outre)"
-
-#~ msgid "E851: Failed to create a new process for the GUI"
-#~ msgstr ""
-#~ "E851: Échec lors de la création d'un nouveau processus pour l'interface "
-#~ "graphique"
-
-#~ msgid "E852: The child process failed to start the GUI"
-#~ msgstr ""
-#~ "E852: Le processus fils n'a pas réussi à démarrer l'interface graphique"
-
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: Impossible de démarrer l'interface graphique"
-
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: Impossible de lire \"%s\""
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr ""
-#~ "E665: Impossible de démarrer l'IHM graphique, aucune police valide trouvée"
-
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: 'guifontwide' est invalide"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: Valeur de 'imactivatekey' invalide"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: Impossible d'allouer la couleur %s"
-
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "Aucune correspondance sous le curseur, recherche de la suivante"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<impossible d'ouvrir> "
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile : impossible d'obtenir la police %s"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr ""
-#~ "E614: vim_SelFile : impossible de revenir dans le répertoire courant"
-
-#~ msgid "Pathname:"
-#~ msgstr "Chemin :"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile : impossible d'obtenir le répertoire courant"
-
-#~ msgid "OK"
-#~ msgstr "Ok"
-
-#~ msgid "Cancel"
-#~ msgstr "Annuler"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr ""
-#~ "Widget scrollbar : Impossible d'obtenir la géométrie du pixmap 'thumb'"
-
-#~ msgid "Vim dialog"
-#~ msgstr "Vim"
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: Impossible de créer un BalloonEval avec message ET callback"
-
-msgid "Yes"
-msgstr "Oui"
-
-msgid "No"
-msgstr "Non"
-
-# todo '_' is for hotkey, i guess?
-#~ msgid "Input _Methods"
-#~ msgstr "_Méthodes de saisie"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "Remplacer - Vim"
-
-#~ msgid "VIM - Search..."
-#~ msgstr "Rechercher - Vim"
-
-#~ msgid "Find what:"
-#~ msgstr "Rechercher :"
-
-#~ msgid "Replace with:"
-#~ msgstr "Remplacer par :"
-
-#~ msgid "Match whole word only"
-#~ msgstr "Mots entiers seulement"
-
-#~ msgid "Match case"
-#~ msgstr "Respecter la casse"
-
-#~ msgid "Direction"
-#~ msgstr "Direction"
-
-#~ msgid "Up"
-#~ msgstr "Haut"
-
-#~ msgid "Down"
-#~ msgstr "Bas"
-
-#~ msgid "Find Next"
-#~ msgstr "Suivant"
-
-#~ msgid "Replace"
-#~ msgstr "Remplacer"
-
-#~ msgid "Replace All"
-#~ msgstr "Remplacer tout"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr ""
-#~ "Vim : Une requête \"die\" a été reçue par le gestionnaire de session\n"
-
-#~ msgid "Close tab"
-#~ msgstr "Fermer l'onglet"
-
-#~ msgid "New tab"
-#~ msgstr "Nouvel onglet"
-
-# DB - todo : un peu long. Cet entrée de menu permet d'ouvrir un fichier
-# dans un nouvel onglet via le sélecteur de fichiers graphique.
-#~ msgid "Open Tab..."
-#~ msgstr "Ouvrir dans un onglet..."
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim : Fenêtre principale détruite inopinément\n"
-
-#~ msgid "&Filter"
-#~ msgstr "&Filtrer"
-
-#~ msgid "&Cancel"
-#~ msgstr "&Annuler"
-
-#~ msgid "Directories"
-#~ msgstr "Répertoires"
-
-#~ msgid "Filter"
-#~ msgstr "Filtre"
-
-#~ msgid "&Help"
-#~ msgstr "&Aide"
-
-#~ msgid "Files"
-#~ msgstr "Fichiers"
-
-#~ msgid "&OK"
-#~ msgstr "&Ok"
-
-#~ msgid "Selection"
-#~ msgstr "Sélection"
-
-#~ msgid "Find &Next"
-#~ msgstr "Suiva&nt"
-
-#~ msgid "&Replace"
-#~ msgstr "&Remplacer"
-
-#~ msgid "Replace &All"
-#~ msgstr "Rempl&acer tout"
-
-#~ msgid "&Undo"
-#~ msgstr "Ann&uler"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: Titre de fenêtre \"%s\" introuvable"
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: Argument non supporté : \"-%s\" ; Utilisez la version OLE."
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: Impossible d'ouvrir une fenêtre dans une application MDI"
-
-#~ msgid "Open tab..."
-#~ msgstr "Ouvrir dans un onglet..."
-
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "Chercher une chaîne (utilisez '\\\\' pour chercher un '\\')"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "Chercher et remplacer (utilisez '\\\\' pour trouver un '\\')"
-
-# DB - Traduction non indispensable puisque le code indique qu'il s'agit d'un
-# paramétrage bidon afin de sélectionner un répertoire plutôt qu'un
-# fichier.
-#~ msgid "Not Used"
-#~ msgstr "Non utilisé"
-
-# DB - Traduction non indispensable puisque le code indique qu'il s'agit d'un
-# paramétrage bidon afin de sélectionner un répertoire plutôt qu'un
-# fichier.
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "Répertoire\t*.rien\n"
-
-# DB - todo : perfectible.
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr ""
-#~ "Vim E458: Erreur d'allocation de couleurs, couleurs possiblement "
-#~ "incorrectes"
-
-# DB - todo : La VF est-elle compréhensible ?
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr ""
-#~ "E250: Des polices manquent dans %s pour les jeux de caractères suivants :"
-
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: Nom du jeu de polices : %s"
-
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "La police '%s' n'a pas une largeur fixe"
-
-#~ msgid "E253: Fontset name: %s\n"
-#~ msgstr "E253: Nom du jeu de polices : %s\n"
-
-#~ msgid "Font0: %s\n"
-#~ msgstr "Font0: %s\n"
-
-#~ msgid "Font1: %s\n"
-#~ msgstr "Font1: %s\n"
-
-#~ msgid "Font%<PRId64> width is not twice that of font0\n"
-#~ msgstr "La largeur de Font%<PRId64> n'est pas le double de celle de Font0\n"
-
-#~ msgid "Font0 width: %<PRId64>\n"
-#~ msgstr "Largeur de Font0 : %<PRId64>\n"
-
-#~ msgid ""
-#~ "Font1 width: %<PRId64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "Largeur de Font1 : %<PRId64>\n"
-#~ "\n"
-
-# DB - todo : Pas certain de mon coup, ici...
-#~ msgid "Invalid font specification"
-#~ msgstr "La spécification de la police est invalide"
-
-#~ msgid "&Dismiss"
-#~ msgstr "Aban&donner"
-
-# DB - todo : Pas certain de mon coup, ici...
-#~ msgid "no specific match"
-#~ msgstr "aucune correspondance particulière"
-
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Choisir une police - Vim"
-
-#~ msgid "Name:"
-#~ msgstr "Nom :"
-
-#~ msgid "Show size in Points"
-#~ msgstr "Afficher la taille en Points"
-
-#~ msgid "Encoding:"
-#~ msgstr "Encodage :"
-
-#~ msgid "Font:"
-#~ msgstr "Police :"
-
-#~ msgid "Style:"
-#~ msgstr "Style :"
-
-#~ msgid "Size:"
-#~ msgstr "Taille :"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: ERREUR dans l'automate Hangul"
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: Erreur stat"
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: impossible d'ouvrir la base de données cscope %s"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr ""
-#~ "E626: impossible d'obtenir des informations sur la base de données cscope"
-
-#~ msgid "Lua library cannot be loaded."
-#~ msgstr "La bibliothèque Lua n'a pas pu être chargée."
-
-#~ msgid "cannot save undo information"
-#~ msgstr "impossible d'enregistrer les informations d'annulation"
-
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr ""
-#~ "E815: Désolé, cette commande est désactivée : les bibliothèques MzScheme "
-#~ "n'ont pas pu être chargées."
-
-#~ msgid "invalid expression"
-#~ msgstr "expression invalide"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "expressions désactivée lors de la compilation"
-
-#~ msgid "hidden option"
-#~ msgstr "option cachée"
-
-#~ msgid "unknown option"
-#~ msgstr "option inconnue"
-
-#~ msgid "window index is out of range"
-#~ msgstr "numéro de fenêtre hors limites"
-
-#~ msgid "couldn't open buffer"
-#~ msgstr "impossible d'ouvrir le tampon"
-
-#~ msgid "cannot delete line"
-#~ msgstr "impossible d'effacer la ligne"
-
-#~ msgid "cannot replace line"
-#~ msgstr "impossible de remplacer la ligne"
-
-#~ msgid "cannot insert line"
-#~ msgstr "impossible d'insérer la ligne"
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "une chaîne ne peut pas contenir de saut-de-ligne"
-
-#~ msgid "error converting Scheme values to Vim"
-#~ msgstr "erreur lors de la conversion d'une valeur de Scheme à Vim"
-
-#~ msgid "Vim error: ~a"
-#~ msgstr "Erreur Vim : ~a"
-
-#~ msgid "Vim error"
-#~ msgstr "Erreur Vim"
-
-#~ msgid "buffer is invalid"
-#~ msgstr "tampon invalide"
-
-#~ msgid "window is invalid"
-#~ msgstr "fenêtre invalide"
-
-#~ msgid "linenr out of range"
-#~ msgstr "numéro de ligne hors limites"
-
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "non autorisé dans le bac à sable"
-
-#~ msgid "E836: This Vim cannot execute :python after using :py3"
-#~ msgstr "E836: Vim ne peut pas exécuter :python après avoir utilisé :py3"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E263: Désolé, commande désactivée : la bibliothèque Python n'a pas pu "
-#~ "être chargée."
-
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Impossible d'invoquer Python récursivement"
-
-#~ msgid "E837: This Vim cannot execute :py3 after using :python"
-#~ msgstr "E837: Vim ne peut pas exécuter :py3 après avoir utilisé :python"
-
-#~ msgid "index must be int or slice"
-#~ msgstr "index doit être int ou slice"
-
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: $_ doit être une instance de chaîne (String)"
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E266: Désolé, commande désactivée : la bibliothèque Ruby n'a pas pu être "
-#~ "chargée."
-
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: « return » inattendu"
-
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: « next » inattendu"
-
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: « break » inattendu"
-
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: « redo » inattendu"
-
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: « retry » hors d'une clause « rescue »"
-
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: Exception non prise en charge"
-
-# DB - todo
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: contexte de longjmp inconnu : %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "Basculer implémentation/définition"
-
-#~ msgid "Show base class of"
-#~ msgstr "Montrer la classe de base de"
-
-#~ msgid "Show overridden member function"
-#~ msgstr "Montrer les fonctions membres surchargées"
-
-#~ msgid "Retrieve from file"
-#~ msgstr "Récupérer du fichier"
-
-#~ msgid "Retrieve from project"
-#~ msgstr "Récupérer du projet"
-
-#~ msgid "Retrieve from all projects"
-#~ msgstr "Récupérer de tous les projets"
-
-#~ msgid "Retrieve"
-#~ msgstr "Récupérer"
-
-#~ msgid "Show source of"
-#~ msgstr "Montrer source de"
-
-#~ msgid "Find symbol"
-#~ msgstr "Trouver symbole"
-
-#~ msgid "Browse class"
-#~ msgstr "Parcourir classe"
-
-#~ msgid "Show class in hierarchy"
-#~ msgstr "Montrer classe dans hiérarchie"
-
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "Montrer classe dans hiérarchie restreinte"
-
-# todo
-#~ msgid "Xref refers to"
-#~ msgstr "Xref référence"
-
-#~ msgid "Xref referred by"
-#~ msgstr "Xref est référencé par"
-
-#~ msgid "Xref has a"
-#~ msgstr "Xref a un(e)"
-
-#~ msgid "Xref used by"
-#~ msgstr "Xref utilisée par"
-
-#~ msgid "Show docu of"
-#~ msgstr "Montrer doc de"
-
-#~ msgid "Generate docu for"
-#~ msgstr "Générer la doc de"
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "Connexion à SNiFF+ impossible. Vérifiez l'environnement (sniffemacs doit "
-#~ "être dans le $PATH).\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff : Erreur de lecture. Déconnexion"
-
-# DB - Les trois messages suivants vont ensembles.
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "SNiFF+ est actuellement "
-
-#~ msgid "not "
-#~ msgstr "dé"
-
-#~ msgid "connected"
-#~ msgstr "connecté"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: Requête SNiFF+ inconnue : %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: Erreur lors de la connexion à SNiFF+"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SNiFF+ n'est pas connecté"
-
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: Ce tampon n'est pas un tampon SNiFF+"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff : Erreur lors d'une écriture. Déconnexion"
-
-#~ msgid "invalid buffer number"
-#~ msgstr "numéro de tampon invalide"
-
-#~ msgid "not implemented yet"
-#~ msgstr "pas encore implémenté"
-
-# 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"
-
-#~ 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"
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Le fichier \"%s\" est introuvable dans 'path'"
-#~ msgid "keyboard interrupt"
-#~ msgstr "interruption clavier"
+#, c-format
+msgid "E799: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E799: ID invalide : %ld (doit être plus grand ou égal à 1)"
-#~ msgid "vim error"
-#~ msgstr "erreur Vim"
+#, c-format
+msgid "E801: ID already taken: %ld"
+msgstr "E801: ID déjà pris: %ld"
-#~ 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 "List or number required"
+msgstr "Liste ou nombre requis"
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr ""
-#~ "Impossible d'inscrire la commande de rappel : tampon/fenêtre en effacement"
+#, c-format
+msgid "E802: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E802: ID invalide : %ld (doit être plus grand ou égal à 1)"
-#~ msgid ""
-#~ "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."
+#, c-format
+msgid "E803: ID not found: %ld"
+msgstr "E803: ID introuvable : %ld"
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr ""
-#~ "Impossible d'inscrire la commande de rappel : réf. tampon/fenêtre "
-#~ "introuvable"
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Impossible de charger la bibliothèque %s"
-#~ 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."
+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 "E572: exit code %d"
-#~ msgstr "E572: code de sortie %d"
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr "E299: Évaluation Perl interdite dans bac à sable sans le module Safe"
-#~ msgid "cannot get line"
-#~ msgstr "Impossible d'obtenir la ligne"
+msgid "Edit with &multiple Vims"
+msgstr "Éditer dans &plusieurs Vims"
-#~ msgid "Unable to register a command server name"
-#~ msgstr "Impossible d'inscrire un nom de serveur de commande"
+msgid "Edit with single &Vim"
+msgstr "Éditer dans un seul &Vim"
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: Échec de l'envoi de la commande au programme cible"
+msgid "Diff with Vim"
+msgstr "&Comparer avec Vim"
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: Id utilisé pour le serveur invalide : %s"
+msgid "Edit with &Vim"
+msgstr "Éditer dans &Vim"
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr ""
-#~ "E251: Entrée registre de l'instance de Vim mal formatée. Suppression !"
+#. Now concatenate
+msgid "Edit with existing Vim - "
+msgstr "Éditer dans le Vim existant - "
-#~ msgid "netbeans is not supported with this GUI\n"
-#~ msgstr "netbeans n'est pas supporté avec cette interface graphique\n"
+msgid "Edits the selected file(s) with Vim"
+msgstr "Édites le(s) fichier(s) sélectionné(s) avec Vim"
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "Ce Vim n'a pas été compilé avec la fonctionnalité diff"
+# 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 "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "'-nb' ne peut pas être utilisé : désactivé à la compilation\n"
+msgid "gvimext.dll error"
+msgstr "Erreur de gvimext.dll"
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim : Erreur : Impossible de démarrer gvim depuis NetBeans\n"
+msgid "Path length too long!"
+msgstr "Le chemin est trop long !"
-# DB - todo (VMS uniquement).
-#~ msgid ""
-#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
-#~ msgstr ""
-#~ "\n"
-#~ "pour lesquels la casse est indifférente (/ pour que le drapeau soit "
-#~ "majuscule)"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\tInscrire ce gvim pour OLE"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\tDésinscrire gvim de OLE"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\tLancer l'interface graphique (comme \"gvim\")"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr ""
-#~ "-f, --nofork\tPremier-plan : ne pas détacher l'interface graphique du "
-#~ "terminal"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\tNe pas utiliser newcli pour l'ouverture des fenêtres"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <périph>\tUtiliser <périphérique> pour les E/S"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\tUtiliser <gvimrc> au lieu du gvimrc habituel"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\tÉditer des fichiers chiffrés"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <display>\tConnecter Vim au serveur X spécifié"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tNe pas se connecter à un serveur X"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr ""
-#~ "--remote <fich>\tÉditer les <fichiers> dans un serveur Vim si possible"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-silent ...\tPareil, mais pas d'erreur s'il n'y a aucun serveur"
-
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr ""
-#~ "--remote-wait <fich>\tComme --remote mais ne quitter qu'à la fin de "
-#~ "l'édition"
-
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-wait-silent\tPareil, mais pas d'erreur s'il n'y a aucun serveur"
-
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <fich>\tComme --remote mais ouvrir un onglet "
-#~ "pour chaque fichier"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr ""
-#~ "--remote-send <tche>\tEnvoyer <touches> à un serveur Vim puis quitter"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr ""
-#~ "--remote-expr <expr>\tÉvaluer <expr> dans un serveur Vim, afficher le "
-#~ "résultat"
-
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr ""
-#~ "--serverlist\t\tLister les noms des serveurs Vim disponibles et quitter"
-
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <nom>\tEnvoyer au/devenir le serveur Vim nommé <nom>"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Arguments reconnus par gvim (version Motif) :\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Arguments reconnus par gvim (version neXtaw) :\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Arguments reconnus par gvim (version Athena) :\n"
+# msgstr "--Pas de lignes dans le tampon--"
+# DB - todo : ou encore : msgstr "--Aucune ligne dans le tampon--"
+msgid "--No lines in buffer--"
+msgstr "--Le tampon est vide--"
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <écran>\tLancer Vim sur ce <display>"
+#.
+#. * 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 "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tIconifier Vim au démarrage"
+msgid "E471: Argument required"
+msgstr "E471: Argument requis"
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr ""
-#~ "-background <coul>\tUtiliser <couleur> pour l'arrière-plan\t (abrv : -"
-#~ "bg)"
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ devrait être suivi de /, ? ou &"
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr ""
-#~ "-foreground <coul>\tUtiliser <couleur> pour le texte normal\t (abrv : -"
-#~ "fg)"
+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 "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr ""
-#~ "-font <fonte>\tUtiliser <fonte> pour le texte normal\t (abrv : -fn)"
+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 "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <fonte>\tUtiliser <fonte> pour le texte gras"
+msgid "E171: Missing :endif"
+msgstr "E171: :endif manquant"
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <fonte>\tUtiliser <fonte> pour le texte italique"
+msgid "E600: Missing :endtry"
+msgstr "E600: :endtry manquant"
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr ""
-#~ "-geometry <géom>\tUtiliser cette <géométrie> initiale\t (abrv : -geom)"
+msgid "E170: Missing :endwhile"
+msgstr "E170: :endwhile manquant"
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr ""
-#~ "-borderwidth <épais>\tUtiliser cette <épaisseur> de bordure\t (abrv : -"
-#~ "bw)"
+msgid "E170: Missing :endfor"
+msgstr "E170: :endfor manquant"
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <lg>\tUtiliser cette <largeur> de barre de défil. (abrv: -"
-#~ "sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr ""
-#~ "-menuheight <haut>\tUtiliser cette <hauteur> de menu\t (abrv : -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tUtiliser la vidéo inverse\t\t (abrv : -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tNe pas utiliser de vidéo inverse\t (abrv : +rv)"
-
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <ressource>\tConfigurer la <ressource> spécifiée"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Arguments reconnus par gvim (version GTK+) :\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr ""
-#~ "-display <display>\tLancer Vim sur ce <display>\t(également : --display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr "--role <rôle>\tDonner un rôle pour identifier la fenêtre principale"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tOuvrir Vim dans un autre widget GTK"
-
-#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
-#~ msgstr "--echo-wid\t\tGvim affiche l'ID de la fenêtre sur stdout"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <titre parent>\tOuvrir Vim dans une application parente"
-
-#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
-#~ msgstr "--windowid <HWND>\tOuvrir Vim dans un autre widget win32"
-
-#~ msgid "No display"
-#~ msgstr "Aucun display"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr " : L'envoi a échoué.\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr " : L'envoi a échoué. Tentative d'exécution locale\n"
-
-#~ msgid "%d of %d edited"
-#~ msgstr "%d édités sur %d"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "Aucun display : L'envoi de l'expression a échoué.\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr " : L'envoi de l'expression a échoué.\n"
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile sans :while"
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: Page de codes non valide"
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor sans :for"
-#~ 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 "E13: File exists (add ! to override)"
+msgstr "E13: Le fichier existe déjà (ajoutez ! pour passer outre)"
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
-#~ msgstr ""
-#~ "E287: Alerte : Impossible d'inscrire la callback de destruction dans la MS"
+msgid "E472: Command failed"
+msgstr "E472: La commande a échoué"
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: la méthode de saisie ne supporte aucun style"
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Jeu de police inconnu : %s"
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr ""
-#~ "E289: le type de préédition de Vim n'est pas supporté par la méthode de "
-#~ "saisie"
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Police inconnue : %s"
-#~ msgid "E843: Error while updating swap file crypt"
-#~ msgstr "E843: Erreur lors de la mise à jour du fichier d'échange crypté"
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: La police \"%s\" n'a pas une chasse (largeur) fixe"
-#~ msgid ""
-#~ "E833: %s is encrypted and this version of Vim does not support encryption"
-#~ msgstr ""
-#~ "E833: %s est chiffré et cette version de Vim ne supporte pas le "
-#~ "chiffrement"
-
-#~ msgid "Swap file is encrypted: \"%s\""
-#~ msgstr "Fichier d'échange chiffré : \"%s\""
+msgid "E473: Internal error"
+msgstr "E473: Erreur interne"
-#~ 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,"
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Erreur interne : %s"
-#~ msgid ""
-#~ "\n"
-#~ "enter the new crypt key."
-#~ msgstr ""
-#~ "\n"
-#~ "tapez la nouvelle clé de chiffrement."
+msgid "Interrupted"
+msgstr "Interrompu"
-#~ 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 "E14: Invalid address"
+msgstr "E14: Adresse invalide"
-#~ 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"
+msgid "E474: Invalid argument"
+msgstr "E474: Argument invalide"
-#~ 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"
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Argument invalide : %s"
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [inutilisable avec cette version de Vim]"
-
-#~ msgid "Tear off this menu"
-#~ msgstr "Détacher ce menu"
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Expression invalide : %s"
-# 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 "E16: Invalid range"
+msgstr "E16: Plage invalide"
-#~ msgid "Save File dialog"
-#~ msgstr "Enregistrer un fichier"
+msgid "E476: Invalid command"
+msgstr "E476: Commande invalide"
-#~ msgid "Open File dialog"
-#~ msgstr "Ouvrir un fichier"
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" est un répertoire"
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: Désolé, pas de sélecteur de fichiers en mode console"
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: L'appel à la bibliothèque a échoué pour \"%s()\""
-#~ msgid "ERROR: "
-#~ msgstr "ERREUR : "
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Impossible de charger la fonction %s de la bibliothèque"
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[octets] total alloué-libéré %<PRIu64>-%<PRIu64>, utilisé %<PRIu64>, pic "
-#~ "%<PRIu64>\n"
+msgid "E19: Mark has invalid line number"
+msgstr "E19: La marque a un numéro de ligne invalide"
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[appels] total re/malloc() %<PRIu64>, total free() %<PRIu64>\n"
-#~ "\n"
+msgid "E20: Mark not set"
+msgstr "E20: Marque non positionnée"
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: La ligne devient trop longue"
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Impossible de modifier, 'modifiable' est désactivé"
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: Erreur interne : lalloc(%<PRId64>, )"
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Trop de récursion dans les scripts"
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: Forme de curseur invalide"
+msgid "E23: No alternate file"
+msgstr "E23: Pas de fichier alternatif"
-#~ msgid "Warning: Using a weak encryption method; see :help 'cm'"
-#~ msgstr ""
-#~ "Alerte : utilisation d'une méthode de chiffrage faible ; consultez :help 'cm'"
+msgid "E24: No such abbreviation"
+msgstr "E24: Cette abréviation n'existe pas"
-#~ msgid "Enter encryption key: "
-#~ msgstr "Tapez la clé de chiffrement : "
+msgid "E477: No ! allowed"
+msgstr "E477: Le ! n'est pas autorisé"
-#~ msgid "Enter same key again: "
-#~ msgstr "Tapez la clé à nouveau : "
+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 "Keys don't match!"
-#~ msgstr "Les clés ne correspondent pas !"
+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 "Cannot connect to Netbeans #2"
-#~ msgstr "Impossible de se connecter à Netbeans n°2"
+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 "Cannot connect to Netbeans"
-#~ msgstr "Impossible de se connecter à Netbeans"
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: Le support de l'arabe n'a pas été compilé dans cette version\n"
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr ""
-#~ "E668: Mode d'accès incorrect au fichier d'infos de connexion NetBeans : "
-#~ "\"%s\""
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Aucun nom de groupe de surbrillance %s"
-# DB : message d'un appel à perror().
-#~ msgid "read from Netbeans socket"
-#~ msgstr "read sur la socket Netbeans"
+msgid "E29: No inserted text yet"
+msgstr "E29: Pas encore de texte inséré"
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: Connexion NetBeans perdue pour le tampon %<PRId64>"
+msgid "E30: No previous command line"
+msgstr "E30: Aucune ligne de commande précédente"
-#~ msgid "E838: netbeans is not supported with this GUI"
-#~ msgstr "E838: netbeans n'est pas supporté avec cette interface graphique"
+msgid "E31: No such mapping"
+msgstr "E31: Mappage inexistant"
-#~ msgid "E511: netbeans already connected"
-#~ msgstr "E511: netbeans déjà connecté"
+msgid "E479: No match"
+msgstr "E479: Aucune correspondance"
-#~ msgid "E505: %s is read-only (add ! to override)"
-#~ msgstr "E505: %s est en lecture seule (ajoutez ! pour passer outre)"
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Aucune correspondance : %s"
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: La fonctionnalité d'évaluation n'est pas disponible"
+msgid "E32: No file name"
+msgstr "E32: Aucun nom de fichier"
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "libération de %<PRId64> lignes"
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Aucune expression régulière de substitution précédente"
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: Impossible de modifier term dans l'interface graphique"
+msgid "E34: No previous command"
+msgstr "E34: Aucune commande précédente"
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: Utilisez \":gui\" pour démarrer l'interface graphique"
+msgid "E35: No previous regular expression"
+msgstr "E35: Aucune expression régulière précédente"
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: Non modifiable dans l'interface graphique GTK+ 2"
+msgid "E481: No range allowed"
+msgstr "E481: Les plages ne sont pas autorisées"
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: Police(s) invalide(s)"
+msgid "E36: Not enough room"
+msgstr "E36: Pas assez de place"
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: Impossible de sélectionner un jeu de polices"
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: aucun serveur nommé \"%s\" n'est enregistré"
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: Jeu de polices invalide"
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Impossible de créer le fichier %s"
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: Impossible de sélectionner une police à largeur double"
+msgid "E483: Can't get temp file name"
+msgstr "E483: Impossible d'obtenir un nom de fichier temporaire"
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: Police à largeur double invalide"
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Impossible d'ouvrir le fichier \"%s\""
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: La souris n'est pas supportée"
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Impossible de lire le fichier %s"
-#~ msgid "cannot open "
-#~ msgstr "impossible d'ouvrir "
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Modifications non enregistrées (ajoutez ! pour passer outre)"
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM : Impossible d'ouvrir la fenêtre !\n"
+msgid "E37: No write since last change"
+msgstr "E37: Modifications non enregistrées"
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Amigados version 2.04 ou ultérieure est nécessaire\n"
+msgid "E38: Null argument"
+msgstr "E38: Argument null"
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "%s version %<PRId64> est nécessaire\n"
+msgid "E39: Number expected"
+msgstr "E39: Nombre attendu"
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "Impossible d'ouvrir NIL :\n"
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Impossible d'ouvrir le fichier d'erreurs %s"
-#~ msgid "Cannot create "
-#~ msgstr "Impossible de créer "
+msgid "E233: cannot open display"
+msgstr "E233: ouverture du display impossible"
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim quitte avec %d\n"
+msgid "E41: Out of memory!"
+msgstr "E41: Mémoire épuisée"
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "Impossible de modifier le mode de la console ?!\n"
+msgid "Pattern not found"
+msgstr "Motif introuvable"
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize : pas une console ?!\n"
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Motif introuvable : %s"
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: Impossible d'exécuter un shell avec l'option -f"
+msgid "E487: Argument must be positive"
+msgstr "E487: L'argument doit être positif"
-#~ msgid "Cannot execute "
-#~ msgstr "Impossible d'exécuter "
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Impossible de retourner au répertoire précédent"
-#~ msgid "shell "
-#~ msgstr "le shell "
+msgid "E42: No Errors"
+msgstr "E42: Aucune erreur"
-#~ msgid " returned\n"
-#~ msgstr " a été retourné\n"
+# DB - TODO : trouver une traduction valable et attestée pour "location".
+msgid "E776: No location list"
+msgstr "E776: Aucune liste d'emplacements"
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE trop petit."
+msgid "E43: Damaged match string"
+msgstr "E43: La chaîne de recherche est endommagée"
-#~ msgid "I/O ERROR"
-#~ msgstr "ERREUR d'E/S"
+msgid "E44: Corrupted regexp program"
+msgstr "E44: L'automate de regexp est corrompu"
-#~ msgid "Message"
-#~ msgstr "Message"
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: L'option 'readonly' est activée (ajoutez ! pour passer outre)"
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr ""
-#~ "'columns' ne vaut pas 80, impossible d'exécuter des commandes externes"
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: La variable \"%s\" est en lecture seule"
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: La sélection de l'imprimante a échoué"
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr ""
+"E794: Impossible de modifier une variable depuis le bac à sable : \"%s\""
-# DB - Contenu des c-formats : Imprimante puis Port.
-#~ msgid "to %s on %s"
-#~ msgstr "vers %s sur %s"
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Impossible d'utiliser une clé vide dans un Dictionnaire"
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: Police d'imprimante inconnue : %s"
+msgid "E715: Dictionary required"
+msgstr "E715: Dictionnaire requis"
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: Erreur d'impression : %s"
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: index de Liste hors limites : %ld au-delà de la fin"
-#~ msgid "Printing '%s'"
-#~ msgstr "Impression de '%s'"
+# DB : Suggestion
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: La fonction %s a reçu trop d'arguments"
-#~ msgid "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 "E716: Key not present in Dictionary: %s"
+msgstr "E716: La clé %s n'existe pas dans le Dictionnaire"
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: Caractère '%c' invalide dans le nom de fonte \"%s\""
+msgid "E714: List required"
+msgstr "E714: Liste requise"
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "L'ouverture du display X a pris %<PRId64> ms"
+#, 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 ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim : Réception d'une erreur X\n"
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Erreur lors de la lecture du fichier d'erreurs"
-#~ msgid "Testing the X display failed"
-#~ msgstr "Le test du display X a échoué"
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Opération interdite dans le bac à sable"
-#~ msgid "Opening the X display timed out"
-#~ msgstr "L'ouverture du display X a dépassé le délai d'attente"
+msgid "E523: Not allowed here"
+msgstr "E523: Interdit à cet endroit"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Impossible d'exécuter le shell sh\n"
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Choix du mode d'écran non supporté"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Impossible de créer des tuyaux (pipes)\n"
+msgid "E49: Invalid scroll size"
+msgstr "E49: Valeur de défilement invalide"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Impossible de forker\n"
+msgid "E91: 'shell' option is empty"
+msgstr "E91: L'option 'shell' est vide"
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Commande interrompue\n"
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Impossible de lire les données du symbole !"
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP a perdu la connexion ICE"
+msgid "E72: Close error on swap file"
+msgstr "E72: Erreur lors de la fermeture du fichier d'échange"
-#~ msgid "Opening the X display failed"
-#~ msgstr "L'ouverture du display X a échoué"
+msgid "E73: tag stack empty"
+msgstr "E73: La pile des marqueurs est vide"
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP : prise en charge d'une requête save-yourself"
+msgid "E74: Command too complex"
+msgstr "E74: Commande trop complexe"
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP : ouverture de la connexion"
+msgid "E75: Name too long"
+msgstr "E75: Nom trop long"
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP : échec de la surveillance de connexion ICE"
+msgid "E76: Too many ["
+msgstr "E76: Trop de ["
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP : SmcOpenConnection a échoué : %s"
+msgid "E77: Too many file names"
+msgstr "E77: Trop de noms de fichiers"
-#~ msgid "At line"
-#~ msgstr "À la ligne"
+msgid "E488: Trailing characters"
+msgstr "E488: Caractères surnuméraires"
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "Impossible de charger vim32.dll !"
+msgid "E78: Unknown mark"
+msgstr "E78: Marque inconnue"
-#~ msgid "VIM Error"
-#~ msgstr "Erreur VIM"
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Impossible de développer les métacaractères"
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "Impossible d'initialiser les pointeurs de fonction vers la DLL !"
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' ne peut pas être plus petit que 'winminheight'"
-#~ msgid "shell returned %d"
-#~ msgstr "le shell a retourné %d"
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' ne peut pas être plus petit que 'winminwidth'"
-# DB - Les événements en question sont ceux des messages qui suivent.
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim : Événement %s intercepté\n"
+msgid "E80: Error while writing"
+msgstr "E80: Erreur lors de l'écriture"
-#~ msgid "close"
-#~ msgstr "de fermeture"
+msgid "Zero count"
+msgstr "Le quantificateur est nul"
-#~ msgid "logoff"
-#~ msgstr "de déconnexion"
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: <SID> utilisé en dehors d'un script"
-#~ msgid "shutdown"
-#~ msgstr "d'arrêt"
+msgid "E449: Invalid expression received"
+msgstr "E449: Expression invalide reçue"
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: Commande introuvable"
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Cette zone est verrouillée et ne peut pas être modifiée"
-#~ msgid ""
-#~ "VIMRUN.EXE not found in your $PATH.\n"
-#~ "External commands will not pause after completion.\n"
-#~ "See :help win32-vimrun for more information."
-#~ msgstr ""
-#~ "VIMRUN.EXE est introuvable votre $PATH.\n"
-#~ "Les commandes externes ne feront pas de pause une fois terminées.\n"
-#~ "Consultez :help win32-vimrun pour plus d'informations."
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr ""
+"E744: NetBeans n'autorise pas la modification des fichiers en lecture seule"
-#~ msgid "Vim Warning"
-#~ msgstr "Alerte Vim"
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: le motif utilise plus de mémoire que 'maxmempattern'"
-#~ msgid "Error file"
-#~ msgstr "Fichier d'erreurs"
+msgid "E749: empty buffer"
+msgstr "E749: tampon vide"
-#~ msgid "E868: Error building NFA with equivalence class!"
-#~ msgstr ""
-#~ "E868: Erreur lors de la construction du NFA avec classe d'équivalence"
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Le tampon %ld n'existe pas"
-#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!"
-#~ msgstr ""
-#~ "E878: (NFA) Impossible d'allouer la mémoire pour parcourir les branches!"
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Délimiteur ou motif de recherche invalide"
-#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
-#~ msgstr ""
-#~ "Alerte : Liste de mots \"%s_%s.spl\" ou \"%s_ascii.spl\" introuvable"
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Le fichier est chargé dans un autre tampon"
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "La conversion dans %s non supportée"
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: L'option '%s' n'est pas activée"
-#~ msgid "E845: Insufficient memory, word list will be incomplete"
-#~ msgstr "E845: mémoire insuffisante, liste de mots peut-être incomplète"
+msgid "E850: Invalid register name"
+msgstr "E850: Nom de registre invalide"
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: Chemin de fichiers de marqueurs tronqué pour %s\n"
+#, c-format
+msgid "E919: Directory not found in '%s': \"%s\""
+msgstr "E919: Répertoire introuvable dans '%s' : \"%s\""
-#~ msgid "new shell started\n"
-#~ msgstr "nouveau shell démarré\n"
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "La recherche a atteint le HAUT, et continue en BAS"
-# DB - Message de débogage.
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "CUT_BUFFER0 utilisé plutôt qu'une sélection vide"
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "La recherche a atteint le BAS, et continue en HAUT"
-# DB - Question O/N.
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "Annulation impossible ; continuer"
-
-#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
-#~ msgstr "E832: Fichier non-chiffré a un fichier d'annulations chiffré : %s"
-
-#~ msgid "E826: Undo file decryption failed: %s"
-#~ msgstr "E826: Déchiffrage du fichier d'annulation a échoué : %s"
-
-#~ msgid "E827: Undo file is encrypted: %s"
-#~ msgstr "E827: Le fichier d'annulations est chiffré : %s"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version graphique MS-Windows 16/32 bits"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version graphique MS-Windows 64 bits"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version graphique MS-Windows 32 bits"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " lancée en mode Win32s"
-
-#~ msgid " with OLE support"
-#~ msgstr " supportant l'OLE"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version console MS-Windows 64 bits"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version console MS-Windows 32 bits"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version MS-Windows 16 bits"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version MS-DOS 32 bits"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version MS-DOS 16 bits"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version MaxOS X (unix)"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version MacOS X"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version MacOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version OpenVMS"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Grosse version "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Version normale "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Petite version "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Version minuscule "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "avec interface graphique GTK2-GNOME."
-
-#~ msgid "with GTK2 GUI."
-#~ msgstr "avec interface graphique GTK2."
-
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "avec interface graphique X11-Motif."
-
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "avec interface graphique X11-neXtaw."
-
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "avec interface graphique X11-Athena."
-
-#~ msgid "with Photon GUI."
-#~ msgstr "avec interface graphique Photon."
-
-#~ msgid "with GUI."
-#~ msgstr "avec une interface graphique."
-
-#~ msgid "with Carbon GUI."
-#~ msgstr "avec interface graphique Carbon."
-
-#~ msgid "with Cocoa GUI."
-#~ msgstr "avec interface graphique Cocoa."
-
-#~ msgid "with (classic) GUI."
-#~ msgstr "avec interface graphique (classic)."
-
-#~ msgid " system gvimrc file: \""
-#~ msgstr " fichier gvimrc système : \""
-
-#~ msgid " user gvimrc file: \""
-#~ msgstr " fichier gvimrc utilisateur : \""
-
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr "2me fichier gvimrc utilisateur : \""
-
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr "3me fichier gvimrc utilisateur : \""
-
-#~ msgid " system menu file: \""
-#~ msgstr " fichier menu système : \""
-
-#~ msgid "Compiler: "
-#~ msgstr "Compilateur : "
+#, c-format
+msgid "Need encryption key for \"%s\""
+msgstr "Besoin de la clé de chiffrement pour \"%s\""
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "menu Aide->Orphelins pour plus d'info"
+msgid "empty keys are not allowed"
+msgstr "les clés vides ne sont pas autorisées"
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "Les modes sont désactivés, le texte saisi est inséré"
+msgid "dictionary is locked"
+msgstr "dictionnaire est verrouillé"
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "menu Édition->Réglages Globaux->Insertion Permanente"
+msgid "list is locked"
+msgstr "liste verrouillée"
-# DB - todo
-#~ msgid " for two modes "
-#~ msgstr " pour les modes "
+#, c-format
+msgid "failed to add key '%s' to dictionary"
+msgstr "l'ajout de clé '%s' au dictionnaire a échoué"
-# DB - todo
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "menu Édition->Réglages Globaux->Compatibilité Vi"
+#, c-format
+msgid "index must be int or slice, not %s"
+msgstr "index doit être int ou slice, et non %s"
-# DB - todo
-#~ msgid " for Vim defaults "
-#~ msgstr " pour déf. de Vim "
+#, c-format
+msgid "expected str() or unicode() instance, but got %s"
+msgstr "attendu instance de str() ou unicode(), mais reçu %s"
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "ALERTE: Windows 95/98/ME détecté"
+#, c-format
+msgid "expected bytes() or str() instance, but got %s"
+msgstr "attendu instance de bytes() ou str(), mais reçu %s"
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr "tapez :help windows95<Entrée> pour plus d'information"
+#, c-format
+msgid ""
+"expected int(), long() or something supporting coercing to long(), but got %s"
+msgstr ""
+"attendu int(), long() ou quelque chose qui peut être transformé en long(), "
+"mais reçu %s"
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: Impossible de charger la bibliothèque %s"
+#, c-format
+msgid "expected int() or something supporting coercing to int(), but got %s"
+msgstr ""
+"attendu int() ou quelque chose qui peut être transformé en int(), mais reçu "
+"%s"
-#~ 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 "value is too large to fit into C int type"
+msgstr "valeur trop grande pour être stockée dans le type C int"
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr ""
-#~ "E299: Évaluation Perl interdite dans bac à sable sans le module Safe"
+msgid "value is too small to fit into C int type"
+msgstr "valeur trop petite pour être stockée dans le type C int"
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "Éditer dans &plusieurs Vims"
+msgid "number must be greater than zero"
+msgstr "le nombre doit être plus grand que zéro"
-#~ msgid "Edit with single &Vim"
-#~ msgstr "Éditer dans un seul &Vim"
+msgid "number must be greater or equal to zero"
+msgstr "le nombre doit être plus grand ou égal à zéro"
-#~ msgid "Diff with Vim"
-#~ msgstr "&Comparer avec Vim"
+msgid "can't delete OutputObject attributes"
+msgstr "impossible d'effacer les attributs d'OutputObject"
-#~ msgid "Edit with &Vim"
-#~ msgstr "Éditer dans &Vim"
+#, c-format
+msgid "invalid attribute: %s"
+msgstr "attribut invalide : %s"
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "Éditer dans le Vim existant - "
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python : Erreur d'initialisation des objets d'E/S"
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "Édites le(s) fichier(s) sélectionné(s) avec Vim"
+msgid "failed to change directory"
+msgstr "changement de répertoire a échoué"
-# 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 !"
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got %s"
+msgstr "attendu un 3-tuple comme résultat de imp.find_module(), mais reçu %s"
-#~ msgid "gvimext.dll error"
-#~ msgstr "Erreur de gvimext.dll"
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
+msgstr ""
+"attendu un 3-tuple comme résultat de imp.find_module(), mais reçu un tuple "
+"de taille %d"
-#~ msgid "Path length too long!"
-#~ msgstr "Le chemin est trop long !"
+msgid "internal error: imp.find_module returned tuple with NULL"
+msgstr "erreur interne : imp.find_module a retourné un tuple contenant NULL"
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: Jeu de police inconnu : %s"
+msgid "cannot delete vim.Dictionary attributes"
+msgstr "impossible d'effacer les attributs de vim.Dictionary"
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: Police inconnue : %s"
+msgid "cannot modify fixed dictionary"
+msgstr "impossible de modifier un dictionnaire fixe"
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: La police \"%s\" n'a pas une chasse (largeur) fixe"
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "impossible d'initialiser l'attribut %s"
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: Impossible de charger la fonction %s de la bibliothèque"
+msgid "hashtab changed during iteration"
+msgstr "la table de hachage a été changée pendant une itération"
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E26: Le support de l'hébreu n'a pas été compilé dans cette version\n"
+#, c-format
+msgid "expected sequence element of size 2, but got sequence of size %d"
+msgstr ""
+"attendu une séquence d'éléments de taille 2, mais reçu une séquence de "
+"taille %d"
-#~ msgid "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 "list constructor does not accept keyword arguments"
+msgstr "le constructeur de liste n'accepte pas les arguments nommés"
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E800: Le support de l'arabe n'a pas été compilé dans cette version\n"
+msgid "list index out of range"
+msgstr "index de liste hors limites"
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: aucun serveur nommé \"%s\" n'est enregistré"
+#. No more suitable format specifications in python-2.3
+#, c-format
+msgid "internal error: failed to get vim list item %d"
+msgstr "erreur interne : accès à un élément %d de liste a échoué"
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: ouverture du display impossible"
+msgid "slice step cannot be zero"
+msgstr "le pas du découpage en tranche ne peut pas être zéro"
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: Expression invalide reçue"
+#, c-format
+msgid "attempt to assign sequence of size greater than %d to extended slice"
+msgstr ""
+"tentative d'assigner une séquence de taille plus grande que %d à un "
+"découpage en tranche étendu "
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: Cette zone est verrouillée et ne peut pas être modifiée"
+#, c-format
+msgid "internal error: no vim list item %d"
+msgstr "erreur interne : pas d'élément %d de liste vim"
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr ""
-#~ "E744: NetBeans n'autorise pas la modification des fichiers en lecture "
-#~ "seule"
+msgid "internal error: not enough list items"
+msgstr "erreur interne : pas assez d'éléments de liste"
-#~ msgid "Need encryption key for \"%s\""
-#~ msgstr "Besoin de la clé de chiffrement pour \"%s\""
+msgid "internal error: failed to add item to list"
+msgstr "erreur interne : ajout d'élément à la liste a échoué"
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "impossible d'effacer les attributs d'OutputObject"
+#, c-format
+msgid "attempt to assign sequence of size %d to extended slice of size %d"
+msgstr ""
+"tentative d'assigner une séquence de taille %d à un découpage en tranche "
+"étendu de taille %d"
-#~ msgid "invalid attribute"
-#~ msgstr "attribut invalide"
+msgid "failed to add item to list"
+msgstr "ajout à la liste a échoué"
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python : Erreur d'initialisation des objets d'E/S"
+msgid "cannot delete vim.List attributes"
+msgstr "impossible d'effacer les attributs de vim.List"
-#~ msgid "empty keys are not allowed"
-#~ msgstr "les clés vides ne sont pas autorisées"
+msgid "cannot modify fixed list"
+msgstr "impossible de modifier une liste fixe"
-#~ msgid "Cannot modify fixed dictionary"
-#~ msgstr "Impossible de modifier un dictionnaire fixe"
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "la fonction sans nom %s n'existe pas"
-#~ msgid "dict is locked"
-#~ msgstr "dictionnaire est verrouillé"
+#, c-format
+msgid "function %s does not exist"
+msgstr "la fonction %s n'existe pas"
-#~ msgid "failed to add key to dictionary"
-#~ msgstr "l'ajout de clé au dictionnaire a échoué"
+#, c-format
+msgid "failed to run function %s"
+msgstr "exécution de la fonction %s a échoué"
-#~ msgid "list index out of range"
-#~ msgstr "index de liste hors limites"
+msgid "unable to get option value"
+msgstr "impossible d'obtenir la valeur d'une option"
-#~ msgid "internal error: failed to get vim list item"
-#~ msgstr "erreur interne : accès à un élément de liste a échoué"
+msgid "internal error: unknown option type"
+msgstr "erreur interne : type d'option inconnu"
-#~ msgid "list is locked"
-#~ msgstr "liste verrouillée"
+msgid "problem while switching windows"
+msgstr "problème lors du changement de fenêtres"
-#~ msgid "Failed to add item to list"
-#~ msgstr "Ajout à la liste a échoué"
+#, c-format
+msgid "unable to unset global option %s"
+msgstr "impossible de désactiver une option globale %s"
-#~ msgid "internal error: failed to add item to list"
-#~ msgstr "erreur interne : ajout d'élément à la liste a échoué"
+#, c-format
+msgid "unable to unset option %s which does not have global value"
+msgstr "impossible de désactiver l'option %s qui n'a pas de valeur globale"
-#~ msgid "cannot delete vim.dictionary attributes"
-#~ msgstr "impossible d'effacer les attributs de vim.dictionary"
+msgid "attempt to refer to deleted tab page"
+msgstr "tentative de référencer un onglet effacé"
-#~ msgid "cannot modify fixed list"
-#~ msgstr "impossible de modifier une liste fixe"
+msgid "no such tab page"
+msgstr "cet onglet n'existe pas"
-#~ msgid "cannot set this attribute"
-#~ msgstr "impossible d'initialiser cet attribut"
+msgid "attempt to refer to deleted window"
+msgstr "tentative de référencer une fenêtre effacée"
-#~ msgid "failed to run function"
-#~ msgstr "exécution de la fonction a échoué"
+msgid "readonly attribute: buffer"
+msgstr "attribut en lecture seule : tampon"
-#~ msgid "unable to unset global option"
-#~ msgstr "impossible de désactiver une option globale"
+msgid "cursor position outside buffer"
+msgstr "curseur positionné en dehors du tampon"
-#~ msgid "unable to unset option without global value"
-#~ msgstr "impossible de désactiver une option sans une valeur globale"
+msgid "no such window"
+msgstr "Cette fenêtre n'existe pas"
-#~ msgid "attempt to refer to deleted tab page"
-#~ msgstr "tentative de référencer un onglet effacé"
+msgid "attempt to refer to deleted buffer"
+msgstr "tentative de référencer un tampon effacé"
-#~ msgid "no such tab page"
-#~ msgstr "cet onglet n'existe pas"
+msgid "failed to rename buffer"
+msgstr "impossible de renommer le tampon"
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "tentative de référencer une fenêtre effacée"
+msgid "mark name must be a single character"
+msgstr "le nom de marque doit être un seul caractère"
-#~ msgid "readonly attribute"
-#~ msgstr "attribut en lecture seule"
+#, c-format
+msgid "expected vim.Buffer object, but got %s"
+msgstr "attendu un objet vim.Buffer, mais reçu %s"
-#~ msgid "cursor position outside buffer"
-#~ msgstr "curseur positionné en dehors du tampon"
+#, c-format
+msgid "failed to switch to buffer %d"
+msgstr "impossible de se déplacer au tampon %d"
-#~ msgid "no such window"
-#~ msgstr "Cette fenêtre n'existe pas"
+#, c-format
+msgid "expected vim.Window object, but got %s"
+msgstr "attendu un objet vim.Window, mais reçu %s"
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "tentative de référencer un tampon effacé"
+msgid "failed to find window in the current tab page"
+msgstr "impossible de trouver une fenêtre dans l'onglet courant"
-#~ msgid "expected vim.buffer object"
-#~ msgstr "objet vim.buffer attendu"
+msgid "did not switch to the specified window"
+msgstr "ne s'est pas déplacé à la fenêtre spécifiée"
-#~ msgid "failed to switch to given buffer"
-#~ msgstr "impossible de se déplacer au tampon donné"
+#, c-format
+msgid "expected vim.TabPage object, but got %s"
+msgstr "attendu un objet vim.TabPage, mais reçu %s"
-#~ msgid "expected vim.window object"
-#~ msgstr "objet vim.window attendu"
+msgid "did not switch to the specified tab page"
+msgstr "impossible de se déplacer à l'onglet spécifié"
-#~ msgid "failed to find window in the current tab page"
-#~ msgstr "impossible de trouver une fenêtre dans l'onglet courant"
+msgid "failed to run the code"
+msgstr "exécution du code a échoué"
-#~ msgid "did not switch to the specified window"
-#~ msgstr "ne s'est pas déplacé à la fenêtre spécifiée"
+msgid "E858: Eval did not return a valid python object"
+msgstr "E858: Eval n'a pas retourné un objet python valide"
-#~ msgid "expected vim.tabpage object"
-#~ msgstr "objet vim.tabpage attendu"
+msgid "E859: Failed to convert returned python object to vim value"
+msgstr "E859: Conversion d'objet python à une valeur de vim a échoué"
-#~ msgid "did not switch to the specified tab page"
-#~ msgstr "impossible de se déplacer à l'onglet spécifié"
+#, c-format
+msgid "unable to convert %s to vim dictionary"
+msgstr "impossible de convertir %s à un dictionnaire vim"
-#~ msgid "failed to run the code"
-#~ msgstr "exécution du code a échoué"
+#, c-format
+msgid "unable to convert %s to vim list"
+msgstr "impossible de convertir %s à une liste de vim"
-#~ msgid "E858: Eval did not return a valid python object"
-#~ msgstr "E858: Eval n'a pas retourné un objet python valide"
+#, c-format
+msgid "unable to convert %s to vim structure"
+msgstr "impossible de convertir %s à une structure de vim"
-#~ msgid "E859: Failed to convert returned python object to vim value"
-#~ msgstr "E859: Conversion d'objet python à une valeur de vim a échoué"
+msgid "internal error: NULL reference passed"
+msgstr "erreur interne : référence NULL passée"
-#~ msgid "unable to convert to vim structure"
-#~ msgstr "conversion à une structure vim impossible"
+msgid "internal error: invalid value type"
+msgstr "erreur interne : type de valeur invalide"
-#~ msgid "NULL reference passed"
-#~ msgstr "référence NULL passée"
+msgid ""
+"Failed to set path hook: sys.path_hooks is not a list\n"
+"You should now do the following:\n"
+"- append vim.path_hook to sys.path_hooks\n"
+"- append vim.VIM_SPECIAL_PATH to sys.path\n"
+msgstr ""
+"Impossible d'initialiser sys.path_hook qui n'est pas un liste\n"
+"Vous devez maintenant :\n"
+"- ajouter vim.path_hook à sys.path_hooks\n"
+"- ajouter vim.VIM_SPECIAL_PATH à sys.path\n"
-#~ msgid "internal error: invalid value type"
-#~ msgstr "erreur interne : type de valeur invalide"
+msgid ""
+"Failed to set path: sys.path is not a list\n"
+"You should now append vim.VIM_SPECIAL_PATH to sys.path"
+msgstr ""
+"Impossible d'initialiser le chemin : sys.math n'est pas une liste\n"
+"Vous devez maintenant ajouter vim.VIM_SPECIAL_PATH à sys.path"
diff --git a/src/nvim/po/ga.po b/src/nvim/po/ga.po
index 761539039d..abb3565077 100644
--- a/src/nvim/po/ga.po
+++ b/src/nvim/po/ga.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vim 7.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-05-26 14:21+0200\n"
+"POT-Creation-Date: 2016-10-25 09:31-0500\n"
"PO-Revision-Date: 2010-04-14 10:01-0500\n"
"Last-Translator: Kevin Patrick Scannell <kscanne@gmail.com>\n"
"Language-Team: Irish <gaeilge-gnulinux@lists.sourceforge.net>\n"
@@ -14,208 +14,171 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : (n>2 && n<7) ? 2 :"
+"(n>6 && n<11) ? 3 : 4;\n"
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "Dramhaíl i ndiaidh argóinte rogha"
+msgid "E831: bf_key_init() called with empty password"
+msgstr "E831: cuireadh glaoch ar bf_key_init() le focal faire folamh"
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr ""
+msgid "E820: sizeof(uint32_t) != 4"
+msgstr "E820: sizeof(uint32_t) != 4"
+
+msgid "E817: Blowfish big/little endian use wrong"
+msgstr "E817: Úsáid mhícheart Blowfish mórcheannach/caolcheannach"
+
+msgid "E818: sha256 test failed"
+msgstr "E818: Theip ar thástáil sha256"
+
+msgid "E819: Blowfish test failed"
+msgstr "E819: Theip ar thástáil Blowfish"
-#: ../buffer.c:92
msgid "[Location List]"
msgstr "[Liosta Suíomh]"
-#: ../buffer.c:93
msgid "[Quickfix List]"
-msgstr "[Liosta Ceartúchán Tapa]"
+msgstr "[Liosta Mearcheartúchán]"
-#: ../buffer.c:94
-#, fuzzy
msgid "E855: Autocommands caused command to abort"
-msgstr "E812: Bhí maolán nó ainm maoláin athraithe ag orduithe uathoibríocha"
+msgstr "E855: Tobscoireadh an t-ordú mar gheall ar uathorduithe"
-#: ../buffer.c:135
msgid "E82: Cannot allocate any buffer, exiting..."
msgstr "E82: Ní féidir maolán a dháileadh, ag scor..."
-#: ../buffer.c:138
msgid "E83: Cannot allocate buffer, using other one..."
msgstr "E83: Ní féidir maolán a dháileadh, ag úsáid cinn eile..."
-#: ../buffer.c:763
+msgid "E931: Buffer cannot be registered"
+msgstr "E931: Ní féidir an maolán a chlárú"
+
+msgid "E937: Attempt to delete a buffer that is in use"
+msgstr "E937: Iarracht ar mhaolán in úsáid a scriosadh"
+
msgid "E515: No buffers were unloaded"
msgstr "E515: Ní raibh aon mhaolán díluchtaithe"
-#: ../buffer.c:765
msgid "E516: No buffers were deleted"
msgstr "E516: Ní raibh aon mhaolán scriosta"
-#: ../buffer.c:767
msgid "E517: No buffers were wiped out"
msgstr "E517: Ní raibh aon mhaolán bánaithe"
-#: ../buffer.c:772
msgid "1 buffer unloaded"
msgstr "Bhí maolán amháin díluchtaithe"
-#: ../buffer.c:774
#, c-format
msgid "%d buffers unloaded"
msgstr "%d maolán folmhaithe"
-#: ../buffer.c:777
msgid "1 buffer deleted"
msgstr "Bhí maolán amháin scriosta"
-#: ../buffer.c:779
#, c-format
msgid "%d buffers deleted"
msgstr "%d maolán scriosta"
-#: ../buffer.c:782
msgid "1 buffer wiped out"
msgstr "Bhí maolán amháin bánaithe"
-#: ../buffer.c:784
#, c-format
msgid "%d buffers wiped out"
msgstr "%d maolán bánaithe"
-#: ../buffer.c:806
msgid "E90: Cannot unload last buffer"
msgstr "E90: Ní féidir an maolán deireanach a dhíluchtú"
-#: ../buffer.c:874
msgid "E84: No modified buffer found"
msgstr "E84: Níor aimsíodh maolán mionathraithe"
#. back where we started, didn't find anything.
-#: ../buffer.c:903
msgid "E85: There is no listed buffer"
msgstr "E85: Níl aon mhaolán liostaithe ann"
-#: ../buffer.c:913
-#, c-format
-msgid "E86: Buffer %<PRId64> does not exist"
-msgstr "E86: Níl a leithéid de mhaolán %<PRId64>"
-
-#: ../buffer.c:915
msgid "E87: Cannot go beyond last buffer"
msgstr "E87: Ní féidir a dhul thar an maolán deireanach"
-#: ../buffer.c:917
msgid "E88: Cannot go before first buffer"
msgstr "E88: Ní féidir a dhul roimh an chéad mhaolán"
-#: ../buffer.c:945
#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
msgstr ""
-"E89: Athraíodh maolán %<PRId64> ach nach bhfuil sé sábháilte ó shin (cuir ! "
-"leis an ordú chun sárú)"
+"E89: Athraíodh maolán %ld ach nach bhfuil sé sábháilte ó shin (cuir ! leis "
+"an ordú chun sárú)"
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
msgid "W14: Warning: List of file names overflow"
msgstr "W14: Rabhadh: Liosta ainmneacha comhaid thar maoil"
-#: ../buffer.c:1555 ../quickfix.c:3361
#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: Maolán %<PRId64> gan aimsiú"
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Maolán %ld gan aimsiú"
-#: ../buffer.c:1798
#, c-format
msgid "E93: More than one match for %s"
msgstr "E93: Níos mó ná teaghrán amháin comhoiriúnaithe le %s"
-#: ../buffer.c:1800
#, c-format
msgid "E94: No matching buffer for %s"
msgstr "E94: Níl aon mhaolán comhoiriúnaithe le %s"
-#: ../buffer.c:2161
#, c-format
-msgid "line %<PRId64>"
-msgstr "líne %<PRId64>:"
+msgid "line %ld"
+msgstr "líne %ld:"
-#: ../buffer.c:2233
msgid "E95: Buffer with this name already exists"
msgstr "E95: Tá maolán ann leis an ainm seo cheana"
-#: ../buffer.c:2498
msgid " [Modified]"
msgstr " [Mionathraithe]"
-#: ../buffer.c:2501
msgid "[Not edited]"
msgstr "[Gan eagrú]"
-#: ../buffer.c:2504
msgid "[New file]"
msgstr "[Comhad nua]"
-#: ../buffer.c:2505
msgid "[Read errors]"
msgstr "[Earráidí léimh]"
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
msgid "[RO]"
msgstr "[L-A]"
-#: ../buffer.c:2507 ../fileio.c:1807
msgid "[readonly]"
msgstr "[inléite amháin]"
-#: ../buffer.c:2524
#, c-format
msgid "1 line --%d%%--"
msgstr "1 líne --%d%%--"
-#: ../buffer.c:2526
#, c-format
-msgid "%<PRId64> lines --%d%%--"
-msgstr "%<PRId64> líne --%d%%--"
+msgid "%ld lines --%d%%--"
+msgstr "%ld líne --%d%%--"
-#: ../buffer.c:2530
#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "líne %<PRId64> de %<PRId64> --%d%%-- col "
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "líne %ld de %ld --%d%%-- col "
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
msgid "[No Name]"
msgstr "[Gan Ainm]"
#. must be a help buffer
-#: ../buffer.c:2667
msgid "help"
msgstr "cabhair"
-#: ../buffer.c:3225 ../screen.c:4883
msgid "[Help]"
msgstr "[Cabhair]"
-#: ../buffer.c:3254 ../screen.c:4887
msgid "[Preview]"
msgstr "[Réamhamharc]"
-#: ../buffer.c:3528
msgid "All"
msgstr "Uile"
-#: ../buffer.c:3528
msgid "Bot"
msgstr "Bun"
-#: ../buffer.c:3531
msgid "Top"
msgstr "Barr"
-#: ../buffer.c:4244
msgid ""
"\n"
"# Buffer list:\n"
@@ -223,11 +186,9 @@ msgstr ""
"\n"
"# Liosta maoláin:\n"
-#: ../buffer.c:4289
msgid "[Scratch]"
msgstr "[Sealadach]"
-#: ../buffer.c:4529
msgid ""
"\n"
"--- Signs ---"
@@ -235,202 +196,236 @@ msgstr ""
"\n"
"--- Comharthaí ---"
-#: ../buffer.c:4538
#, c-format
msgid "Signs for %s:"
msgstr "Comharthaí do %s:"
-#: ../buffer.c:4543
#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " líne=%<PRId64> id=%d ainm=%s"
+msgid " line=%ld id=%d name=%s"
+msgstr " líne=%ld id=%d ainm=%s"
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: Idirstad ar iarraidh"
+msgid "E902: Cannot connect to port"
+msgstr "E902: Ní féidir ceangal leis an bport"
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: Mód neamhcheadaithe"
+msgid "E901: gethostbyname() in channel_open()"
+msgstr "E901: gethostbyname() in channel_open()"
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: ag súil le digit"
+msgid "E898: socket() in channel_open()"
+msgstr "E898: socket() in channel_open()"
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: Céatadán neamhcheadaithe"
+msgid "E903: received command with non-string argument"
+msgstr "E903: fuarthas ordú le hargóint nach bhfuil ina theaghrán"
+
+msgid "E904: last argument for expr/call must be a number"
+msgstr "E904: ní mór don argóint dheireanach ar expr/call a bheith ina huimhir"
+
+msgid "E904: third argument for call must be a list"
+msgstr "E904: Caithfidh an tríú argóint a bheith ina liosta"
+
+#, c-format
+msgid "E905: received unknown command: %s"
+msgstr "E905: fuarthas ordú anaithnid: %s"
+
+#, c-format
+msgid "E630: %s(): write while not connected"
+msgstr "E630: %s(): scríobh gan ceangal a bheith ann"
+
+#, c-format
+msgid "E631: %s(): write failed"
+msgstr "E631: %s(): theip ar scríobh"
+
+#, c-format
+msgid "E917: Cannot use a callback with %s()"
+msgstr "E917: Ní féidir aisghlaoch a úsáid le %s()"
+
+msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel"
+msgstr "E912: ní féidir ch_evalexpr()/ch_sendexpr() a úsáid le cainéal raw nó nl"
+
+msgid "E906: not an open channel"
+msgstr "E906: ní cainéal oscailte é"
+
+msgid "E920: _io file requires _name to be set"
+msgstr "E920: caithfear _name a shocrú chun comhad _io a úsáid"
+
+msgid "E915: in_io buffer requires in_buf or in_name to be set"
+msgstr "E915: caithfear in_buf nó in_name a shocrú chun maolán in_io a úsáid"
+
+#, c-format
+msgid "E918: buffer must be loaded: %s"
+msgstr "E918: ní mór an maolán a luchtú: %s"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: Comhad criptithe le modh anaithnid"
+
+msgid "Warning: Using a weak encryption method; see :help 'cm'"
+msgstr "Rabhadh: Criptiúchán lag; féach :help 'cm'"
+
+msgid "Enter encryption key: "
+msgstr "Iontráil eochair chriptiúcháin: "
+
+msgid "Enter same key again: "
+msgstr "Iontráil an eochair arís: "
+
+msgid "Keys don't match!"
+msgstr "Níl na heochracha comhoiriúnach le chéile!"
+
+msgid "[crypted]"
+msgstr "[criptithe]"
-#: ../diff.c:146
#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: Ní féidir diff a dhéanamh ar níos mó ná %<PRId64> maolán"
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Idirstad ar iarraidh i bhFoclóir: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Eochair dhúblach i bhFoclóir: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Camóg ar iarraidh i bhFoclóir: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: '}' ar iarraidh ag deireadh foclóra: %s"
+
+msgid "extend() argument"
+msgstr "argóint extend()"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Tá eochair ann cheana: %s"
+
+#, c-format
+msgid "E96: Cannot diff more than %ld buffers"
+msgstr "E96: Ní féidir diff a dhéanamh ar níos mó ná %ld maolán"
-#: ../diff.c:753
msgid "E810: Cannot read or write temp files"
msgstr "E810: Ní féidir comhaid shealadacha a léamh nó a scríobh"
-#: ../diff.c:755
msgid "E97: Cannot create diffs"
msgstr "E97: Ní féidir diffeanna a chruthú"
-#: ../diff.c:966
+msgid "Patch file"
+msgstr "Comhad paiste"
+
msgid "E816: Cannot read patch output"
msgstr "E816: Ní féidir aschur ó 'patch' a léamh"
-#: ../diff.c:1220
msgid "E98: Cannot read diff output"
msgstr "E98: Ní féidir aschur ó 'diff' a léamh"
-#: ../diff.c:2081
msgid "E99: Current buffer is not in diff mode"
msgstr "E99: Níl an maolán reatha sa mhód diff"
-#: ../diff.c:2100
msgid "E793: No other buffer in diff mode is modifiable"
msgstr "E793: Ní féidir aon mhaolán eile a athrú sa mhód diff"
-#: ../diff.c:2102
msgid "E100: No other buffer in diff mode"
msgstr "E100: Níl aon mhaolán eile sa mhód diff"
-#: ../diff.c:2112
msgid "E101: More than two buffers in diff mode, don't know which one to use"
msgstr ""
"E101: Tá níos mó ná dhá mhaolán sa mhód diff, níl fhios agam cé acu ba chóir "
"a úsáid"
-#: ../diff.c:2141
#, c-format
msgid "E102: Can't find buffer \"%s\""
msgstr "E102: Tá maolán \"%s\" gan aimsiú"
-#: ../diff.c:2152
#, c-format
msgid "E103: Buffer \"%s\" is not in diff mode"
msgstr "E103: Níl maolán \"%s\" i mód diff"
-#: ../diff.c:2193
msgid "E787: Buffer changed unexpectedly"
msgstr "E787: Athraíodh an maolán gan choinne"
-#: ../digraph.c:1598
msgid "E104: Escape not allowed in digraph"
msgstr "E104: Ní cheadaítear carachtair éalúcháin i ndéghraf"
-#: ../digraph.c:1760
msgid "E544: Keymap file not found"
msgstr "E544: Comhad eochairmhapála gan aimsiú"
-#: ../digraph.c:1785
msgid "E105: Using :loadkeymap not in a sourced file"
msgstr "E105: Ag úsáid :loadkeymap ach ní comhad foinsithe é seo"
-#: ../digraph.c:1821
msgid "E791: Empty keymap entry"
msgstr "E791: Iontráil fholamh eochairmhapála"
-#: ../edit.c:82
msgid " Keyword completion (^N^P)"
msgstr " Comhlánú lorgfhocal (^N^P)"
#. ctrl_x_mode == 0, ^P/^N compl.
-#: ../edit.c:83
msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
msgstr " mód ^X (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
-#: ../edit.c:85
msgid " Whole line completion (^L^N^P)"
msgstr " Comhlánú Línte Ina Iomlán (^L^N^P)"
-#: ../edit.c:86
msgid " File name completion (^F^N^P)"
msgstr " Comhlánú de na hainmneacha comhaid (^F^N^P)"
-#: ../edit.c:87
msgid " Tag completion (^]^N^P)"
msgstr " Comhlánú clibeanna (^]/^N/^P)"
-#: ../edit.c:88
msgid " Path pattern completion (^N^P)"
msgstr " Comhlánú Conaire (^N^P)"
-#: ../edit.c:89
msgid " Definition completion (^D^N^P)"
msgstr " Comhlánú de na sainmhínithe (^D^N^P)"
-#: ../edit.c:91
msgid " Dictionary completion (^K^N^P)"
msgstr " Comhlánú foclóra (^K^N^P)"
-#: ../edit.c:92
msgid " Thesaurus completion (^T^N^P)"
msgstr " Comhlánú teasárais (^T^N^P)"
-#: ../edit.c:93
msgid " Command-line completion (^V^N^P)"
msgstr " Comhlánú den líne ordaithe (^V^N^P)"
-#: ../edit.c:94
msgid " User defined completion (^U^N^P)"
msgstr " Comhlánú saincheaptha (^U^N^P)"
-#: ../edit.c:95
msgid " Omni completion (^O^N^P)"
msgstr " Comhlánú Omni (^O^N^P)"
-#: ../edit.c:96
msgid " Spelling suggestion (s^N^P)"
msgstr " Moladh litrithe (s^N^P)"
-#: ../edit.c:97
msgid " Keyword Local completion (^N^P)"
msgstr " Comhlánú logánta lorgfhocal (^N^P)"
-#: ../edit.c:100
msgid "Hit end of paragraph"
msgstr "Sroicheadh críoch an pharagraif"
-#: ../edit.c:101
-#, fuzzy
msgid "E839: Completion function changed window"
-msgstr "E813: Ní féidir fuinneog autocmd a dhúnadh"
+msgstr "E839: D'athraigh an fheidhm chomhlánaithe an fhuinneog"
-#: ../edit.c:102
msgid "E840: Completion function deleted text"
-msgstr ""
+msgstr "E840: Scrios an fheidhm chomhlánaithe roinnt téacs"
-#: ../edit.c:1847
msgid "'dictionary' option is empty"
msgstr "tá an rogha 'dictionary' folamh"
-#: ../edit.c:1848
msgid "'thesaurus' option is empty"
msgstr "tá an rogha 'thesaurus' folamh"
-#: ../edit.c:2655
#, c-format
msgid "Scanning dictionary: %s"
msgstr "Foclóir á scanadh: %s"
-#: ../edit.c:3079
msgid " (insert) Scroll (^E/^Y)"
msgstr " (ionsáigh) Scrollaigh (^E/^Y)"
-#: ../edit.c:3081
msgid " (replace) Scroll (^E/^Y)"
msgstr " (ionadaigh) Scrollaigh (^E/^Y)"
-#: ../edit.c:3587
#, c-format
msgid "Scanning: %s"
msgstr "%s á scanadh"
-#: ../edit.c:3614
msgid "Scanning tags."
msgstr "Clibeanna á scanadh."
-#: ../edit.c:4519
msgid " Adding"
msgstr " Méadú"
@@ -438,702 +433,451 @@ msgstr " Méadú"
#. * be called before line = ml_get(), or when this address is no
#. * longer needed. -- Acevedo.
#.
-#: ../edit.c:4562
msgid "-- Searching..."
msgstr "-- Ag Cuardach..."
-#: ../edit.c:4618
msgid "Back at original"
msgstr "Ar ais ag an mbunáit"
-#: ../edit.c:4621
msgid "Word from other line"
msgstr "Focal as líne eile"
-#: ../edit.c:4624
msgid "The only match"
msgstr "An t-aon teaghrán amháin comhoiriúnaithe"
-#: ../edit.c:4680
#, c-format
msgid "match %d of %d"
msgstr "comhoiriúnú %d as %d"
-#: ../edit.c:4684
#, c-format
msgid "match %d"
msgstr "comhoiriúnú %d"
-#: ../eval.c:137
+#. maximum nesting of lists and dicts
msgid "E18: Unexpected characters in :let"
msgstr "E18: Carachtair gan choinne i :let"
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: innéacs liosta as raon: %<PRId64>"
-
-#: ../eval.c:139
#, c-format
msgid "E121: Undefined variable: %s"
msgstr "E121: Athróg gan sainmhíniú: %s"
-#: ../eval.c:140
msgid "E111: Missing ']'"
msgstr "E111: `]' ar iarraidh"
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: Caithfidh argóint de %s a bheith ina Liosta"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: Caithfidh argóint de %s a bheith ina Liosta nó Foclóir"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Ní féidir eochair fholamh a úsáid le Foclóir"
-
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: Tá gá le liosta"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: Tá gá le foclóir"
-
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: An iomarca argóintí d'fheidhm: %s"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: Níl an eochair seo san Fhoclóir: %s"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: Tá feidhm %s ann cheana, cuir ! leis an ordú chun é a asáitiú"
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: Tá an iontráil foclóra seo ann cheana"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: Tá gá le Funcref"
-
-#: ../eval.c:153
msgid "E719: Cannot use [:] with a Dictionary"
msgstr "E719: Ní féidir [:] a úsáid le foclóir"
-#: ../eval.c:154
#, c-format
msgid "E734: Wrong variable type for %s="
msgstr "E734: Cineál mícheart athróige le haghaidh %s="
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: Feidhm anaithnid: %s"
-
-#: ../eval.c:156
#, c-format
msgid "E461: Illegal variable name: %s"
msgstr "E461: Ainm athróige neamhcheadaithe: %s"
-#: ../eval.c:157
msgid "E806: using Float as a String"
msgstr "E806: Snámhphointe á úsáid mar Theaghrán"
-#: ../eval.c:1830
msgid "E687: Less targets than List items"
msgstr "E687: Níos lú spriocanna ná míreanna Liosta"
-#: ../eval.c:1834
msgid "E688: More targets than List items"
msgstr "E688: Níos mó spriocanna ná míreanna Liosta"
-#: ../eval.c:1906
msgid "Double ; in list of variables"
msgstr "; dúblach i liosta na n-athróg"
-#: ../eval.c:2078
#, c-format
msgid "E738: Can't list variables for %s"
msgstr "E738: Ní féidir athróga do %s a thaispeáint"
-#: ../eval.c:2391
msgid "E689: Can only index a List or Dictionary"
msgstr "E689: Is féidir Liosta nó Foclóir amháin a innéacsú"
-#: ../eval.c:2396
msgid "E708: [:] must come last"
msgstr "E708: caithfidh [:] a bheith ar deireadh"
-#: ../eval.c:2439
msgid "E709: [:] requires a List value"
msgstr "E709: ní foláir Liosta a thabhairt le [:]"
-#: ../eval.c:2674
msgid "E710: List value has more items than target"
msgstr "E710: Tá níos mó míreanna ag an Liosta ná an sprioc"
-#: ../eval.c:2678
msgid "E711: List value has not enough items"
msgstr "E711: Níl go leor míreanna ag an Liosta"
-#: ../eval.c:2867
msgid "E690: Missing \"in\" after :for"
msgstr "E690: \"in\" ar iarraidh i ndiaidh :for"
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: Lúibíní ar iarraidh: %s"
-
-#: ../eval.c:3263
#, c-format
msgid "E108: No such variable: \"%s\""
msgstr "E108: Níl a leithéid d'athróg: \"%s\""
-#: ../eval.c:3333
msgid "E743: variable nested too deep for (un)lock"
msgstr "E743: athróg neadaithe ródhomhain chun í a (dí)ghlasáil"
-#: ../eval.c:3630
msgid "E109: Missing ':' after '?'"
msgstr "E109: ':' ar iarraidh i ndiaidh '?'"
-#: ../eval.c:3893
msgid "E691: Can only compare List with List"
msgstr "E691: Is féidir Liosta a chur i gcomparáid le Liosta eile amháin"
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
+msgid "E692: Invalid operation for List"
msgstr "E692: Oibríocht neamhbhailí ar Liostaí"
-#: ../eval.c:3915
msgid "E735: Can only compare Dictionary with Dictionary"
msgstr "E735: Is féidir Foclóir a chur i gcomparáid le Foclóir eile amháin"
-#: ../eval.c:3917
msgid "E736: Invalid operation for Dictionary"
msgstr "E736: Oibríocht neamhbhailí ar Fhoclóir"
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: Is féidir Funcref a chur i gcomparáid le Funcref eile amháin"
-
-#: ../eval.c:3934
msgid "E694: Invalid operation for Funcrefs"
msgstr "E694: Oibríocht neamhbhailí ar Funcref"
-#: ../eval.c:4277
msgid "E804: Cannot use '%' with Float"
msgstr "E804: Ní féidir '%' a úsáid le Snámhphointe"
-#: ../eval.c:4478
msgid "E110: Missing ')'"
msgstr "E110: ')' ar iarraidh"
-#: ../eval.c:4609
msgid "E695: Cannot index a Funcref"
msgstr "E695: Ní féidir Funcref a innéacsú"
-#: ../eval.c:4839
+msgid "E909: Cannot index a special variable"
+msgstr "E909: Ní féidir athróg speisialta a innéacsú"
+
#, c-format
msgid "E112: Option name missing: %s"
msgstr "E112: Ainm rogha ar iarraidh: %s"
-#: ../eval.c:4855
#, c-format
msgid "E113: Unknown option: %s"
msgstr "E113: Rogha anaithnid: %s"
-#: ../eval.c:4904
#, c-format
msgid "E114: Missing quote: %s"
msgstr "E114: Comhartha athfhriotail ar iarraidh: %s"
-#: ../eval.c:5020
#, c-format
msgid "E115: Missing quote: %s"
msgstr "E115: Comhartha athfhriotail ar iarraidh: %s"
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: Camóg ar iarraidh i Liosta: %s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: ']' ar iarraidh ag deireadh liosta: %s"
-
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: Idirstad ar iarraidh i bhFoclóir: %s"
-
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: Eochair dhúblach i bhFoclóir: \"%s\""
-
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: Camóg ar iarraidh i bhFoclóir: %s"
-
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: '}' ar iarraidh ag deireadh foclóra: %s"
+msgid "Not enough memory to set references, garbage collection aborted!"
+msgstr ""
+"Níl go leor cuimhne ann le tagairtí a shocrú; bailiú dramhaíola á thobscor!"
-#: ../eval.c:6555
msgid "E724: variable nested too deep for displaying"
msgstr "E724: athróg neadaithe ródhomhain chun í a thaispeáint"
-#: ../eval.c:7188
-#, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E740: An iomarca argóintí d'fheidhm %s"
-
-#: ../eval.c:7190
-#, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E116: Argóintí neamhbhailí d'fheidhm %s"
-
-#: ../eval.c:7377
-#, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E117: Feidhm anaithnid: %s"
-
-#: ../eval.c:7383
-#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: Níl go leor feidhmeanna d'fheidhm: %s"
-
-#: ../eval.c:7387
-#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: <SID> á úsáid ach gan a bheith i gcomhthéacs scripte: %s"
-
-#: ../eval.c:7391
-#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E725: Feidhm 'dict' á ghlao gan Foclóir: %s"
-
-#: ../eval.c:7453
-msgid "E808: Number or Float required"
-msgstr "E808: Uimhir nó Snámhphointe de dhíth"
-
-#: ../eval.c:7503
-#, fuzzy
-msgid "add() argument"
-msgstr "argóint -c"
-
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: An iomarca argóintí"
-
-#: ../eval.c:8073
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: is féidir complete() a úsáid sa mhód Ionsáite amháin"
-
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "&Ok"
-
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: Tá eochair ann cheana: %s"
-
-#: ../eval.c:8692
-#, fuzzy
-msgid "extend() argument"
-msgstr "argóint --cmd"
-
-#: ../eval.c:8915
-#, fuzzy
-msgid "map() argument"
-msgstr "argóint -c"
-
-#: ../eval.c:8916
-#, fuzzy
-msgid "filter() argument"
-msgstr "argóint -c"
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld líne: "
-
-#: ../eval.c:9291
-#, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E700: Feidhm anaithnid: %s"
-
-#: ../eval.c:10729
-msgid "called inputrestore() more often than inputsave()"
-msgstr "Glaodh inputrestore() níos minice ná inputsave()"
-
-#: ../eval.c:10771
-#, fuzzy
-msgid "insert() argument"
-msgstr "argóint -c"
-
-#: ../eval.c:10841
-msgid "E786: Range not allowed"
-msgstr "E786: Ní cheadaítear an raon"
-
-#: ../eval.c:11140
-msgid "E701: Invalid type for len()"
-msgstr "E701: Cineál neamhbhailí le haghaidh len()"
-
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr "E726: Is nialas í an chéim"
-
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr "E727: Tosach thar dheireadh"
-
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr "<folamh>"
-
-#: ../eval.c:12282
-#, fuzzy
-msgid "remove() argument"
-msgstr "argóint --cmd"
+msgid "E805: Using a Float as a Number"
+msgstr "E805: Snámhphointe á úsáid mar Uimhir"
-#: ../eval.c:12466
-msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: An iomarca naisc shiombalacha (ciogal?)"
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Funcref á úsáid mar Uimhir"
-#: ../eval.c:12593
-#, fuzzy
-msgid "reverse() argument"
-msgstr "argóint -c"
+msgid "E745: Using a List as a Number"
+msgstr "E745: Liosta á úsáid mar Uimhir"
-#: ../eval.c:13721
-#, fuzzy
-msgid "sort() argument"
-msgstr "argóint -c"
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Foclóir á úsáid mar Uimhir"
-#: ../eval.c:13721
-#, fuzzy
-msgid "uniq() argument"
-msgstr "argóint -c"
+msgid "E910: Using a Job as a Number"
+msgstr "E910: Jab á úsáid mar Uimhir"
-#: ../eval.c:13776
-msgid "E702: Sort compare function failed"
-msgstr "E702: Theip ar fheidhm chomparáide le linn sórtála"
+msgid "E913: Using a Channel as a Number"
+msgstr "E913: Cainéal á úsáid mar Uimhir"
-#: ../eval.c:13806
-#, fuzzy
-msgid "E882: Uniq compare function failed"
-msgstr "E702: Theip ar fheidhm chomparáide le linn sórtála"
+msgid "E891: Using a Funcref as a Float"
+msgstr "E891: Funcref á úsáid mar Shnámhphointe"
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(Neamhbhailí)"
+msgid "E892: Using a String as a Float"
+msgstr "E892: Teaghrán á úsáid mar Shnámhphointe"
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: Earráid agus comhad sealadach á scríobh"
+msgid "E893: Using a List as a Float"
+msgstr "E893: Liosta á úsáid mar Shnámhphointe"
-#: ../eval.c:16159
-msgid "E805: Using a Float as a Number"
-msgstr "E805: Snámhphointe á úsáid mar Uimhir"
+msgid "E894: Using a Dictionary as a Float"
+msgstr "E894: Foclóir á úsáid mar Shnámhphointe"
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr "E703: Funcref á úsáid mar Uimhir"
+msgid "E907: Using a special value as a Float"
+msgstr "E907: Luach speisialta á úsáid mar Shnámhphointe"
-#: ../eval.c:16170
-msgid "E745: Using a List as a Number"
-msgstr "E745: Liosta á úsáid mar Uimhir"
+msgid "E911: Using a Job as a Float"
+msgstr "E911: Jab á úsáid mar Shnámhphointe"
-#: ../eval.c:16173
-msgid "E728: Using a Dictionary as a Number"
-msgstr "E728: Foclóir á úsáid mar Uimhir"
+msgid "E914: Using a Channel as a Float"
+msgstr "E914: Cainéal á úsáid mar Shnámhphointe"
-#: ../eval.c:16259
msgid "E729: using Funcref as a String"
msgstr "E729: Funcref á úsáid mar Theaghrán"
-#: ../eval.c:16262
msgid "E730: using List as a String"
msgstr "E730: Liosta á úsáid mar Theaghrán"
-#: ../eval.c:16265
msgid "E731: using Dictionary as a String"
msgstr "E731: Foclóir á úsáid mar Theaghrán"
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: Mímheaitseáil idir cineálacha athróige: %s"
+msgid "E908: using an invalid value as a String"
+msgstr "E908: luach neamhbhailí á úsáid mar Theaghrán"
-#: ../eval.c:16705
#, c-format
msgid "E795: Cannot delete variable %s"
msgstr "E795: Ní féidir athróg %s a scriosadh"
-#: ../eval.c:16724
#, c-format
msgid "E704: Funcref variable name must start with a capital: %s"
msgstr "E704: Caithfidh ceannlitir a bheith ar dtús ainm Funcref: %s"
-#: ../eval.c:16732
#, c-format
msgid "E705: Variable name conflicts with existing function: %s"
msgstr "E705: Tagann ainm athróige salach ar fheidhm atá ann cheana: %s"
-#: ../eval.c:16763
#, c-format
msgid "E741: Value is locked: %s"
msgstr "E741: Tá an luach faoi ghlas: %s"
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
msgid "Unknown"
msgstr "Anaithnid"
-#: ../eval.c:16768
#, c-format
msgid "E742: Cannot change value of %s"
msgstr "E742: Ní féidir an luach de %s a athrú"
-#: ../eval.c:16838
msgid "E698: variable nested too deep for making a copy"
msgstr "E698: athróg neadaithe ródhomhain chun í a chóipeáil"
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: Feidhm gan sainmhíniú: %s"
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# athróga comhchoiteanna:\n"
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: '(' ar iarraidh: %s"
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tSocraithe is déanaí ó "
-#: ../eval.c:17293
-#, fuzzy
-msgid "E862: Cannot use g: here"
-msgstr "E284: Ní féidir luachanna IC a shocrú"
+msgid "map() argument"
+msgstr "argóint map()"
+
+msgid "filter() argument"
+msgstr "argóint filter()"
-#: ../eval.c:17312
#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: Argóint neamhcheadaithe: %s"
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Caithfidh argóint de %s a bheith ina Liosta"
-#: ../eval.c:17323
-#, fuzzy, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E125: Argóint neamhcheadaithe: %s"
+msgid "E928: String required"
+msgstr "E928: Teaghrán de dhíth"
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: :endfunction ar iarraidh"
+msgid "E808: Number or Float required"
+msgstr "E808: Uimhir nó Snámhphointe de dhíth"
-#: ../eval.c:17537
-#, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E707: Tagann ainm na feidhme salach ar athróg: %s"
+msgid "add() argument"
+msgstr "argóint add()"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: is féidir complete() a úsáid sa mhód Ionsáite amháin"
+
+#.
+#. * Yes this is ugly, I don't particularly like it either. But doing it
+#. * this way has the compelling advantage that translations need not to
+#. * be touched at all. See below what 'ok' and 'ync' are used for.
+#.
+msgid "&Ok"
+msgstr "&Ok"
-#: ../eval.c:17549
#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr ""
-"E127: Ní féidir sainmhíniú nua a dhéanamh ar fheidhm %s: In úsáid cheana"
+msgid "+-%s%3ld line: "
+msgid_plural "+-%s%3ld lines: "
+msgstr[0] "+-%s%3ld líne: "
+msgstr[1] "+-%s%3ld líne: "
+msgstr[2] "+-%s%3ld líne: "
+msgstr[3] "+-%s%3ld líne: "
+msgstr[4] "+-%s%3ld líne: "
-#: ../eval.c:17604
#, c-format
-msgid "E746: Function name does not match script file name: %s"
-msgstr ""
-"E746: Níl ainm na feidhme comhoiriúnach le hainm comhaid na scripte: %s"
+msgid "E700: Unknown function: %s"
+msgstr "E700: Feidhm anaithnid: %s"
-#: ../eval.c:17716
-msgid "E129: Function name required"
-msgstr "E129: Tá gá le hainm feidhme"
+msgid "E922: expected a dict"
+msgstr "E922: bhíothas ag súil le foclóir"
-#: ../eval.c:17824
-#, fuzzy, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr ""
-"E128: Caithfidh ceannlitir a bheith ar dtús ainm feidhme, nó idirstad a "
-"bheith ann: %s"
+msgid "E923: Second argument of function() must be a list or a dict"
+msgstr "E923: Caithfidh an dara hargóint de function() a bheith ina liosta nó ina foclóir"
-#: ../eval.c:17833
-#, fuzzy, c-format
-msgid "E884: Function name cannot contain a colon: %s"
+msgid ""
+"&OK\n"
+"&Cancel"
msgstr ""
-"E128: Caithfidh ceannlitir a bheith ar dtús ainm feidhme, nó idirstad a "
-"bheith ann: %s"
+"&OK\n"
+"&Cealaigh"
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: Ní féidir feidhm %s a scriosadh: Tá sé in úsáid faoi láthair"
+msgid "called inputrestore() more often than inputsave()"
+msgstr "Glaodh inputrestore() níos minice ná inputsave()"
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: Doimhneacht na nglaonna níos mó ná 'maxfuncdepth'"
+msgid "insert() argument"
+msgstr "argóint insert()"
-#: ../eval.c:18568
-#, c-format
-msgid "calling %s"
-msgstr "%s á glao"
+msgid "E786: Range not allowed"
+msgstr "E786: Ní cheadaítear an raon"
-#: ../eval.c:18651
-#, c-format
-msgid "%s aborted"
-msgstr "%s tobscortha"
+msgid "E916: not a valid job"
+msgstr "E916: ní jab bailí é"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Cineál neamhbhailí le haghaidh len()"
-#: ../eval.c:18653
#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s ag aisfhilleadh #%<PRId64>"
+msgid "E798: ID is reserved for \":match\": %ld"
+msgstr "E798: Aitheantas in áirithe do \":match\": %ld"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Is nialas í an chéim"
+
+msgid "E727: Start past end"
+msgstr "E727: Tosach thar dheireadh"
+
+msgid "<empty>"
+msgstr "<folamh>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Níl aon nasc le freastalaí Vim"
-#: ../eval.c:18670
#, c-format
-msgid "%s returning %s"
-msgstr "%s ag aisfhilleadh %s"
+msgid "E241: Unable to send to %s"
+msgstr "E241: Ní féidir aon rud a sheoladh chuig %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Ní féidir freagra ón fhreastalaí a léamh"
+
+msgid "remove() argument"
+msgstr "argóint remove()"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: An iomarca naisc shiombalacha (ciogal?)"
+
+msgid "reverse() argument"
+msgstr "argóint reverse()"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Ní féidir aon rud a sheoladh chuig an chliant"
-#: ../eval.c:18691 ../ex_cmds2.c:2695
#, c-format
-msgid "continuing in %s"
-msgstr "ag leanúint i %s"
+msgid "E927: Invalid action: '%s'"
+msgstr "E927: Gníomh neamhbhailí: '%s'"
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: Caithfidh :return a bheith isteach i bhfeidhm"
+msgid "sort() argument"
+msgstr "argóint sort()"
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# athróga comhchoiteanna:\n"
+msgid "uniq() argument"
+msgstr "argóint uniq()"
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\tSocraithe is déanaí ó "
+msgid "E702: Sort compare function failed"
+msgstr "E702: Theip ar fheidhm chomparáide le linn sórtála"
-#: ../eval.c:19272
-msgid "No old files"
-msgstr "Gan seanchomhaid"
+msgid "E882: Uniq compare function failed"
+msgstr "E882: Theip ar fheidhm chomparáide Uniq"
+
+msgid "(Invalid)"
+msgstr "(Neamhbhailí)"
+
+#, c-format
+msgid "E935: invalid submatch number: %d"
+msgstr "E935: uimhir fho-mheaitseála neamhbhailí: %d"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Earráid agus comhad sealadach á scríobh"
+
+msgid "E921: Invalid callback argument"
+msgstr "E921: Argóint neamhbhailí ar aisghlaoch"
-#: ../ex_cmds.c:122
#, c-format
msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
msgstr "<%s>%s%s %d, Heics %02x, Ocht %03o"
-#: ../ex_cmds.c:145
#, c-format
msgid "> %d, Hex %04x, Octal %o"
msgstr "> %d, Heics %04x, Ocht %o"
-#: ../ex_cmds.c:146
#, c-format
msgid "> %d, Hex %08x, Octal %o"
msgstr "> %d, Heics %08x, Ocht %o"
-#: ../ex_cmds.c:684
msgid "E134: Move lines into themselves"
msgstr "E134: Bog línte isteach iontu féin"
-#: ../ex_cmds.c:747
msgid "1 line moved"
msgstr "Bogadh líne amháin"
-#: ../ex_cmds.c:749
#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "Bogadh %<PRId64> líne"
+msgid "%ld lines moved"
+msgstr "Bogadh %ld líne"
-#: ../ex_cmds.c:1175
#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "Scagadh %<PRId64> líne"
+msgid "%ld lines filtered"
+msgstr "Scagadh %ld líne"
-#: ../ex_cmds.c:1194
msgid "E135: *Filter* Autocommands must not change current buffer"
msgstr ""
"E135: Ní cheadaítear d'uathorduithe *scagaire* an maolán reatha a athrú"
-#: ../ex_cmds.c:1244
msgid "[No write since last change]\n"
msgstr "[Athraithe agus nach sábháilte ó shin]\n"
-#: ../ex_cmds.c:1424
#, c-format
msgid "%sviminfo: %s in line: "
msgstr "%sviminfo: %s i líne: "
-#: ../ex_cmds.c:1431
msgid "E136: viminfo: Too many errors, skipping rest of file"
msgstr ""
"E136: viminfo: An iomarca earráidí, ag scipeáil an chuid eile den chomhad"
-#: ../ex_cmds.c:1458
#, c-format
msgid "Reading viminfo file \"%s\"%s%s%s"
msgstr "Comhad viminfo \"%s\"%s%s%s á léamh"
-#: ../ex_cmds.c:1460
msgid " info"
msgstr " eolas"
-#: ../ex_cmds.c:1461
msgid " marks"
msgstr " marcanna"
-#: ../ex_cmds.c:1462
msgid " oldfiles"
msgstr " seanchomhad"
-#: ../ex_cmds.c:1463
msgid " FAILED"
msgstr " TEIPTHE"
#. avoid a wait_return for this message, it's annoying
-#: ../ex_cmds.c:1541
#, c-format
msgid "E137: Viminfo file is not writable: %s"
msgstr "E137: Níl an comhad Viminfo inscríofa: %s"
-#: ../ex_cmds.c:1626
+#, c-format
+msgid "E929: Too many viminfo temp files, like %s!"
+msgstr "E929: An iomarca comhad sealadach viminfo, mar shampla %s!"
+
#, c-format
msgid "E138: Can't write viminfo file %s!"
msgstr "E138: Ní féidir comhad viminfo %s a scríobh!"
-#: ../ex_cmds.c:1635
#, c-format
msgid "Writing viminfo file \"%s\""
msgstr "Comhad viminfo \"%s\" á scríobh"
+#, c-format
+msgid "E886: Can't rename viminfo file to %s!"
+msgstr "E886: Ní féidir ainm %s a chur ar an gcomhad viminfo!"
+
#. Write the info:
-#: ../ex_cmds.c:1720
#, c-format
msgid "# This viminfo file was generated by Vim %s.\n"
msgstr "# Chruthaigh Vim an comhad viminfo seo %s.\n"
-#: ../ex_cmds.c:1722
msgid ""
"# You may edit it if you're careful!\n"
"\n"
@@ -1141,47 +885,47 @@ msgstr ""
"# Is féidir leat an comhad seo a chur in eagar ach bí cúramach!\n"
"\n"
-#: ../ex_cmds.c:1723
msgid "# Value of 'encoding' when this file was written\n"
msgstr "# Luach 'encoding' agus an comhad seo á scríobh\n"
-#: ../ex_cmds.c:1800
msgid "Illegal starting char"
msgstr "Carachtar neamhcheadaithe tosaigh"
-#: ../ex_cmds.c:2162
+msgid ""
+"\n"
+"# Bar lines, copied verbatim:\n"
+msgstr ""
+"\n"
+"# Barralínte, cóipeáilte focal ar fhocal:\n"
+
+msgid "Save As"
+msgstr "Sábháil Mar"
+
msgid "Write partial file?"
msgstr "Scríobh comhad neamhiomlán?"
-#: ../ex_cmds.c:2166
msgid "E140: Use ! to write partial buffer"
msgstr "E140: Bain úsáid as ! chun maolán neamhiomlán a scríobh"
-#: ../ex_cmds.c:2281
#, c-format
msgid "Overwrite existing file \"%s\"?"
msgstr "Forscríobh comhad \"%s\" atá ann cheana?"
-#: ../ex_cmds.c:2317
#, c-format
msgid "Swap file \"%s\" exists, overwrite anyway?"
msgstr "Tá comhad babhtála \"%s\" ann cheana; forscríobh mar sin féin?"
-#: ../ex_cmds.c:2326
#, c-format
msgid "E768: Swap file exists: %s (:silent! overrides)"
msgstr "E768: Tá comhad babhtála ann cheana: %s (úsáid :silent! chun sárú)"
-#: ../ex_cmds.c:2381
#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: Níl aon ainm ar mhaolán %<PRId64>"
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Níl aon ainm ar mhaolán %ld"
-#: ../ex_cmds.c:2412
msgid "E142: File not written: Writing is disabled by 'write' option"
msgstr "E142: Níor scríobhadh an comhad: díchumasaithe leis an rogha 'write'"
-#: ../ex_cmds.c:2434
#, c-format
msgid ""
"'readonly' option is set for \"%s\".\n"
@@ -1190,7 +934,6 @@ msgstr ""
"tá an rogha 'readonly' socraithe do \"%s\".\n"
"Ar mhaith leat é a scríobh mar sin féin?"
-#: ../ex_cmds.c:2439
#, c-format
msgid ""
"File permissions of \"%s\" are read-only.\n"
@@ -1201,85 +944,70 @@ msgstr ""
"Seans gurbh fhéidir scríobh ann mar sin féin.\n"
"An bhfuil fonn ort triail a bhaint as?"
-#: ../ex_cmds.c:2451
#, c-format
msgid "E505: \"%s\" is read-only (add ! to override)"
msgstr "E505: is inléite amháin é \"%s\" (cuir ! leis an ordú chun sárú)"
-#: ../ex_cmds.c:3120
+msgid "Edit File"
+msgstr "Cuir Comhad in Eagar"
+
#, c-format
msgid "E143: Autocommands unexpectedly deleted new buffer %s"
msgstr "E143: Scrios na huathorduithe maolán nua %s go tobann"
-#: ../ex_cmds.c:3313
msgid "E144: non-numeric argument to :z"
msgstr "E144: argóint neamhuimhriúil chun :z"
-#: ../ex_cmds.c:3404
msgid "E145: Shell commands not allowed in rvim"
msgstr "E145: Ní cheadaítear orduithe blaoisce i rvim"
-#: ../ex_cmds.c:3498
msgid "E146: Regular expressions can't be delimited by letters"
msgstr ""
"E146: Ní cheadaítear litreacha mar theormharcóirí ar shloinn ionadaíochta"
-#: ../ex_cmds.c:3964
#, c-format
msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
msgstr "cuir %s ina ionad (y/n/a/q/l/^E/^Y)?"
-#: ../ex_cmds.c:4379
msgid "(Interrupted) "
msgstr "(Idirbhriste) "
-#: ../ex_cmds.c:4384
msgid "1 match"
msgstr "1 rud comhoiriúnach"
-#: ../ex_cmds.c:4384
msgid "1 substitution"
msgstr "1 ionadaíocht"
-#: ../ex_cmds.c:4387
#, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> rud comhoiriúnach"
+msgid "%ld matches"
+msgstr "%ld rud comhoiriúnach"
-#: ../ex_cmds.c:4388
#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> ionadaíocht"
+msgid "%ld substitutions"
+msgstr "%ld ionadaíocht"
-#: ../ex_cmds.c:4392
msgid " on 1 line"
msgstr " ar líne amháin"
-#: ../ex_cmds.c:4395
#, c-format
-msgid " on %<PRId64> lines"
-msgstr " ar %<PRId64> líne"
+msgid " on %ld lines"
+msgstr " ar %ld líne"
-#: ../ex_cmds.c:4438
msgid "E147: Cannot do :global recursive"
msgstr "E147: Ní cheadaítear :global go hathchúrsach"
# should have ":"
-#: ../ex_cmds.c:4467
msgid "E148: Regular expression missing from global"
msgstr "E148: Slonn ionadaíochta ar iarraidh ó :global"
-#: ../ex_cmds.c:4508
#, c-format
msgid "Pattern found in every line: %s"
msgstr "Aimsíodh an patrún i ngach líne: %s"
-#: ../ex_cmds.c:4510
-#, fuzzy, c-format
+#, c-format
msgid "Pattern not found: %s"
-msgstr "Patrún gan aimsiú"
+msgstr "Patrún gan aimsiú: %s"
-#: ../ex_cmds.c:4587
msgid ""
"\n"
"# Last Substitute String:\n"
@@ -1289,682 +1017,599 @@ msgstr ""
"# Teaghrán Ionadach Is Déanaí:\n"
"$"
-#: ../ex_cmds.c:4679
msgid "E478: Don't panic!"
msgstr "E478: Ná téigh i scaoll!"
-#: ../ex_cmds.c:4717
#, c-format
msgid "E661: Sorry, no '%s' help for %s"
msgstr "E661: Tá brón orm, ní aon chabhair '%s' do %s"
-#: ../ex_cmds.c:4719
#, c-format
msgid "E149: Sorry, no help for %s"
msgstr "E149: Tá brón orm, níl aon chabhair do %s"
-#: ../ex_cmds.c:4751
#, c-format
msgid "Sorry, help file \"%s\" not found"
msgstr "Tá brón orm, comhad cabhrach \"%s\" gan aimsiú"
-#: ../ex_cmds.c:5323
#, c-format
-msgid "E150: Not a directory: %s"
-msgstr "E150: Ní comhadlann é: %s"
+msgid "E151: No match: %s"
+msgstr "E151: Gan meaitseáil: %s"
-#: ../ex_cmds.c:5446
#, c-format
msgid "E152: Cannot open %s for writing"
msgstr "E152: Ní féidir %s a oscailt chun scríobh ann"
-#: ../ex_cmds.c:5471
#, c-format
msgid "E153: Unable to open %s for reading"
msgstr "E153: Ní féidir %s a oscailt chun é a léamh"
-#: ../ex_cmds.c:5500
#, c-format
msgid "E670: Mix of help file encodings within a language: %s"
msgstr "E670: Ionchóduithe éagsúla do chomhaid chabhracha i dteanga aonair: %s"
-#: ../ex_cmds.c:5565
#, c-format
msgid "E154: Duplicate tag \"%s\" in file %s/%s"
msgstr "E154: Clib dhúblach \"%s\" i gcomhad %s/%s"
-#: ../ex_cmds.c:5687
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Ní comhadlann é: %s"
+
#, c-format
msgid "E160: Unknown sign command: %s"
msgstr "E160: Ordú anaithnid comhartha: %s"
-#: ../ex_cmds.c:5704
msgid "E156: Missing sign name"
msgstr "E156: Ainm comhartha ar iarraidh"
-#: ../ex_cmds.c:5746
msgid "E612: Too many signs defined"
msgstr "E612: An iomarca comharthaí sainmhínithe"
-#: ../ex_cmds.c:5813
#, c-format
msgid "E239: Invalid sign text: %s"
msgstr "E239: Téacs neamhbhailí comhartha: %s"
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
#, c-format
msgid "E155: Unknown sign: %s"
msgstr "E155: Comhartha anaithnid: %s"
-#: ../ex_cmds.c:5877
msgid "E159: Missing sign number"
msgstr "E159: Uimhir chomhartha ar iarraidh"
-#: ../ex_cmds.c:5971
#, c-format
msgid "E158: Invalid buffer name: %s"
msgstr "E158: Ainm maoláin neamhbhailí: %s"
-#: ../ex_cmds.c:6008
+msgid "E934: Cannot jump to a buffer that does not have a name"
+msgstr "E934: Ní féidir léim go maolán gan ainm"
+
#, c-format
-msgid "E157: Invalid sign ID: %<PRId64>"
-msgstr "E157: ID neamhbhailí comhartha: %<PRId64>"
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: ID neamhbhailí comhartha: %ld"
+
+#, c-format
+msgid "E885: Not possible to change sign %s"
+msgstr "E885: Ní féidir an comhartha a athrú: %s"
+
+msgid " (NOT FOUND)"
+msgstr " (AR IARRAIDH)"
-#: ../ex_cmds.c:6066
msgid " (not supported)"
msgstr " (níl an rogha seo ar fáil)"
-#: ../ex_cmds.c:6169
msgid "[Deleted]"
msgstr "[Scriosta]"
-#: ../ex_cmds2.c:139
+msgid "No old files"
+msgstr "Gan seanchomhaid"
+
msgid "Entering Debug mode. Type \"cont\" to continue."
msgstr "Mód dífhabhtaithe á thosú. Clóscríobh \"cont\" chun leanúint."
-#: ../ex_cmds2.c:143 ../ex_docmd.c:759
#, c-format
-msgid "line %<PRId64>: %s"
-msgstr "líne %<PRId64>: %s"
+msgid "line %ld: %s"
+msgstr "líne %ld: %s"
-#: ../ex_cmds2.c:145
#, c-format
msgid "cmd: %s"
msgstr "ordú: %s"
-#: ../ex_cmds2.c:322
+msgid "frame is zero"
+msgstr "is nialas é an fráma"
+
#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "Brisphointe i \"%s%s\" líne %<PRId64>"
+msgid "frame at highest level: %d"
+msgstr "fráma ag an leibhéal is airde: %d"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Brisphointe i \"%s%s\" líne %ld"
-#: ../ex_cmds2.c:581
#, c-format
msgid "E161: Breakpoint not found: %s"
msgstr "E161: Brisphointe gan aimsiú: %s"
-#: ../ex_cmds2.c:611
msgid "No breakpoints defined"
msgstr "Níl aon bhrisphointe socraithe"
-#: ../ex_cmds2.c:617
#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s líne %<PRId64>"
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s líne %ld"
-#: ../ex_cmds2.c:942
msgid "E750: First use \":profile start {fname}\""
msgstr "E750: Úsáid \":profile start {ainm}\" ar dtús"
-#: ../ex_cmds2.c:1269
#, c-format
msgid "Save changes to \"%s\"?"
msgstr "Sábháil athruithe ar \"%s\"?"
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
msgid "Untitled"
msgstr "Gan Teideal"
-#: ../ex_cmds2.c:1421
#, c-format
msgid "E162: No write since last change for buffer \"%s\""
msgstr "E162: Athraíodh maolán \"%s\" ach nach bhfuil sé sábháilte ó shin"
-#: ../ex_cmds2.c:1480
msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
msgstr "Rabhadh: Chuathas i maolán eile go tobann (seiceáil na huathorduithe)"
-#: ../ex_cmds2.c:1826
msgid "E163: There is only one file to edit"
msgstr "E163: Níl ach aon chomhad amháin le cur in eagar"
-#: ../ex_cmds2.c:1828
msgid "E164: Cannot go before first file"
msgstr "E164: Ní féidir a dhul roimh an chéad chomhad"
-#: ../ex_cmds2.c:1830
msgid "E165: Cannot go beyond last file"
msgstr "E165: Ní féidir a dhul thar an gcomhad deireanach"
-#: ../ex_cmds2.c:2175
#, c-format
msgid "E666: compiler not supported: %s"
msgstr "E666: ní ghlactar leis an tiomsaitheoir: %s"
-#: ../ex_cmds2.c:2257
#, c-format
msgid "Searching for \"%s\" in \"%s\""
msgstr "Ag déanamh cuardach ar \"%s\" i \"%s\""
-#: ../ex_cmds2.c:2284
#, c-format
msgid "Searching for \"%s\""
msgstr "Ag déanamh cuardach ar \"%s\""
-#: ../ex_cmds2.c:2307
#, c-format
-msgid "not found in 'runtimepath': \"%s\""
-msgstr "gan aimsiú i 'runtimepath': \"%s\""
+msgid "not found in '%s': \"%s\""
+msgstr "gan aimsiú in '%s': \"%s\""
+
+msgid "Source Vim script"
+msgstr "Foinsigh script Vim"
-#: ../ex_cmds2.c:2472
#, c-format
msgid "Cannot source a directory: \"%s\""
msgstr "Ní féidir comhadlann a léamh: \"%s\""
-#: ../ex_cmds2.c:2518
#, c-format
msgid "could not source \"%s\""
msgstr "níorbh fhéidir \"%s\" a léamh"
-#: ../ex_cmds2.c:2520
#, c-format
-msgid "line %<PRId64>: could not source \"%s\""
-msgstr "líne %<PRId64>: níorbh fhéidir \"%s\" a fhoinsiú"
+msgid "line %ld: could not source \"%s\""
+msgstr "líne %ld: níorbh fhéidir \"%s\" a fhoinsiú"
-#: ../ex_cmds2.c:2535
#, c-format
msgid "sourcing \"%s\""
msgstr "\"%s\" á fhoinsiú"
-#: ../ex_cmds2.c:2537
#, c-format
-msgid "line %<PRId64>: sourcing \"%s\""
-msgstr "líne %<PRId64>: \"%s\" á fhoinsiú"
+msgid "line %ld: sourcing \"%s\""
+msgstr "líne %ld: \"%s\" á fhoinsiú"
-#: ../ex_cmds2.c:2693
#, c-format
msgid "finished sourcing %s"
msgstr "deireadh ag foinsiú %s"
-#: ../ex_cmds2.c:2765
+#, c-format
+msgid "continuing in %s"
+msgstr "ag leanúint i %s"
+
msgid "modeline"
msgstr "módlíne"
-#: ../ex_cmds2.c:2767
msgid "--cmd argument"
msgstr "argóint --cmd"
-#: ../ex_cmds2.c:2769
msgid "-c argument"
msgstr "argóint -c"
-#: ../ex_cmds2.c:2771
msgid "environment variable"
msgstr "athróg thimpeallachta"
-#: ../ex_cmds2.c:2773
msgid "error handler"
msgstr "láimhseálaí earráidí"
-#: ../ex_cmds2.c:3020
msgid "W15: Warning: Wrong line separator, ^M may be missing"
msgstr ""
"W15: Rabhadh: Deighilteoir línte mícheart, is féidir go bhfuil ^M ar iarraidh"
-#: ../ex_cmds2.c:3139
msgid "E167: :scriptencoding used outside of a sourced file"
msgstr "E167: ní úsáidtear :scriptencoding ach i gcomhad foinsithe"
-#: ../ex_cmds2.c:3166
msgid "E168: :finish used outside of a sourced file"
msgstr "E168: ní úsáidtear :finish ach i gcomhaid foinsithe"
-#: ../ex_cmds2.c:3389
#, c-format
msgid "Current %slanguage: \"%s\""
msgstr "%sTeanga faoi láthair: \"%s\""
-#: ../ex_cmds2.c:3404
#, c-format
msgid "E197: Cannot set language to \"%s\""
msgstr "E197: Ní féidir an teanga a shocrú mar \"%s\""
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
msgstr "Mód Ex á thosú. Clóscríobh \"visual\" le haghaidh an ghnáthmhód."
# in FARF -KPS
-#: ../ex_docmd.c:428
msgid "E501: At end-of-file"
msgstr "E501: Ag an chomhadchríoch"
-#: ../ex_docmd.c:513
msgid "E169: Command too recursive"
msgstr "E169: Ordú ró-athchúrsach"
-#: ../ex_docmd.c:1006
#, c-format
msgid "E605: Exception not caught: %s"
msgstr "E605: Eisceacht gan láimhseáil: %s"
-#: ../ex_docmd.c:1085
msgid "End of sourced file"
msgstr "Críoch chomhaid foinsithe"
-#: ../ex_docmd.c:1086
msgid "End of function"
msgstr "Críoch fheidhme"
-#: ../ex_docmd.c:1628
msgid "E464: Ambiguous use of user-defined command"
msgstr "E464: Úsáid athbhríoch d'ordú saincheaptha"
-#: ../ex_docmd.c:1638
msgid "E492: Not an editor command"
msgstr "E492: Níl ina ordú eagarthóra"
-#: ../ex_docmd.c:1729
msgid "E493: Backwards range given"
msgstr "E493: Raon droim ar ais"
-#: ../ex_docmd.c:1733
msgid "Backwards range given, OK to swap"
msgstr "Raon droim ar ais, babhtáil"
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
msgid "E494: Use w or w>>"
msgstr "E494: Bain úsáid as w nó w>>"
-#: ../ex_docmd.c:3454
-msgid "E319: The command is not available in this version"
+msgid "E319: Sorry, the command is not available in this version"
msgstr "E319: Tá brón orm, níl an t-ordú ar fáil sa leagan seo"
-#: ../ex_docmd.c:3752
msgid "E172: Only one file name allowed"
msgstr "E172: Ní cheadaítear ach aon ainm comhaid amháin"
-#: ../ex_docmd.c:4238
msgid "1 more file to edit. Quit anyway?"
msgstr "1 comhad le cur in eagar fós. Scoir mar sin féin?"
-#: ../ex_docmd.c:4242
#, c-format
msgid "%d more files to edit. Quit anyway?"
msgstr "%d comhad le cur in eagar fós. Scoir mar sin féin?"
-#: ../ex_docmd.c:4248
msgid "E173: 1 more file to edit"
msgstr "E173: 1 chomhad le heagrú fós"
-#: ../ex_docmd.c:4250
#, c-format
-msgid "E173: %<PRId64> more files to edit"
-msgstr "E173: %<PRId64> comhad le cur in eagar"
+msgid "E173: %ld more files to edit"
+msgstr "E173: %ld comhad le cur in eagar"
-#: ../ex_docmd.c:4320
msgid "E174: Command already exists: add ! to replace it"
msgstr "E174: Tá an t-ordú ann cheana: cuir ! leis chun sárú"
-#: ../ex_docmd.c:4432
msgid ""
"\n"
-" Name Args Range Complete Definition"
+" Name Args Address Complete Definition"
msgstr ""
"\n"
-" Ainm Arg Raon Iomlán Sainmhíniú"
+" Ainm Arg Seoladh Iomlán Sainmhíniú"
-#: ../ex_docmd.c:4516
msgid "No user-defined commands found"
msgstr "Níl aon ordú aimsithe atá sainithe ag an úsáideoir"
-#: ../ex_docmd.c:4538
msgid "E175: No attribute specified"
msgstr "E175: Níl aon aitreabúid sainithe"
-#: ../ex_docmd.c:4583
msgid "E176: Invalid number of arguments"
msgstr "E176: Tá líon na n-argóintí mícheart"
-#: ../ex_docmd.c:4594
msgid "E177: Count cannot be specified twice"
msgstr "E177: Ní cheadaítear an t-áireamh a bheith tugtha faoi dhó"
-#: ../ex_docmd.c:4603
msgid "E178: Invalid default value for count"
msgstr "E178: Luach réamhshocraithe neamhbhailí ar áireamh"
-#: ../ex_docmd.c:4625
msgid "E179: argument required for -complete"
msgstr "E179: tá gá le hargóint i ndiaidh -complete"
-#: ../ex_docmd.c:4635
+msgid "E179: argument required for -addr"
+msgstr "E179: tá gá le hargóint i ndiaidh -addr"
+
#, c-format
msgid "E181: Invalid attribute: %s"
msgstr "E181: Aitreabúid neamhbhailí: %s"
-#: ../ex_docmd.c:4678
msgid "E182: Invalid command name"
msgstr "E182: Ainm neamhbhailí ordaithe"
-#: ../ex_docmd.c:4691
msgid "E183: User defined commands must start with an uppercase letter"
msgstr ""
"E183: Caithfidh ceannlitir a bheith ar dtús orduithe atá sainithe ag an "
"úsáideoir"
-#: ../ex_docmd.c:4696
-#, fuzzy
msgid "E841: Reserved name, cannot be used for user defined command"
-msgstr "E464: Úsáid athbhríoch d'ordú saincheaptha"
+msgstr ""
+"E841: Ainm in áirithe, ní féidir é a chur ar ordú sainithe ag an úsáideoir"
-#: ../ex_docmd.c:4751
#, c-format
msgid "E184: No such user-defined command: %s"
msgstr "E184: Níl a leithéid d'ordú saincheaptha: %s"
-#: ../ex_docmd.c:5219
+#, c-format
+msgid "E180: Invalid address type value: %s"
+msgstr "E180: Cineál neamhbhailí seolta: %s"
+
#, c-format
msgid "E180: Invalid complete value: %s"
msgstr "E180: Luach iomlán neamhbhailí: %s"
-#: ../ex_docmd.c:5225
msgid "E468: Completion argument only allowed for custom completion"
msgstr ""
"E468: Ní cheadaítear argóint chomhlánaithe ach le comhlánú saincheaptha"
-#: ../ex_docmd.c:5231
msgid "E467: Custom completion requires a function argument"
msgstr "E467: Tá gá le hargóint fheidhme le comhlánú saincheaptha"
-#: ../ex_docmd.c:5257
-#, fuzzy, c-format
+msgid "unknown"
+msgstr "anaithnid"
+
+#, c-format
msgid "E185: Cannot find color scheme '%s'"
-msgstr "E185: Scéim dathanna %s gan aimsiú"
+msgstr "E185: Scéim dathanna '%s' gan aimsiú"
-#: ../ex_docmd.c:5263
msgid "Greetings, Vim user!"
msgstr "Dia duit, a úsáideoir Vim!"
-#: ../ex_docmd.c:5431
msgid "E784: Cannot close last tab page"
-msgstr "E784: Ní féidir an leathanach cluaisín deiridh a dhúnadh"
+msgstr "E784: Ní féidir an leathanach cluaisíní deiridh a dhúnadh"
-#: ../ex_docmd.c:5462
msgid "Already only one tab page"
-msgstr "Níl ach leathanach cluaisín amháin cheana féin"
+msgstr "Níl ach leathanach cluaisíní amháin cheana féin"
+
+msgid "Edit File in new window"
+msgstr "Cuir comhad in eagar i bhfuinneog nua"
-#: ../ex_docmd.c:6004
#, c-format
msgid "Tab page %d"
msgstr "Leathanach cluaisín %d"
-#: ../ex_docmd.c:6295
msgid "No swap file"
msgstr "Níl aon chomhad babhtála ann"
-#: ../ex_docmd.c:6478
+msgid "Append File"
+msgstr "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ú)"
-#: ../ex_docmd.c:6485
msgid "E186: No previous directory"
msgstr "E186: Níl aon chomhadlann roimhe seo"
-#: ../ex_docmd.c:6530
msgid "E187: Unknown"
msgstr "E187: Anaithnid"
-#: ../ex_docmd.c:6610
msgid "E465: :winsize requires two number arguments"
msgstr "E465: ní foláir dhá argóint uimhriúla le :winsize"
-#: ../ex_docmd.c:6655
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Ionad na fuinneoige: X %d, Y %d"
+
msgid "E188: Obtaining window position not implemented for this platform"
msgstr "E188: Ní féidir ionad na fuinneoige a fháil amach ar an chóras seo"
-#: ../ex_docmd.c:6662
msgid "E466: :winpos requires two number arguments"
msgstr "E466: ní foláir dhá argóint uimhriúla le :winpos"
-#: ../ex_docmd.c:7241
+msgid "E930: Cannot use :redir inside execute()"
+msgstr "E930: Ní féidir :redir a úsáid laistigh de execute()"
+
+msgid "Save Redirection"
+msgstr "Sábháil Atreorú"
+
+msgid "Save View"
+msgstr "Sábháil an tAmharc"
+
+msgid "Save Session"
+msgstr "Sábháil an Seisiún"
+
+msgid "Save Setup"
+msgstr "Sábháil an Socrú"
+
#, c-format
msgid "E739: Cannot create directory: %s"
msgstr "E739: Ní féidir comhadlann a chruthú: %s"
-#: ../ex_docmd.c:7268
#, c-format
msgid "E189: \"%s\" exists (add ! to override)"
msgstr "E189: Tá \"%s\" ann cheana (cuir ! leis an ordú chun sárú)"
-#: ../ex_docmd.c:7273
#, c-format
msgid "E190: Cannot open \"%s\" for writing"
msgstr "E190: Ní féidir \"%s\" a oscailt chun léamh"
#. set mark
-#: ../ex_docmd.c:7294
msgid "E191: Argument must be a letter or forward/backward quote"
msgstr "E191: Caithfidh an argóint a bheith litir nó comhartha athfhriotal"
-#: ../ex_docmd.c:7333
msgid "E192: Recursive use of :normal too deep"
msgstr "E192: athchúrsáil :normal ródhomhain"
-#: ../ex_docmd.c:7807
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: níl #< ar fáil gan ghné +eval"
+
msgid "E194: No alternate file name to substitute for '#'"
msgstr "E194: Níl aon ainm comhaid a chur in ionad '#'"
-#: ../ex_docmd.c:7841
msgid "E495: no autocommand file name to substitute for \"<afile>\""
msgstr "E495: níl aon ainm comhaid uathordaithe le cur in ionad \"<afile>\""
-#: ../ex_docmd.c:7850
msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
msgstr "E496: níl aon uimhir mhaolán uathordaithe le cur in ionad \"<abuf>\""
-#: ../ex_docmd.c:7861
msgid "E497: no autocommand match name to substitute for \"<amatch>\""
msgstr ""
"E497: níl aon ainm meaitseála uathordaithe le cur in ionad \"<amatch>\""
-#: ../ex_docmd.c:7870
msgid "E498: no :source file name to substitute for \"<sfile>\""
msgstr "E498: níl aon ainm comhaid :source le cur in ionad \"<sfile>\""
-#: ../ex_docmd.c:7876
-#, fuzzy
msgid "E842: no line number to use for \"<slnum>\""
-msgstr "E498: níl aon ainm comhaid :source le cur in ionad \"<sfile>\""
+msgstr "E842: níl aon líne-uimhir ar fáil le haghaidh \"<slnum>\""
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
+#, no-c-format
msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
msgstr ""
"E499: Ainm comhaid folamh le haghaidh '%' nó '#', oibreoidh sé le \":p:h\" "
"amháin"
-#: ../ex_docmd.c:7905
msgid "E500: Evaluates to an empty string"
msgstr "E500: Luacháiltear é seo mar theaghrán folamh"
-#: ../ex_docmd.c:8838
msgid "E195: Cannot open viminfo file for reading"
msgstr "E195: Ní féidir an comhad viminfo a oscailt chun léamh"
-#: ../ex_eval.c:464
+msgid "E196: No digraphs in this version"
+msgstr "E196: Ní cheadaítear déghraif sa leagan seo"
+
msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
msgstr "E608: Ní féidir eisceachtaí a :throw le réimír 'Vim'"
#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
#, c-format
msgid "Exception thrown: %s"
msgstr "Gineadh eisceacht: %s"
-#: ../ex_eval.c:545
#, c-format
msgid "Exception finished: %s"
msgstr "Eisceacht curtha i gcrích: %s"
-#: ../ex_eval.c:546
#, c-format
msgid "Exception discarded: %s"
msgstr "Eisceacht curtha i leataobh: %s"
-#: ../ex_eval.c:588 ../ex_eval.c:634
#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, líne %<PRId64>"
+msgid "%s, line %ld"
+msgstr "%s, líne %ld"
#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
#, c-format
msgid "Exception caught: %s"
msgstr "Láimhseáladh eisceacht: %s"
-#: ../ex_eval.c:676
#, c-format
msgid "%s made pending"
msgstr "%s ar feitheamh anois"
-#: ../ex_eval.c:679
#, c-format
msgid "%s resumed"
msgstr "atosaíodh %s"
-#: ../ex_eval.c:683
#, c-format
msgid "%s discarded"
msgstr "%s curtha i leataobh"
-#: ../ex_eval.c:708
msgid "Exception"
msgstr "Eisceacht"
-#: ../ex_eval.c:713
msgid "Error and interrupt"
msgstr "Earráid agus idirbhriseadh"
-#: ../ex_eval.c:715
msgid "Error"
msgstr "Earráid"
#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
msgid "Interrupt"
msgstr "Idirbhriseadh"
-#: ../ex_eval.c:795
msgid "E579: :if nesting too deep"
msgstr "E579: :if neadaithe ródhomhain"
-#: ../ex_eval.c:830
msgid "E580: :endif without :if"
msgstr "E580: :endif gan :if"
-#: ../ex_eval.c:873
msgid "E581: :else without :if"
msgstr "E581: :else gan :if"
-#: ../ex_eval.c:876
msgid "E582: :elseif without :if"
msgstr "E582: :elseif gan :if"
-#: ../ex_eval.c:880
msgid "E583: multiple :else"
msgstr "E583: :else iomadúla"
-#: ../ex_eval.c:883
msgid "E584: :elseif after :else"
msgstr "E584: :elseif i ndiaidh :else"
-#: ../ex_eval.c:941
msgid "E585: :while/:for nesting too deep"
msgstr "E585: :while/:for neadaithe ródhomhain"
-#: ../ex_eval.c:1028
msgid "E586: :continue without :while or :for"
msgstr "E586: :continue gan :while ná :for"
-#: ../ex_eval.c:1061
msgid "E587: :break without :while or :for"
msgstr "E587: :break gan :while ná :for"
-#: ../ex_eval.c:1102
msgid "E732: Using :endfor with :while"
msgstr "E732: :endfor á úsáid le :while"
-#: ../ex_eval.c:1104
msgid "E733: Using :endwhile with :for"
msgstr "E733: :endwhile á úsáid le :for"
-#: ../ex_eval.c:1247
msgid "E601: :try nesting too deep"
msgstr "E601: :try neadaithe ródhomhain"
-#: ../ex_eval.c:1317
msgid "E603: :catch without :try"
msgstr "E603: :catch gan :try"
#. Give up for a ":catch" after ":finally" and ignore it.
#. * Just parse.
-#: ../ex_eval.c:1332
msgid "E604: :catch after :finally"
msgstr "E604: :catch i ndiaidh :finally"
-#: ../ex_eval.c:1451
msgid "E606: :finally without :try"
msgstr "E606: :finally gan :try"
#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
msgid "E607: multiple :finally"
msgstr "E607: :finally iomadúla"
-#: ../ex_eval.c:1571
msgid "E602: :endtry without :try"
msgstr "E602: :endtry gan :try"
-#: ../ex_eval.c:2026
msgid "E193: :endfunction not inside a function"
msgstr "E193: Caithfidh :endfunction a bheith isteach i bhfeidhm"
-#: ../ex_getln.c:1643
msgid "E788: Not allowed to edit another buffer now"
msgstr "E788: Níl cead agat maolán eile a chur in eagar anois"
-#: ../ex_getln.c:1656
msgid "E811: Not allowed to change buffer information now"
msgstr "E811: Níl cead agat faisnéis an mhaoláin a athrú anois"
-#: ../ex_getln.c:3178
msgid "tagname"
msgstr "clibainm"
-#: ../ex_getln.c:3181
msgid " kind file\n"
msgstr " cineál comhaid\n"
-#: ../ex_getln.c:4799
msgid "'history' option is zero"
msgstr "tá an rogha 'history' nialas"
-#: ../ex_getln.c:5046
#, c-format
msgid ""
"\n"
@@ -1975,310 +1620,230 @@ msgstr ""
# this gets plugged into the %s in the previous string,
# hence the colon
-#: ../ex_getln.c:5047
msgid "Command Line"
msgstr "Líne na nOrduithe:"
-#: ../ex_getln.c:5048
msgid "Search String"
msgstr "Teaghrán Cuardaigh"
-#: ../ex_getln.c:5049
msgid "Expression"
msgstr "Sloinn:"
-#: ../ex_getln.c:5050
msgid "Input Line"
msgstr "Líne an Ionchuir:"
-#: ../ex_getln.c:5117
+msgid "Debug Line"
+msgstr "Líne Dhífhabhtaithe"
+
msgid "E198: cmd_pchar beyond the command length"
msgstr "E198: cmd_pchar os cionn fad an ordaithe"
-#: ../ex_getln.c:5279
msgid "E199: Active window or buffer deleted"
msgstr "E199: Scriosadh an fhuinneog reatha nó an maolán reatha"
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr ""
-
-#: ../file_search.c:446
-#, c-format
-msgid ""
-"E343: Invalid path: '**[number]' must be at the end of the path or be "
-"followed by '%s'."
-msgstr ""
-"E343: Conair neamhbhailí: ní mór '**[uimhir]' a bheith ag deireadh na "
-"conaire, nó le '%s' ina dhiaidh."
-
-#: ../file_search.c:1505
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: Ní féidir comhadlann \"%s\" a aimsiú sa cdpath"
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: Ní féidir comhad \"%s\" a aimsiú sa chonair"
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: Níl comhadlann \"%s\" sa cdpath a thuilleadh"
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: Níl comhad \"%s\" sa chonair a thuilleadh"
-
-#: ../fileio.c:137
msgid "E812: Autocommands changed buffer or buffer name"
msgstr "E812: Bhí maolán nó ainm maoláin athraithe ag orduithe uathoibríocha"
-#: ../fileio.c:368
msgid "Illegal file name"
msgstr "Ainm comhaid neamhcheadaithe"
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
msgid "is a directory"
msgstr "is comhadlann é"
-#: ../fileio.c:397
msgid "is not a file"
msgstr "ní comhad é"
-#: ../fileio.c:508 ../fileio.c:3522
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "is gléas é seo (díchumasaithe le rogha 'opendevice')"
+
msgid "[New File]"
msgstr "[Comhad Nua]"
-#: ../fileio.c:511
msgid "[New DIRECTORY]"
msgstr "[COMHADLANN nua]"
-#: ../fileio.c:529 ../fileio.c:532
msgid "[File too big]"
msgstr "[Comhad rómhór]"
-#: ../fileio.c:534
msgid "[Permission Denied]"
msgstr "[Cead Diúltaithe]"
-#: ../fileio.c:653
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr "E200: Rinne uathorduithe *ReadPre praiseach as an chomhad"
-#: ../fileio.c:655
msgid "E201: *ReadPre autocommands must not change current buffer"
msgstr "E201: Ní cheadaítear d'uathorduithe *ReadPre an maolán reatha a athrú"
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
+msgid "Vim: Reading from stdin...\n"
msgstr "Vim: Ag léamh ón ionchur caighdeánach...\n"
+msgid "Reading from stdin..."
+msgstr "Ag léamh ón ionchur caighdeánach..."
+
#. Re-opening the original file failed!
-#: ../fileio.c:909
msgid "E202: Conversion made file unreadable!"
msgstr "E202: Comhad doléite i ndiaidh an tiontaithe!"
-#. fifo or socket
-#: ../fileio.c:1782
msgid "[fifo/socket]"
msgstr "[fifo/soicéad]"
# `TITA' ?! -KPS
-#. fifo
-#: ../fileio.c:1788
msgid "[fifo]"
msgstr "[fifo]"
-#. or socket
-#: ../fileio.c:1794
msgid "[socket]"
msgstr "[soicéad]"
-#. or character special
-#: ../fileio.c:1801
msgid "[character special]"
msgstr "[comhad speisialta den chineál carachtar]"
-#: ../fileio.c:1815
msgid "[CR missing]"
msgstr "[CR ar iarraidh]"
-#: ../fileio.c:1819
msgid "[long lines split]"
msgstr "[línte fada deighilte]"
-#: ../fileio.c:1823 ../fileio.c:3512
msgid "[NOT converted]"
msgstr "[NÍ tiontaithe]"
-#: ../fileio.c:1826 ../fileio.c:3515
msgid "[converted]"
msgstr "[tiontaithe]"
-#: ../fileio.c:1831
#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[EARRÁID TIONTAITHE i líne %<PRId64>]"
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[EARRÁID TIONTAITHE i líne %ld]"
-#: ../fileio.c:1835
#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[BEART NEAMHCHEADAITHE i líne %<PRId64>]"
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[BEART NEAMHCHEADAITHE i líne %ld]"
-#: ../fileio.c:1838
msgid "[READ ERRORS]"
msgstr "[EARRÁIDÍ LÉIMH]"
-#: ../fileio.c:2104
msgid "Can't find temp file for conversion"
msgstr "Ní féidir comhad sealadach a aimsiú le haghaidh tiontaithe"
-#: ../fileio.c:2110
msgid "Conversion with 'charconvert' failed"
msgstr "Theip ar thiontú le 'charconvert'"
-#: ../fileio.c:2113
msgid "can't read output of 'charconvert'"
msgstr "ní féidir an t-aschur ó 'charconvert' a léamh"
-#: ../fileio.c:2437
msgid "E676: No matching autocommands for acwrite buffer"
msgstr "E676: Níl aon uathordú comhoiriúnaithe le haghaidh maoláin acwrite"
-#: ../fileio.c:2466
msgid "E203: Autocommands deleted or unloaded buffer to be written"
msgstr "E203: Scrios nó dhíluchtaigh uathorduithe an maolán le scríobh"
-#: ../fileio.c:2486
msgid "E204: Autocommand changed number of lines in unexpected way"
msgstr "E204: D'athraigh uathordú líon na línte gan choinne"
-#: ../fileio.c:2548 ../fileio.c:2565
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "Ní cheadaíonn NetBeans maoláin gan athrú a bheith scríofa"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Ní cheadaítear maoláin NetBeans a bheith scríofa go neamhiomlán"
+
msgid "is not a file or writable device"
msgstr "ní comhad ná gléas inscríofa á"
-#: ../fileio.c:2601
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "díchumasaíodh scríobh chuig gléas le rogha 'opendevice'"
+
msgid "is read-only (add ! to override)"
msgstr "is inléite amháin é (cuir ! leis an ordú chun sárú)"
-#: ../fileio.c:2886
msgid "E506: Can't write to backup file (add ! to override)"
msgstr ""
"E506: Ní féidir scríobh a dhéanamh sa chomhad cúltaca (úsáid ! chun sárú)"
-#: ../fileio.c:2898
msgid "E507: Close error for backup file (add ! to override)"
msgstr ""
"E507: Earráid agus comhad cúltaca á dhúnadh (cuir ! leis an ordú chun sárú)"
-#: ../fileio.c:2901
msgid "E508: Can't read file for backup (add ! to override)"
msgstr ""
"E508: Ní féidir an comhad cúltaca a léamh (cuir ! leis an ordú chun sárú)"
-#: ../fileio.c:2923
msgid "E509: Cannot create backup file (add ! to override)"
msgstr ""
"E509: Ní féidir comhad cúltaca a chruthú (cuir ! leis an ordú chun sárú)"
-#: ../fileio.c:3008
msgid "E510: Can't make backup file (add ! to override)"
msgstr ""
"E510: Ní féidir comhad cúltaca a chruthú (cuir ! leis an ordú chun sárú)"
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Chaillfí an forc acmhainne (cuir ! leis an ordú chun sárú)"
+
msgid "E214: Can't find temp file for writing"
msgstr "E214: Ní féidir comhad sealadach a aimsiú chun scríobh ann"
-#: ../fileio.c:3134
msgid "E213: Cannot convert (add ! to write without conversion)"
msgstr "E213: Ní féidir tiontú (cuir ! leis an ordú chun scríobh gan tiontú)"
-#: ../fileio.c:3169
msgid "E166: Can't open linked file for writing"
msgstr "E166: Ní féidir comhad nasctha a oscailt chun scríobh ann"
-#: ../fileio.c:3173
msgid "E212: Can't open file for writing"
msgstr "E212: Ní féidir comhad a oscailt chun scríobh ann"
-#: ../fileio.c:3363
msgid "E667: Fsync failed"
msgstr "E667: Theip ar fsync"
-#: ../fileio.c:3398
msgid "E512: Close failed"
msgstr "E512: Theip ar dúnadh"
-#: ../fileio.c:3436
msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
msgstr ""
"E513: earráid le linn scríobh, theip ar thiontú (úsáid 'fenc' folamh chun "
"sárú)"
-#: ../fileio.c:3441
#, c-format
msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
"override)"
msgstr ""
-"E513: earráid le linn scríofa, theip ar thiontú ar líne %<PRId64> (úsáid "
-"'fenc' folamh le sárú)"
+"E513: earráid le linn scríofa, theip ar thiontú ar líne %ld (úsáid 'fenc' "
+"folamh le sárú)"
-#: ../fileio.c:3448
msgid "E514: write error (file system full?)"
msgstr "E514: earráid le linn scríofa (an bhfuil an córas comhaid lán?)"
-#: ../fileio.c:3506
msgid " CONVERSION ERROR"
msgstr " EARRÁID TIONTAITHE"
-#: ../fileio.c:3509
#, c-format
-msgid " in line %<PRId64>;"
-msgstr " ar líne %<PRId64>;"
+msgid " in line %ld;"
+msgstr " ar líne %ld;"
-#: ../fileio.c:3519
msgid "[Device]"
msgstr "[Gléas]"
-#: ../fileio.c:3522
msgid "[New]"
msgstr "[Nua]"
-#: ../fileio.c:3535
msgid " [a]"
msgstr " [a]"
-#: ../fileio.c:3535
msgid " appended"
msgstr " iarcheangailte"
-#: ../fileio.c:3537
msgid " [w]"
msgstr " [w]"
-#: ../fileio.c:3537
msgid " written"
msgstr " scríofa"
-#: ../fileio.c:3579
msgid "E205: Patchmode: can't save original file"
msgstr "E205: Patchmode: ní féidir an comhad bunúsach a shábháil"
-#: ../fileio.c:3602
msgid "E206: patchmode: can't touch empty original file"
msgstr "E206: patchmode: ní féidir an comhad bunúsach folamh a theagmháil"
-#: ../fileio.c:3616
msgid "E207: Can't delete backup file"
msgstr "E207: Ní féidir an comhad cúltaca a scriosadh"
-#: ../fileio.c:3672
msgid ""
"\n"
"WARNING: Original file may be lost or damaged\n"
@@ -2286,96 +1851,75 @@ msgstr ""
"\n"
"RABHADH: Is féidir gur caillte nó loite an comhad bunúsach\n"
-#: ../fileio.c:3675
msgid "don't quit the editor until the file is successfully written!"
msgstr "ná scoir go dtí go scríobhfaí an comhad!"
-#: ../fileio.c:3795
msgid "[dos]"
msgstr "[dos]"
-#: ../fileio.c:3795
msgid "[dos format]"
msgstr "[formáid dos]"
-#: ../fileio.c:3801
msgid "[mac]"
msgstr "[mac]"
-#: ../fileio.c:3801
msgid "[mac format]"
msgstr "[formáid mac]"
-#: ../fileio.c:3807
msgid "[unix]"
msgstr "[unix]"
-#: ../fileio.c:3807
msgid "[unix format]"
msgstr "[formáid unix]"
-#: ../fileio.c:3831
msgid "1 line, "
msgstr "1 líne, "
-#: ../fileio.c:3833
#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> líne, "
+msgid "%ld lines, "
+msgstr "%ld líne, "
-#: ../fileio.c:3836
msgid "1 character"
msgstr "1 carachtar"
-#: ../fileio.c:3838
#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> carachtar"
+msgid "%lld characters"
+msgstr "%lld carachtar"
-#: ../fileio.c:3849
msgid "[noeol]"
msgstr "[ganEOL]"
-#: ../fileio.c:3849
msgid "[Incomplete last line]"
msgstr "[Is neamhiomlán an líne dheireanach]"
#. don't overwrite messages here
#. must give this prompt
#. don't use emsg() here, don't want to flush the buffers
-#: ../fileio.c:3865
msgid "WARNING: The file has been changed since reading it!!!"
msgstr "RABHADH: Athraíodh an comhad ó léadh é!!!"
-#: ../fileio.c:3867
msgid "Do you really want to write to it"
msgstr "An bhfuil tú cinnte gur mhaith leat é a scríobh"
-#: ../fileio.c:4648
#, c-format
msgid "E208: Error writing to \"%s\""
msgstr "E208: Earráid agus \"%s\" á scríobh"
-#: ../fileio.c:4655
#, c-format
msgid "E209: Error closing \"%s\""
msgstr "E209: Earráid agus \"%s\" á dhúnadh"
-#: ../fileio.c:4657
#, c-format
msgid "E210: Error reading \"%s\""
msgstr "E210: Earráid agus \"%s\" á léamh"
-#: ../fileio.c:4883
msgid "E246: FileChangedShell autocommand deleted buffer"
msgstr "E246: Scrios uathordú FileChangedShell an maolán"
-#: ../fileio.c:4894
#, c-format
msgid "E211: File \"%s\" no longer available"
msgstr "E211: Níl comhad \"%s\" ar fáil feasta"
-#: ../fileio.c:4906
#, c-format
msgid ""
"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
@@ -2383,39 +1927,31 @@ msgid ""
msgstr ""
"W12: Rabhadh: Athraíodh comhad \"%s\" agus athraíodh an maolán i Vim fosta"
-#: ../fileio.c:4907
msgid "See \":help W12\" for more info."
msgstr "Bain triail as \":help W12\" chun tuilleadh eolais a fháil."
-#: ../fileio.c:4910
#, c-format
msgid "W11: Warning: File \"%s\" has changed since editing started"
msgstr "W11: Rabhadh: Athraíodh comhad \"%s\" ó tosaíodh é a chur in eagar"
-#: ../fileio.c:4911
msgid "See \":help W11\" for more info."
msgstr "Bain triail as \":help W11\" chun tuilleadh eolais a fháil."
-#: ../fileio.c:4914
#, c-format
msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
msgstr ""
"W16: Rabhadh: Athraíodh mód an chomhaid \"%s\" ó tosaíodh é a chur in eagar"
-#: ../fileio.c:4915
msgid "See \":help W16\" for more info."
msgstr "Bain triail as \":help W16\" chun tuilleadh eolais a fháil."
-#: ../fileio.c:4927
#, c-format
msgid "W13: Warning: File \"%s\" has been created after editing started"
msgstr "W13: Rabhadh: Cruthaíodh comhad \"%s\" ó tosaíodh é a chur in eagar"
-#: ../fileio.c:4947
msgid "Warning"
msgstr "Rabhadh"
-#: ../fileio.c:4948
msgid ""
"&OK\n"
"&Load File"
@@ -2423,48 +1959,45 @@ msgstr ""
"&OK\n"
"&Luchtaigh Comhad"
-#: ../fileio.c:5065
#, c-format
msgid "E462: Could not prepare for reloading \"%s\""
msgstr "E462: Ní féidir \"%s\" a ullmhú le haghaidh athluchtaithe"
-#: ../fileio.c:5078
#, c-format
msgid "E321: Could not reload \"%s\""
msgstr "E321: Ní féidir \"%s\" a athluchtú"
-#: ../fileio.c:5601
msgid "--Deleted--"
msgstr "--Scriosta--"
-#: ../fileio.c:5732
#, c-format
msgid "auto-removing autocommand: %s <buffer=%d>"
msgstr "uathordú á bhaint go huathoibríoch: %s <maolán=%d>"
#. the group doesn't exist
-#: ../fileio.c:5772
#, c-format
msgid "E367: No such group: \"%s\""
msgstr "E367: Níl a leithéid de ghrúpa: \"%s\""
-#: ../fileio.c:5897
+msgid "E936: Cannot delete the current group"
+msgstr "E936: Ní féidir an grúpa reatha a scriosadh"
+
+msgid "W19: Deleting augroup that is still in use"
+msgstr "W19: Iarracht ar augroup atá fós in úsáid a scriosadh"
+
#, c-format
msgid "E215: Illegal character after *: %s"
msgstr "E215: Carachtar neamhcheadaithe i ndiaidh *: %s"
-#: ../fileio.c:5905
#, c-format
msgid "E216: No such event: %s"
msgstr "E216: Níl a leithéid de theagmhas: %s"
-#: ../fileio.c:5907
#, c-format
msgid "E216: No such group or event: %s"
msgstr "E216: Níl a leithéid de ghrúpa nó theagmhas: %s"
#. Highlight title
-#: ../fileio.c:6090
msgid ""
"\n"
"--- Auto-Commands ---"
@@ -2472,765 +2005,567 @@ msgstr ""
"\n"
"--- Uathorduithe ---"
-#: ../fileio.c:6293
#, c-format
msgid "E680: <buffer=%d>: invalid buffer number "
msgstr "E680: <maolán=%d>: uimhir neamhbhailí mhaoláin "
-#: ../fileio.c:6370
msgid "E217: Can't execute autocommands for ALL events"
msgstr "E217: Ní féidir uathorduithe a rith i gcomhair teagmhas UILE"
-#: ../fileio.c:6393
msgid "No matching autocommands"
msgstr "Níl aon uathordú comhoiriúnaithe"
-#: ../fileio.c:6831
msgid "E218: autocommand nesting too deep"
msgstr "E218: uathordú neadaithe ródhomhain"
-#: ../fileio.c:7143
#, c-format
msgid "%s Auto commands for \"%s\""
msgstr "%s Uathorduithe do \"%s\""
-#: ../fileio.c:7149
#, c-format
msgid "Executing %s"
msgstr "%s á rith"
-#: ../fileio.c:7211
#, c-format
msgid "autocommand %s"
msgstr "uathordú %s"
-#: ../fileio.c:7795
msgid "E219: Missing {."
msgstr "E219: { ar iarraidh."
-#: ../fileio.c:7797
msgid "E220: Missing }."
msgstr "E220: } ar iarraidh."
-#: ../fold.c:93
msgid "E490: No fold found"
msgstr "E490: Níor aimsíodh aon fhilleadh"
-#: ../fold.c:544
msgid "E350: Cannot create fold with current 'foldmethod'"
msgstr "E350: Ní féidir filleadh a chruthú leis an 'foldmethod' reatha"
-#: ../fold.c:546
msgid "E351: Cannot delete fold with current 'foldmethod'"
msgstr "E351: Ní féidir filleadh a scriosadh leis an 'foldmethod' reatha"
-#: ../fold.c:1784
#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld líne fillte "
+msgid "+--%3ld line folded "
+msgid_plural "+--%3ld lines folded "
+msgstr[0] "+--%3ld líne fillte "
+msgstr[1] "+--%3ld líne fillte "
+msgstr[2] "+--%3ld líne fillte "
+msgstr[3] "+--%3ld líne fillte "
+msgstr[4] "+--%3ld líne fillte "
-#. buffer has already been read
-#: ../getchar.c:273
msgid "E222: Add to read buffer"
msgstr "E222: Cuir leis an maolán léite"
-#: ../getchar.c:2040
msgid "E223: recursive mapping"
msgstr "E223: mapáil athchúrsach"
-#: ../getchar.c:2849
#, c-format
msgid "E224: global abbreviation already exists for %s"
msgstr "E224: tá giorrúchán comhchoiteann ann cheana le haghaidh %s"
-#: ../getchar.c:2852
#, c-format
msgid "E225: global mapping already exists for %s"
msgstr "E225: tá mapáil chomhchoiteann ann cheana le haghaidh %s"
-#: ../getchar.c:2952
#, c-format
msgid "E226: abbreviation already exists for %s"
msgstr "E226: tá giorrúchán ann cheana le haghaidh %s"
-#: ../getchar.c:2955
#, c-format
msgid "E227: mapping already exists for %s"
msgstr "E227: tá mapáil ann cheana le haghaidh %s"
-#: ../getchar.c:3008
msgid "No abbreviation found"
msgstr "Níor aimsíodh aon ghiorrúchán"
-#: ../getchar.c:3010
msgid "No mapping found"
msgstr "Níor aimsíodh aon mhapáil"
-#: ../getchar.c:3974
msgid "E228: makemap: Illegal mode"
msgstr "E228: makemap: Mód neamhcheadaithe"
-#. key value of 'cedit' option
-#. type of cmdline window or 0
-#. result of cmdline window or 0
-#: ../globals.h:924
-msgid "--No lines in buffer--"
-msgstr "--Tá an maolán folamh--"
-
-#.
-#. * The error messages that can be shared are included here.
-#. * Excluded are errors that are only used once and debugging messages.
-#.
-#: ../globals.h:996
-msgid "E470: Command aborted"
-msgstr "E470: Ordú tobscortha"
+msgid "E851: Failed to create a new process for the GUI"
+msgstr "E851: Níorbh fhéidir próiseas nua a chruthú don GUI"
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: Tá gá le hargóint"
+msgid "E852: The child process failed to start the GUI"
+msgstr "E852: Theip ar an macphróiseas an GUI a thosú"
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: Ba chóir /, ? nó & a chur i ndiaidh \\"
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Ní féidir an GUI a chur ag obair"
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr ""
-"E11: Neamhbhailí i bhfuinneog líne na n-orduithe; <CR>=rith, CTRL-C=scoir"
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Ní féidir léamh ó \"%s\""
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgid "E665: Cannot start GUI, no valid font found"
msgstr ""
-"E12: Ní cheadaítear ordú ó exrc/vimrc sa chomhadlann reatha ná ó chuardach "
-"clibe"
+"E665: Ní féidir an GUI a chur ag obair, níl aon chlófhoireann bhailí ann"
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: :endif ar iarraidh"
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' neamhbhailí"
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: :endtry ar iarraidh"
-
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: :endwhile ar iarraidh"
-
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: :endfor ar iarraidh"
-
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: :endwhile gan :while"
-
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: :endfor gan :for"
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Luach neamhbhailí ar 'imactivatekey'"
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: Tá comhad ann cheana (cuir ! leis an ordú chun forscríobh)"
-
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: Theip ar ordú"
-
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: Earráid inmheánach"
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Ní féidir dath %s a dháileadh"
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "Idirbhriste"
+msgid "No match at cursor, finding next"
+msgstr "Níl a leithéid ag an chúrsóir, ag cuardach ar an chéad cheann eile"
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: Drochsheoladh"
+msgid "<cannot open> "
+msgstr "<ní féidir a oscailt> "
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: Argóint neamhbhailí"
-
-#: ../globals.h:1015
#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: Argóint neamhbhailí: %s"
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: níl aon fháil ar an chlófhoireann %s"
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: Slonn neamhbhailí: %s"
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: ní féidir dul ar ais go dtí an chomhadlann reatha"
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: Raon neamhbhailí"
+msgid "Pathname:"
+msgstr "Conair:"
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: Ordú neamhbhailí"
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: níl an chomhadlann reatha ar fáil"
-#: ../globals.h:1019
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: is comhadlann \"%s\""
+msgid "OK"
+msgstr "OK"
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: Méid neamhbhailí scrollaithe"
+msgid "Cancel"
+msgstr "Cealaigh"
-#: ../globals.h:1021
-msgid "E901: Job table is full"
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
msgstr ""
+"Giuirléid Scrollbharra: Ní féidir céimseata an mhapa picteilíní a fháil."
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: Theip ar ghlao leabharlainne \"%s()\""
-
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: Tá líne-uimhir neamhbhailí ag an mharc"
+msgid "Vim dialog"
+msgstr "Dialóg Vim"
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: Marc gan socrú"
-
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
+msgid "E232: Cannot create BalloonEval with both message and callback"
msgstr ""
-"E21: Ní féidir athruithe a chur i bhfeidhm, níl an bhratach 'modifiable' "
-"socraithe"
+"E232: Ní féidir BalloonEval a chruthú le teachtaireacht agus aisghlaoch araon"
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: scripteanna neadaithe ródhomhain"
+msgid "_Cancel"
+msgstr "_Cealaigh"
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: Níl aon chomhad malartach"
+msgid "_Save"
+msgstr "_Sábháil"
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: Níl a leithéid de ghiorrúchán ann"
+msgid "_Open"
+msgstr "_Oscail"
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: Ní cheadaítear !"
+msgid "_OK"
+msgstr "_OK"
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: Ní féidir an GUI a úsáid: Níor cumasaíodh é ag am tiomsaithe"
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Tá\n"
+"&Níl\n"
+"&Cealaigh"
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: Níl a leithéid d'ainm grúpa aibhsithe: %s"
+msgid "Yes"
+msgstr "Tá"
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: Níl aon téacs ionsáite go dtí seo"
+msgid "No"
+msgstr "Níl"
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: Níl aon líne na n-orduithe roimhe seo"
+msgid "Input _Methods"
+msgstr "_Modhanna ionchuir"
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: Níl a leithéid de mhapáil"
+# in OLT --KPS
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Cuardaigh agus Athchuir..."
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: Níl aon rud comhoiriúnach ann"
+msgid "VIM - Search..."
+msgstr "VIM - Cuardaigh..."
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: Níl aon rud comhoiriúnach ann: %s"
+msgid "Find what:"
+msgstr "Aimsigh:"
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: Níl aon ainm comhaid"
+msgid "Replace with:"
+msgstr "Le cur in ionad:"
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: Níl aon slonn ionadaíochta roimhe seo"
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Focal iomlán amháin"
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: Níl aon ordú roimhe seo"
+#. match case button
+msgid "Match case"
+msgstr "Meaitseáil an cás"
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: Níl aon slonn ionadaíochta roimhe seo"
+msgid "Direction"
+msgstr "Treo"
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: Ní cheadaítear raon"
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Suas"
-#: ../globals.h:1048
-msgid "E36: Not enough room"
-msgstr "E36: Níl slí a dhóthain ann"
+msgid "Down"
+msgstr "Síos"
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: Ní féidir comhad %s a chruthú"
+msgid "Find Next"
+msgstr "An Chéad Cheann Eile"
-#: ../globals.h:1050
-msgid "E483: Can't get temp file name"
-msgstr "E483: Níl aon fháil ar ainm comhaid sealadach"
+msgid "Replace"
+msgstr "Ionadaigh"
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: Ní féidir comhad %s a oscailt"
+msgid "Replace All"
+msgstr "Ionadaigh Uile"
-#: ../globals.h:1052
-#, c-format
-msgid "E485: Can't read file %s"
-msgstr "E485: Ní féidir comhad %s a léamh"
+msgid "_Close"
+msgstr "_Dún"
-#: ../globals.h:1054
-msgid "E37: No write since last change (add ! to override)"
-msgstr "E37: Tá athruithe ann gan sábháil (cuir ! leis an ordú chun sárú)"
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: Fuarthas iarratas \"die\" ó bhainisteoir an tseisiúin\n"
-#: ../globals.h:1055
-#, fuzzy
-msgid "E37: No write since last change"
-msgstr "[Athraithe agus nach sábháilte ó shin]\n"
+msgid "Close tab"
+msgstr "Dún cluaisín"
-#: ../globals.h:1056
-msgid "E38: Null argument"
-msgstr "E38: Argóint nialasach"
-
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: Ag súil le huimhir"
+msgid "New tab"
+msgstr "Cluaisín nua"
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: Ní féidir an comhad earráide %s a oscailt"
+msgid "Open Tab..."
+msgstr "Oscail Cluaisín..."
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: Cuimhne ídithe!"
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Milleadh an príomhfhuinneog gan choinne\n"
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "Patrún gan aimsiú"
+msgid "&Filter"
+msgstr "&Scagaire"
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: Patrún gan aimsiú: %s"
+msgid "&Cancel"
+msgstr "&Cealaigh"
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: Ní foláir argóint dheimhneach"
+msgid "Directories"
+msgstr "Comhadlanna"
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: Ní féidir a fhilleadh ar an chomhadlann roimhe seo"
+msgid "Filter"
+msgstr "Scagaire"
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: Níl Aon Earráid Ann"
+msgid "&Help"
+msgstr "&Cabhair"
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: Gan liosta suíomh"
+msgid "Files"
+msgstr "Comhaid"
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: Teaghrán cuardaigh loite"
+msgid "&OK"
+msgstr "&OK"
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: Clár na sloinn ionadaíochta truaillithe"
+msgid "Selection"
+msgstr "Roghnú"
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: tá an rogha 'readonly' socraithe (cuir ! leis an ordú chun sárú)"
+msgid "Find &Next"
+msgstr "An Chéad Chea&nn Eile"
-#: ../globals.h:1073
-#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: Ní féidir athróg inléite amháin \"%s\" a athrú"
+msgid "&Replace"
+msgstr "&Ionadaigh"
-#: ../globals.h:1075
-#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E794: Ní féidir athróg a shocrú sa bhosca gainimh: \"%s\""
+msgid "Replace &All"
+msgstr "Ionadaigh &Uile"
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: Earráid agus comhad earráide á léamh"
+msgid "&Undo"
+msgstr "&Cealaigh"
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: Ní cheadaítear é seo i mbosca gainimh"
+msgid "Open tab..."
+msgstr "Oscail cluaisín..."
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: Ní cheadaítear é anseo"
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Aimsigh teaghrán (bain úsáid as '\\\\' chun '\\' a aimsiú)"
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: Ní féidir an mód scáileáin a shocrú"
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Aimsigh & Athchuir (úsáid '\\\\' chun '\\' a aimsiú)"
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: Méid neamhbhailí scrollaithe"
+#. We fake this: Use a filter that doesn't select anything and a default
+#. * file name that won't be used.
+msgid "Not Used"
+msgstr "Gan Úsáid"
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: rogha 'shell' folamh"
+msgid "Directory\t*.nothing\n"
+msgstr "Comhadlann\t*.neamhní\n"
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: Níorbh fhéidir na sonraí comhartha a léamh!"
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Ní féidir teideal na fuinneoige \"%s\" a aimsiú"
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: Earráid agus comhad babhtála á dhúnadh"
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Argóint gan tacaíocht: \"-%s\"; Bain úsáid as an leagan OLE."
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: tá cruach na gclibeanna folamh"
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Ní féidir fuinneog a oscailt isteach i bhfeidhmchlár MDI"
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: Ordú róchasta"
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: Ní féidir iontráil dathmhapála a dháileadh, is féidir go mbeidh "
+"dathanna míchearta ann"
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: Ainm rófhada"
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr ""
+"E250: Clónna ar iarraidh le haghaidh na dtacar carachtar i dtacar cló %s:"
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: an iomarca ["
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Ainm an tacar cló: %s"
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: An iomarca ainmneacha comhaid"
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Ní cló aonleithid é '%s'"
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: Carachtair chun deiridh"
+#, c-format
+msgid "E253: Fontset name: %s"
+msgstr "E253: Ainm an tacar cló: %s"
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: Marc anaithnid"
+#, c-format
+msgid "Font0: %s"
+msgstr "Cló0: %s"
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: Ní féidir saoróga a leathnú"
+#, c-format
+msgid "Font1: %s"
+msgstr "Cló1: %s"
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: ní cheadaítear 'winheight' a bheith níos lú ná 'winminheight'"
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "Níl Cló%ld níos leithne faoi dhó ná cló0"
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: ní cheadaítear 'winwidth' a bheith níos lú ná 'winminwidth'"
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "Leithead Cló0: %ld"
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: Earráid agus á scríobh"
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "Leithead cló1: %ld"
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "Nialas"
+msgid "Invalid font specification"
+msgstr "Sonrú neamhbhailí cló"
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: <SID> á úsáid nach i gcomhthéacs scripte"
+msgid "&Dismiss"
+msgstr "&Ruaig"
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: Earráid inmheánach: %s"
+msgid "no specific match"
+msgstr "níl a leithéid ann"
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: úsáideann an patrún níos mó cuimhne ná 'maxmempattern'"
+msgid "Vim - Font Selector"
+msgstr "Vim - Roghnú Cló"
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: maolán folamh"
+msgid "Name:"
+msgstr "Ainm:"
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: Patrún nó teormharcóir neamhbhailí cuardaigh"
+#. create toggle button
+msgid "Show size in Points"
+msgstr "Taispeáin méid (Pointí)"
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: Tá an comhad luchtaithe i maolán eile"
+msgid "Encoding:"
+msgstr "Ionchódú:"
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: Rogha '%s' gan socrú"
+msgid "Font:"
+msgstr "Cló:"
-#: ../globals.h:1111
-#, fuzzy
-msgid "E850: Invalid register name"
-msgstr "E354: Ainm neamhbhailí tabhaill: '%s'"
+msgid "Style:"
+msgstr "Stíl:"
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "Buaileadh an BARR le linn an chuardaigh, ag leanúint ag an CHRÍOCH"
+msgid "Size:"
+msgstr "Méid:"
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "Buaileadh an BUN le linn an chuardaigh, ag leanúint ag an BHARR"
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: EARRÁID leis na huathoibreáin Hangul"
-#: ../hardcopy.c:240
msgid "E550: Missing colon"
msgstr "E550: Idirstad ar iarraidh"
-#: ../hardcopy.c:252
msgid "E551: Illegal component"
msgstr "E551: Comhpháirt neamhcheadaithe"
-#: ../hardcopy.c:259
msgid "E552: digit expected"
msgstr "E552: ag súil le digit"
-#: ../hardcopy.c:473
#, c-format
msgid "Page %d"
msgstr "Leathanach %d"
-#: ../hardcopy.c:597
msgid "No text to be printed"
msgstr "Níl aon téacs le priontáil"
-#: ../hardcopy.c:668
#, c-format
msgid "Printing page %d (%d%%)"
msgstr "Leathanach %d (%d%%) á phriontáil"
-#: ../hardcopy.c:680
#, c-format
msgid " Copy %d of %d"
msgstr " Cóip %d de %d"
-#: ../hardcopy.c:733
#, c-format
msgid "Printed: %s"
msgstr "Priontáilte: %s"
-#: ../hardcopy.c:740
msgid "Printing aborted"
msgstr "Priontáil tobscortha"
-#: ../hardcopy.c:1365
msgid "E455: Error writing to PostScript output file"
msgstr "E455: Earráid le linn scríobh chuig aschomhad PostScript"
-#: ../hardcopy.c:1747
#, c-format
msgid "E624: Can't open file \"%s\""
msgstr "E624: Ní féidir an comhad \"%s\" a oscailt"
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
#, c-format
msgid "E457: Can't read PostScript resource file \"%s\""
msgstr "E457: Ní féidir comhad acmhainne PostScript \"%s\" a léamh"
-#: ../hardcopy.c:1772
#, c-format
msgid "E618: file \"%s\" is not a PostScript resource file"
msgstr "E618: Níl comhad \"%s\" ina chomhad acmhainne PostScript"
-#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844
#, c-format
msgid "E619: file \"%s\" is not a supported PostScript resource file"
msgstr "E619: Tá \"%s\" ina chomhad acmhainne PostScript gan tacú"
-#: ../hardcopy.c:1856
#, c-format
msgid "E621: \"%s\" resource file has wrong version"
msgstr "E621: Tá an leagan mícheart ar an gcomhad acmhainne \"%s\""
-#: ../hardcopy.c:2225
msgid "E673: Incompatible multi-byte encoding and character set."
msgstr "E673: Ionchódú agus tacar carachtar ilbhirt neamh-chomhoiriúnach."
-#: ../hardcopy.c:2238
msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
msgstr ""
"E674: ní cheadaítear printmbcharset a bheith folamh le hionchódú ilbhirt."
-#: ../hardcopy.c:2254
msgid "E675: No default font specified for multi-byte printing."
msgstr "E675: Níor réamhshocraíodh cló le haghaidh priontála ilbhirt."
-#: ../hardcopy.c:2426
msgid "E324: Can't open PostScript output file"
msgstr "E324: Ní féidir aschomhad PostScript a oscailt"
-#: ../hardcopy.c:2458
#, c-format
msgid "E456: Can't open file \"%s\""
msgstr "E456: Ní féidir an comhad \"%s\" a oscailt"
-#: ../hardcopy.c:2583
msgid "E456: Can't find PostScript resource file \"prolog.ps\""
msgstr "E456: Comhad acmhainne PostScript \"prolog.ps\" gan aimsiú"
-#: ../hardcopy.c:2593
msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
msgstr "E456: Comhad acmhainne PostScript \"cidfont.ps\" gan aimsiú"
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
#, c-format
msgid "E456: Can't find PostScript resource file \"%s.ps\""
msgstr "E456: Comhad acmhainne PostScript \"%s.ps\" gan aimsiú"
-#: ../hardcopy.c:2654
#, c-format
msgid "E620: Unable to convert to print encoding \"%s\""
msgstr "E620: Ní féidir an t-ionchódú priontála \"%s\" a thiontú"
-#: ../hardcopy.c:2877
msgid "Sending to printer..."
msgstr "Á sheoladh chuig an phrintéir..."
-#: ../hardcopy.c:2881
msgid "E365: Failed to print PostScript file"
msgstr "E365: Theip ar phriontáil comhaid PostScript"
-#: ../hardcopy.c:2883
msgid "Print job sent."
msgstr "Seoladh jab priontála."
-#: ../if_cscope.c:85
msgid "Add a new database"
msgstr "Bunachar sonraí nua"
-#: ../if_cscope.c:87
msgid "Query for a pattern"
msgstr "Iarratas ar phatrún"
-#: ../if_cscope.c:89
msgid "Show this message"
msgstr "Taispeáin an teachtaireacht seo"
-#: ../if_cscope.c:91
msgid "Kill a connection"
msgstr "Maraigh nasc"
-#: ../if_cscope.c:93
msgid "Reinit all connections"
msgstr "Atúsaigh gach nasc"
-#: ../if_cscope.c:95
msgid "Show connections"
msgstr "Taispeáin naisc"
-#: ../if_cscope.c:101
#, c-format
msgid "E560: Usage: cs[cope] %s"
msgstr "E560: Úsáid: cs[cope] %s"
-#: ../if_cscope.c:225
msgid "This cscope command does not support splitting the window.\n"
msgstr "Ní féidir fuinneoga a scoilteadh leis an ordú seo `cscope'.\n"
-#: ../if_cscope.c:266
msgid "E562: Usage: cstag <ident>"
msgstr "E562: Úsáid: cstag <ident>"
-#: ../if_cscope.c:313
msgid "E257: cstag: tag not found"
msgstr "E257: cstag: clib gan aimsiú"
-#: ../if_cscope.c:461
#, c-format
msgid "E563: stat(%s) error: %d"
msgstr "E563: earráid stat(%s): %d"
-#: ../if_cscope.c:551
+msgid "E563: stat error"
+msgstr "E563: earráid stat"
+
#, c-format
msgid "E564: %s is not a directory or a valid cscope database"
msgstr "E564: Níl %s ina comhadlann nó bunachar sonraí cscope bailí"
-#: ../if_cscope.c:566
#, c-format
msgid "Added cscope database %s"
msgstr "Bunachar sonraí nua cscope: %s"
-#: ../if_cscope.c:616
#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: earráid agus an nasc cscope %<PRId64> á léamh"
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: earráid agus an nasc cscope %ld á léamh"
-#: ../if_cscope.c:711
msgid "E561: unknown cscope search type"
msgstr "E561: cineál anaithnid cuardaigh cscope"
-#: ../if_cscope.c:752 ../if_cscope.c:789
msgid "E566: Could not create cscope pipes"
msgstr "E566: Níorbh fhéidir píopaí cscope a chruthú"
-#: ../if_cscope.c:767
msgid "E622: Could not fork for cscope"
msgstr "E622: Níorbh fhéidir forc a dhéanamh le haghaidh cscope"
-#: ../if_cscope.c:849
-#, fuzzy
msgid "cs_create_connection setpgid failed"
-msgstr "theip ar rith cs_create_connection"
+msgstr "theip ar setpgid do cs_create_connection"
-#: ../if_cscope.c:853 ../if_cscope.c:889
msgid "cs_create_connection exec failed"
msgstr "theip ar rith cs_create_connection"
-#: ../if_cscope.c:863 ../if_cscope.c:902
msgid "cs_create_connection: fdopen for to_fp failed"
msgstr "cs_create_connection: theip ar fdopen le haghaidh to_fp"
-#: ../if_cscope.c:865 ../if_cscope.c:906
msgid "cs_create_connection: fdopen for fr_fp failed"
msgstr "cs_create_connection: theip ar fdopen le haghaidh fr_fp"
-#: ../if_cscope.c:890
msgid "E623: Could not spawn cscope process"
msgstr "E623: Níorbh fhéidir próiseas cscope a sceitheadh"
-#: ../if_cscope.c:932
msgid "E567: no cscope connections"
msgstr "E567: níl aon nasc cscope ann"
-#: ../if_cscope.c:1009
#, c-format
msgid "E469: invalid cscopequickfix flag %c for %c"
msgstr "E469: bratach neamhbhailí cscopequickfix %c le haghaidh %c"
-#: ../if_cscope.c:1058
#, c-format
msgid "E259: no matches found for cscope query %s of %s"
msgstr ""
"E259: níor aimsíodh aon rud comhoiriúnach leis an iarratas cscope %s de %s"
-#: ../if_cscope.c:1142
msgid "cscope commands:\n"
msgstr "Orduithe cscope:\n"
-#: ../if_cscope.c:1150
#, c-format
msgid "%-5s: %s%*s (Usage: %s)"
msgstr "%-5s: %s%*s (Úsáid: %s)"
-#: ../if_cscope.c:1155
-#, fuzzy
msgid ""
"\n"
+" a: Find assignments to this symbol\n"
" c: Find functions calling this function\n"
" d: Find functions called by this function\n"
" e: Find this egrep pattern\n"
@@ -3241,6 +2576,7 @@ msgid ""
" t: Find this text string\n"
msgstr ""
"\n"
+" a: Aimsigh ráitis sannacháin leis an tsiombail seo\n"
" c: Aimsigh feidhmeanna a chuireann glaoch ar an bhfeidhm seo\n"
" d: Aimsigh feidhmeanna a gcuireann an fheidhm seo glaoch orthu\n"
" e: Aimsigh an patrún egrep seo\n"
@@ -3248,33 +2584,34 @@ msgstr ""
" g: Aimsigh an sainmhíniú seo\n"
" i: Aimsigh comhaid a #include-áil an comhad seo\n"
" s: Aimsigh an tsiombail C seo\n"
-" t: Aimsigh sanntaí do\n"
+" t: Aimsigh an teaghrán téacs seo\n"
+
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: ní féidir bunachar sonraí cscope a oscailt: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: ní féidir eolas a fháil faoin bhunachar sonraí cscope"
-#: ../if_cscope.c:1226
msgid "E568: duplicate cscope database not added"
msgstr "E568: níor cuireadh bunachar sonraí dúblach cscope leis"
-#: ../if_cscope.c:1335
#, c-format
msgid "E261: cscope connection %s not found"
msgstr "E261: nasc cscope %s gan aimsiú"
-#: ../if_cscope.c:1364
#, c-format
msgid "cscope connection %s closed"
msgstr "Dúnadh nasc cscope %s"
#. should not reach here
-#: ../if_cscope.c:1486
msgid "E570: fatal error in cs_manage_matches"
msgstr "E570: earráid mharfach i cs_manage_matches"
-#: ../if_cscope.c:1693
#, c-format
msgid "Cscope tag: %s"
msgstr "Clib cscope: %s"
-#: ../if_cscope.c:1711
msgid ""
"\n"
" # line"
@@ -3282,88 +2619,301 @@ msgstr ""
"\n"
" # líne"
-#: ../if_cscope.c:1713
msgid "filename / context / line\n"
msgstr "ainm comhaid / comhthéacs / líne\n"
-#: ../if_cscope.c:1809
#, c-format
msgid "E609: Cscope error: %s"
msgstr "E609: Earráid cscope: %s"
-#: ../if_cscope.c:2053
msgid "All cscope databases reset"
msgstr "Athshocraíodh gach bunachar sonraí cscope"
-#: ../if_cscope.c:2123
msgid "no cscope connections\n"
msgstr "níl aon nasc cscope\n"
-#: ../if_cscope.c:2126
msgid " # pid database name prepend path\n"
msgstr " # pid ainm bunachair conair thosaigh\n"
-#: ../main.c:144
+msgid "Lua library cannot be loaded."
+msgstr "Ní féidir an leabharlann Lua a luchtú."
+
+msgid "cannot save undo information"
+msgstr "ní féidir eolas cealaithe a shábháil"
+
+msgid ""
+"E815: Sorry, this command is disabled, the MzScheme libraries could not be "
+"loaded."
+msgstr ""
+"E815: Tá brón orm, bhí an t-ordú seo díchumasaithe, níorbh fhéidir "
+"leabharlanna MzScheme a luchtú."
+
+msgid ""
+"E895: Sorry, this command is disabled, the MzScheme's racket/base module "
+"could not be loaded."
+msgstr ""
+"E895: Ár leithscéal, tá an t-ordú seo díchumasaithe; níorbh fhéidir "
+"modúl racket/base MzScheme a luchtú."
+
+msgid "invalid expression"
+msgstr "slonn neamhbhailí"
+
+msgid "expressions disabled at compile time"
+msgstr "díchumasaíodh sloinn ag am an tiomsaithe"
+
+msgid "hidden option"
+msgstr "rogha fholaithe"
+
+msgid "unknown option"
+msgstr "rogha anaithnid"
+
+msgid "window index is out of range"
+msgstr "innéacs fuinneoige as raon"
+
+msgid "couldn't open buffer"
+msgstr "ní féidir maolán a oscailt"
+
+msgid "cannot delete line"
+msgstr "ní féidir an líne a scriosadh"
+
+msgid "cannot replace line"
+msgstr "ní féidir an líne a athchur"
+
+msgid "cannot insert line"
+msgstr "ní féidir líne a ionsá"
+
+msgid "string cannot contain newlines"
+msgstr "ní cheadaítear carachtair líne nua sa teaghrán"
+
+msgid "error converting Scheme values to Vim"
+msgstr "earráid agus luach Scheme á thiontú go Vim"
+
+msgid "Vim error: ~a"
+msgstr "earráid Vim: ~a"
+
+msgid "Vim error"
+msgstr "earráid Vim"
+
+msgid "buffer is invalid"
+msgstr "maolán neamhbhailí"
+
+msgid "window is invalid"
+msgstr "fuinneog neamhbhailí"
+
+msgid "linenr out of range"
+msgstr "líne-uimhir as raon"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "ní cheadaítear é seo i mbosca gainimh Vim"
+
+msgid "E836: This Vim cannot execute :python after using :py3"
+msgstr ""
+"E836: Ní féidir leis an leagan seo de Vim :python a rith tar éis :py3 a úsáid"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: Tá brón orm, níl an t-ordú seo le fáil, níorbh fhéidir an leabharlann "
+"Python a luchtú."
+
+msgid ""
+"E887: Sorry, this command is disabled, the Python's site module could not be "
+"loaded."
+msgstr ""
+"E887: Ár leithscéal, níl an t-ordú seo le fáil, níorbh fhéidir an modúl "
+"Python a luchtú."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Ní féidir Python a rith go hathchúrsach"
+
+msgid "E837: This Vim cannot execute :py3 after using :python"
+msgstr ""
+"E837: Ní féidir leis an leagan seo de Vim :py3 a rith tar éis :python a úsáid"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: caithfidh $_ a bheith cineál Teaghráin"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: Tá brón orm, níl an t-ordú seo le fáil, níorbh fhéidir an leabharlann "
+"Ruby a luchtú."
+
+msgid "E267: unexpected return"
+msgstr "E267: \"return\" gan choinne"
+
+msgid "E268: unexpected next"
+msgstr "E268: \"next\" gan choinne"
+
+msgid "E269: unexpected break"
+msgstr "E269: \"break\" gan choinne"
+
+msgid "E270: unexpected redo"
+msgstr "E270: \"redo\" gan choinne"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: \"retry\" taobh amuigh de chlásal tarrthála"
+
+msgid "E272: unhandled exception"
+msgstr "E272: eisceacht gan láimhseáil"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: stádas anaithnid longjmp %d"
+
+msgid "invalid buffer number"
+msgstr "uimhir neamhbhailí mhaoláin"
+
+msgid "not implemented yet"
+msgstr "níl ar fáil"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "ní féidir lín(t)e a shocrú"
+
+msgid "invalid mark name"
+msgstr "ainm neamhbhailí mairc"
+
+msgid "mark not set"
+msgstr "marc gan socrú"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "líne %d colún %d"
+
+msgid "cannot insert/append line"
+msgstr "ní féidir líne a ionsá/iarcheangal"
+
+msgid "line number out of range"
+msgstr "líne-uimhir as raon"
+
+msgid "unknown flag: "
+msgstr "bratach anaithnid: "
+
+msgid "unknown vimOption"
+msgstr "vimOption anaithnid"
+
+msgid "keyboard interrupt"
+msgstr "idirbhriseadh méarchláir"
+
+msgid "vim error"
+msgstr "earráid vim"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "ní féidir ordú maoláin/fuinneoige a chruthú: réad á scriosadh"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr "ní féidir ordú aisghlaoch a chlárú: maolán/fuinneog á scriosadh cheana"
+
+#. This should never happen. Famous last word?
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr ""
+"E280: EARRÁID MHARFACH TCL: liosta truaillithe tagartha!? Seol tuairisc "
+"fhabht chuig <vim-dev@vim.org> le do thoil"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"ní féidir ordú aisghlaoch a chlárú: tagairt mhaolán/fhuinneoige gan aimsiú"
+
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"E571: Tá brón orm, níl an t-ordú seo le fáil: níorbh fhéidir an leabharlann "
+"Tcl a luchtú."
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: cód scortha %d"
+
+msgid "cannot get line"
+msgstr "ní féidir an líne a fháil"
+
+msgid "Unable to register a command server name"
+msgstr "Ní féidir ainm fhreastalaí ordaithe a chlárú"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Theip ar sheoladh ordú chuig an sprioc-chlár"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: Aitheantas neamhbhailí freastalaí in úsáid: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: Airí míchumtha sa chlárlann áisc VIM. Scriosta!"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Camóg ar iarraidh i Liosta: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: ']' ar iarraidh ag deireadh liosta: %s"
+
msgid "Unknown option argument"
msgstr "Argóint anaithnid rogha"
-#: ../main.c:146
msgid "Too many edit arguments"
msgstr "An iomarca argóintí eagarthóireachta"
-#: ../main.c:148
msgid "Argument missing after"
msgstr "Argóint ar iarraidh i ndiaidh"
-#: ../main.c:150
msgid "Garbage after option argument"
msgstr "Dramhaíl i ndiaidh argóinte rogha"
-#: ../main.c:152
msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
msgstr ""
"An iomarca argóintí den chineál \"+ordú\", \"-c ordú\" nó \"--cmd ordú\""
-#: ../main.c:154
msgid "Invalid argument for"
msgstr "Argóint neamhbhailí do"
-#: ../main.c:294
#, c-format
msgid "%d files to edit\n"
msgstr "%d comhad le heagrú\n"
-#: ../main.c:1342
+msgid "netbeans is not supported with this GUI\n"
+msgstr "Ní thacaítear le netbeans sa GUI seo\n"
+
+msgid "'-nb' cannot be used: not enabled at compile time\n"
+msgstr "Ní féidir '-nb' a úsáid: níor cumasaíodh é ag am tiomsaithe\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Níor tiomsaíodh an leagan Vim seo le `diff' ar fáil."
+
msgid "Attempt to open script file again: \""
msgstr "Déan iarracht ar oscailt na scripte arís: \""
-#: ../main.c:1350
msgid "Cannot open for reading: \""
msgstr "Ní féidir é a oscailt chun léamh: \""
-#: ../main.c:1393
msgid "Cannot open for script output: \""
msgstr "Ní féidir a oscailt le haghaidh an aschuir scripte: \""
-#: ../main.c:1622
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Earráid: Theip ar thosú gvim ó NetBeans\n"
+
+msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n"
+msgstr "Vim: Earráid: Ní féidir an leagan seo de Vim a rith i dteirminéal Cygwin\n"
+
msgid "Vim: Warning: Output is not to a terminal\n"
msgstr "Vim: Rabhadh: Níl an t-aschur ag dul chuig teirminéal\n"
-#: ../main.c:1624
msgid "Vim: Warning: Input is not from a terminal\n"
msgstr "Vim: Rabhadh: Níl an t-ionchur ag teacht ó theirminéal\n"
#. just in case..
-#: ../main.c:1891
msgid "pre-vimrc command line"
msgstr "líne na n-orduithe pre-vimrc"
-#: ../main.c:1964
#, c-format
msgid "E282: Cannot read from \"%s\""
msgstr "E282: Ní féidir léamh ó \"%s\""
-#: ../main.c:2149
msgid ""
"\n"
"More info with: \"vim -h\"\n"
@@ -3371,23 +2921,18 @@ msgstr ""
"\n"
"Tuilleadh eolais: \"vim -h\"\n"
-#: ../main.c:2178
msgid "[file ..] edit specified file(s)"
msgstr "[comhad ..] cuir na comhaid ceaptha in eagar"
-#: ../main.c:2179
msgid "- read text from stdin"
msgstr "- scríobh téacs ó stdin"
-#: ../main.c:2180
msgid "-t tag edit file where tag is defined"
msgstr "-t tag cuir an comhad ina bhfuil an chlib in eagar"
-#: ../main.c:2181
msgid "-q [errorfile] edit file with first error"
msgstr "-q [comhadearr] cuir comhad leis an chéad earráid in eagar"
-#: ../main.c:2187
msgid ""
"\n"
"\n"
@@ -3397,11 +2942,9 @@ msgstr ""
"\n"
"úsáid:"
-#: ../main.c:2189
msgid " vim [arguments] "
msgstr " vim [argóintí] "
-#: ../main.c:2193
msgid ""
"\n"
" or:"
@@ -3409,7 +2952,14 @@ msgstr ""
"\n"
" nó:"
-#: ../main.c:2196
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"Nuair nach cásíogair é, cuir '/' ag tosach na brataí chun í a chur sa chás "
+"uachtair"
+
msgid ""
"\n"
"\n"
@@ -3419,194 +2969,338 @@ msgstr ""
"\n"
"Argóintí:\n"
-#: ../main.c:2197
msgid "--\t\t\tOnly file names after this"
msgstr "--\t\t\tNí cheadaítear ach ainmneacha comhaid i ndiaidh é seo"
-#: ../main.c:2199
msgid "--literal\t\tDon't expand wildcards"
msgstr "--literal\t\tNá leathnaigh saoróga"
-#: ../main.c:2201
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tCláraigh an gvim seo le haghaidh OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tDíchláraigh an gvim seo le haghaidh OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tRith agus úsáid an GUI (mar \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f nó --nofork\tTulra: Ná déan forc agus an GUI á thosú"
+
msgid "-v\t\t\tVi mode (like \"vi\")"
msgstr "-v\t\t\tMód Vi (mar \"vi\")"
-#: ../main.c:2202
msgid "-e\t\t\tEx mode (like \"ex\")"
msgstr "-e\t\t\tMód Ex (mar \"ex\")"
-#: ../main.c:2203
msgid "-E\t\t\tImproved Ex mode"
-msgstr ""
+msgstr "-E\t\t\tMód Ex feabhsaithe"
-#: ../main.c:2204
msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
msgstr "-s\t\t\tMód ciúin (baiscphróiseála) (do \"ex\" amháin)"
-#: ../main.c:2205
msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
msgstr "-d\t\t\tMód diff (mar \"vimdiff\")"
-#: ../main.c:2206
msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
msgstr "-y\t\t\tMód éasca (mar \"evim\", gan mhóid)"
-#: ../main.c:2207
msgid "-R\t\t\tReadonly mode (like \"view\")"
msgstr "-R\t\t\tMód inléite amháin (mar \"view\")"
-#: ../main.c:2208
msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
msgstr "-Z\t\t\tMód srianta (mar \"rvim\")"
-#: ../main.c:2209
msgid "-m\t\t\tModifications (writing files) not allowed"
msgstr "-m\t\t\tNí cheadaítear athruithe (.i. scríobh na gcomhad)"
-#: ../main.c:2210
msgid "-M\t\t\tModifications in text not allowed"
msgstr "-M\t\t\tNí cheadaítear athruithe sa téacs"
-#: ../main.c:2211
msgid "-b\t\t\tBinary mode"
msgstr "-b\t\t\tMód dénártha"
-#: ../main.c:2212
msgid "-l\t\t\tLisp mode"
msgstr "-l\t\t\tMód Lisp"
-#: ../main.c:2213
msgid "-C\t\t\tCompatible with Vi: 'compatible'"
msgstr "-C\t\t\tComhoiriúnach le Vi: 'compatible'"
-#: ../main.c:2214
msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
msgstr "-N\t\t\tNí comhoiriúnaithe le Vi go hiomlán: 'nocompatible'"
-#: ../main.c:2215
msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
msgstr ""
"-V[N][fname]\t\tBí foclach [leibhéal N] [logáil teachtaireachtaí i fname]"
-#: ../main.c:2216
msgid "-D\t\t\tDebugging mode"
msgstr "-D\t\t\tMód dífhabhtaithe"
-#: ../main.c:2217
msgid "-n\t\t\tNo swap file, use memory only"
msgstr "-n\t\t\tNá húsáid comhad babhtála .i. ná húsáid ach an chuimhne"
-#: ../main.c:2218
msgid "-r\t\t\tList swap files and exit"
msgstr "-r\t\t\tTaispeáin comhaid bhabhtála agus scoir"
-#: ../main.c:2219
msgid "-r (with file name)\tRecover crashed session"
msgstr "-r (le hainm comhaid)\tAthshlánaigh ó chliseadh"
-#: ../main.c:2220
msgid "-L\t\t\tSame as -r"
msgstr "-L\t\t\tAr comhbhrí le -r"
-#: ../main.c:2221
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tNá húsáid newcli chun fuinneog a oscailt"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <gléas>\t\tBain úsáid as <gléas> do I/A"
+
msgid "-A\t\t\tstart in Arabic mode"
msgstr "-A\t\t\ttosaigh sa mhód Araibise"
-#: ../main.c:2222
msgid "-H\t\t\tStart in Hebrew mode"
msgstr "-H\t\t\tTosaigh sa mhód Eabhraise"
-#: ../main.c:2223
msgid "-F\t\t\tStart in Farsi mode"
msgstr "-F\t\t\tTosaigh sa mhód Pheirsise"
-#: ../main.c:2224
msgid "-T <terminal>\tSet terminal type to <terminal>"
msgstr "-T <teirminéal>\tSocraigh cineál teirminéal"
-#: ../main.c:2225
+msgid "--not-a-term\t\tSkip warning for input/output not being a terminal"
+msgstr "--not-a-term\t\tNá bac le rabhadh faoi ionchur/aschur gan a bheith ón teirminéal"
+
msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
msgstr "-u <vimrc>\t\tÚsáid <vimrc> in ionad aon .vimrc"
-#: ../main.c:2226
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tBain úsáid as <gvimrc> in ionad aon .gvimrc"
+
msgid "--noplugin\t\tDon't load plugin scripts"
msgstr "--noplugin\t\tNá luchtaigh breiseáin"
-#: ../main.c:2227
msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
-msgstr "-p[N]\t\tOscail N leathanach cluaisín (default: ceann do gach comhad)"
+msgstr "-p[N]\t\tOscail N leathanach cluaisíní (default: ceann do gach comhad)"
-#: ../main.c:2228
msgid "-o[N]\t\tOpen N windows (default: one for each file)"
msgstr "-o[N]\t\tOscail N fuinneog (réamhshocrú: ceann do gach comhad)"
-#: ../main.c:2229
msgid "-O[N]\t\tLike -o but split vertically"
msgstr "-O[N]\t\tMar -o, ach roinn go hingearach"
-#: ../main.c:2230
msgid "+\t\t\tStart at end of file"
msgstr "+\t\t\tTosaigh ag an chomhadchríoch"
-#: ../main.c:2231
msgid "+<lnum>\t\tStart at line <lnum>"
msgstr "+<lnum>\t\tTosaigh ar líne <lnum>"
-#: ../main.c:2232
msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
msgstr "--cmd <ordú>\tRith <ordú> roimh aon chomhad vimrc a luchtú"
-#: ../main.c:2233
msgid "-c <command>\t\tExecute <command> after loading the first file"
msgstr "-c <ordú>\t\tRith <ordú> i ndiaidh luchtú an chéad chomhad"
-#: ../main.c:2235
msgid "-S <session>\t\tSource file <session> after loading the first file"
msgstr ""
"-S <seisiún>\t\tLéigh comhad <seisiún> i ndiaidh an chéad chomhad á léamh"
-#: ../main.c:2236
msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
msgstr "-s <script>\tLéigh orduithe gnáthmhóid ón chomhad <script>"
-#: ../main.c:2237
msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
msgstr ""
"-w <script>\tIarcheangail gach ordú iontráilte leis an gcomhad <script>"
-#: ../main.c:2238
msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
msgstr "-W <aschur>\tScríobh gach ordú clóscríofa sa chomhad <aschur>"
-#: ../main.c:2240
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tCuir comhaid chriptithe in eagar"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <freastalaí>\tNasc vim leis an bhfreastalaí-X seo"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tNá naisc leis an bhfreastalaí X"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr ""
+"--remote <comhaid>\tCuir <comhaid> in eagar le freastalaí Vim más féidir"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-silent <comhaid> Mar an gcéanna, ná déan gearán mura bhfuil "
+"freastalaí ann"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr ""
+"--remote-wait <comhaid> Mar --remote ach fan leis na comhaid a bheith "
+"curtha in eagar"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-wait-silent <comhaid> Mar an gcéanna, ná déan gearán mura bhfuil "
+"freastalaí ann"
+
+msgid ""
+"--remote-tab[-wait][-silent] <files> As --remote but use tab page per file"
+msgstr ""
+"--remote-tab[-wait][-silent] <comhaid> Cosúil le --remote ach oscail "
+"cluaisín do gach comhad"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr ""
+"--remote-send <eochracha>\tSeol <eochracha> chuig freastalaí Vim agus scoir"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr ""
+"--remote-expr <slonn>\tLuacháil <slonn> le freastalaí Vim agus taispeáin an "
+"toradh"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tTaispeáin freastalaithe Vim atá ar fáil agus scoir"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <ainm>\tSeol chuig/Téigh i do fhreastalaí Vim <ainm>"
+
msgid "--startuptime <file>\tWrite startup timing messages to <file>"
msgstr ""
"--startuptime <comhad>\tScríobh faisnéis maidir le tréimhse tosaithe i "
"<comhad>"
-#: ../main.c:2242
msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
msgstr "-i <viminfo>\t\tÚsáid <viminfo> in ionad .viminfo"
-#: ../main.c:2243
msgid "-h or --help\tPrint Help (this message) and exit"
msgstr "-h nó --help\tTaispeáin an chabhair seo agus scoir"
-#: ../main.c:2244
msgid "--version\t\tPrint version information and exit"
msgstr "--version\t\tTaispeáin eolas faoin leagan agus scoir"
-#: ../mark.c:676
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Argóintí ar eolas do gvim (leagan Motif):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Argóintí ar eolas do gvim (leagan neXtaw):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Argóintí ar eolas do gvim (leagan Athena):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <scáileán>\tRith vim ar <scáileán>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tTosaigh vim sa mhód íoslaghdaithe"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <dath>\tBain úsáid as <dath> don chúlra (-bg fosta)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <dath>\tÚsáid <dath> le haghaidh gnáth-théacs (fosta: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <cló>\t\tÚsáid <cló> le haghaidh gnáth-théacs (fosta: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <cló>\tBain úsáid as <cló> do chló trom"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <cló>\tÚsáid <cló> le haghaidh téacs iodálach"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr ""
+"-geometry <geoim>\tÚsáid <geoim> le haghaidh na céimseatan tosaigh (fosta: -"
+"geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <leithead>\tSocraigh <leithead> na himlíne (-bw fosta)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <leithead> Socraigh leithead na scrollbharraí a bheith "
+"<leithead> (fosta: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr ""
+"-menuheight <airde>\tSocraigh airde an bharra roghchláir a bheith <airde> "
+"(fosta: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tÚsáid fís aisiompaithe (fosta: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tNá húsáid fís aisiompaithe (fosta: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <acmhainn>\tSocraigh an acmhainn sainithe"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Argóintí ar eolas do gvim (leagan GTK+):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <scáileán>\tRith vim ar <scáileán> (fosta: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "--role <ról>\tSocraigh ról sainiúil chun an phríomhfhuinneog a aithint"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tOscail Vim isteach i ngiuirléid GTK eile"
+
+msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
+msgstr "--echo-wid\t\tTaispeánann gvim aitheantas na fuinneoige ar stdout"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <máthairchlár>\tOscail Vim isteach sa mháthairchlár"
+
+msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
+msgstr "--windowid <HWND>\tOscail Vim isteach i ngiuirléid win32 eile"
+
+msgid "No display"
+msgstr "Gan taispeáint"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Theip ar seoladh.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Theip ar seoladh. Ag baint triail as go logánta\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d as %d déanta"
+
+msgid "No display: Send expression failed.\n"
+msgstr "Gan taispeáint: Theip ar sheoladh sloinn.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Theip ar sheoladh sloinn.\n"
+
msgid "No marks set"
msgstr "Níl aon mharc socraithe"
-#: ../mark.c:678
#, c-format
msgid "E283: No marks matching \"%s\""
msgstr "E283: Níl aon mharc comhoiriúnaithe le \"%s\""
#. Highlight title
-#: ../mark.c:687
msgid ""
"\n"
"mark line col file/text"
@@ -3615,7 +3309,6 @@ msgstr ""
"marc líne col comhad/téacs"
#. Highlight title
-#: ../mark.c:789
msgid ""
"\n"
" jump line col file/text"
@@ -3624,7 +3317,6 @@ msgstr ""
" léim líne col comhad/téacs"
#. Highlight title
-#: ../mark.c:831
msgid ""
"\n"
"change line col text"
@@ -3632,7 +3324,6 @@ msgstr ""
"\n"
"athrú líne col téacs"
-#: ../mark.c:1238
msgid ""
"\n"
"# File marks:\n"
@@ -3641,7 +3332,6 @@ msgstr ""
"# Marcanna comhaid:\n"
#. Write the jumplist with -'
-#: ../mark.c:1271
msgid ""
"\n"
"# Jumplist (newest first):\n"
@@ -3649,7 +3339,6 @@ msgstr ""
"\n"
"# Liosta léimeanna (is nuaí i dtosach):\n"
-#: ../mark.c:1352
msgid ""
"\n"
"# History of marks within files (newest to oldest):\n"
@@ -3657,86 +3346,90 @@ msgstr ""
"\n"
"# Stair na marcanna i gcomhaid (is nuaí ar dtús):\n"
-#: ../mark.c:1431
msgid "Missing '>'"
msgstr "`>' ar iarraidh"
-#: ../memfile.c:426
+msgid "E543: Not a valid codepage"
+msgstr "E543: Ní códleathanach bailí é"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Ní féidir luachanna IC a shocrú"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Theip ar chruthú comhthéacs ionchuir"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Theip ar oscailt mhodh ionchuir"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: Rabhadh: Níorbh fhéidir aisghlaoch léirscriosta a shocrú le IM"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: Ní thacaíonn an modh ionchuir aon stíl"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: ní thacaíonn an modh ionchuir mo chineál réamheagair"
+
msgid "E293: block was not locked"
msgstr "E293: ní raibh an bloc faoi ghlas"
-#: ../memfile.c:799
msgid "E294: Seek error in swap file read"
msgstr "E294: Earráid chuardaigh agus comhad babhtála á léamh"
-#: ../memfile.c:803
msgid "E295: Read error in swap file"
msgstr "E295: Earráid sa léamh i gcomhad babhtála"
-#: ../memfile.c:849
msgid "E296: Seek error in swap file write"
msgstr "E296: Earráid chuardaigh agus comhad babhtála á scríobh"
-#: ../memfile.c:865
msgid "E297: Write error in swap file"
msgstr "E297: Earráid sa scríobh i gcomhad babhtála"
-#: ../memfile.c:1036
msgid "E300: Swap file already exists (symlink attack?)"
msgstr "E300: Tá comhad babhtála ann cheana (ionsaí le naisc shiombalacha?)"
-#: ../memline.c:318
msgid "E298: Didn't get block nr 0?"
msgstr "E298: Ní bhfuarthas bloc 0?"
-#: ../memline.c:361
msgid "E298: Didn't get block nr 1?"
msgstr "E298: Ní bhfuarthas bloc a haon?"
-#: ../memline.c:377
msgid "E298: Didn't get block nr 2?"
msgstr "E298: Ní bhfuarthas bloc a dó?"
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: Earráid agus criptiú an chomhaid bhabhtála á nuashonrú"
+
#. could not (re)open the swap file, what can we do????
-#: ../memline.c:465
msgid "E301: Oops, lost the swap file!!!"
msgstr "E301: Úps, cailleadh an comhad babhtála!!!"
-#: ../memline.c:477
msgid "E302: Could not rename swap file"
msgstr "E302: Níorbh fhéidir an comhad babhtála a athainmniú"
-#: ../memline.c:554
#, c-format
msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
msgstr ""
"E303: Ní féidir comhad babhtála le haghaidh \"%s\" a oscailt, ní féidir "
"athshlánú"
-#: ../memline.c:666
msgid "E304: ml_upd_block0(): Didn't get block 0??"
msgstr "E304: ml_upd_block0(): Ní bhfuarthas bloc 0??"
-#. no swap files found
-#: ../memline.c:830
#, c-format
msgid "E305: No swap file found for %s"
msgstr "E305: Níor aimsíodh comhad babhtála le haghaidh %s"
-#: ../memline.c:839
msgid "Enter number of swap file to use (0 to quit): "
msgstr "Iontráil uimhir an chomhaid babhtála le húsáid (0 = scoir): "
-#: ../memline.c:879
#, c-format
msgid "E306: Cannot open %s"
msgstr "E306: Ní féidir %s a oscailt"
-#: ../memline.c:897
msgid "Unable to read block 0 from "
msgstr "Ní féidir bloc 0 a léamh ó "
-#: ../memline.c:900
msgid ""
"\n"
"Maybe no changes were made or Vim did not update the swap file."
@@ -3745,28 +3438,22 @@ msgstr ""
"B'fhéidir nach raibh aon athrú á dhéanamh, nó tá an comhad\n"
"babhtála as dáta."
-#: ../memline.c:909
msgid " cannot be used with this version of Vim.\n"
msgstr " níl ar fáil leis an leagan seo de Vim.\n"
-#: ../memline.c:911
msgid "Use Vim version 3.0.\n"
msgstr "Bain úsáid as Vim, leagan 3.0.\n"
-#: ../memline.c:916
#, c-format
msgid "E307: %s does not look like a Vim swap file"
msgstr "E307: Níl %s cosúil le comhad babhtála Vim"
-#: ../memline.c:922
msgid " cannot be used on this computer.\n"
msgstr " níl ar fáil ar an ríomhaire seo.\n"
-#: ../memline.c:924
msgid "The file was created on "
msgstr "Cruthaíodh an comhad seo ar "
-#: ../memline.c:928
msgid ""
",\n"
"or the file has been damaged."
@@ -3774,86 +3461,107 @@ msgstr ""
",\n"
"is é sin nó rinneadh dochar don chomhad."
-#: ../memline.c:945
+#, c-format
+msgid ""
+"E833: %s is encrypted and this version of Vim does not support encryption"
+msgstr ""
+"E833: tá %s criptithe agus ní thacaíonn an leagan seo de Vim le criptiú"
+
msgid " has been damaged (page size is smaller than minimum value).\n"
msgstr " rinneadh dochar dó (méid an leathanaigh níos lú ná an íosmhéid).\n"
-#: ../memline.c:974
#, c-format
msgid "Using swap file \"%s\""
msgstr "Comhad babhtála \"%s\" á úsáid"
-#: ../memline.c:980
#, c-format
msgid "Original file \"%s\""
msgstr "Comhad bunúsach \"%s\""
-#: ../memline.c:995
msgid "E308: Warning: Original file may have been changed"
msgstr "E308: Rabhadh: Is féidir gur athraíodh an comhad bunúsach"
-#: ../memline.c:1061
+#, c-format
+msgid "Swap file is encrypted: \"%s\""
+msgstr "Tá an comhad babhtála criptithe: \"%s\""
+
+msgid ""
+"\n"
+"If you entered a new crypt key but did not write the text file,"
+msgstr ""
+"\n"
+"Má chuir tú eochair nua chriptiúcháin isteach, ach mura scríobh tú an "
+"téacschomhad,"
+
+msgid ""
+"\n"
+"enter the new crypt key."
+msgstr ""
+"\n"
+"cuir isteach an eochair nua chriptiúcháin."
+
+msgid ""
+"\n"
+"If you wrote the text file after changing the crypt key press enter"
+msgstr ""
+"\n"
+"Má scríobh tú an téacschomhad tar éis duit an eochair chriptiúcháín a athrú, "
+"brúigh Enter"
+
+msgid ""
+"\n"
+"to use the same key for text file and swap file"
+msgstr ""
+"\n"
+"chun an eochair chéanna a úsáid don téacschomhad agus an comhad babhtála"
+
#, c-format
msgid "E309: Unable to read block 1 from %s"
msgstr "E309: Ní féidir bloc a haon a léamh ó %s"
-#: ../memline.c:1065
msgid "???MANY LINES MISSING"
msgstr "???GO LEOR LÍNTE AR IARRAIDH"
-#: ../memline.c:1076
msgid "???LINE COUNT WRONG"
msgstr "???LÍON MÍCHEART NA LÍNTE"
-#: ../memline.c:1082
msgid "???EMPTY BLOCK"
msgstr "???BLOC FOLAMH"
-#: ../memline.c:1103
msgid "???LINES MISSING"
msgstr "???LÍNTE AR IARRAIDH"
-#: ../memline.c:1128
#, c-format
msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
msgstr "E310: Aitheantas mícheart ar bhloc a haon (níl %s ina chomhad .swp?)"
-#: ../memline.c:1133
msgid "???BLOCK MISSING"
msgstr "???BLOC AR IARRAIDH"
-#: ../memline.c:1147
msgid "??? from here until ???END lines may be messed up"
msgstr "??? is féidir go ndearnadh praiseach de línte ó anseo go ???END"
-#: ../memline.c:1164
msgid "??? from here until ???END lines may have been inserted/deleted"
msgstr "??? is féidir go bhfuil línte ionsáite/scriosta ó anseo go ???END"
-#: ../memline.c:1181
msgid "???END"
msgstr "???DEIREADH"
-#: ../memline.c:1238
msgid "E311: Recovery Interrupted"
msgstr "E311: Idirbhriseadh an t-athshlánú"
-#: ../memline.c:1243
msgid ""
"E312: Errors detected while recovering; look for lines starting with ???"
msgstr ""
"E312: Braitheadh earráidí le linn athshlánaithe; féach ar na línte le ??? ar "
"tosach"
-#: ../memline.c:1245
msgid "See \":help E312\" for more information."
msgstr "Bain triail as \":help E312\" chun tuilleadh eolais a fháil."
-#: ../memline.c:1249
msgid "Recovery completed. You should check if everything is OK."
msgstr "Athshlánaíodh. Ba chóir duit gach rud a sheiceáil uair amháin eile."
-#: ../memline.c:1251
msgid ""
"\n"
"(You might want to write out this file under another name\n"
@@ -3861,73 +3569,61 @@ msgstr ""
"\n"
"(B'fhéidir gur mian leat an comhad seo a shábháil de réir ainm eile\n"
-#: ../memline.c:1252
-#, fuzzy
msgid "and run diff with the original file to check for changes)"
-msgstr ""
-"agus déan comparáid leis an chomhad bhunúsach (m.sh. le `diff') chun "
-"athruithe a scrúdú)\n"
+msgstr "agus déan comparáid leis an mbunchomhad chun athruithe a lorg)"
-#: ../memline.c:1254
msgid "Recovery completed. Buffer contents equals file contents."
msgstr ""
+"Athshlánú críochnaithe. Is ionann an t-ábhar sa mhaolán agus an t-ábhar sa "
+"chomhad."
-#: ../memline.c:1255
-#, fuzzy
msgid ""
"\n"
"You may want to delete the .swp file now.\n"
"\n"
msgstr ""
-"Scrios an comhad .swp tar éis sin.\n"
"\n"
+"B'fhéidir gur mhaith leat an comhad .swp a scriosadh anois.\n"
+"\n"
+
+msgid "Using crypt key from swap file for the text file.\n"
+msgstr ""
+"Eochair chriptiúcháin ón gcomhad babhtála á húsáid ar an téacschomhad.\n"
#. use msg() to start the scrolling properly
-#: ../memline.c:1327
msgid "Swap files found:"
msgstr "Comhaid bhabhtála aimsithe:"
-#: ../memline.c:1446
msgid " In current directory:\n"
msgstr " Sa chomhadlann reatha:\n"
-#: ../memline.c:1448
msgid " Using specified name:\n"
msgstr " Ag baint úsáid as ainm socraithe:\n"
-#: ../memline.c:1450
msgid " In directory "
msgstr " Sa chomhadlann "
-#: ../memline.c:1465
msgid " -- none --\n"
msgstr " -- neamhní --\n"
-#: ../memline.c:1527
msgid " owned by: "
msgstr " úinéir: "
-#: ../memline.c:1529
msgid " dated: "
msgstr " dátaithe: "
-#: ../memline.c:1532 ../memline.c:3231
msgid " dated: "
msgstr " dátaithe: "
-#: ../memline.c:1548
msgid " [from Vim version 3.0]"
msgstr " [ó leagan 3.0 Vim]"
-#: ../memline.c:1550
msgid " [does not look like a Vim swap file]"
msgstr " [ní cosúil le comhad babhtála Vim]"
-#: ../memline.c:1552
msgid " file name: "
msgstr " ainm comhaid: "
-#: ../memline.c:1558
msgid ""
"\n"
" modified: "
@@ -3935,15 +3631,12 @@ msgstr ""
"\n"
" mionathraithe: "
-#: ../memline.c:1559
msgid "YES"
msgstr "IS SEA"
-#: ../memline.c:1559
msgid "no"
msgstr "ní hea"
-#: ../memline.c:1562
msgid ""
"\n"
" user name: "
@@ -3951,11 +3644,9 @@ msgstr ""
"\n"
" úsáideoir: "
-#: ../memline.c:1568
msgid " host name: "
msgstr " ainm an óstríomhaire: "
-#: ../memline.c:1570
msgid ""
"\n"
" host name: "
@@ -3963,7 +3654,6 @@ msgstr ""
"\n"
" óstainm: "
-#: ../memline.c:1575
msgid ""
"\n"
" process ID: "
@@ -3971,11 +3661,16 @@ msgstr ""
"\n"
" PID: "
-#: ../memline.c:1579
msgid " (still running)"
msgstr " (ag rith fós)"
-#: ../memline.c:1586
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [ní inúsáidte leis an leagan seo Vim]"
+
msgid ""
"\n"
" [not usable on this computer]"
@@ -3983,97 +3678,75 @@ msgstr ""
"\n"
" [ní inúsáidte ar an ríomhaire seo]"
-#: ../memline.c:1590
msgid " [cannot be read]"
msgstr " [ní féidir a léamh]"
-#: ../memline.c:1593
msgid " [cannot be opened]"
msgstr " [ní féidir oscailt]"
-#: ../memline.c:1698
msgid "E313: Cannot preserve, there is no swap file"
msgstr "E313: Ní féidir é a chaomhnú, níl aon chomhad babhtála ann"
-#: ../memline.c:1747
msgid "File preserved"
msgstr "Caomhnaíodh an comhad"
-#: ../memline.c:1749
msgid "E314: Preserve failed"
msgstr "E314: Theip ar chaomhnú"
-#: ../memline.c:1819
#, c-format
-msgid "E315: ml_get: invalid lnum: %<PRId64>"
-msgstr "E315: ml_get: lnum neamhbhailí: %<PRId64>"
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: lnum neamhbhailí: %ld"
-#: ../memline.c:1851
#, c-format
-msgid "E316: ml_get: cannot find line %<PRId64>"
-msgstr "E316: ml_get: líne %<PRId64> gan aimsiú"
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: líne %ld gan aimsiú"
-#: ../memline.c:2236
msgid "E317: pointer block id wrong 3"
msgstr "E317: aitheantas mícheart ar an mbloc pointeora 3"
-#: ../memline.c:2311
msgid "stack_idx should be 0"
msgstr "ba chóir do stack_idx a bheith 0"
-#: ../memline.c:2369
msgid "E318: Updated too many blocks?"
msgstr "E318: An iomarca bloic nuashonraithe?"
-#: ../memline.c:2511
msgid "E317: pointer block id wrong 4"
msgstr "E317: aitheantas mícheart ar an mbloc pointeora 4"
-#: ../memline.c:2536
msgid "deleted block 1?"
msgstr "bloc a haon scriosta?"
-#: ../memline.c:2707
#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: Líne %<PRId64> gan aimsiú"
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Líne %ld gan aimsiú"
-#: ../memline.c:2916
msgid "E317: pointer block id wrong"
msgstr "E317: aitheantas mícheart ar an mbloc pointeora"
-#: ../memline.c:2930
msgid "pe_line_count is zero"
msgstr "is 0 pe_line_count\""
-#: ../memline.c:2955
#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: líne-uimhir as raon: %<PRId64> thar dheireadh"
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: líne-uimhir as raon: %ld thar dheireadh"
-#: ../memline.c:2959
#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: líon mícheart na línte i mbloc %<PRId64>"
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: líon mícheart na línte i mbloc %ld"
-#: ../memline.c:2999
msgid "Stack size increases"
msgstr "Méadaíonn an chruach"
-#: ../memline.c:3038
msgid "E317: pointer block id wrong 2"
msgstr "E317: aitheantas mícheart ar an mbloc pointeora 2"
-#: ../memline.c:3070
#, c-format
msgid "E773: Symlink loop for \"%s\""
msgstr "E773: Ciogal i naisc shiombalacha le haghaidh \"%s\""
-#: ../memline.c:3221
msgid "E325: ATTENTION"
msgstr "E325: AIRE"
-#: ../memline.c:3222
msgid ""
"\n"
"Found a swap file by the name \""
@@ -4081,45 +3754,31 @@ msgstr ""
"\n"
"Fuarthas comhad babhtála darbh ainm \""
-#: ../memline.c:3226
msgid "While opening file \""
msgstr "Agus an comhad seo á oscailt: \""
-#: ../memline.c:3239
msgid " NEWER than swap file!\n"
msgstr " NÍOS NUAÍ ná comhad babhtála!\n"
-#: ../memline.c:3244
-#, fuzzy
+#. Some of these messages are long to allow translation to
+#. * other languages.
msgid ""
"\n"
"(1) Another program may be editing the same file. If this is the case,\n"
" be careful not to end up with two different instances of the same\n"
-" file when making changes."
+" file when making changes. Quit, or continue with caution.\n"
msgstr ""
"\n"
-"(1) Is féidir go bhfuil clár eile ag rochtain an comhad seo.\n"
-" Más ea, bí cúramach nach bhfuil dhá leagan den chomhad\n"
-" céanna.\n"
-
-#: ../memline.c:3245
-#, fuzzy
-msgid " Quit, or continue with caution.\n"
-msgstr " Scoir, nó lean ar aghaidh go hairdeallach.\n"
+"(1) Seans go bhfuil an comhad seo á chur in eagar ag clár eile. Má tá,\n"
+" bí cúramach nach bhfuil dhá leagan den chomhad céanna agat nuair\n"
+" a athraíonn tú é. Scoir anois, nó lean ort go faichilleach.\n"
-#: ../memline.c:3246
-#, fuzzy
msgid "(2) An edit session for this file crashed.\n"
-msgstr ""
-"\n"
-"(2) Rinne Vim thobscor agus an comhad seo\n"
-" idir lámha agat.\n"
+msgstr "(2) Thuairteáil seisiún eagarthóireachta.\n"
-#: ../memline.c:3247
msgid " If this is the case, use \":recover\" or \"vim -r "
msgstr " Más amhlaidh, bain úsáid as \":recover\" nó \"vim -r "
-#: ../memline.c:3249
msgid ""
"\"\n"
" to recover the changes (see \":help recovery\").\n"
@@ -4127,11 +3786,9 @@ msgstr ""
"\"\n"
" chun na hathruithe a fháil ar ais (féach \":help recovery\").\n"
-#: ../memline.c:3250
msgid " If you did this already, delete the swap file \""
msgstr " Má tá sé seo déanta cheana agat, scrios an comhad babhtála \""
-#: ../memline.c:3252
msgid ""
"\"\n"
" to avoid this message.\n"
@@ -4139,23 +3796,18 @@ msgstr ""
"\"\n"
" chun an teachtaireacht seo a sheachaint.\n"
-#: ../memline.c:3450 ../memline.c:3452
msgid "Swap file \""
msgstr "Comhad babhtála \""
-#: ../memline.c:3451 ../memline.c:3455
msgid "\" already exists!"
msgstr "\" tá sé ann cheana!"
-#: ../memline.c:3457
msgid "VIM - ATTENTION"
msgstr "VIM - AIRE"
-#: ../memline.c:3459
msgid "Swap file already exists!"
msgstr "Tá comhad babhtála ann cheana!"
-#: ../memline.c:3464
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4169,7 +3821,6 @@ msgstr ""
"&Scoir\n"
"&Tobscoir"
-#: ../memline.c:3467
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4185,58 +3836,36 @@ msgstr ""
"&Scoir\n"
"&Tobscoir"
-#.
-#. * Change the ".swp" extension to find another file that can be used.
-#. * First decrement the last char: ".swo", ".swn", etc.
-#. * If that still isn't enough decrement the last but one char: ".svz"
-#. * Can happen when editing many "No Name" buffers.
-#.
-#. ".s?a"
-#. ".saa": tried enough, give up
-#: ../memline.c:3528
msgid "E326: Too many swap files found"
msgstr "E326: Aimsíodh an iomarca comhaid bhabhtála"
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: Cuimhne ídithe! (%<PRIu64> beart á ndáileadh)"
-
-#: ../menu.c:62
msgid "E327: Part of menu-item path is not sub-menu"
msgstr "E327: Ní fo-roghchlár í páirt de chonair roghchláir"
-#: ../menu.c:63
msgid "E328: Menu only exists in another mode"
msgstr "E328: Níl an roghchlár ar fáil sa mhód seo"
-#: ../menu.c:64
#, c-format
msgid "E329: No menu \"%s\""
msgstr "E329: Níl aon roghchlár darbh ainm \"%s\""
#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
msgid "E792: Empty menu name"
msgstr "E792: Ainm folamh ar an roghchlár"
-#: ../menu.c:340
msgid "E330: Menu path must not lead to a sub-menu"
msgstr "E330: Ní cheadaítear conair roghchláir a threoraíonn go fo-roghchlár"
-#: ../menu.c:365
msgid "E331: Must not add menu items directly to menu bar"
msgstr ""
"E331: Ní cheadaítear míreanna roghchláir a chur le barra roghchláir go "
"díreach"
-#: ../menu.c:370
msgid "E332: Separator cannot be part of a menu path"
msgstr "E332: Ní cheadaítear deighilteoir mar pháirt de chonair roghchláir"
#. Now we have found the matching menu, and we list the mappings
#. Highlight title
-#: ../menu.c:762
msgid ""
"\n"
"--- Menus ---"
@@ -4244,69 +3873,61 @@ msgstr ""
"\n"
"--- Roghchláir ---"
-#: ../menu.c:1313
+msgid "Tear off this menu"
+msgstr "Bain an roghchlár seo"
+
msgid "E333: Menu path must lead to a menu item"
msgstr "E333: Ní mór conair roghchláir a threorú chun mír roghchláir"
-#: ../menu.c:1330
#, c-format
msgid "E334: Menu not found: %s"
msgstr "E334: Roghchlár gan aimsiú: %s"
-#: ../menu.c:1396
#, c-format
msgid "E335: Menu not defined for %s mode"
msgstr "E335: Níl an roghchlár ar fáil sa mhód %s"
-#: ../menu.c:1426
msgid "E336: Menu path must lead to a sub-menu"
msgstr "E336: Ní mór conair roghchláir a threorú chun fo-roghchlár"
-#: ../menu.c:1447
msgid "E337: Menu not found - check menu names"
msgstr "E337: Roghchlár gan aimsiú - deimhnigh ainmneacha na roghchlár"
-#: ../message.c:423
#, c-format
msgid "Error detected while processing %s:"
msgstr "Earráid agus %s á phróiseáil:"
-#: ../message.c:445
#, c-format
msgid "line %4ld:"
msgstr "líne %4ld:"
-#: ../message.c:617
#, c-format
msgid "E354: Invalid register name: '%s'"
msgstr "E354: Ainm neamhbhailí tabhaill: '%s'"
-#: ../message.c:986
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr ""
+"Cothaitheoir na dteachtaireachtaí: Kevin P. Scannell <scannell@slu.edu>"
+
msgid "Interrupt: "
msgstr "Idirbhriseadh: "
-#: ../message.c:988
msgid "Press ENTER or type command to continue"
msgstr "Brúigh ENTER nó iontráil ordú le leanúint"
-#: ../message.c:1843
#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s líne %<PRId64>"
+msgid "%s line %ld"
+msgstr "%s líne %ld"
-#: ../message.c:2392
msgid "-- More --"
msgstr "-- Tuilleadh --"
-#: ../message.c:2398
msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
msgstr " SPÁS/d/j: scáileán/leathanach/líne síos, b/u/k: suas, q: scoir "
-#: ../message.c:3021 ../message.c:3031
msgid "Question"
msgstr "Ceist"
-#: ../message.c:3023
msgid ""
"&Yes\n"
"&No"
@@ -4314,17 +3935,6 @@ msgstr ""
"&Tá\n"
"&Níl"
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"&Tá\n"
-"&Níl\n"
-"&Cealaigh"
-
-#: ../message.c:3045
msgid ""
"&Yes\n"
"&No\n"
@@ -4338,180 +3948,251 @@ msgstr ""
"&Dealaigh Uile\n"
"&Cealaigh"
-#: ../message.c:3058
+msgid "Select Directory dialog"
+msgstr "Dialóg `Roghnaigh Comhadlann'"
+
+msgid "Save File dialog"
+msgstr "Dialóg `Sábháil Comhad'"
+
+msgid "Open File dialog"
+msgstr "Dialóg `Oscail Comhad'"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Níl brabhsálaí comhaid ar fáil sa mhód consóil"
+
msgid "E766: Insufficient arguments for printf()"
msgstr "E766: Easpa argóintí d'fheidhm printf()"
-#: ../message.c:3119
msgid "E807: Expected Float argument for printf()"
msgstr "E807: Bhíothas ag súil le hargóint Snámhphointe d'fheidhm printf()"
-#: ../message.c:3873
msgid "E767: Too many arguments to printf()"
msgstr "E767: An iomarca argóintí d'fheidhm printf()"
-#: ../misc1.c:2256
msgid "W10: Warning: Changing a readonly file"
msgstr "W10: Rabhadh: Comhad inléite amháin á athrú"
-#: ../misc1.c:2537
msgid "Type number and <Enter> or click with mouse (empty cancels): "
msgstr ""
"Clóscríobh uimhir agus <Enter> nó cliceáil leis an luch (fág folamh le "
"cealú): "
-#: ../misc1.c:2539
msgid "Type number and <Enter> (empty cancels): "
msgstr "Clóscríobh uimhir agus <Enter> (fág folamh le cealú): "
-#: ../misc1.c:2585
msgid "1 more line"
msgstr "1 líne eile"
-#: ../misc1.c:2588
msgid "1 line less"
msgstr "1 líne níos lú"
-#: ../misc1.c:2593
#, c-format
-msgid "%<PRId64> more lines"
-msgstr "%<PRId64> líne eile"
+msgid "%ld more lines"
+msgstr "%ld líne eile"
-#: ../misc1.c:2596
#, c-format
-msgid "%<PRId64> fewer lines"
-msgstr "%<PRId64> líne níos lú"
+msgid "%ld fewer lines"
+msgstr "%ld líne níos lú"
-#: ../misc1.c:2599
msgid " (Interrupted)"
msgstr " (Idirbhriste)"
-#: ../misc1.c:2635
msgid "Beep!"
msgstr "Bíp!"
-#: ../misc2.c:738
+msgid "ERROR: "
+msgstr "EARRÁID: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[beart] iomlán dáilte-saor %lu-%lu, in úsáid %lu, buaic %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[glaonna] re/malloc(): %lu, free(): %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Tá an líne ag éirí rófhada"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Earráid inmheánach: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Cuimhne ídithe! (%lu beart á ndáileadh)"
+
#, c-format
msgid "Calling shell to execute: \"%s\""
msgstr "An t-ordú seo á rith leis an bhlaosc: \"%s\""
-#: ../normal.c:183
+msgid "E545: Missing colon"
+msgstr "E545: Idirstad ar iarraidh"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Mód neamhcheadaithe"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Cruth neamhcheadaithe luiche"
+
+msgid "E548: digit expected"
+msgstr "E548: ag súil le digit"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Céatadán neamhcheadaithe"
+
+msgid "E854: path too long for completion"
+msgstr "E854: conair rófhada le comhlánú"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: Conair neamhbhailí: ní mór '**[uimhir]' a bheith ag deireadh na "
+"conaire, nó le '%s' ina dhiaidh."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Ní féidir comhadlann \"%s\" a aimsiú sa cdpath"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Ní féidir comhad \"%s\" a aimsiú sa chonair"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Níl comhadlann \"%s\" sa cdpath a thuilleadh"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Níl comhad \"%s\" sa chonair a thuilleadh"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: Mód mícheart rochtana ar an chomhad eolas naisc NetBeans: \"%s\""
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Cailleadh nasc NetBeans le haghaidh maoláin %ld"
+
+msgid "E838: netbeans is not supported with this GUI"
+msgstr "E838: Ní thacaítear le netbeans sa GUI seo"
+
+msgid "E511: netbeans already connected"
+msgstr "E511: Tá netbeans ceangailte cheana"
+
+#, c-format
+msgid "E505: %s is read-only (add ! to override)"
+msgstr "E505: Tá %s inléite amháin (cuir ! leis chun sárú)"
+
msgid "E349: No identifier under cursor"
msgstr "E349: Níl aitheantóir faoin chúrsóir"
-#: ../normal.c:1866
msgid "E774: 'operatorfunc' is empty"
msgstr "E774: 'operatorfunc' folamh"
-#: ../normal.c:2637
+msgid "E775: Eval feature not available"
+msgstr "E775: Níl an ghné Eval le fáil"
+
msgid "Warning: terminal cannot highlight"
msgstr "Rabhadh: ní féidir leis an teirminéal aibhsiú"
-#: ../normal.c:2807
msgid "E348: No string under cursor"
msgstr "E348: Níl teaghrán faoin chúrsóir"
-#: ../normal.c:3937
msgid "E352: Cannot erase folds with current 'foldmethod'"
msgstr "E352: Ní féidir fillteacha a léirscriosadh leis an 'foldmethod' reatha"
-#: ../normal.c:5897
msgid "E664: changelist is empty"
msgstr "E664: tá liosta na n-athruithe folamh"
-#: ../normal.c:5899
msgid "E662: At start of changelist"
msgstr "E662: Ag tosach liosta na n-athruithe"
-#: ../normal.c:5901
msgid "E663: At end of changelist"
msgstr "E663: Ag deireadh liosta na n-athruithe"
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
+msgid "Type :quit<Enter> to exit Vim"
msgstr "Clóscríobh :quit<Enter> chun Vim a scor"
# ouch - English -ed ?
-#: ../ops.c:248
#, c-format
msgid "1 line %sed 1 time"
msgstr "1 líne %s uair amháin"
# ouch - English -ed ?
-#: ../ops.c:250
#, c-format
msgid "1 line %sed %d times"
msgstr "1 líne %s %d uair"
# ouch - English -ed ?
-#: ../ops.c:253
#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> líne %sed uair amháin"
+msgid "%ld lines %sed 1 time"
+msgstr "%ld líne %sed uair amháin"
# ouch - English -ed ?
-#: ../ops.c:256
#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> líne %sed %d uair"
+msgid "%ld lines %sed %d times"
+msgstr "%ld líne %sed %d uair"
-#: ../ops.c:592
#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "%<PRId64> líne le heangú... "
+msgid "%ld lines to indent... "
+msgstr "%ld líne le heangú... "
-#: ../ops.c:634
msgid "1 line indented "
msgstr "eangaíodh líne amháin "
-#: ../ops.c:636
#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "%<PRId64> líne eangaithe "
+msgid "%ld lines indented "
+msgstr "%ld líne eangaithe "
-#: ../ops.c:938
msgid "E748: No previously used register"
msgstr "E748: Níl aon tabhall úsáidte roimhe seo"
#. must display the prompt
-#: ../ops.c:1433
msgid "cannot yank; delete anyway"
msgstr "ní féidir a sracadh; scrios mar sin féin"
-#: ../ops.c:1929
msgid "1 line changed"
msgstr "athraíodh líne amháin"
-#: ../ops.c:1931
#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "athraíodh %<PRId64> líne"
+msgid "%ld lines changed"
+msgstr "athraíodh %ld líne"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "%ld líne á saoradh"
-#: ../ops.c:2521
msgid "block of 1 line yanked"
msgstr "sracadh bloc de líne amháin"
-#: ../ops.c:2523
msgid "1 line yanked"
msgstr "sracadh líne amháin"
-#: ../ops.c:2525
#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "sracadh bloc de %<PRId64> líne"
+msgid "block of %ld lines yanked"
+msgstr "sracadh bloc de %ld líne"
-#: ../ops.c:2528
#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "%<PRId64> líne sractha"
+msgid "%ld lines yanked"
+msgstr "%ld líne sractha"
-#: ../ops.c:2710
#, c-format
msgid "E353: Nothing in register %s"
msgstr "E353: Tabhall folamh %s"
#. Highlight title
-#: ../ops.c:3185
msgid ""
"\n"
"--- Registers ---"
@@ -4519,11 +4200,9 @@ msgstr ""
"\n"
"--- Tabhaill ---"
-#: ../ops.c:4455
msgid "Illegal register name"
msgstr "Ainm neamhcheadaithe tabhaill"
-#: ../ops.c:4533
msgid ""
"\n"
"# Registers:\n"
@@ -4531,185 +4210,175 @@ msgstr ""
"\n"
"# Tabhaill:\n"
-#: ../ops.c:4575
#, c-format
msgid "E574: Unknown register type %d"
msgstr "E574: Cineál anaithnid tabhaill %d"
-#: ../ops.c:5089
+msgid ""
+"E883: search pattern and expression register may not contain two or more "
+"lines"
+msgstr ""
+"E883: ní cheadaítear níos mó ná líne amháin i bpatrún cuardaigh ná sa "
+"slonntabhall"
+
#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> Colún; "
+msgid "%ld Cols; "
+msgstr "%ld Colún; "
-#: ../ops.c:5097
#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Roghnaíodh %s%<PRId64> as %<PRId64> Líne; %<PRId64> as %<PRId64> Focal; "
-"%<PRId64> as %<PRId64> Beart"
+msgid "Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes"
+msgstr "Roghnaíodh %s%ld as %ld Líne; %lld as %lld Focal; %lld as %lld Beart"
-#: ../ops.c:5105
#, c-format
msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
+"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of "
+"%lld Bytes"
msgstr ""
-"Roghnaíodh %s%<PRId64> as %<PRId64> Líne; %<PRId64> as %<PRId64> Focal; "
-"%<PRId64> as %<PRId64> Carachtar; %<PRId64> as %<PRId64> Beart"
+"Roghnaíodh %s%ld as %ld Líne; %lld as %lld Focal; %lld as %lld Carachtar; %lld as %lld Beart"
-#: ../ops.c:5123
#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
-msgstr ""
-"Col %s as %s; Líne %<PRId64> as %<PRId64>; Focal %<PRId64> as %<PRId64>; "
-"Beart %<PRId64> as %<PRId64>"
+msgid "Col %s of %s; Line %ld of %ld; Word %lld of %lld; Byte %lld of %lld"
+msgstr "Col %s as %s; Líne %ld as %ld; Focal %lld as %lld; Beart %lld as %lld"
-#: ../ops.c:5133
#, c-format
msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
+"Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte "
+"%lld of %lld"
msgstr ""
-"Col %s as %s; Líne %<PRId64> as %<PRId64>; Focal %<PRId64> as %<PRId64>; "
-"Carachtar %<PRId64> as %<PRId64>; Beart %<PRId64> as %<PRId64>"
+"Col %s as %s; Líne %ld as %ld; Focal %lld as %lld; Carachtar %lld as %lld; Beart %lld as %lld"
-#: ../ops.c:5146
#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> do BOM)"
+msgid "(+%ld for BOM)"
+msgstr "(+%ld do BOM)"
-#: ../option.c:1238
msgid "%<%f%h%m%=Page %N"
msgstr "%<%f%h%m%=Leathanach %N"
-#: ../option.c:1574
msgid "Thanks for flying Vim"
msgstr "Go raibh míle maith agat as Vim a úsáid"
-#. found a mismatch: skip
-#: ../option.c:2698
msgid "E518: Unknown option"
msgstr "E518: Rogha anaithnid"
-#: ../option.c:2709
msgid "E519: Option not supported"
msgstr "E519: Níl an rogha seo ar fáil"
-#: ../option.c:2740
msgid "E520: Not allowed in a modeline"
msgstr "E520: Ní cheadaithe i módlíne"
-#: ../option.c:2815
msgid "E846: Key code not set"
-msgstr ""
+msgstr "E846: Cód eochrach gan socrú"
-#: ../option.c:2924
msgid "E521: Number required after ="
msgstr "E521: Tá gá le huimhir i ndiaidh ="
-#: ../option.c:3226 ../option.c:3864
msgid "E522: Not found in termcap"
msgstr "E522: Gan aimsiú sa termcap"
-#: ../option.c:3335
#, c-format
msgid "E539: Illegal character <%s>"
msgstr "E539: Carachtar neamhcheadaithe <%s>"
-#: ../option.c:3862
+#, c-format
+msgid "For option %s"
+msgstr "Le haghaidh rogha %s"
+
msgid "E529: Cannot set 'term' to empty string"
msgstr "E529: Ní féidir 'term' a shocrú mar theaghrán folamh"
-#: ../option.c:3885
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: Ní féidir 'term' a athrú sa GUI"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Úsáid \":gui\" chun an GUI a chur ag obair"
+
msgid "E589: 'backupext' and 'patchmode' are equal"
msgstr "E589: is ionann iad 'backupext' agus 'patchmode'"
-#: ../option.c:3964
msgid "E834: Conflicts with value of 'listchars'"
-msgstr ""
+msgstr "E834: Tagann sé salach ar luach de 'listchars'"
-#: ../option.c:3966
msgid "E835: Conflicts with value of 'fillchars'"
-msgstr ""
+msgstr "E835: Tagann sé salach ar luach de 'fillchars'"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Ní féidir é a athrú sa GUI GTK+ 2"
-#: ../option.c:4163
msgid "E524: Missing colon"
msgstr "E524: Idirstad ar iarraidh"
-#: ../option.c:4165
msgid "E525: Zero length string"
msgstr "E525: Teaghrán folamh"
-#: ../option.c:4220
#, c-format
msgid "E526: Missing number after <%s>"
msgstr "E526: Uimhir ar iarraidh i ndiaidh <%s>"
-#: ../option.c:4232
msgid "E527: Missing comma"
msgstr "E527: Camóg ar iarraidh"
-#: ../option.c:4239
msgid "E528: Must specify a ' value"
msgstr "E528: Caithfidh luach ' a shonrú"
-#: ../option.c:4271
msgid "E595: contains unprintable or wide character"
msgstr "E595: tá carachtar neamhghrafach nó leathan ann"
-#: ../option.c:4469
+msgid "E596: Invalid font(s)"
+msgstr "E596: Cló(nna) neamhbhailí"
+
+msgid "E597: can't select fontset"
+msgstr "E597: ní féidir tacar cló a roghnú"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Tacar cló neamhbhailí"
+
+msgid "E533: can't select wide font"
+msgstr "E533: ní féidir cló leathan a roghnú"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Cló leathan neamhbhailí"
+
#, c-format
msgid "E535: Illegal character after <%c>"
msgstr "E535: Carachtar neamhbhailí i ndiaidh <%c>"
-#: ../option.c:4534
msgid "E536: comma required"
msgstr "E536: tá gá le camóg"
-#: ../option.c:4543
#, c-format
msgid "E537: 'commentstring' must be empty or contain %s"
msgstr ""
"E537: ní mór %s a bheith i 'commentstring', is é sin nó ní mór dó a bheith "
"folamh"
-#: ../option.c:4928
+msgid "E538: No mouse support"
+msgstr "E538: Gan tacaíocht luiche"
+
msgid "E540: Unclosed expression sequence"
msgstr "E540: Seicheamh gan dúnadh"
-#: ../option.c:4932
msgid "E541: too many items"
msgstr "E541: an iomarca míreanna"
-#: ../option.c:4934
msgid "E542: unbalanced groups"
msgstr "E542: grúpaí neamhchothromaithe"
-#: ../option.c:5148
msgid "E590: A preview window already exists"
msgstr "E590: Tá fuinneog réamhamhairc ann cheana"
-#: ../option.c:5311
msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
msgstr ""
"W17: Tá UTF-8 ag teastáil le haghaidh Araibise, socraigh é le ':set "
"encoding=utf-8'"
-#: ../option.c:5623
#, c-format
msgid "E593: Need at least %d lines"
msgstr "E593: Tá gá le %d líne ar a laghad"
-#: ../option.c:5631
#, c-format
msgid "E594: Need at least %d columns"
msgstr "E594: Tá gá le %d colún ar a laghad"
-#: ../option.c:6011
#, c-format
msgid "E355: Unknown option: %s"
msgstr "E355: Rogha anaithnid: %s"
@@ -4717,12 +4386,10 @@ msgstr "E355: Rogha anaithnid: %s"
#. There's another character after zeros or the string
#. * is empty. In both cases, we are trying to set a
#. * num option using a string.
-#: ../option.c:6037
#, c-format
msgid "E521: Number required: &%s = '%s'"
msgstr "E521: Uimhir de dhíth: &%s = '%s'"
-#: ../option.c:6149
msgid ""
"\n"
"--- Terminal codes ---"
@@ -4730,7 +4397,6 @@ msgstr ""
"\n"
"--- Cóid teirminéil ---"
-#: ../option.c:6151
msgid ""
"\n"
"--- Global option values ---"
@@ -4738,7 +4404,6 @@ msgstr ""
"\n"
"--- Luachanna na roghanna comhchoiteann ---"
-#: ../option.c:6153
msgid ""
"\n"
"--- Local option values ---"
@@ -4746,7 +4411,6 @@ msgstr ""
"\n"
"--- Luachanna na roghanna logánta ---"
-#: ../option.c:6155
msgid ""
"\n"
"--- Options ---"
@@ -4754,29 +4418,148 @@ msgstr ""
"\n"
"--- Roghanna ---"
-#: ../option.c:6816
msgid "E356: get_varp ERROR"
msgstr "E356: EARRÁID get_varp"
-#: ../option.c:7696
#, c-format
msgid "E357: 'langmap': Matching character missing for %s"
msgstr "E357: 'langmap': Carachtar comhoiriúnach ar iarraidh le haghaidh %s"
-#: ../option.c:7715
#, c-format
msgid "E358: 'langmap': Extra characters after semicolon: %s"
msgstr "E358: 'langmap': Carachtair breise i ndiaidh an idirstad: %s"
-#: ../os/shell.c:194
+msgid "cannot open "
+msgstr "ní féidir a oscailt: "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Ní féidir fuinneog a oscailt!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Tá gá le Amigados leagan 2.04 nó níos déanaí\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Tá gá le %s, leagan %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Ní féidir NIL a oscailt:\n"
+
+msgid "Cannot create "
+msgstr "Ní féidir a chruthú: "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim á scor le stádas %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "ní féidir mód consóil a athrú ?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: ní consól é seo??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Ní féidir blaosc a rith le rogha -f"
+
+msgid "Cannot execute "
+msgstr "Ní féidir blaosc a rith: "
+
+msgid "shell "
+msgstr "blaosc "
+
+msgid " returned\n"
+msgstr " aisfhilleadh\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE róbheag."
+
+msgid "I/O ERROR"
+msgstr "EARRÁID I/A"
+
+msgid "Message"
+msgstr "Teachtaireacht"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Theip ar roghnú printéara"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "go %s ar %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Clófhoireann anaithnid printéara: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Earráid phriontála: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "'%s' á phriontáil"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr ""
+"E244: Ainm neamhcheadaithe ar thacar carachtar \"%s\" mar pháirt d'ainm cló "
+"\"%s\""
+
+#, c-format
+msgid "E244: Illegal quality name \"%s\" in font name \"%s\""
+msgstr ""
+"E244: Ainm neamhcheadaithe ar cháilíocht \"%s\" in ainm cló \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Carachtar neamhcheadaithe '%c' mar pháirt d'ainm cló \"%s\""
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Thóg %ld ms chun an scáileán X a oscailt"
+
msgid ""
"\n"
-"Cannot execute shell "
+"Vim: Got X error\n"
msgstr ""
"\n"
-"Ní féidir blaosc a rith "
+"Vim: Fuarthas earráid ó X\n"
+
+msgid "Testing the X display failed"
+msgstr "Theip ar thástáil an scáileáin X"
+
+msgid "Opening the X display timed out"
+msgstr "Oscailt an scáileáin X thar am"
+
+msgid ""
+"\n"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Níorbh fhéidir comhthéacs slándála a fháil le haghaidh "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Níorbh fhéidir comhthéacs slándála a shocrú le haghaidh "
+
+#, c-format
+msgid "Could not set security context %s for %s"
+msgstr "Níorbh fhéidir comhthéacs slándála %s a shocrú le haghaidh %s"
+
+#, c-format
+msgid "Could not get security context %s for %s. Removing it!"
+msgstr "Níorbh fhéidir comhthéacs slándála %s a fháil le haghaidh %s. Á bhaint!"
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Ní féidir an bhlaosc sh a rith\n"
-#: ../os/shell.c:439
msgid ""
"\n"
"shell returned "
@@ -4784,472 +4567,476 @@ msgstr ""
"\n"
"d'aisfhill an bhlaosc "
-#: ../os_unix.c:465 ../os_unix.c:471
msgid ""
"\n"
-"Could not get security context for "
+"Cannot create pipes\n"
msgstr ""
"\n"
-"Níorbh fhéidir comhthéacs slándála a fháil le haghaidh "
+"Ní féidir píopaí a chruthú\n"
-#: ../os_unix.c:479
+# "fork" not in standard refs/corpus. Maybe want a "gabhl*" word instead? -KPS
msgid ""
"\n"
-"Could not set security context for "
+"Cannot fork\n"
msgstr ""
"\n"
-"Níorbh fhéidir comhthéacs slándála a shocrú le haghaidh "
+"Ní féidir forc a dhéanamh\n"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Ní féidir blaosc a rith "
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Ordú críochnaithe\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "Chaill XSMP an nasc ICE"
-#: ../os_unix.c:1558 ../os_unix.c:1647
#, c-format
msgid "dlerror = \"%s\""
msgstr "dlerror = \"%s\""
-#: ../path.c:1449
+msgid "Opening the X display failed"
+msgstr "Theip ar oscailt an scáileáin X"
+
+msgid "XSMP handling save-yourself request"
+msgstr "Iarratas sábháil-do-féin á láimhseáil ag XSMP"
+
+msgid "XSMP opening connection"
+msgstr "Nasc á oscailt ag XSMP"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "Theip ar fhaire nasc ICE XSMP"
+
#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: Níl aon fháil ar chomhad \"%s\" sa chonair"
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "Theip ar XSMP SmcOpenConnection: %s"
+
+msgid "At line"
+msgstr "Ag líne"
+
+msgid "Could not load vim32.dll!"
+msgstr "Níorbh fhéidir vim32.dll a luchtú!"
+
+msgid "VIM Error"
+msgstr "Earráid VIM"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Níorbh fhéidir pointeoirí feidhme a chóiriú i gcomhair an DLL!"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Fuarthas teagmhas %s\n"
+
+msgid "close"
+msgstr "dún"
+
+msgid "logoff"
+msgstr "logáil amach"
+
+msgid "shutdown"
+msgstr "múchadh"
+
+msgid "E371: Command not found"
+msgstr "E371: Ní bhfuarthas an t-ordú"
+
+msgid ""
+"VIMRUN.EXE not found in your $PATH.\n"
+"External commands will not pause after completion.\n"
+"See :help win32-vimrun for more information."
+msgstr ""
+"Níor aimsíodh VIMRUN.EXE i do $PATH.\n"
+"Ní mhoilleoidh orduithe seachtracha agus iad curtha i gcrích.\n"
+"Féach ar :help win32-vimrun chun níos mó eolas a fháil."
+
+msgid "Vim Warning"
+msgstr "Rabhadh Vim"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "d'aisfhill an bhlaosc %d"
-#: ../quickfix.c:359
#, c-format
msgid "E372: Too many %%%c in format string"
msgstr "E372: An iomarca %%%c i dteaghrán formáide"
-#: ../quickfix.c:371
#, c-format
msgid "E373: Unexpected %%%c in format string"
msgstr "E373: %%%c gan choinne i dteaghrán formáide"
-#: ../quickfix.c:420
msgid "E374: Missing ] in format string"
msgstr "E374: ] ar iarraidh i dteaghrán formáide"
-#: ../quickfix.c:431
#, c-format
msgid "E375: Unsupported %%%c in format string"
msgstr "E375: %%%c gan tacaíocht i dteaghrán formáide"
-#: ../quickfix.c:448
#, c-format
msgid "E376: Invalid %%%c in format string prefix"
msgstr "E376: %%%c neamhbhailí i réimír an teaghráin formáide"
-#: ../quickfix.c:454
#, c-format
msgid "E377: Invalid %%%c in format string"
msgstr "E377: %%%c neamhbhailí i dteaghrán formáide"
#. nothing found
-#: ../quickfix.c:477
msgid "E378: 'errorformat' contains no pattern"
msgstr "E378: Níl aon phatrún i 'errorformat'"
-#: ../quickfix.c:695
msgid "E379: Missing or empty directory name"
msgstr "E379: Ainm comhadlainne ar iarraidh, nó folamh"
-#: ../quickfix.c:1305
msgid "E553: No more items"
msgstr "E553: Níl aon mhír eile"
-#: ../quickfix.c:1674
+msgid "E924: Current window was closed"
+msgstr "E924: Dúnadh an fhuinneog reatha"
+
+msgid "E925: Current quickfix was changed"
+msgstr "E925: Athraíodh an mearcheartúchán reatha"
+
+msgid "E926: Current location list was changed"
+msgstr "E926: Athraíodh an liosta suíomh reatha"
+
#, c-format
msgid "(%d of %d)%s%s: "
msgstr "(%d as %d)%s%s: "
-#: ../quickfix.c:1676
msgid " (line deleted)"
msgstr " (líne scriosta)"
-#: ../quickfix.c:1863
+#, c-format
+msgid "%serror list %d of %d; %d errors "
+msgstr "%sliosta earráidí %d as %d; %d earráid "
+
msgid "E380: At bottom of quickfix stack"
-msgstr "E380: In íochtar na cruaiche quickfix"
+msgstr "E380: In íochtar chruach na mearcheartúchán"
-#: ../quickfix.c:1869
msgid "E381: At top of quickfix stack"
-msgstr "E381: In uachtar na cruaiche quickfix"
+msgstr "E381: In uachtar chruach na mearcheartúchán"
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "liosta earráidí %d as %d; %d earráid"
+msgid "No entries"
+msgstr "Gan iontráil"
-#: ../quickfix.c:2427
msgid "E382: Cannot write, 'buftype' option is set"
msgstr "E382: Ní féidir scríobh, rogha 'buftype' socraithe"
-#: ../quickfix.c:2812
+msgid "Error file"
+msgstr "Comhad earráide"
+
msgid "E683: File name missing or invalid pattern"
msgstr "E683: Ainm comhaid ar iarraidh, nó patrún neamhbhailí"
-#: ../quickfix.c:2911
#, c-format
msgid "Cannot open file \"%s\""
msgstr "Ní féidir comhad \"%s\" a oscailt"
-#: ../quickfix.c:3429
msgid "E681: Buffer is not loaded"
msgstr "E681: Níl an maolán luchtaithe"
-#: ../quickfix.c:3487
msgid "E777: String or List expected"
msgstr "E777: Bhíothas ag súil le Teaghrán nó Liosta"
-#: ../regexp.c:359
#, c-format
msgid "E369: invalid item in %s%%[]"
msgstr "E369: mír neamhbhailí i %s%%[]"
-#: ../regexp.c:374
#, c-format
msgid "E769: Missing ] after %s["
msgstr "E769: ] ar iarraidh i ndiaidh %s["
-#: ../regexp.c:375
#, c-format
msgid "E53: Unmatched %s%%("
msgstr "E53: %s%%( corr"
-#: ../regexp.c:376
#, c-format
msgid "E54: Unmatched %s("
msgstr "E54: %s( corr"
-#: ../regexp.c:377
#, c-format
msgid "E55: Unmatched %s)"
msgstr "E55: %s) corr"
-#: ../regexp.c:378
msgid "E66: \\z( not allowed here"
msgstr "E66: ní cheadaítear \\z( anseo"
-#: ../regexp.c:379
msgid "E67: \\z1 et al. not allowed here"
msgstr "E67: ní cheadaítear \\z1 et al. anseo"
-#: ../regexp.c:380
#, c-format
msgid "E69: Missing ] after %s%%["
msgstr "E69: ] ar iarraidh i ndiaidh %s%%["
-#: ../regexp.c:381
#, c-format
msgid "E70: Empty %s%%[]"
msgstr "E70: %s%%[] folamh"
-#: ../regexp.c:1209 ../regexp.c:1224
msgid "E339: Pattern too long"
msgstr "E339: Slonn rófhada"
-#: ../regexp.c:1371
msgid "E50: Too many \\z("
msgstr "E50: an iomarca \\z("
-#: ../regexp.c:1378
#, c-format
msgid "E51: Too many %s("
msgstr "E51: an iomarca %s("
-#: ../regexp.c:1427
msgid "E52: Unmatched \\z("
msgstr "E52: \\z( corr"
-#: ../regexp.c:1637
#, c-format
msgid "E59: invalid character after %s@"
msgstr "E59: carachtar neamhbhailí i ndiaidh %s@"
-#: ../regexp.c:1672
#, c-format
msgid "E60: Too many complex %s{...}s"
msgstr "E60: An iomarca %s{...} coimpléascach"
-#: ../regexp.c:1687
#, c-format
msgid "E61: Nested %s*"
msgstr "E61: %s* neadaithe"
-#: ../regexp.c:1690
#, c-format
msgid "E62: Nested %s%c"
msgstr "E62: %s%c neadaithe"
-#: ../regexp.c:1800
msgid "E63: invalid use of \\_"
msgstr "E63: úsáid neamhbhailí de \\_"
-#: ../regexp.c:1850
#, c-format
msgid "E64: %s%c follows nothing"
msgstr "E64: níl aon rud roimh %s%c"
-#: ../regexp.c:1902
msgid "E65: Illegal back reference"
msgstr "E65: Cúltagairt neamhbhailí"
-#: ../regexp.c:1943
msgid "E68: Invalid character after \\z"
msgstr "E68: Carachtar neamhbhailí i ndiaidh \\z"
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
#, c-format
msgid "E678: Invalid character after %s%%[dxouU]"
msgstr "E678: Carachtar neamhbhailí i ndiaidh %s%%[dxouU]"
-#: ../regexp.c:2107
#, c-format
msgid "E71: Invalid character after %s%%"
msgstr "E71: Carachtar neamhbhailí i ndiaidh %s%%"
-#: ../regexp.c:3017
#, c-format
msgid "E554: Syntax error in %s{...}"
msgstr "E554: Earráid chomhréire i %s{...}"
-#: ../regexp.c:3805
msgid "External submatches:\n"
msgstr "Fo-mheaitseáil sheachtrach:\n"
-#: ../regexp.c:7022
+#, c-format
+msgid "E888: (NFA regexp) cannot repeat %s"
+msgstr "E888: (slonn NFA) ní féidir %s a athdhéanamh"
+
msgid ""
"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
"used "
msgstr ""
+"E864: Ní cheadaítear ach 0, 1, nó 2 tar éis \\%#=. Úsáidfear an t-inneall "
+"uathoibríoch "
-#: ../regexp_nfa.c:239
-msgid "E865: (NFA) Regexp end encountered prematurely"
+msgid "Switching to backtracking RE engine for pattern: "
msgstr ""
+"Ag athrú go dtí an t-inneall rianaithe siar le haghaidh an phatrúin seo: "
+
+msgid "E865: (NFA) Regexp end encountered prematurely"
+msgstr "E865: (NFA) Thángthas ar dheireadh an tsloinn gan súil leis"
-#: ../regexp_nfa.c:240
#, c-format
msgid "E866: (NFA regexp) Misplaced %c"
-msgstr ""
+msgstr "E866: (slonn NFA) %c as áit"
-#: ../regexp_nfa.c:242
#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr ""
+msgid "E877: (NFA regexp) Invalid character class: %ld"
+msgstr "E877: (slonn NFA) Aicme carachtar neamhbhailí: %ld"
-#: ../regexp_nfa.c:1261
#, c-format
msgid "E867: (NFA) Unknown operator '\\z%c'"
-msgstr ""
+msgstr "E867: (NFA) Oibreoir anaithnid '\\z%c'"
-#: ../regexp_nfa.c:1387
#, c-format
msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr ""
+msgstr "E867: (NFA) Oibreoir anaithnid '\\%%%c'"
+
+#. should never happen
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: Earráid agus NFA á thógáil le haicme coibhéise!"
-#: ../regexp_nfa.c:1802
#, c-format
msgid "E869: (NFA) Unknown operator '\\@%c'"
-msgstr ""
+msgstr "E869: (NFA) Oibreoir anaithnid '\\@%c'"
-#: ../regexp_nfa.c:1831
msgid "E870: (NFA regexp) Error reading repetition limits"
-msgstr ""
+msgstr "E870: (slonn NFA) Earráid agus teorainneacha athdhéanta á léamh"
#. Can't have a multi follow a multi.
-#: ../regexp_nfa.c:1895
msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
-msgstr ""
+msgstr "E871: (slonn NFA) Ní cheadaítear ilchodach tar éis ilchodach!"
#. Too many `('
-#: ../regexp_nfa.c:2037
msgid "E872: (NFA regexp) Too many '('"
-msgstr ""
+msgstr "E872: (slonn NFA) An iomarca '('"
-#: ../regexp_nfa.c:2042
-#, fuzzy
msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E50: an iomarca \\z("
+msgstr "E879: (slonn NFA) An iomarca \\z("
-#: ../regexp_nfa.c:2066
msgid "E873: (NFA regexp) proper termination error"
-msgstr ""
+msgstr "E873: (slonn NFA) críochnú neamhoiriúnach"
-#: ../regexp_nfa.c:2599
msgid "E874: (NFA) Could not pop the stack !"
-msgstr ""
+msgstr "E874: (NFA) Níorbh fhéidir an chruach a phlobadh!"
-#: ../regexp_nfa.c:3298
msgid ""
"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
"left on stack"
msgstr ""
+"E875: (slonn NFA) (Le linn tiontaithe ó postfix go NFA), an iomarca "
+"staideanna fágtha ar an gcruach"
-#: ../regexp_nfa.c:3302
msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
+msgstr "E876: (slonn NFA) Níl go leor spáis ann don NFA iomlán "
+
+msgid "E878: (NFA) Could not allocate memory for branch traversal!"
msgstr ""
+"E878: (NFA) Níorbh fhéidir cuimhne a leithdháileadh leis an gcraobh a "
+"thrasnaíl!"
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
msgid ""
"Could not open temporary log file for writing, displaying on stderr ... "
msgstr ""
+"Níorbh fhéidir logchomhad sealadach a oscailt le scríobh ann, á thaispeáint "
+"ar stderr..."
-#: ../regexp_nfa.c:4840
#, c-format
msgid "(NFA) COULD NOT OPEN %s !"
-msgstr ""
+msgstr "(NFA) NÍORBH FHÉIDIR %s A OSCAILT!"
-#: ../regexp_nfa.c:6049
-#, fuzzy
msgid "Could not open temporary log file for writing "
-msgstr "E214: Ní féidir comhad sealadach a aimsiú chun scríobh ann"
+msgstr "Níorbh fhéidir logchomhad sealadach a oscailt le scríobh ann "
-#: ../screen.c:7435
msgid " VREPLACE"
msgstr " V-IONADAIGH"
-#: ../screen.c:7437
msgid " REPLACE"
msgstr " ATHCHUR"
-#: ../screen.c:7440
msgid " REVERSE"
msgstr " TIONTÚ"
-#: ../screen.c:7441
msgid " INSERT"
msgstr " IONSÁ"
-#: ../screen.c:7443
msgid " (insert)"
msgstr " (ionsáigh)"
-#: ../screen.c:7445
msgid " (replace)"
msgstr " (ionadaigh)"
-#: ../screen.c:7447
msgid " (vreplace)"
msgstr " (v-ionadaigh)"
-#: ../screen.c:7449
msgid " Hebrew"
msgstr " Eabhrais"
-#: ../screen.c:7454
msgid " Arabic"
msgstr " Araibis"
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (teanga)"
-
-#: ../screen.c:7459
msgid " (paste)"
msgstr " (greamaigh)"
-#: ../screen.c:7469
msgid " VISUAL"
msgstr " RADHARCACH"
-#: ../screen.c:7470
msgid " VISUAL LINE"
msgstr " LÍNE RADHARCACH"
-#: ../screen.c:7471
msgid " VISUAL BLOCK"
msgstr " BLOC RADHARCACH"
-#: ../screen.c:7472
msgid " SELECT"
msgstr " ROGHNÚ"
-#: ../screen.c:7473
msgid " SELECT LINE"
msgstr " SELECT LINE"
-#: ../screen.c:7474
msgid " SELECT BLOCK"
msgstr " SELECT BLOCK"
-#: ../screen.c:7486 ../screen.c:7541
msgid "recording"
msgstr "á thaifeadadh"
-#: ../search.c:487
#, c-format
msgid "E383: Invalid search string: %s"
msgstr "E383: Teaghrán cuardaigh neamhbhailí: %s"
-#: ../search.c:832
#, c-format
msgid "E384: search hit TOP without match for: %s"
msgstr "E384: bhuail an cuardach an BARR gan teaghrán comhoiriúnach le %s"
-#: ../search.c:835
#, c-format
msgid "E385: search hit BOTTOM without match for: %s"
msgstr "E385: bhuail an cuardach an BUN gan teaghrán comhoiriúnach le %s"
-#: ../search.c:1200
msgid "E386: Expected '?' or '/' after ';'"
msgstr "E386: Ag súil le '?' nó '/' i ndiaidh ';'"
-#: ../search.c:4085
msgid " (includes previously listed match)"
msgstr " (tá an teaghrán comhoiriúnaithe roimhe seo san áireamh)"
#. cursor at status line
-#: ../search.c:4104
msgid "--- Included files "
msgstr "--- Comhaid cheanntáisc "
-#: ../search.c:4106
msgid "not found "
msgstr "gan aimsiú"
-#: ../search.c:4107
msgid "in path ---\n"
msgstr "i gconair ---\n"
-#: ../search.c:4168
msgid " (Already listed)"
msgstr " (Liostaithe cheana féin)"
-#: ../search.c:4170
msgid " NOT FOUND"
msgstr " AR IARRAIDH"
-#: ../search.c:4211
#, c-format
msgid "Scanning included file: %s"
msgstr "Comhad ceanntáisc á scanadh: %s"
-#: ../search.c:4216
#, c-format
msgid "Searching included file %s"
msgstr "Comhad ceanntáisc %s á chuardach"
-#: ../search.c:4405
msgid "E387: Match is on current line"
msgstr "E387: Tá an teaghrán comhoiriúnaithe ar an líne reatha"
-#: ../search.c:4517
msgid "All included files were found"
msgstr "Aimsíodh gach comhad ceanntáisc"
-#: ../search.c:4519
msgid "No included files"
msgstr "Gan comhaid cheanntáisc"
-#: ../search.c:4527
msgid "E388: Couldn't find definition"
msgstr "E388: Sainmhíniú gan aimsiú"
-#: ../search.c:4529
msgid "E389: Couldn't find pattern"
msgstr "E389: Patrún gan aimsiú"
-#: ../search.c:4668
msgid "Substitute "
msgstr "Ionadú "
# in .viminfo
-#: ../search.c:4681
#, c-format
msgid ""
"\n"
@@ -5260,98 +5047,130 @@ msgstr ""
"# %sPatrún Cuardaigh Is Déanaí:\n"
"~"
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: Earráid fhormáide i gcomhad litrithe"
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Níl seiceáil litrithe cumasaithe"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
+msgstr ""
+"Rabhadh: Ní féidir liosta focal \"%s_%s.spl\" nó \"%s_ascii.spl\" a aimsiú"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr ""
+"Rabhadh: Ní féidir liosta focal \"%s.%s.spl\" nó \"%s.ascii.spl\" a aimsiú"
+
+msgid "E797: SpellFileMissing autocommand deleted buffer"
+msgstr "E797: Scrios uathordú SpellFileMissing an maolán"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Rabhadh: réigiún %s gan tacaíocht"
+
+msgid "Sorry, no suggestions"
+msgstr "Tá brón orm, níl aon mholadh ann"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Tá brón orm, níl ach %ld moladh ann"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Athraigh \"%.*s\" go:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Níl aon ionadaí litrithe roimhe seo"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Gan aimsiú: %s"
-#: ../spell.c:952
msgid "E758: Truncated spell file"
msgstr "E758: Comhad teasctha litrithe"
-#: ../spell.c:953
#, c-format
msgid "Trailing text in %s line %d: %s"
msgstr "Téacs chun deiridh i %s líne %d: %s"
-#: ../spell.c:954
#, c-format
msgid "Affix name too long in %s line %d: %s"
msgstr "Ainm foircinn rófhada i %s líne %d: %s"
-#: ../spell.c:955
msgid "E761: Format error in affix file FOL, LOW or UPP"
msgstr "E761: Earráid fhormáide i gcomhad foircinn FOL, LOW, nó UPP"
-#: ../spell.c:957
msgid "E762: Character in FOL, LOW or UPP is out of range"
msgstr "E762: Carachtar i FOL, LOW nó UPP as raon"
-#: ../spell.c:958
msgid "Compressing word tree..."
msgstr "Crann focal á chomhbhrú..."
-#: ../spell.c:1951
-msgid "E756: Spell checking is not enabled"
-msgstr "E756: Níl seiceáil litrithe cumasaithe"
-
-#: ../spell.c:2249
-#, c-format
-msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
-msgstr ""
-"Rabhadh: Ní féidir liosta focal \"%s.%s.spl\" nó \"%s.ascii.spl\" a aimsiú"
-
-#: ../spell.c:2473
#, c-format
msgid "Reading spell file \"%s\""
msgstr "Comhad litrithe \"%s\" á léamh"
-#: ../spell.c:2496
msgid "E757: This does not look like a spell file"
msgstr "E757: Níl sé cosúil le comhad litrithe"
-#: ../spell.c:2501
msgid "E771: Old spell file, needs to be updated"
msgstr "E771: Seanchomhad litrithe, tá gá lena nuashonrú"
-#: ../spell.c:2504
msgid "E772: Spell file is for newer version of Vim"
msgstr "E772: Oibríonn an comhad litrithe le leagan níos nuaí de Vim"
-#: ../spell.c:2602
msgid "E770: Unsupported section in spell file"
msgstr "E770: Rannán gan tacaíocht i gcomhad litrithe"
-#: ../spell.c:3762
#, c-format
-msgid "Warning: region %s not supported"
-msgstr "Rabhadh: réigiún %s gan tacaíocht"
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Níl sé cosúil le comhad .sug: %s"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Seanchomhad .sug, tá gá lena nuashonrú: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: Oibríonn an comhad .sug le leagan níos nuaí de Vim: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: Níl an comhad .sug comhoiriúnach leis an gcomhad .spl: %s"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: earráid agus comhad .sug á léamh: %s"
-#: ../spell.c:4550
#, c-format
msgid "Reading affix file %s ..."
msgstr "Comhad foircinn %s á léamh..."
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
msgid "Conversion failure for word in %s line %d: %s"
msgstr "Theip ar thiontú focail i %s líne %d: %s"
-#: ../spell.c:4630 ../spell.c:6170
#, c-format
msgid "Conversion in %s not supported: from %s to %s"
msgstr "Tiontú i %s gan tacaíocht: ó %s go %s"
-#: ../spell.c:4642
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Tiontú i %s gan tacaíocht"
+
#, c-format
msgid "Invalid value for FLAG in %s line %d: %s"
msgstr "Luach neamhbhailí ar FLAG i %s líne %d: %s"
-#: ../spell.c:4655
#, c-format
msgid "FLAG after using flags in %s line %d: %s"
msgstr "FLAG i ndiaidh bratacha in úsáid i %s líne %d: %s"
-#: ../spell.c:4723
#, c-format
msgid ""
"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
@@ -5360,7 +5179,6 @@ msgstr ""
"Seans go bhfaighfidh tú torthaí míchearta má chuireann tú COMPOUNDFORBIDFLAG "
"tar éis míre PFX i %s líne %d"
-#: ../spell.c:4731
#, c-format
msgid ""
"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
@@ -5369,42 +5187,34 @@ msgstr ""
"Seans go bhfaighfidh tú torthaí míchearta má chuireann tú COMPOUNDPERMITFLAG "
"tar éis míre PFX i %s líne %d"
-#: ../spell.c:4747
#, c-format
msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
msgstr "Luach mícheart ar COMPOUNDRULES i %s líne %d: %s"
-#: ../spell.c:4771
#, c-format
msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
msgstr "Luach mícheart ar COMPOUNDWORDMAX i %s líne %d: %s"
-#: ../spell.c:4777
#, c-format
msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
msgstr "Luach mícheart ar COMPOUNDMIN i %s líne %d: %s"
-#: ../spell.c:4783
#, c-format
msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
msgstr "Luach mícheart ar COMPOUNDSYLMAX i %s líne %d: %s"
-#: ../spell.c:4795
#, c-format
msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
msgstr "Luach mícheart ar CHECKCOMPOUNDPATTERN i %s líne %d: %s"
-#: ../spell.c:4847
#, c-format
msgid "Different combining flag in continued affix block in %s line %d: %s"
msgstr "Bratach dhifriúil cheangail i mbloc leanta foircinn i %s líne %d: %s"
-#: ../spell.c:4850
#, c-format
msgid "Duplicate affix in %s line %d: %s"
msgstr "Clib dhúblach i %s líne %d: %s"
-#: ../spell.c:4871
#, c-format
msgid ""
"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
@@ -5413,335 +5223,230 @@ msgstr ""
"Foirceann in úsáid le haghaidh BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/"
"NOSUGGEST freisin i %s líne %d: %s"
-#: ../spell.c:4893
#, c-format
msgid "Expected Y or N in %s line %d: %s"
msgstr "Bhíothas ag súil le `Y' nó `N' i %s líne %d: %s"
-#: ../spell.c:4968
#, c-format
msgid "Broken condition in %s line %d: %s"
msgstr "Coinníoll briste i %s líne %d: %s"
-#: ../spell.c:5091
#, c-format
msgid "Expected REP(SAL) count in %s line %d"
msgstr "Bhíothas ag súil le líon na REP(SAL) i %s líne %d"
-#: ../spell.c:5120
#, c-format
msgid "Expected MAP count in %s line %d"
msgstr "Bhíothas ag súil le líon na MAP i %s líne %d"
-#: ../spell.c:5132
#, c-format
msgid "Duplicate character in MAP in %s line %d"
msgstr "Carachtar dúblach i MAP i %s líne %d"
-#: ../spell.c:5176
#, c-format
msgid "Unrecognized or duplicate item in %s line %d: %s"
msgstr "Mír anaithnid nó dhúblach i %s líne %d: %s"
-#: ../spell.c:5197
#, c-format
msgid "Missing FOL/LOW/UPP line in %s"
msgstr "Líne FOL/LOW/UPP ar iarraidh i %s"
-#: ../spell.c:5220
msgid "COMPOUNDSYLMAX used without SYLLABLE"
msgstr "COMPOUNDSYLMAX in úsáid gan SYLLABLE"
-#: ../spell.c:5236
msgid "Too many postponed prefixes"
msgstr "An iomarca réimíreanna curtha siar"
-#: ../spell.c:5238
msgid "Too many compound flags"
msgstr "An iomarca bratach comhfhocail"
-#: ../spell.c:5240
msgid "Too many postponed prefixes and/or compound flags"
msgstr "An iomarca réimíreanna curtha siar agus/nó bratacha comhfhocal"
-#: ../spell.c:5250
#, c-format
msgid "Missing SOFO%s line in %s"
msgstr "Líne SOFO%s ar iarraidh i %s"
-#: ../spell.c:5253
#, c-format
msgid "Both SAL and SOFO lines in %s"
msgstr "Línte SAL agus SOFO araon i %s"
-#: ../spell.c:5331
#, c-format
msgid "Flag is not a number in %s line %d: %s"
msgstr "Ní uimhir í an bhratach i %s líne %d: %s"
-#: ../spell.c:5334
#, c-format
msgid "Illegal flag in %s line %d: %s"
msgstr "Bratach neamhcheadaithe i %s líne %d: %s"
-#: ../spell.c:5493 ../spell.c:5501
#, c-format
msgid "%s value differs from what is used in another .aff file"
msgstr "Tá difear idir luach %s agus an luach i gcomhad .aff eile"
-#: ../spell.c:5602
#, c-format
msgid "Reading dictionary file %s ..."
msgstr "Foclóir %s á léamh ..."
-#: ../spell.c:5611
#, c-format
msgid "E760: No word count in %s"
msgstr "E760: Líon na bhfocal ar iarraidh i %s"
-#: ../spell.c:5669
#, c-format
msgid "line %6d, word %6d - %s"
msgstr "líne %6d, focal %6d - %s"
-#: ../spell.c:5691
#, c-format
msgid "Duplicate word in %s line %d: %s"
msgstr "Focal dúblach i %s líne %d: %s"
-#: ../spell.c:5694
#, c-format
msgid "First duplicate word in %s line %d: %s"
msgstr "An chéad fhocal dúblach i %s líne %d: %s"
-#: ../spell.c:5746
#, c-format
msgid "%d duplicate word(s) in %s"
msgstr "%d focal dúblach i %s"
-#: ../spell.c:5748
#, c-format
msgid "Ignored %d word(s) with non-ASCII characters in %s"
msgstr "Rinneadh neamhshuim ar %d focal le carachtair neamh-ASCII i %s"
-#: ../spell.c:6115
#, c-format
msgid "Reading word file %s ..."
msgstr "Comhad focail %s á léamh ..."
-#: ../spell.c:6155
#, c-format
msgid "Duplicate /encoding= line ignored in %s line %d: %s"
msgstr "Rinneadh neamhshuim ar líne dhúblach `/encoding=' i %s líne %d: %s"
-#: ../spell.c:6159
#, c-format
msgid "/encoding= line after word ignored in %s line %d: %s"
msgstr ""
"Rinneadh neamhshuim ar líne `/encoding=' i ndiaidh focail i %s líne %d: %s"
-#: ../spell.c:6180
#, c-format
msgid "Duplicate /regions= line ignored in %s line %d: %s"
msgstr "Rinneadh neamhshuim ar líne `/regions=' i %s líne %d: %s"
-#: ../spell.c:6185
#, c-format
msgid "Too many regions in %s line %d: %s"
msgstr "An iomarca réigiún i %s líne %d: %s"
-#: ../spell.c:6198
#, c-format
msgid "/ line ignored in %s line %d: %s"
msgstr "Rinneadh neamhshuim ar líne `/' i %s líne %d: %s"
-#: ../spell.c:6224
#, c-format
msgid "Invalid region nr in %s line %d: %s"
msgstr "Uimhir neamhbhailí réigiúin i %s líne %d: %s"
-#: ../spell.c:6230
#, c-format
msgid "Unrecognized flags in %s line %d: %s"
msgstr "Bratacha anaithnide i %s líne %d: %s"
-#: ../spell.c:6257
#, c-format
msgid "Ignored %d words with non-ASCII characters"
msgstr "Rinneadh neamhshuim ar %d focal le carachtair neamh-ASCII"
-#: ../spell.c:6656
+msgid "E845: Insufficient memory, word list will be incomplete"
+msgstr "E845: Easpa cuimhne, beidh an liosta focal neamhiomlán"
+
#, c-format
msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
msgstr "Comhbhrúdh %d as %d nód; %d (%d%%) fágtha"
-#: ../spell.c:7340
msgid "Reading back spell file..."
msgstr "Comhad litrithe á léamh arís..."
-#. Go through the trie of good words, soundfold each word and add it to
-#. the soundfold trie.
-#: ../spell.c:7357
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
msgid "Performing soundfolding..."
msgstr "Fuaimfhilleadh..."
-#: ../spell.c:7368
#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "Líon na bhfocal tar éis fuaimfhillte: %<PRId64>"
+msgid "Number of words after soundfolding: %ld"
+msgstr "Líon na bhfocal tar éis fuaimfhillte: %ld"
-#: ../spell.c:7476
#, c-format
msgid "Total number of words: %d"
msgstr "Líon iomlán na bhfocal: %d"
-#: ../spell.c:7655
#, c-format
msgid "Writing suggestion file %s ..."
msgstr "Comhad moltaí %s á scríobh ..."
-#: ../spell.c:7707 ../spell.c:7927
#, c-format
msgid "Estimated runtime memory use: %d bytes"
msgstr "Cuimhne measta a bheith in úsáid le linn rite: %d beart"
-#: ../spell.c:7820
msgid "E751: Output file name must not have region name"
msgstr "E751: Ní cheadaítear ainm réigiúin in ainm an aschomhaid"
-#: ../spell.c:7822
msgid "E754: Only up to 8 regions supported"
msgstr "E754: Ní thacaítear le níos mó ná 8 réigiún"
-#: ../spell.c:7846
#, c-format
msgid "E755: Invalid region in %s"
msgstr "E755: Réigiún neamhbhailí i %s"
-#: ../spell.c:7907
msgid "Warning: both compounding and NOBREAK specified"
msgstr "Rabhadh: sonraíodh comhfhocail agus NOBREAK araon"
-#: ../spell.c:7920
#, c-format
msgid "Writing spell file %s ..."
msgstr "Comhad litrithe %s á scríobh ..."
-#: ../spell.c:7925
msgid "Done!"
msgstr "Críochnaithe!"
-#: ../spell.c:8034
#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: níl %<PRId64> iontráil i 'spellfile'"
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: níl %ld iontráil i 'spellfile'"
-#: ../spell.c:8074
-#, fuzzy, c-format
+#, c-format
msgid "Word '%.*s' removed from %s"
-msgstr "Baineadh focal ó %s"
+msgstr "Baineadh focal '%.*s' ó %s"
-#: ../spell.c:8117
-#, fuzzy, c-format
+#, c-format
msgid "Word '%.*s' added to %s"
-msgstr "Cuireadh focal le %s"
+msgstr "Cuireadh focal '%.*s' le %s"
-#: ../spell.c:8381
msgid "E763: Word characters differ between spell files"
msgstr "E763: Tá carachtair dhifriúla fhocail sna comhaid litrithe"
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "Tá brón orm, níl aon mholadh ann"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "Tá brón orm, níl ach %<PRId64> moladh ann"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "Athraigh \"%.*s\" go:"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < \"%.*s\""
-
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: Níl aon ionadaí litrithe roimhe seo"
-
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: Gan aimsiú: %s"
-
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: Níl sé cosúil le comhad .sug: %s"
-
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: Seanchomhad .sug, tá gá lena nuashonrú: %s"
-
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: Oibríonn an comhad .sug le leagan níos nuaí de Vim: %s"
-
-#: ../spell.c:9295
-#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr "E781: Níl an comhad .sug comhoiriúnach leis an gcomhad .spl: %s"
-
-#: ../spell.c:9305
-#, 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.
-#: ../spell.c:11575
+#. * file.
msgid "E783: duplicate char in MAP entry"
msgstr "E783: carachtar dúblach in iontráil MAP"
-#: ../syntax.c:266
msgid "No Syntax items defined for this buffer"
msgstr "Níl aon mhír chomhréire sainmhínithe le haghaidh an mhaoláin seo"
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
#, c-format
msgid "E390: Illegal argument: %s"
msgstr "E390: Argóint neamhcheadaithe: %s"
-#: ../syntax.c:3299
+msgid "syntax iskeyword "
+msgstr "comhréir iskeyword "
+
#, c-format
msgid "E391: No such syntax cluster: %s"
msgstr "E391: Níl a leithéid de mhogall comhréire: %s"
-#: ../syntax.c:3433
msgid "syncing on C-style comments"
msgstr "ag sioncrónú ar nóta den nós C"
-#: ../syntax.c:3439
msgid "no syncing"
msgstr "gan sioncrónú"
-#: ../syntax.c:3441
msgid "syncing starts "
msgstr "tosaíonn an sioncrónú "
-#: ../syntax.c:3443 ../syntax.c:3506
msgid " lines before top line"
msgstr " línte roimh an bharr"
-#: ../syntax.c:3448
msgid ""
"\n"
"--- Syntax sync items ---"
@@ -5749,7 +5454,6 @@ msgstr ""
"\n"
"--- Míreanna Comhréire Sionc ---"
-#: ../syntax.c:3452
msgid ""
"\n"
"syncing on items"
@@ -5757,7 +5461,6 @@ msgstr ""
"\n"
"ag sioncrónú ar mhíreanna"
-#: ../syntax.c:3457
msgid ""
"\n"
"--- Syntax items ---"
@@ -5765,275 +5468,217 @@ msgstr ""
"\n"
"--- Míreanna comhréire ---"
-#: ../syntax.c:3475
#, c-format
msgid "E392: No such syntax cluster: %s"
msgstr "E392: Níl a leithéid de mhogall comhréire: %s"
-#: ../syntax.c:3497
msgid "minimal "
msgstr "íosta "
-#: ../syntax.c:3503
msgid "maximal "
msgstr "uasta "
-#: ../syntax.c:3513
msgid "; match "
msgstr "; meaitseáil "
-#: ../syntax.c:3515
msgid " line breaks"
msgstr " bristeacha líne"
-#: ../syntax.c:4076
msgid "E395: contains argument not accepted here"
msgstr "E395: tá argóint ann nach nglactar leis anseo"
-#: ../syntax.c:4096
-#, fuzzy
msgid "E844: invalid cchar value"
-msgstr "E474: Argóint neamhbhailí"
+msgstr "E844: luach neamhbhailí cchar"
-#: ../syntax.c:4107
msgid "E393: group[t]here not accepted here"
msgstr "E393: ní ghlactar le group[t]here anseo"
-#: ../syntax.c:4126
#, c-format
msgid "E394: Didn't find region item for %s"
msgstr "E394: Níor aimsíodh mír réigiúin le haghaidh %s"
-#: ../syntax.c:4188
msgid "E397: Filename required"
msgstr "E397: Tá gá le hainm comhaid"
-#: ../syntax.c:4221
-#, fuzzy
msgid "E847: Too many syntax includes"
-msgstr "E77: An iomarca ainmneacha comhaid"
+msgstr "E847: An iomarca comhad comhréire in úsáid"
-#: ../syntax.c:4303
#, c-format
msgid "E789: Missing ']': %s"
msgstr "E789: ']' ar iarraidh: %s"
-#: ../syntax.c:4531
+#, c-format
+msgid "E890: trailing char after ']': %s]%s"
+msgstr "E890: carachtar tar éis ']': %s]%s"
+
#, c-format
msgid "E398: Missing '=': %s"
msgstr "E398: '=' ar iarraidh: %s"
-#: ../syntax.c:4666
#, c-format
msgid "E399: Not enough arguments: syntax region %s"
msgstr "E399: Níl go leor argóintí ann: réigiún comhréire %s"
-#: ../syntax.c:4870
-#, fuzzy
msgid "E848: Too many syntax clusters"
-msgstr "E391: Níl a leithéid de mhogall comhréire: %s"
+msgstr "E848: An iomarca mogall comhréire"
-#: ../syntax.c:4954
msgid "E400: No cluster specified"
msgstr "E400: Níor sonraíodh mogall"
-#. end delimiter not found
-#: ../syntax.c:4986
#, c-format
msgid "E401: Pattern delimiter not found: %s"
msgstr "E401: Teormharcóir patrúin gan aimsiú: %s"
-#: ../syntax.c:5049
#, c-format
msgid "E402: Garbage after pattern: %s"
msgstr "E402: Dramhaíl i ndiaidh patrúin: %s"
-#: ../syntax.c:5120
msgid "E403: syntax sync: line continuations pattern specified twice"
msgstr "E403: comhréir sionc: tugadh patrún leanúint líne faoi dhó"
-#: ../syntax.c:5169
#, c-format
msgid "E404: Illegal arguments: %s"
msgstr "E404: Argóintí neamhcheadaithe: %s"
-#: ../syntax.c:5217
#, c-format
msgid "E405: Missing equal sign: %s"
msgstr "E405: Sín chothroime ar iarraidh: %s"
-#: ../syntax.c:5222
#, c-format
msgid "E406: Empty argument: %s"
msgstr "E406: Argóint fholamh: %s"
-#: ../syntax.c:5240
#, c-format
msgid "E407: %s not allowed here"
msgstr "E407: ní cheadaítear %s anseo"
-#: ../syntax.c:5246
#, c-format
msgid "E408: %s must be first in contains list"
msgstr "E408: ní foláir %s a thabhairt ar dtús sa liosta `contains'"
-#: ../syntax.c:5304
#, c-format
msgid "E409: Unknown group name: %s"
msgstr "E409: Ainm anaithnid grúpa: %s"
-#: ../syntax.c:5512
#, c-format
msgid "E410: Invalid :syntax subcommand: %s"
msgstr "E410: Fo-ordú neamhbhailí :syntax: %s"
-#: ../syntax.c:5854
msgid ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
msgstr ""
+" IOMLÁN LÍON MEAITS IS MOILLE MEÁN AINM PATRÚN"
-#: ../syntax.c:6146
msgid "E679: recursive loop loading syncolor.vim"
msgstr "E679: lúb athchúrsach agus syncolor.vim á luchtú"
-#: ../syntax.c:6256
#, c-format
msgid "E411: highlight group not found: %s"
msgstr "E411: Grúpa aibhsithe gan aimsiú: %s"
-#: ../syntax.c:6278
#, c-format
msgid "E412: Not enough arguments: \":highlight link %s\""
msgstr "E412: Easpa argóintí: \":highlight link %s\""
-#: ../syntax.c:6284
#, c-format
msgid "E413: Too many arguments: \":highlight link %s\""
msgstr "E413: An iomarca argóintí: \":highlight link %s\""
-#: ../syntax.c:6302
msgid "E414: group has settings, highlight link ignored"
msgstr ""
"E414: tá socruithe ag an ghrúpa, ag déanamh neamhshuim ar nasc aibhsithe"
-#: ../syntax.c:6367
#, c-format
msgid "E415: unexpected equal sign: %s"
msgstr "E415: sín chothroime gan choinne: %s"
-#: ../syntax.c:6395
#, c-format
msgid "E416: missing equal sign: %s"
msgstr "E416: sín chothroime ar iarraidh: %s"
-#: ../syntax.c:6418
#, c-format
msgid "E417: missing argument: %s"
msgstr "E417: argóint ar iarraidh: %s"
-#: ../syntax.c:6446
#, c-format
msgid "E418: Illegal value: %s"
msgstr "E418: Luach neamhcheadaithe: %s"
-#: ../syntax.c:6496
msgid "E419: FG color unknown"
msgstr "E419: Dath anaithnid an chúlra"
-#: ../syntax.c:6504
msgid "E420: BG color unknown"
msgstr "E420: Dath anaithnid an tulra"
-#: ../syntax.c:6564
#, c-format
msgid "E421: Color name or number not recognized: %s"
msgstr "E421: Níor aithníodh ainm/uimhir an datha: %s"
-#: ../syntax.c:6714
#, c-format
msgid "E422: terminal code too long: %s"
msgstr "E422: cód teirminéil rófhada: %s"
-#: ../syntax.c:6753
#, c-format
msgid "E423: Illegal argument: %s"
msgstr "E423: Argóint neamhcheadaithe: %s"
-#: ../syntax.c:6925
msgid "E424: Too many different highlighting attributes in use"
msgstr "E424: An iomarca tréithe aibhsithe in úsáid"
-#: ../syntax.c:7427
msgid "E669: Unprintable character in group name"
msgstr "E669: Carachtar neamhghrafach in ainm grúpa"
-#: ../syntax.c:7434
msgid "W18: Invalid character in group name"
msgstr "W18: Carachtar neamhbhailí in ainm grúpa"
-#: ../syntax.c:7448
msgid "E849: Too many highlight and syntax groups"
-msgstr ""
+msgstr "E849: An iomarca grúpaí aibhsithe agus comhréire"
-#: ../tag.c:104
msgid "E555: at bottom of tag stack"
msgstr "E555: in íochtar na cruaiche clibeanna"
-#: ../tag.c:105
msgid "E556: at top of tag stack"
msgstr "E556: in uachtar na cruaiche clibeanna"
-#: ../tag.c:380
msgid "E425: Cannot go before first matching tag"
msgstr "E425: Ní féidir a dhul roimh an chéad chlib chomhoiriúnach"
-#: ../tag.c:504
#, c-format
msgid "E426: tag not found: %s"
msgstr "E426: clib gan aimsiú: %s"
-#: ../tag.c:528
msgid " # pri kind tag"
msgstr " # tos cin clib"
-#: ../tag.c:531
msgid "file\n"
msgstr "comhad\n"
-#: ../tag.c:829
msgid "E427: There is only one matching tag"
msgstr "E427: Tá aon chlib chomhoiriúnach amháin"
-#: ../tag.c:831
msgid "E428: Cannot go beyond last matching tag"
msgstr "E428: Ní féidir a dhul thar an chlib chomhoiriúnach deireanach"
-#: ../tag.c:850
#, c-format
msgid "File \"%s\" does not exist"
msgstr "Níl a leithéid de chomhad \"%s\" ann"
#. Give an indication of the number of matching tags
-#: ../tag.c:859
#, c-format
msgid "tag %d of %d%s"
msgstr "clib %d as %d%s"
-#: ../tag.c:862
msgid " or more"
msgstr " nó os a chionn"
-#: ../tag.c:864
msgid " Using tag with different case!"
msgstr " Ag úsáid clib le cás eile!"
-#: ../tag.c:909
#, c-format
msgid "E429: File \"%s\" does not exist"
msgstr "E429: Níl a leithéid de chomhad \"%s\""
#. Highlight title
-#: ../tag.c:960
msgid ""
"\n"
" # TO tag FROM line in file/text"
@@ -6041,79 +5686,66 @@ msgstr ""
"\n"
" # Go clib Ó líne i gcomhad/téacs"
-#: ../tag.c:1303
#, c-format
msgid "Searching tags file %s"
msgstr "Comhad clibeanna %s á chuardach"
-#: ../tag.c:1545
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Teascadh conair an chomhaid clibeanna le haghaidh %s\n"
+
msgid "Ignoring long line in tags file"
msgstr "Ag déanamh neamhaird de líne fhada sa chomhad clibeanna"
-#: ../tag.c:1915
#, c-format
msgid "E431: Format error in tags file \"%s\""
msgstr "E431: Earráid fhormáide i gcomhad clibeanna \"%s\""
-#: ../tag.c:1917
#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "Roimh bheart %<PRId64>"
+msgid "Before byte %ld"
+msgstr "Roimh bheart %ld"
-#: ../tag.c:1929
#, c-format
msgid "E432: Tags file not sorted: %s"
msgstr "E432: Comhad clibeanna gan sórtáil: %s"
#. never opened any tags file
-#: ../tag.c:1960
msgid "E433: No tags file"
msgstr "E433: Níl aon chomhad clibeanna"
-#: ../tag.c:2536
msgid "E434: Can't find tag pattern"
msgstr "E434: Patrún clibe gan aimsiú"
-#: ../tag.c:2544
msgid "E435: Couldn't find tag, just guessing!"
msgstr "E435: Clib gan aimsiú, ag tabhairt buille faoi thuairim!"
-#: ../tag.c:2797
-#, fuzzy, c-format
+#, c-format
msgid "Duplicate field name: %s"
-msgstr "Clib dhúblach i %s líne %d: %s"
+msgstr "Ainm réimse dúbailte: %s"
-#: ../term.c:1442
msgid "' not known. Available builtin terminals are:"
msgstr "' anaithnid. Is iad seo na teirminéil insuite:"
-#: ../term.c:1463
msgid "defaulting to '"
msgstr "réamhshocrú = '"
-#: ../term.c:1731
msgid "E557: Cannot open termcap file"
msgstr "E557: Ní féidir an comhad termcap a oscailt"
-#: ../term.c:1735
msgid "E558: Terminal entry not found in terminfo"
msgstr "E558: Iontráil teirminéil gan aimsiú sa terminfo"
-#: ../term.c:1737
msgid "E559: Terminal entry not found in termcap"
msgstr "E559: Iontráil teirminéil gan aimsiú sa termcap"
-#: ../term.c:1878
#, c-format
msgid "E436: No \"%s\" entry in termcap"
msgstr "E436: Níl aon iontráil \"%s\" sa termcap"
-#: ../term.c:2249
msgid "E437: terminal capability \"cm\" required"
msgstr "E437: tá gá leis an chumas teirminéil \"cm\""
#. Highlight title
-#: ../term.c:4376
msgid ""
"\n"
"--- Terminal keys ---"
@@ -6121,169 +5753,342 @@ msgstr ""
"\n"
"--- Eochracha teirminéil ---"
-#: ../ui.c:481
+msgid "Cannot open $VIMRUNTIME/rgb.txt"
+msgstr "Ní féidir $VIMRUNTIME/rgb.txt a oscailt"
+
+msgid "new shell started\n"
+msgstr "tosaíodh blaosc nua\n"
+
msgid "Vim: Error reading input, exiting...\n"
msgstr "Vim: Earráid agus an t-inchomhad á léamh; ag scor...\n"
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Úsáideadh CUT_BUFFER0 in ionad roghnúcháin folaimh"
+
#. This happens when the FileChangedRO autocommand changes the
#. * file in a way it becomes shorter.
-#: ../undo.c:379
-#, fuzzy
msgid "E881: Line count changed unexpectedly"
-msgstr "E787: Athraíodh an maolán gan choinne"
+msgstr "E881: Athraíodh líon na línte gan súil leis"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Ní féidir a chealú; lean ar aghaidh mar sin féin"
-#: ../undo.c:627
-#, fuzzy, c-format
+#, c-format
msgid "E828: Cannot open undo file for writing: %s"
-msgstr "E212: Ní féidir comhad a oscailt chun scríobh ann"
+msgstr "E828: Ní féidir comhad staire a oscailt le scríobh ann: %s"
-#: ../undo.c:717
#, c-format
msgid "E825: Corrupted undo file (%s): %s"
-msgstr ""
+msgstr "E825: Comhad staire truaillithe (%s): %s"
-#: ../undo.c:1039
msgid "Cannot write undo file in any directory in 'undodir'"
-msgstr ""
+msgstr "Ní féidir comhad staire a shábháil in aon chomhadlann in 'undodir'"
-#: ../undo.c:1074
#, c-format
msgid "Will not overwrite with undo file, cannot read: %s"
-msgstr ""
+msgstr "Ní forscríobhfar le comhad staire, ní féidir é a léamh: %s"
-#: ../undo.c:1092
#, c-format
msgid "Will not overwrite, this is not an undo file: %s"
-msgstr ""
+msgstr "Ní forscríobhfar é, ní comhad staire é seo: %s"
-#: ../undo.c:1108
msgid "Skipping undo file write, nothing to undo"
-msgstr ""
+msgstr "Ní scríobhfar an comhad staire, níl aon stair ann"
-#: ../undo.c:1121
-#, fuzzy, c-format
+#, c-format
msgid "Writing undo file: %s"
-msgstr "Comhad viminfo \"%s\" á scríobh"
+msgstr "Comhad staire á scríobh: %s"
-#: ../undo.c:1213
-#, fuzzy, c-format
+#, c-format
msgid "E829: write error in undo file: %s"
-msgstr "E297: Earráid sa scríobh i gcomhad babhtála"
+msgstr "E829: earráid le linn scríofa i gcomhad staire: %s"
-#: ../undo.c:1280
#, c-format
msgid "Not reading undo file, owner differs: %s"
-msgstr ""
+msgstr "Níor léadh an comhad staire; úinéir difriúil: %s"
-#: ../undo.c:1292
-#, fuzzy, c-format
+#, c-format
msgid "Reading undo file: %s"
-msgstr "Comhad focail %s á léamh ..."
+msgstr "Comhad staire á léamh: %s"
-#: ../undo.c:1299
-#, fuzzy, c-format
+#, c-format
msgid "E822: Cannot open undo file for reading: %s"
-msgstr "E195: Ní féidir an comhad viminfo a oscailt chun léamh"
+msgstr "E822: Ní féidir an comhad staire a oscailt lena léamh: %s"
-#: ../undo.c:1308
-#, fuzzy, c-format
+#, c-format
msgid "E823: Not an undo file: %s"
-msgstr "E753: Gan aimsiú: %s"
+msgstr "E823: Ní comhad staire é: %s"
+
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: Comhad neamhchriptithe le comhad staire criptithe: %s"
-#: ../undo.c:1313
-#, fuzzy, c-format
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: Níorbh fhéidir an comhad staire a dhíchriptiú: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: Tá an comhad staire criptithe: %s"
+
+#, c-format
msgid "E824: Incompatible undo file: %s"
-msgstr "E484: Ní féidir comhad %s a oscailt"
+msgstr "E824: Comhad staire neamh-chomhoiriúnach: %s"
-#: ../undo.c:1328
msgid "File contents changed, cannot use undo info"
-msgstr ""
+msgstr "Athraíodh ábhar an chomhaid, ní féidir comhad staire a úsáid"
-#: ../undo.c:1497
-#, fuzzy, c-format
+#, c-format
msgid "Finished reading undo file %s"
-msgstr "deireadh ag foinsiú %s"
+msgstr "Comhad staire %s léite"
-#: ../undo.c:1586 ../undo.c:1812
msgid "Already at oldest change"
msgstr "Ag an athrú is sine cheana"
-#: ../undo.c:1597 ../undo.c:1814
msgid "Already at newest change"
msgstr "Ag an athrú is nuaí cheana"
-#: ../undo.c:1806
-#, fuzzy, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "Níor aimsíodh cealú uimhir a %<PRId64>"
+#, c-format
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Mír staire %ld gan aimsiú"
-#: ../undo.c:1979
msgid "E438: u_undo: line numbers wrong"
msgstr "E438: u_undo: líne-uimhreacha míchearta"
-#: ../undo.c:2183
msgid "more line"
msgstr "líne eile"
-#: ../undo.c:2185
msgid "more lines"
msgstr "líne eile"
-#: ../undo.c:2187
msgid "line less"
msgstr "líne níos lú"
-#: ../undo.c:2189
msgid "fewer lines"
msgstr "líne níos lú"
-#: ../undo.c:2193
msgid "change"
msgstr "athrú"
-#: ../undo.c:2195
msgid "changes"
msgstr "athrú"
-#: ../undo.c:2225
#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s; %s #%<PRId64> %s"
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
-#: ../undo.c:2228
msgid "before"
msgstr "roimh"
-#: ../undo.c:2228
msgid "after"
msgstr "tar éis"
-#: ../undo.c:2325
msgid "Nothing to undo"
msgstr "Níl faic le cealú"
-#: ../undo.c:2330
msgid "number changes when saved"
-msgstr ""
+msgstr "athraíonn an uimhir ag am sábhála"
-#: ../undo.c:2360
#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> soicind ó shin"
+msgid "%ld seconds ago"
+msgstr "%ld soicind ó shin"
-#: ../undo.c:2372
msgid "E790: undojoin is not allowed after undo"
msgstr "E790: ní cheadaítear \"undojoin\" tar éis \"undo\""
-#: ../undo.c:2466
msgid "E439: undo list corrupt"
msgstr "E439: tá an liosta cealaithe truaillithe"
-#: ../undo.c:2495
msgid "E440: undo line missing"
msgstr "E440: líne chealaithe ar iarraidh"
-#: ../version.c:600
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: Tá feidhm %s ann cheana, cuir ! leis an ordú chun é a asáitiú"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Tá an iontráil foclóra seo ann cheana"
+
+msgid "E718: Funcref required"
+msgstr "E718: Tá gá le Funcref"
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Feidhm anaithnid: %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Argóint neamhcheadaithe: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Argóint dhúbailte: %s"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: An iomarca argóintí d'fheidhm %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Argóintí neamhbhailí d'fheidhm %s"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Doimhneacht na nglaonna níos mó ná 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "%s á glao"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s tobscortha"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s ag aisfhilleadh #%ld"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s ag aisfhilleadh %s"
+
+msgid "E699: Too many arguments"
+msgstr "E699: An iomarca argóintí"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Feidhm anaithnid: %s"
+
+#, c-format
+msgid "E933: Function was deleted: %s"
+msgstr "E933: Scriosadh an fheidhm: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Níl go leor feidhmeanna d'fheidhm: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: <SID> á úsáid ach gan a bheith i gcomhthéacs scripte: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Feidhm 'dict' á ghlao gan Foclóir: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Tá gá le hainm feidhme"
+
+#, c-format
+msgid "E128: Function name must start with a capital or \"s:\": %s"
+msgstr ""
+"E128: Caithfidh ceannlitir a bheith ar dtús ainm feidhme, nó \"s:\": %s"
+
+#, c-format
+msgid "E884: Function name cannot contain a colon: %s"
+msgstr "E884: Ní cheadaítear idirstad in ainm feidhme: %s"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Feidhm gan sainmhíniú: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: '(' ar iarraidh: %s"
+
+msgid "E862: Cannot use g: here"
+msgstr "E862: Ní féidir g: a úsáid anseo"
+
+#, c-format
+msgid "E932: Closure function should not be at top level: %s"
+msgstr "E932: Ní mór don chlabhsúr a bheith ag an mbarrleibhéal: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: :endfunction ar iarraidh"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: Tagann ainm na feidhme salach ar athróg: %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr ""
+"E127: Ní féidir sainmhíniú nua a dhéanamh ar fheidhm %s: In úsáid cheana"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr ""
+"E746: Níl ainm na feidhme comhoiriúnach le hainm comhaid na scripte: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Ní féidir feidhm %s a scriosadh: Tá sé in úsáid faoi láthair"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: Caithfidh :return a bheith isteach i bhfeidhm"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Lúibíní ar iarraidh: %s"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"Leagan GUI 64 giotán MS-Windows"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"Leagan GUI 32 giotán MS-Windows"
+
+msgid " with OLE support"
+msgstr " le tacaíocht OLE"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit console version"
+msgstr ""
+"\n"
+"Leagan consóil 64 giotán MS-Windows"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"Leagan consóil 32 giotán MS-Windows"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"Leagan MacOS X (unix)"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"Leagan MacOS X"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"Leagan MacOS"
+
+msgid ""
+"\n"
+"OpenVMS version"
+msgstr ""
+"\n"
+"Leagan OpenVMS"
+
msgid ""
"\n"
"Included patches: "
@@ -6291,7 +6096,6 @@ msgstr ""
"\n"
"Paistí san áireamh: "
-#: ../version.c:627
msgid ""
"\n"
"Extra patches: "
@@ -6299,11 +6103,9 @@ msgstr ""
"\n"
"Paistí sa bhreis: "
-#: ../version.c:639 ../version.c:864
msgid "Modified by "
msgstr "Mionathraithe ag "
-#: ../version.c:646
msgid ""
"\n"
"Compiled "
@@ -6312,11 +6114,9 @@ msgstr ""
"Tiomsaithe "
# with "Tiomsaithe"
-#: ../version.c:649
msgid "by "
msgstr "ag "
-#: ../version.c:660
msgid ""
"\n"
"Huge version "
@@ -6324,656 +6124,952 @@ msgstr ""
"\n"
"Leagan ollmhór "
-#: ../version.c:661
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Leagan mór "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Leagan coitianta "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Leagan beag "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Leagan beag bídeach "
+
msgid "without GUI."
msgstr "gan GUI."
-#: ../version.c:662
+msgid "with GTK3 GUI."
+msgstr "le GUI GTK3."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "le GUI GTK2-GNOME."
+
+msgid "with GTK2 GUI."
+msgstr "le GUI GTK2."
+
+msgid "with X11-Motif GUI."
+msgstr "le GUI X11-Motif."
+
+msgid "with X11-neXtaw GUI."
+msgstr "le GUI X11-neXtaw."
+
+msgid "with X11-Athena GUI."
+msgstr "le GUI X11-Athena."
+
+msgid "with Photon GUI."
+msgstr "le GUI Photon."
+
+msgid "with GUI."
+msgstr "le GUI."
+
+msgid "with Carbon GUI."
+msgstr "le GUI Carbon."
+
+msgid "with Cocoa GUI."
+msgstr "le GUI Cocoa."
+
+msgid "with (classic) GUI."
+msgstr "le GUI (clasaiceach)."
+
msgid " Features included (+) or not (-):\n"
msgstr " Gnéithe san áireamh (+) nó nach bhfuil (-):\n"
-#: ../version.c:667
msgid " system vimrc file: \""
msgstr " comhad vimrc an chórais: \""
-#: ../version.c:672
msgid " user vimrc file: \""
msgstr " comhad vimrc úsáideora: \""
-#: ../version.c:677
msgid " 2nd user vimrc file: \""
msgstr " dara comhad vimrc úsáideora: \""
-#: ../version.c:682
msgid " 3rd user vimrc file: \""
msgstr " tríú comhad vimrc úsáideora: \""
-#: ../version.c:687
msgid " user exrc file: \""
msgstr " comhad exrc úsáideora: \""
-#: ../version.c:692
msgid " 2nd user exrc file: \""
msgstr " dara comhad úsáideora exrc: \""
-#: ../version.c:699
+msgid " system gvimrc file: \""
+msgstr " comhad gvimrc córais: \""
+
+msgid " user gvimrc file: \""
+msgstr " comhad gvimrc úsáideora: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr "dara comhad gvimrc úsáideora: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr "tríú comhad gvimrc úsáideora: \""
+
+msgid " defaults file: \""
+msgstr " comhad na réamhshocruithe: \""
+
+msgid " system menu file: \""
+msgstr " comhad roghchláir an chórais: \""
+
msgid " fall-back for $VIM: \""
msgstr " rogha thánaisteach do $VIM: \""
-#: ../version.c:705
msgid " f-b for $VIMRUNTIME: \""
msgstr " f-b do $VIMRUNTIME: \""
-#: ../version.c:709
msgid "Compilation: "
msgstr "Tiomsú: "
-#: ../version.c:712
+msgid "Compiler: "
+msgstr "Tiomsaitheoir: "
+
msgid "Linking: "
msgstr "Nascáil: "
-#: ../version.c:717
msgid " DEBUG BUILD"
msgstr " LEAGAN DÍFHABHTAITHE"
-#: ../version.c:767
msgid "VIM - Vi IMproved"
msgstr "VIM - Vi IMproved"
-#: ../version.c:769
msgid "version "
msgstr "leagan "
-#: ../version.c:770
msgid "by Bram Moolenaar et al."
msgstr "le Bram Moolenaar et al."
-#: ../version.c:774
msgid "Vim is open source and freely distributable"
msgstr "Is saorbhogearra é Vim"
-#: ../version.c:776
msgid "Help poor children in Uganda!"
msgstr "Tabhair cabhair do pháistí bochta in Uganda!"
-#: ../version.c:777
msgid "type :help iccf<Enter> for information "
msgstr "clóscríobh :help iccf<Enter> chun eolas a fháil "
-#: ../version.c:779
msgid "type :q<Enter> to exit "
msgstr "clóscríobh :q<Enter> chun scoir "
-#: ../version.c:780
msgid "type :help<Enter> or <F1> for on-line help"
msgstr "clóscríobh :help<Enter> nó <F1> le haghaidh cabhrach ar líne"
-#: ../version.c:781
-msgid "type :help version7<Enter> for version info"
-msgstr "clóscríobh :help version7<Enter> le haghaidh eolais faoin leagan"
+msgid "type :help version8<Enter> for version info"
+msgstr "clóscríobh :help version8<Enter> le haghaidh eolais faoin leagan"
-#: ../version.c:784
msgid "Running in Vi compatible mode"
msgstr "Sa mhód comhoiriúnachta Vi"
-#: ../version.c:785
msgid "type :set nocp<Enter> for Vim defaults"
msgstr ""
"clóscríobh :set nocp<Enter> chun na réamhshocruithe Vim a thaispeáint"
-#: ../version.c:786
msgid "type :help cp-default<Enter> for info on this"
msgstr ""
"clóscríobh :help cp-default<Enter> chun níos mó eolas faoi seo a fháil"
-#: ../version.c:827
+# don't see where to localize "Help->Orphans"? --kps
+msgid "menu Help->Orphans for information "
+msgstr "roghchlár Help->Orphans chun eolas a fháil "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "Á rith gan mhóid, ag ionsá an téacs atá iontráilte"
+
+# same problem --kps
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "roghchlár Edit->Global Settings->Toggle Insert Mode "
+
+msgid " for two modes "
+msgstr " do dhá mhód "
+
+# same problem --kps
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "roghchlár Edit->Global Settings->Toggle Vi Compatible"
+
+msgid " for Vim defaults "
+msgstr " le haghaidh réamhshocruithe Vim "
+
msgid "Sponsor Vim development!"
msgstr "Bí i d'urraitheoir Vim!"
-#: ../version.c:828
msgid "Become a registered Vim user!"
msgstr "Bí i d'úsáideoir cláraithe Vim!"
-#: ../version.c:831
msgid "type :help sponsor<Enter> for information "
msgstr "clóscríobh :help sponsor<Enter> chun eolas a fháil "
-#: ../version.c:832
msgid "type :help register<Enter> for information "
msgstr "clóscríobh :help register<Enter> chun eolas a fháil "
-#: ../version.c:834
msgid "menu Help->Sponsor/Register for information "
msgstr "roghchlár Help->Sponsor/Register chun eolas a fháil "
-#: ../window.c:119
msgid "Already only one window"
msgstr "Níl ach aon fhuinneog amháin ann cheana"
-#: ../window.c:224
msgid "E441: There is no preview window"
msgstr "E441: Níl aon fhuinneog réamhamhairc ann"
-#: ../window.c:559
msgid "E442: Can't split topleft and botright at the same time"
msgstr "E442: Ní féidir a scoilteadh topleft agus botright san am céanna"
-#: ../window.c:1228
msgid "E443: Cannot rotate when another window is split"
msgstr "E443: Ní féidir rothlú nuair atá fuinneog eile scoilte"
-#: ../window.c:1803
msgid "E444: Cannot close last window"
msgstr "E444: Ní féidir an fhuinneog dheiridh a dhúnadh"
-#: ../window.c:1810
msgid "E813: Cannot close autocmd window"
msgstr "E813: Ní féidir fuinneog autocmd a dhúnadh"
-#: ../window.c:1814
msgid "E814: Cannot close window, only autocmd window would remain"
msgstr ""
"E814: Ní féidir an fhuinneog a dhúnadh, ní bheadh ach fuinneog autocmd fágtha"
-#: ../window.c:2717
msgid "E445: Other window contains changes"
msgstr "E445: Tá athruithe ann san fhuinneog eile"
-#: ../window.c:4805
msgid "E446: No file name under cursor"
msgstr "E446: Níl ainm comhaid faoin chúrsóir"
-#~ msgid "Patch file"
-#~ msgstr "Comhad paiste"
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Níl aon fháil ar chomhad \"%s\" sa chonair"
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "&OK\n"
-#~ "&Cealaigh"
+#, c-format
+msgid "E799: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E799: Aitheantas neamhbhailí: %ld (ní mór dó a bheith >= 1)"
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Níl aon nasc le freastalaí Vim"
+#, c-format
+msgid "E801: ID already taken: %ld"
+msgstr "E801: Aitheantas in úsáid cheana: %ld"
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: Ní féidir aon rud a sheoladh chuig %s"
+msgid "List or number required"
+msgstr "Tá gá le liosta nó uimhir"
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: Ní féidir freagra ón fhreastalaí a léamh"
+#, c-format
+msgid "E802: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E802: Aitheantas neamhbhailí: %ld (ní mór dó a bheith >= 1)"
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: Ní féidir aon rud a sheoladh chuig an chliant"
+#, c-format
+msgid "E803: ID not found: %ld"
+msgstr "E803: Aitheantas gan aimsiú: %ld"
-#~ msgid "Save As"
-#~ msgstr "Sábháil Mar"
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Níorbh fhéidir an leabharlann %s a oscailt"
-#~ msgid "Edit File"
-#~ msgstr "Cuir Comhad in Eagar"
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr ""
+"Tá brón orm, níl an t-ordú seo le fáil: níorbh fhéidir an leabharlann Perl a "
+"luchtú."
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (AR IARRAIDH)"
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr "E299: Ní cheadaítear luacháil Perl i mbosca gainimh gan an modúl Safe"
-#~ msgid "Source Vim script"
-#~ msgstr "Foinsigh script Vim"
+msgid "Edit with &multiple Vims"
+msgstr "Cuir in eagar le Vimeanna io&madúla"
-#~ msgid "Edit File in new window"
-#~ msgstr "Cuir comhad in eagar i bhfuinneog nua"
+msgid "Edit with single &Vim"
+msgstr "Cuir in eagar le &Vim aonair"
-#~ msgid "Append File"
-#~ msgstr "Cuir Comhad i nDeireadh"
+msgid "Diff with Vim"
+msgstr "Diff le Vim"
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "Ionad na fuinneoige: X %d, Y %d"
+msgid "Edit with &Vim"
+msgstr "Cuir in Eagar le &Vim"
-#~ msgid "Save Redirection"
-#~ msgstr "Sábháil Atreorú"
+#. Now concatenate
+msgid "Edit with existing Vim - "
+msgstr "Cuir in Eagar le Vim beo - "
-#~ msgid "Save View"
-#~ msgstr "Sábháil an tAmharc"
+msgid "Edits the selected file(s) with Vim"
+msgstr "Cuir an comhad roghnaithe in eagar le Vim"
-#~ msgid "Save Session"
-#~ msgstr "Sábháil an Seisiún"
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr ""
+"Earráid agus próiseas á chruthú: Deimhnigh go bhfuil gvim i do chonair!"
-#~ msgid "Save Setup"
-#~ msgstr "Sábháil an Socrú"
+msgid "gvimext.dll error"
+msgstr "earráid gvimext.dll"
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: níl #< ar fáil gan ghné +eval"
+msgid "Path length too long!"
+msgstr "Conair rófhada!"
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: Ní cheadaítear déghraif sa leagan seo"
+msgid "--No lines in buffer--"
+msgstr "--Tá an maolán folamh--"
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr "is gléas é seo (díchumasaithe le rogha 'opendevice')"
+#.
+#. * The error messages that can be shared are included here.
+#. * Excluded are errors that are only used once and debugging messages.
+#.
+msgid "E470: Command aborted"
+msgstr "E470: Ordú tobscortha"
-#~ msgid "Reading from stdin..."
-#~ msgstr "Ag léamh ón ionchur caighdeánach..."
+msgid "E471: Argument required"
+msgstr "E471: Tá gá le hargóint"
-#~ msgid "[crypted]"
-#~ msgstr "[criptithe]"
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: Ba chóir /, ? nó & a chur i ndiaidh \\"
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "Ní cheadaíonn NetBeans maoláin gan athrú a bheith scríofa"
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr ""
+"E11: Neamhbhailí i bhfuinneog líne na n-orduithe; <CR>=rith, CTRL-C=scoir"
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "Ní cheadaítear maoláin NetBeans a bheith scríofa go neamhiomlán"
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: Ní cheadaítear ordú ó exrc/vimrc sa chomhadlann reatha ná ó chuardach "
+"clibe"
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "díchumasaíodh scríobh chuig gléas le rogha 'opendevice'"
+msgid "E171: Missing :endif"
+msgstr "E171: :endif ar iarraidh"
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: Chaillfí an forc acmhainne (cuir ! leis an ordú chun sárú)"
+msgid "E600: Missing :endtry"
+msgstr "E600: :endtry ar iarraidh"
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: Ní féidir an GUI a chur ag obair"
+msgid "E170: Missing :endwhile"
+msgstr "E170: :endwhile ar iarraidh"
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: Ní féidir léamh ó \"%s\""
+msgid "E170: Missing :endfor"
+msgstr "E170: :endfor ar iarraidh"
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr ""
-#~ "E665: Ní féidir an GUI a chur ag obair, níl aon chlófhoireann bhailí ann"
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile gan :while"
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: 'guifontwide' neamhbhailí"
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor gan :for"
+
+msgid "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ú"
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: Luach neamhbhailí ar 'imactivatekey'"
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Tacar cló anaithnid: %s"
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: Ní féidir dath %s a dháileadh"
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Clófhoireann anaithnid: %s"
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "Níl a leithéid ag an chúrsóir, ag cuardach ar an chéad cheann eile"
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Ní cló aonleithid é \"%s\""
-#~ msgid "<cannot open> "
-#~ msgstr "<ní féidir a oscailt> "
+msgid "E473: Internal error"
+msgstr "E473: Earráid inmheánach"
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: níl aon fháil ar an chlófhoireann %s"
+msgid "Interrupted"
+msgstr "Idirbhriste"
-#~ 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 "E14: Invalid address"
+msgstr "E14: Drochsheoladh"
-#~ msgid "Pathname:"
-#~ msgstr "Conair:"
+msgid "E474: Invalid argument"
+msgstr "E474: Argóint neamhbhailí"
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: níl an chomhadlann reatha ar fáil"
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Argóint neamhbhailí: %s"
-#~ msgid "OK"
-#~ msgstr "OK"
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Slonn neamhbhailí: %s"
-#~ msgid "Cancel"
-#~ msgstr "Cealaigh"
+msgid "E16: Invalid range"
+msgstr "E16: Raon neamhbhailí"
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr ""
-#~ "Giuirléid Scrollbharra: Ní féidir céimseata an mhapa picteilíní a fháil."
+msgid "E476: Invalid command"
+msgstr "E476: Ordú neamhbhailí"
-#~ msgid "Vim dialog"
-#~ msgstr "Dialóg Vim"
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: is comhadlann \"%s\""
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr ""
-#~ "E232: Ní féidir BalloonEval a chruthú le teachtaireacht agus aisghlaoch "
-#~ "araon"
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Theip ar ghlao leabharlainne \"%s()\""
-#~ msgid "Vim dialog..."
-#~ msgstr "Dialóg Vim..."
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Ní féidir feidhm %s leabharlainne a luchtú"
-#~ msgid "Input _Methods"
-#~ msgstr "_Modhanna ionchuir"
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Tá líne-uimhir neamhbhailí ag an mharc"
-# in OLT --KPS
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - Cuardaigh agus Athchuir..."
+msgid "E20: Mark not set"
+msgstr "E20: Marc gan socrú"
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - Cuardaigh..."
+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 "Find what:"
-#~ msgstr "Aimsigh:"
+msgid "E22: Scripts nested too deep"
+msgstr "E22: scripteanna neadaithe ródhomhain"
-#~ msgid "Replace with:"
-#~ msgstr "Le cur in ionad:"
+msgid "E23: No alternate file"
+msgstr "E23: Níl aon chomhad malartach"
-#~ msgid "Match whole word only"
-#~ msgstr "Focal iomlán amháin"
+msgid "E24: No such abbreviation"
+msgstr "E24: Níl a leithéid de ghiorrúchán ann"
-#~ msgid "Match case"
-#~ msgstr "Meaitseáil an cás"
+msgid "E477: No ! allowed"
+msgstr "E477: Ní cheadaítear !"
-#~ msgid "Direction"
-#~ msgstr "Treo"
+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 "Up"
-#~ msgstr "Suas"
+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 "Down"
-#~ msgstr "Síos"
+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 "Find Next"
-#~ msgstr "An Chéad Cheann Eile"
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr ""
+"E800: Níl tacaíocht Araibise ar fáil: Níor cumasaíodh é ag am tiomsaithe\n"
-#~ msgid "Replace"
-#~ msgstr "Ionadaigh"
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Níl a leithéid d'ainm grúpa aibhsithe: %s"
-#~ msgid "Replace All"
-#~ msgstr "Ionadaigh Uile"
+msgid "E29: No inserted text yet"
+msgstr "E29: Níl aon téacs ionsáite go dtí seo"
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: Fuarthas iarratas \"die\" ó bhainisteoir an tseisiúin\n"
+msgid "E30: No previous command line"
+msgstr "E30: Níl aon líne na n-orduithe roimhe seo"
-#~ msgid "Close"
-#~ msgstr "Dún"
+msgid "E31: No such mapping"
+msgstr "E31: Níl a leithéid de mhapáil"
-#~ msgid "New tab"
-#~ msgstr "Cluaisín nua"
+msgid "E479: No match"
+msgstr "E479: Níl aon rud comhoiriúnach ann"
-#~ msgid "Open Tab..."
-#~ msgstr "Oscail Cluaisín..."
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Níl aon rud comhoiriúnach ann: %s"
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: Milleadh an príomhfhuinneog gan choinne\n"
+msgid "E32: No file name"
+msgstr "E32: Níl aon ainm comhaid"
-#~ msgid "Font Selection"
-#~ msgstr "Roghnú Cló"
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Níl aon slonn ionadaíochta roimhe seo"
-#~ msgid "&Filter"
-#~ msgstr "&Scagaire"
+msgid "E34: No previous command"
+msgstr "E34: Níl aon ordú roimhe seo"
-#~ msgid "&Cancel"
-#~ msgstr "&Cealaigh"
+msgid "E35: No previous regular expression"
+msgstr "E35: Níl aon slonn ionadaíochta roimhe seo"
-#~ msgid "Directories"
-#~ msgstr "Comhadlanna"
+msgid "E481: No range allowed"
+msgstr "E481: Ní cheadaítear raon"
-#~ msgid "Filter"
-#~ msgstr "Scagaire"
+msgid "E36: Not enough room"
+msgstr "E36: Níl slí a dhóthain ann"
-#~ msgid "&Help"
-#~ msgstr "&Cabhair"
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: níl aon fhreastalaí cláraithe leis an ainm \"%s\""
-#~ msgid "Files"
-#~ msgstr "Comhaid"
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Ní féidir comhad %s a chruthú"
-#~ msgid "&OK"
-#~ msgstr "&OK"
+msgid "E483: Can't get temp file name"
+msgstr "E483: Níl aon fháil ar ainm comhaid sealadach"
-#~ msgid "Selection"
-#~ msgstr "Roghnú"
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Ní féidir comhad %s a oscailt"
-#~ msgid "Find &Next"
-#~ msgstr "An Chéad Chea&nn Eile"
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Ní féidir comhad %s a léamh"
-#~ msgid "&Replace"
-#~ msgstr "&Ionadaigh"
+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 "Replace &All"
-#~ msgstr "Ionadaigh &Uile"
+msgid "E37: No write since last change"
+msgstr "E37: Gan scríobh ón athrú is déanaí"
-#~ msgid "&Undo"
-#~ msgstr "&Cealaigh"
+msgid "E38: Null argument"
+msgstr "E38: Argóint nialasach"
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: Ní féidir teideal na fuinneoige \"%s\" a aimsiú"
+msgid "E39: Number expected"
+msgstr "E39: Ag súil le huimhir"
-#~ 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."
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Ní féidir an comhad earráide %s a oscailt"
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: Ní féidir fuinneog a oscailt isteach i bhfeidhmchlár MDI"
+msgid "E233: cannot open display"
+msgstr "E233: ní féidir an scáileán a oscailt"
-#~ msgid "Close tab"
-#~ msgstr "Dún cluaisín"
+msgid "E41: Out of memory!"
+msgstr "E41: Cuimhne ídithe!"
-#~ msgid "Open tab..."
-#~ msgstr "Oscail cluaisín..."
+msgid "Pattern not found"
+msgstr "Patrún gan aimsiú"
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "Aimsigh teaghrán (bain úsáid as '\\\\' chun '\\' a aimsiú)"
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Patrún gan aimsiú: %s"
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "Aimsigh & Athchuir (úsáid '\\\\' chun '\\' a aimsiú)"
+msgid "E487: Argument must be positive"
+msgstr "E487: Ní foláir argóint dheimhneach"
-#~ msgid "Not Used"
-#~ msgstr "Gan Úsáid"
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Ní féidir a fhilleadh ar an chomhadlann roimhe seo"
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "Comhadlann\t*.neamhní\n"
+msgid "E42: No Errors"
+msgstr "E42: Níl Aon Earráid Ann"
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr ""
-#~ "Vim E458: Ní féidir iontráil dathmhapála a dháileadh, is féidir go mbeidh "
-#~ "dathanna míchearta ann"
+msgid "E776: No location list"
+msgstr "E776: Gan liosta suíomh"
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr ""
-#~ "E250: Clónna ar iarraidh le haghaidh na dtacar carachtar i dtacar cló %s:"
+msgid "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ú)"
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: Ainm an tacar cló: %s"
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Ní féidir athróg inléite amháin \"%s\" a athrú"
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "Ní cló aonleithid é '%s'"
+#, 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 "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Ní féidir eochair fholamh a úsáid le Foclóir"
-#~ msgid "E253: Fontset name: %s\n"
-#~ msgstr "E253: Ainm an tacar cló: %s\n"
+msgid "E715: Dictionary required"
+msgstr "E715: Tá gá le foclóir"
-#~ msgid "Font0: %s\n"
-#~ msgstr "Cló0: %s\n"
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: innéacs liosta as raon: %ld"
-#~ msgid "Font1: %s\n"
-#~ msgstr "Cló1: %s\n"
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: An iomarca argóintí d'fheidhm: %s"
-#~ msgid "Font%<PRId64> width is not twice that of font0\n"
-#~ msgstr "Níl Cló%<PRId64> níos leithne faoi dhó ná cló0\n"
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: Níl an eochair seo san Fhoclóir: %s"
-#~ msgid "Font0 width: %<PRId64>\n"
-#~ msgstr "Leithead Cló0: %<PRId64>\n"
+msgid "E714: List required"
+msgstr "E714: Tá gá le liosta"
-#~ msgid ""
-#~ "Font1 width: %<PRId64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "Leithead Cló1: %<PRId64>\n"
-#~ "\n"
+#, 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 "Invalid font specification"
-#~ msgstr "Sonrú neamhbhailí cló"
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Earráid agus comhad earráide á léamh"
-#~ msgid "&Dismiss"
-#~ msgstr "&Ruaig"
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Ní cheadaítear é seo i mbosca gainimh"
-#~ msgid "no specific match"
-#~ msgstr "níl a leithéid ann"
+msgid "E523: Not allowed here"
+msgstr "E523: Ní cheadaítear é anseo"
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - Roghnú Cló"
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Ní féidir an mód scáileáin a shocrú"
-#~ msgid "Name:"
-#~ msgstr "Ainm:"
+msgid "E49: Invalid scroll size"
+msgstr "E49: Méid neamhbhailí scrollaithe"
-#~ msgid "Show size in Points"
-#~ msgstr "Taispeáin méid (Pointí)"
+msgid "E91: 'shell' option is empty"
+msgstr "E91: rogha 'shell' folamh"
-#~ msgid "Encoding:"
-#~ msgstr "Ionchódú:"
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Níorbh fhéidir na sonraí comhartha a léamh!"
-#~ msgid "Font:"
-#~ msgstr "Cló:"
+msgid "E72: Close error on swap file"
+msgstr "E72: Earráid agus comhad babhtála á dhúnadh"
-#~ msgid "Style:"
-#~ msgstr "Stíl:"
+msgid "E73: tag stack empty"
+msgstr "E73: tá cruach na gclibeanna folamh"
-#~ msgid "Size:"
-#~ msgstr "Méid:"
+msgid "E74: Command too complex"
+msgstr "E74: Ordú róchasta"
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: EARRÁID leis na huathoibreáin Hangul"
+msgid "E75: Name too long"
+msgstr "E75: Ainm rófhada"
-#~ msgid "E563: stat error"
-#~ msgstr "E563: earráid stat"
+msgid "E76: Too many ["
+msgstr "E76: an iomarca ["
+
+msgid "E77: Too many file names"
+msgstr "E77: An iomarca ainmneacha comhaid"
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: ní féidir bunachar sonraí cscope a oscailt: %s"
+msgid "E488: Trailing characters"
+msgstr "E488: Carachtair chun deiridh"
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: ní féidir eolas a fháil faoin bhunachar sonraí cscope"
+msgid "E78: Unknown mark"
+msgstr "E78: Marc anaithnid"
-#~ 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 "E79: Cannot expand wildcards"
+msgstr "E79: Ní féidir saoróga a leathnú"
-#~ msgid "invalid expression"
-#~ msgstr "slonn neamhbhailí"
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: ní cheadaítear 'winheight' a bheith níos lú ná 'winminheight'"
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "díchumasaíodh sloinn ag am an tiomsaithe"
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: ní cheadaítear 'winwidth' a bheith níos lú ná 'winminwidth'"
-#~ msgid "hidden option"
-#~ msgstr "rogha fholaithe"
+msgid "E80: Error while writing"
+msgstr "E80: Earráid agus á scríobh"
-#~ msgid "unknown option"
-#~ msgstr "rogha anaithnid"
+msgid "Zero count"
+msgstr "Nialas"
-#~ msgid "window index is out of range"
-#~ msgstr "innéacs fuinneoige as raon"
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: <SID> á úsáid nach i gcomhthéacs scripte"
-#~ msgid "couldn't open buffer"
-#~ msgstr "ní féidir maolán a oscailt"
+msgid "E449: Invalid expression received"
+msgstr "E449: Fuarthas slonn neamhbhailí"
-#~ msgid "cannot save undo information"
-#~ msgstr "ní féidir eolas cealaithe a shábháil"
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Réigiún cosanta, ní féidir é a athrú"
-#~ msgid "cannot delete line"
-#~ msgstr "ní féidir an líne a scriosadh"
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: Ní cheadaíonn NetBeans aon athrú i gcomhaid inléite amháin"
-#~ msgid "cannot replace line"
-#~ msgstr "ní féidir an líne a athchur"
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Earráid inmheánach: %s"
-#~ msgid "cannot insert line"
-#~ msgstr "ní féidir líne a ionsá"
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: úsáideann an patrún níos mó cuimhne ná 'maxmempattern'"
-#~ msgid "string cannot contain newlines"
-#~ msgstr "ní cheadaítear carachtair líne nua sa teaghrán"
+msgid "E749: empty buffer"
+msgstr "E749: maolán folamh"
-#~ msgid "Vim error: ~a"
-#~ msgstr "earráid Vim: ~a"
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Níl a leithéid de mhaolán %ld"
-#~ msgid "Vim error"
-#~ msgstr "earráid Vim"
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Patrún nó teormharcóir neamhbhailí cuardaigh"
-#~ msgid "buffer is invalid"
-#~ msgstr "maolán neamhbhailí"
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Tá an comhad luchtaithe i maolán eile"
-#~ msgid "window is invalid"
-#~ msgstr "fuinneog neamhbhailí"
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Rogha '%s' gan socrú"
-#~ msgid "linenr out of range"
-#~ msgstr "líne-uimhir as raon"
+msgid "E850: Invalid register name"
+msgstr "E850: Ainm neamhbhailí tabhaill"
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "ní cheadaítear é seo i mbosca gainimh Vim"
+#, c-format
+msgid "E919: Directory not found in '%s': \"%s\""
+msgstr "E919: Comhadlann gan aimsiú in '%s': \"%s\""
-#~ 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 "search hit TOP, continuing at BOTTOM"
+msgstr "Buaileadh an BARR le linn an chuardaigh, ag leanúint ag an CHRÍOCH"
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Ní féidir Python a rith go hathchúrsach"
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "Buaileadh an BUN le linn an chuardaigh, ag leanúint ag an BHARR"
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "ní féidir tréithe OutputObject a scriosadh"
+#, c-format
+msgid "Need encryption key for \"%s\""
+msgstr "Eochair chriptiúcháin le haghaidh \"%s\" de dhíth"
-#~ msgid "softspace must be an integer"
-#~ msgstr "caithfidh softspace a bheith ina shlánuimhir"
+msgid "empty keys are not allowed"
+msgstr "ní cheadaítear eochracha folmha"
-#~ msgid "invalid attribute"
-#~ msgstr "aitreabúid neamhbhailí"
+msgid "dictionary is locked"
+msgstr "tá an foclóir faoi ghlas"
-#~ msgid "writelines() requires list of strings"
-#~ msgstr "liosta teaghrán ag teastáil ó writelines()"
+msgid "list is locked"
+msgstr "tá an liosta faoi ghlas"
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: Earráid agus réada I/A á dtúsú"
+#, c-format
+msgid "failed to add key '%s' to dictionary"
+msgstr "níorbh fhéidir eochair '%s' a chur leis an bhfoclóir"
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "rinneadh iarracht ar mhaolán scriosta a rochtain"
+#, c-format
+msgid "index must be int or slice, not %s"
+msgstr "ní mór don innéacs a bheith ina shlánuimhir nó ina shlisne, seachas %s"
-#~ msgid "line number out of range"
-#~ msgstr "líne-uimhir as raon"
+#, c-format
+msgid "expected str() or unicode() instance, but got %s"
+msgstr "bhíothas ag súil le str() nó unicode(), ach fuarthas %s"
-#~ msgid "<buffer object (deleted) at %p>"
-#~ msgstr "<réad maoláin (scriosta) ag %p>"
+#, c-format
+msgid "expected bytes() or str() instance, but got %s"
+msgstr "bhíothas ag súil le bytes() nó str(), ach fuarthas %s"
-#~ msgid "invalid mark name"
-#~ msgstr "ainm neamhbhailí mairc"
+#, c-format
+msgid ""
+"expected int(), long() or something supporting coercing to long(), but got %s"
+msgstr ""
+"bhíothas ag súil le int(), long(), nó rud éigin inathraithe ina long(), ach "
+"fuarthas %s"
-#~ msgid "no such buffer"
-#~ msgstr "níl a leithéid de mhaolán ann"
+#, c-format
+msgid "expected int() or something supporting coercing to int(), but got %s"
+msgstr ""
+"bhíothas ag súil le int() nó rud éigin inathraithe ina int(), ach fuarthas %s"
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "rinneadh iarracht ar fhuinneog scriosta a rochtain"
+msgid "value is too large to fit into C int type"
+msgstr "tá an luach níos mó ná athróg int sa teanga C"
-#~ msgid "readonly attribute"
-#~ msgstr "tréith inléite amháin"
+msgid "value is too small to fit into C int type"
+msgstr "tá an luach níos lú ná athróg int sa teanga C"
-#~ msgid "cursor position outside buffer"
-#~ msgstr "cúrsóir taobh amuigh den mhaolán"
+msgid "number must be greater than zero"
+msgstr "ní mór don uimhir a bheith deimhneach"
-#~ msgid "<window object (deleted) at %p>"
-#~ msgstr "<réad fuinneoige (scriosta) ag %p>"
+msgid "number must be greater or equal to zero"
+msgstr "ní mór don uimhir a bheith >= 0"
-#~ msgid "<window object (unknown) at %p>"
-#~ msgstr "<réad fuinneoige (anaithnid) ag %p>"
+msgid "can't delete OutputObject attributes"
+msgstr "ní féidir tréithe OutputObject a scriosadh"
-#~ msgid "<window %d>"
-#~ msgstr "<fuinneog %d>"
+#, c-format
+msgid "invalid attribute: %s"
+msgstr "aitreabúid neamhbhailí: %s"
-#~ msgid "no such window"
-#~ msgstr "níl a leithéid d'fhuinneog ann"
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: Earráid agus réada I/A á dtúsú"
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: caithfidh $_ a bheith cineál Teaghráin"
+msgid "failed to change directory"
+msgstr "níorbh fhéidir an chomhadlann a athrú"
-#~ 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ú."
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got %s"
+msgstr ""
+"bhíothas ag súil le 3-chodach mar thoradh ar imp.find_module(), ach fuarthas "
+"%s"
+
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
+msgstr ""
+"bhíothas ag súil le 3-chodach mar thoradh ar imp.find_module(), ach fuarthas "
+"%d-chodach"
+
+msgid "internal error: imp.find_module returned tuple with NULL"
+msgstr "earráid inmheánach: fuarthas codach NULL ar ais ó imp.find_module"
+
+msgid "cannot delete vim.Dictionary attributes"
+msgstr "ní féidir tréithe vim.Dictionary a scriosadh"
+
+msgid "cannot modify fixed dictionary"
+msgstr "ní féidir foclóir socraithe a athrú"
+
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "ní féidir tréith %s a shocrú"
+
+msgid "hashtab changed during iteration"
+msgstr "athraíodh an haistáb le linn atriallta"
+
+#, c-format
+msgid "expected sequence element of size 2, but got sequence of size %d"
+msgstr "bhíothas ag súil le heilimint de mhéid 2, ach fuarthas méid %d"
+
+msgid "list constructor does not accept keyword arguments"
+msgstr "ní ghlacann cruthaitheoir an liosta le hargóintí eochairfhocail"
+
+msgid "list index out of range"
+msgstr "innéacs liosta as raon"
+
+#. No more suitable format specifications in python-2.3
+#, c-format
+msgid "internal error: failed to get vim list item %d"
+msgstr "earráid inmheánach: níl aon fháil ar mhír %d sa liosta vim"
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: \"return\" gan choinne"
+msgid "slice step cannot be zero"
+msgstr "ní cheadaítear slisne le céim 0"
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: \"next\" gan choinne"
+#, c-format
+msgid "attempt to assign sequence of size greater than %d to extended slice"
+msgstr "iarracht ar sheicheamh níos mó ná %d a shannadh do shlisne fadaithe"
+
+#, c-format
+msgid "internal error: no vim list item %d"
+msgstr "earráid inmheánach: níl aon mhír %d sa liosta vim"
+
+msgid "internal error: not enough list items"
+msgstr "earráid inmheánach: níl go leor míreanna liosta ann"
+
+msgid "internal error: failed to add item to list"
+msgstr "earráid inmheánach: níorbh fhéidir mír a chur leis an liosta"
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: \"break\" gan choinne"
+#, c-format
+msgid "attempt to assign sequence of size %d to extended slice of size %d"
+msgstr "iarracht ar sheicheamh de mhéid %d a shannadh do shlisne de mhéid %d"
+
+msgid "failed to add item to list"
+msgstr "níorbh fhéidir mír a chur leis an liosta"
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: \"redo\" gan choinne"
+msgid "cannot delete vim.List attributes"
+msgstr "ní féidir tréithe vim.List a scriosadh"
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: \"retry\" taobh amuigh de chlásal tarrthála"
+msgid "cannot modify fixed list"
+msgstr "ní féidir liosta socraithe a athrú"
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: eisceacht gan láimhseáil"
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "níl feidhm %s gan ainm ann"
+
+#, c-format
+msgid "function %s does not exist"
+msgstr "níl feidhm %s ann"
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: stádas anaithnid longjmp %d"
+#, c-format
+msgid "failed to run function %s"
+msgstr "níorbh fhéidir feidhm %s a rith"
+
+msgid "unable to get option value"
+msgstr "ní féidir luach na rogha a fháil"
+
+msgid "internal error: unknown option type"
+msgstr "earráid inmheánach: cineál rogha anaithnid"
+
+msgid "problem while switching windows"
+msgstr "tharla earráid agus an fhuinneog á hathrú"
+
+#, c-format
+msgid "unable to unset global option %s"
+msgstr "ní féidir rogha chomhchoiteann %s a dhíshocrú"
+
+#, c-format
+msgid "unable to unset option %s which does not have global value"
+msgstr "ní féidir rogha %s gan luach comhchoiteann a dhíshocrú"
+
+msgid "attempt to refer to deleted tab page"
+msgstr "tagairt déanta do leathanach cluaisíní scriosta"
+
+msgid "no such tab page"
+msgstr "níl a leithéid de leathanach cluaisíní ann"
+
+msgid "attempt to refer to deleted window"
+msgstr "rinneadh iarracht ar fhuinneog scriosta a rochtain"
+
+msgid "readonly attribute: buffer"
+msgstr "tréith inléite amháin: maolán"
+
+msgid "cursor position outside buffer"
+msgstr "cúrsóir taobh amuigh den mhaolán"
+
+msgid "no such window"
+msgstr "níl a leithéid d'fhuinneog ann"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "rinneadh iarracht ar mhaolán scriosta a rochtain"
+
+msgid "failed to rename buffer"
+msgstr "níorbh fhéidir ainm nua a chur ar an maolán"
+
+msgid "mark name must be a single character"
+msgstr "ní cheadaítear ach carachtar amháin in ainm an mhairc"
+
+#, c-format
+msgid "expected vim.Buffer object, but got %s"
+msgstr "bhíothas ag súil le réad vim.Buffer, ach fuarthas %s"
+
+#, c-format
+msgid "failed to switch to buffer %d"
+msgstr "níorbh fhéidir athrú go dtí maolán a %d"
+
+#, c-format
+msgid "expected vim.Window object, but got %s"
+msgstr "bhíothas ag súil le réad vim.Window, ach fuarthas %s"
+
+msgid "failed to find window in the current tab page"
+msgstr "níor aimsíodh fuinneog sa leathanach cluaisíní reatha"
+
+msgid "did not switch to the specified window"
+msgstr "níor athraíodh go dtí an fhuinneog roghnaithe"
+
+#, c-format
+msgid "expected vim.TabPage object, but got %s"
+msgstr "bhíothas ag súil le réad vim.TabPage, ach fuarthas %s"
+
+msgid "did not switch to the specified tab page"
+msgstr "níor athraíodh go dtí an leathanach cluaisíní roghnaithe"
+
+msgid "failed to run the code"
+msgstr "níorbh fhéidir an cód a chur ar siúl"
+
+msgid "E858: Eval did not return a valid python object"
+msgstr "E858: Ní bhfuarthas réad bailí python ar ais ó Eval"
+
+msgid "E859: Failed to convert returned python object to vim value"
+msgstr "E859: Níorbh fhéidir luach vim a dhéanamh as an réad python"
+
+#, c-format
+msgid "unable to convert %s to vim dictionary"
+msgstr "ní féidir foclóir vim a dhéanamh as %s"
+
+#, c-format
+msgid "unable to convert %s to vim list"
+msgstr "ní féidir liosta vim a dhéanamh as %s"
+
+#, c-format
+msgid "unable to convert %s to vim structure"
+msgstr "ní féidir struchtúr vim a dhéanamh as %s"
+
+msgid "internal error: NULL reference passed"
+msgstr "earráid inmheánach: tagairt NULL seolta"
+
+msgid "internal error: invalid value type"
+msgstr "earráid inmheánach: cineál neamhbhailí"
+
+msgid ""
+"Failed to set path hook: sys.path_hooks is not a list\n"
+"You should now do the following:\n"
+"- append vim.path_hook to sys.path_hooks\n"
+"- append vim.VIM_SPECIAL_PATH to sys.path\n"
+msgstr ""
+"Níorbh fhéidir path_hook a shocrú: ní liosta é sys.path_hooks\n"
+"Ba chóir duit na rudaí seo a leanas a dhéanamh:\n"
+"- cuir vim.path_hook le deireadh sys.path_hooks\n"
+"- cuir vim.VIM_SPECIAL_PATH le deireadh sys.path\n"
+
+msgid ""
+"Failed to set path: sys.path is not a list\n"
+"You should now append vim.VIM_SPECIAL_PATH to sys.path"
+msgstr ""
+"Níorbh fhéidir an chonair a shocrú: ní liosta é sys.path\n"
+"Ba chóir duit vim.VIM_SPECIAL_PATH a cheangal le deireadh sys.path"
+
+#~ msgid "E693: Can only compare Funcref with Funcref"
+#~ msgstr "E693: Is féidir Funcref a chur i gcomparáid le Funcref eile amháin"
+
+#~ msgid "E706: Variable type mismatch for: %s"
+#~ msgstr "E706: Mímheaitseáil idir cineálacha athróige: %s"
+
+#~ msgid "%ld characters"
+#~ msgstr "%ld carachtar"
#~ msgid "Toggle implementation/definition"
#~ msgstr "Scoránaigh feidhmiú/sainmhíniú"
@@ -7063,255 +7159,112 @@ msgstr "E446: Níl ainm comhaid faoin chúrsóir"
#~ msgid "Sniff: Error during write. Disconnected"
#~ msgstr "Sniff: Earráid sa scríobh. Dínasctha"
-#~ msgid "invalid buffer number"
-#~ msgstr "uimhir neamhbhailí mhaoláin"
-
-#~ msgid "not implemented yet"
-#~ msgstr "níl ar fáil"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "ní féidir lín(t)e a shocrú"
-
-#~ msgid "mark not set"
-#~ msgstr "marc gan socrú"
-
-#~ msgid "row %d column %d"
-#~ msgstr "líne %d colún %d"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "ní féidir líne a ionsá/iarcheangal"
-
-#~ msgid "unknown flag: "
-#~ msgstr "bratach anaithnid: "
-
-#~ msgid "unknown vimOption"
-#~ msgstr "vimOption anaithnid"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "idirbhriseadh méarchláir"
-
-#~ msgid "vim error"
-#~ msgstr "earráid vim"
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr "ní féidir ordú maoláin/fuinneoige a chruthú: réad á scriosadh"
-
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr ""
-#~ "ní féidir ordú aisghlaoch a chlárú: maolán/fuinneog á scriosadh cheana"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr ""
-#~ "E280: EARRÁID MHARFACH TCL: liosta truaillithe tagartha!? Seol tuairisc "
-#~ "fhabht chuig <vim-dev@vim.org> le do thoil"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr ""
-#~ "ní féidir ordú aisghlaoch a chlárú: tagairt mhaolán/fhuinneoige gan aimsiú"
-
-#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E571: Tá brón orm, níl an t-ordú seo le fáil: níorbh fhéidir an "
-#~ "leabharlann Tcl a luchtú."
+#~ msgid " Quit, or continue with caution.\n"
+#~ msgstr " Scoir, nó lean ar aghaidh go hairdeallach.\n"
-#~ msgid ""
-#~ "E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim."
-#~ "org"
-#~ msgstr ""
-#~ "E281: EARRÁID TCL: níl an cód scortha ina shlánuimhir!? Seol tuairisc "
-#~ "fhabht chuig <vim-dev@vim.org> le do thoil"
-
-#~ msgid "E572: exit code %d"
-#~ msgstr "E572: cód scortha %d"
+#~ msgid "Cannot connect to Netbeans #2"
+#~ msgstr "Ní féidir nascadh le Netbeans #2"
-#~ msgid "cannot get line"
-#~ msgstr "ní féidir an líne a fháil"
+#~ msgid "read from Netbeans socket"
+#~ msgstr "léadh ó shoicéad Netbeans"
-#~ msgid "Unable to register a command server name"
-#~ msgstr "Ní féidir ainm fhreastalaí ordaithe a chlárú"
+#~ msgid "'columns' is not 80, cannot execute external commands"
+#~ msgstr "ní 80 é 'columns', ní féidir orduithe seachtracha a rith"
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: Theip ar sheoladh ordú chuig an sprioc-chlár"
+#~ msgid "Could not set security context "
+#~ msgstr "Níorbh fhéidir comhthéacs slándála a shocrú "
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: Aitheantas neamhbhailí freastalaí in úsáid: %s"
+#~ msgid " for "
+#~ msgstr " le haghaidh "
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr "E251: Airí míchumtha sa chlárlann áisc VIM. Scriosta!"
+#~ msgid "Could not get security context "
+#~ msgstr "Níorbh fhéidir comhthéacs slándála a fháil "
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "Níor tiomsaíodh an leagan Vim seo le `diff' ar fáil."
+#~ msgid ". Removing it!\n"
+#~ msgstr ". Á scriosadh!\n"
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "Ní féidir '-nb' a úsáid: níor cumasaíodh é ag am tiomsaithe\n"
+#~ msgid " (lang)"
+#~ msgstr " (teanga)"
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: Earráid: Theip ar thosú gvim ó NetBeans\n"
+#~ msgid "E759: Format error in spell file"
+#~ msgstr "E759: Earráid fhormáide i gcomhad litrithe"
#~ msgid ""
#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
+#~ "MS-Windows 16/32-bit GUI version"
#~ msgstr ""
#~ "\n"
-#~ "Nuair nach cásíogair é, cuir '/' ag tosach na brataí chun í a chur sa "
-#~ "chás uachtair"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\tCláraigh an gvim seo le haghaidh OLE"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tDíchláraigh an gvim seo le haghaidh OLE"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tRith agus úsáid an GUI (mar \"gvim\")"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f nó --nofork\tTulra: Ná déan forc agus an GUI á thosú"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\tNá húsáid newcli chun fuinneog a oscailt"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <gléas>\t\tBain úsáid as <gléas> do I/A"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\tBain úsáid as <gvimrc> in ionad aon .gvimrc"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\tCuir comhaid chriptithe in eagar"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <freastalaí>\tNasc vim leis an bhfreastalaí-X seo"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tNá naisc leis an bhfreastalaí X"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr ""
-#~ "--remote <comhaid>\tCuir <comhaid> in eagar le freastalaí Vim más féidir"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-silent <comhaid> Mar an gcéanna, ná déan gearán mura bhfuil "
-#~ "freastalaí ann"
-
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr ""
-#~ "--remote-wait <comhaid> Mar --remote ach fan leis na comhaid a bheith "
-#~ "curtha in eagar"
-
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-wait-silent <comhaid> Mar an gcéanna, ná déan gearán mura "
-#~ "bhfuil freastalaí ann"
-
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <comhaid> Cosúil le --remote ach oscail "
-#~ "cluaisín do gach comhad"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr ""
-#~ "--remote-send <eochracha>\tSeol <eochracha> chuig freastalaí Vim agus "
-#~ "scoir"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr ""
-#~ "--remote-expr <slonn>\tLuacháil <slonn> le freastalaí Vim agus taispeáin "
-#~ "an toradh"
-
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr "--serverlist\t\tTaispeáin freastalaithe Vim atá ar fáil agus scoir"
+#~ "Leagan GUI 16/32 giotán MS-Windows"
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <ainm>\tSeol chuig/Téigh i do fhreastalaí Vim <ainm>"
+#~ msgid " in Win32s mode"
+#~ msgstr " i mód Win32s"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
+#~ "MS-Windows 16-bit version"
#~ msgstr ""
#~ "\n"
-#~ "Argóintí ar eolas do gvim (leagan Motif):\n"
+#~ "Leagan 16 giotán MS-Windows"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
+#~ "32-bit MS-DOS version"
#~ msgstr ""
#~ "\n"
-#~ "Argóintí ar eolas do gvim (leagan neXtaw):\n"
+#~ "Leagan 32 giotán MS-DOS"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
+#~ "16-bit MS-DOS version"
#~ msgstr ""
#~ "\n"
-#~ "Argóintí ar eolas do gvim (leagan Athena):\n"
+#~ "Leagan 16 giotán MS-DOS"
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <scáileán>\tRith vim ar <scáileán>"
+#~ msgid "WARNING: Windows 95/98/ME detected"
+#~ msgstr "RABHADH: Braitheadh Windows 95/98/ME"
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tTosaigh vim sa mhód íoslaghdaithe"
+#~ msgid "type :help windows95<Enter> for info on this"
+#~ msgstr "clóscríobh :help windows95<Enter> chun eolas a fháil "
-#~ msgid "-name <name>\t\tUse resource as if vim was <name>"
-#~ msgstr "-name <ainm>\t\tÚsáid acmhainn mar a bheadh vim <ainm>"
+#~ msgid "function constructor does not accept keyword arguments"
+#~ msgstr "ní ghlacann cruthaitheoir na feidhme le hargóintí eochairfhocail"
-#~ msgid "\t\t\t (Unimplemented)\n"
-#~ msgstr "\t\t\t (Níl ar fáil)\n"
+#~ msgid "Vim dialog..."
+#~ msgstr "Dialóg Vim..."
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <dath>\tBain úsáid as <dath> don chúlra (-bg fosta)"
+#~ msgid "Font Selection"
+#~ msgstr "Roghnú Cló"
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr ""
-#~ "-foreground <dath>\tÚsáid <dath> le haghaidh gnáth-théacs (fosta: -fg)"
+#~ msgid "softspace must be an integer"
+#~ msgstr "caithfidh softspace a bheith ina shlánuimhir"
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <cló>\t\tÚsáid <cló> le haghaidh gnáth-théacs (fosta: -fn)"
+#~ msgid "writelines() requires list of strings"
+#~ msgstr "liosta teaghrán ag teastáil ó writelines()"
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <cló>\tBain úsáid as <cló> do chló trom"
+#~ msgid "<buffer object (deleted) at %p>"
+#~ msgstr "<réad maoláin (scriosta) ag %p>"
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <cló>\tÚsáid <cló> le haghaidh téacs iodálach"
+#~ msgid "<window object (deleted) at %p>"
+#~ msgstr "<réad fuinneoige (scriosta) ag %p>"
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr ""
-#~ "-geometry <geoim>\tÚsáid <geoim> le haghaidh na céimseatan tosaigh "
-#~ "(fosta: -geom)"
+#~ msgid "<window object (unknown) at %p>"
+#~ msgstr "<réad fuinneoige (anaithnid) ag %p>"
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <leithead>\tSocraigh <leithead> na himlíne (-bw fosta)"
+#~ msgid "<window %d>"
+#~ msgstr "<fuinneog %d>"
#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <leithead> Socraigh leithead na scrollbharraí a bheith "
-#~ "<leithead> (fosta: -sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+#~ "E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim."
+#~ "org"
#~ msgstr ""
-#~ "-menuheight <airde>\tSocraigh airde an bharra roghchláir a bheith <airde> "
-#~ "(fosta: -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tÚsáid fís aisiompaithe (fosta: -rv)"
+#~ "E281: EARRÁID TCL: níl an cód scortha ina shlánuimhir!? Seol tuairisc "
+#~ "fhabht chuig <vim-dev@vim.org> le do thoil"
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tNá húsáid fís aisiompaithe (fosta: +rv)"
+#~ msgid "-name <name>\t\tUse resource as if vim was <name>"
+#~ msgstr "-name <ainm>\t\tÚsáid acmhainn mar a bheadh vim <ainm>"
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <acmhainn>\tSocraigh an acmhainn sainithe"
+#~ msgid "\t\t\t (Unimplemented)\n"
+#~ msgstr "\t\t\t (Níl ar fáil)\n"
#~ msgid ""
#~ "\n"
@@ -7326,66 +7279,6 @@ msgstr "E446: Níl ainm comhaid faoin chúrsóir"
#~ msgid "--rows <number>\tInitial height of window in rows"
#~ msgstr "--rows <uimhir>\tAirde fhuinneoige i dtosach (rónna)"
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argóintí ar eolas do gvim (leagan GTK+):\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <scáileán>\tRith vim ar <scáileán> (fosta: --display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr ""
-#~ "--role <ról>\tSocraigh ról sainiúil chun an phríomhfhuinneog a aithint"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tOscail Vim isteach i ngiuirléid GTK eile"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <máthairchlár>\tOscail Vim isteach sa mháthairchlár"
-
-#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
-#~ msgstr "--windowid <HWND>\tOscail Vim isteach i ngiuirléid win32 eile"
-
-#~ msgid "No display"
-#~ msgstr "Gan taispeáint"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr ": Theip ar seoladh.\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": Theip ar seoladh. Ag baint triail as go logánta\n"
-
-#~ msgid "%d of %d edited"
-#~ msgstr "%d as %d déanta"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "Gan taispeáint: Theip ar sheoladh sloinn.\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": Theip ar sheoladh sloinn.\n"
-
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: Ní códleathanach bailí é"
-
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: Theip ar chruthú comhthéacs ionchuir"
-
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: Theip ar oscailt mhodh ionchuir"
-
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
-#~ msgstr ""
-#~ "E287: Rabhadh: Níorbh fhéidir aisghlaoch léirscriosta a shocrú le IM"
-
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: Ní thacaíonn an modh ionchuir aon stíl"
-
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr "E289: ní thacaíonn an modh ionchuir mo chineál réamheagair"
-
#~ msgid "E290: over-the-spot style requires fontset"
#~ msgstr "E290: tacar cló ag teastáil ó stíl thar-an-spota"
@@ -7397,197 +7290,15 @@ msgstr "E446: Níl ainm comhaid faoin chúrsóir"
#~ msgid "E292: Input Method Server is not running"
#~ msgstr "E292: Níl an Freastalaí Mhodh Ionchuir ag rith"
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [ní inúsáidte leis an leagan seo Vim]"
-
-#~ msgid "Tear off this menu"
-#~ msgstr "Bain an roghchlár seo"
-
-#~ msgid "Select Directory dialog"
-#~ msgstr "Dialóg `Roghnaigh Comhadlann'"
-
-#~ msgid "Save File dialog"
-#~ msgstr "Dialóg `Sábháil Comhad'"
-
-#~ msgid "Open File dialog"
-#~ msgstr "Dialóg `Oscail Comhad'"
-
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: Níl brabhsálaí comhaid ar fáil sa mhód consóil"
-
#~ msgid "Vim: preserving files...\n"
#~ msgstr "Vim: comhaid á gcaomhnú...\n"
#~ msgid "Vim: Finished.\n"
#~ msgstr "Vim: Críochnaithe.\n"
-#~ msgid "ERROR: "
-#~ msgstr "EARRÁID: "
-
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[beart] iomlán dáilte-saor %<PRIu64>-%<PRIu64>, in úsáid %<PRIu64>, buaic "
-#~ "%<PRIu64>\n"
-
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[glaonna] re/malloc(): %<PRIu64>, free(): %<PRIu64>\n"
-#~ "\n"
-
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: Tá an líne ag éirí rófhada"
-
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: Earráid inmheánach: lalloc(%<PRId64>, )"
-
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: Cruth neamhcheadaithe luiche"
-
-#~ msgid "Enter encryption key: "
-#~ msgstr "Iontráil eochair chriptiúcháin: "
-
-#~ msgid "Enter same key again: "
-#~ msgstr "Iontráil an eochair arís: "
-
-#~ msgid "Keys don't match!"
-#~ msgstr "Níl na heochracha comhoiriúnach le chéile!"
-
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Ní féidir nascadh le Netbeans #2"
-
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Ní féidir nascadh le Netbeans"
-
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr ""
-#~ "E668: Mód mícheart rochtana ar an chomhad eolas naisc NetBeans: \"%s\""
-
-#~ msgid "read from Netbeans socket"
-#~ msgstr "léadh ó shoicéad Netbeans"
-
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: Cailleadh nasc NetBeans le haghaidh maoláin %<PRId64>"
-
#~ msgid "E505: "
#~ msgstr "E505: "
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: Níl an ghné Eval le fáil"
-
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "%<PRId64> líne á saoradh"
-
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: Ní féidir 'term' a athrú sa GUI"
-
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: Úsáid \":gui\" chun an GUI a chur ag obair"
-
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: Ní féidir é a athrú sa GUI GTK+ 2"
-
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: Cló(nna) neamhbhailí"
-
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: ní féidir tacar cló a roghnú"
-
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: Tacar cló neamhbhailí"
-
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: ní féidir cló leathan a roghnú"
-
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: Cló leathan neamhbhailí"
-
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: Gan tacaíocht luiche"
-
-#~ msgid "cannot open "
-#~ msgstr "ní féidir a oscailt: "
-
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: Ní féidir fuinneog a oscailt!\n"
-
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Tá gá le Amigados leagan 2.04 nó níos déanaí\n"
-
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "Tá gá le %s, leagan %<PRId64>\n"
-
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "Ní féidir NIL a oscailt:\n"
-
-#~ msgid "Cannot create "
-#~ msgstr "Ní féidir a chruthú: "
-
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim á scor le stádas %d\n"
-
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "ní féidir mód consóil a athrú ?!\n"
-
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: ní consól é seo??\n"
-
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: Ní féidir blaosc a rith le rogha -f"
-
-#~ msgid "Cannot execute "
-#~ msgstr "Ní féidir blaosc a rith: "
-
-#~ msgid "shell "
-#~ msgstr "blaosc "
-
-#~ msgid " returned\n"
-#~ msgstr " aisfhilleadh\n"
-
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE róbheag."
-
-#~ msgid "I/O ERROR"
-#~ msgstr "EARRÁID I/A"
-
-#~ msgid "Message"
-#~ msgstr "Teachtaireacht"
-
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "ní 80 é 'columns', ní féidir orduithe seachtracha a rith"
-
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: Theip ar roghnú printéara"
-
-#~ msgid "to %s on %s"
-#~ msgstr "go %s ar %s"
-
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: Clófhoireann anaithnid printéara: %s"
-
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: Earráid phriontála: %s"
-
-#~ msgid "Printing '%s'"
-#~ msgstr "'%s' á phriontáil"
-
-#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
-#~ msgstr ""
-#~ "E244: Ainm neamhcheadaithe ar thacar carachtar \"%s\" mar pháirt d'ainm "
-#~ "cló \"%s\""
-
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: Carachtar neamhcheadaithe '%c' mar pháirt d'ainm cló \"%s\""
-
#~ msgid "Vim: Double signal, exiting\n"
#~ msgstr "Vim: Comhartha dúbailte, ag scor\n"
@@ -7597,419 +7308,23 @@ msgstr "E446: Níl ainm comhaid faoin chúrsóir"
#~ msgid "Vim: Caught deadly signal\n"
#~ msgstr "Vim: Fuarthas comhartha marfach\n"
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "Thóg %<PRId64> ms chun an scáileán X a oscailt"
-
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim: Fuarthas earráid ó X\n"
-
-#~ msgid "Testing the X display failed"
-#~ msgstr "Theip ar thástáil an scáileáin X"
-
-#~ msgid "Opening the X display timed out"
-#~ msgstr "Oscailt an scáileáin X thar am"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ní féidir an bhlaosc sh a rith\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ní féidir píopaí a chruthú\n"
-
-# "fork" not in standard refs/corpus. Maybe want a "gabhl*" word instead? -KPS
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ní féidir forc a dhéanamh\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ordú críochnaithe\n"
-
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "Chaill XSMP an nasc ICE"
-
-#~ msgid "Opening the X display failed"
-#~ msgstr "Theip ar oscailt an scáileáin X"
-
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "Iarratas sábháil-do-féin á láimhseáil ag XSMP"
-
-#~ msgid "XSMP opening connection"
-#~ msgstr "Nasc á oscailt ag XSMP"
-
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "Theip ar fhaire nasc ICE XSMP"
-
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "Theip ar XSMP SmcOpenConnection: %s"
-
-#~ msgid "At line"
-#~ msgstr "Ag líne"
-
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "Níorbh fhéidir vim32.dll a luchtú!"
-
-#~ msgid "VIM Error"
-#~ msgstr "Earráid VIM"
-
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "Níorbh fhéidir pointeoirí feidhme a chóiriú i gcomhair an DLL!"
-
-#~ msgid "shell returned %d"
-#~ msgstr "d'aisfhill an bhlaosc %d"
-
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: Fuarthas teagmhas %s\n"
-
-#~ msgid "close"
-#~ msgstr "dún"
-
-#~ msgid "logoff"
-#~ msgstr "logáil amach"
-
-#~ msgid "shutdown"
-#~ msgstr "múchadh"
-
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: Ní bhfuarthas an t-ordú"
-
-#~ msgid ""
-#~ "VIMRUN.EXE not found in your $PATH.\n"
-#~ "External commands will not pause after completion.\n"
-#~ "See :help win32-vimrun for more information."
-#~ msgstr ""
-#~ "Níor aimsíodh VIMRUN.EXE i do $PATH.\n"
-#~ "Ní mhoilleoidh orduithe seachtracha agus iad curtha i gcrích.\n"
-#~ "Féach ar :help win32-vimrun chun níos mó eolas a fháil."
-
-#~ msgid "Vim Warning"
-#~ msgstr "Rabhadh Vim"
-
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "Tiontú i %s gan tacaíocht"
-
#~ msgid "E396: containedin argument not accepted here"
#~ msgstr "E396: ní ghlactar leis an argóint containedin anseo"
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: Teascadh conair an chomhaid clibeanna le haghaidh %s\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "tosaíodh blaosc nua\n"
-
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "Úsáideadh CUT_BUFFER0 in ionad roghnúcháin folaimh"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "Ní féidir a chealú; lean ar aghaidh mar sin féin"
-
# columns?
#~ msgid "number changes time"
#~ msgstr "uimhir athruithe am"
#~ msgid ""
#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan GUI 16/32 giotán MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan GUI 64 giotán MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan GUI 32 giotán MS-Windows"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " i mód Win32s"
-
-#~ msgid " with OLE support"
-#~ msgstr " le tacaíocht OLE"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan consóil 64 giotán MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan consóil 32 giotán MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan 16 giotán MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan 32 giotán MS-DOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan 16 giotán MS-DOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan MacOS X (unix)"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan MacOS X"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan MacOS"
-
-#~ msgid ""
-#~ "\n"
#~ "RISC OS version"
#~ msgstr ""
#~ "\n"
#~ "Leagan RISC OS"
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan OpenVMS"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan mór "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan coitianta "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan beag "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan beag bídeach "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "le GUI GTK2-GNOME."
-
#~ msgid "with GTK-GNOME GUI."
#~ msgstr "le GUI GTK-GNOME."
-#~ msgid "with GTK2 GUI."
-#~ msgstr "le GUI GTK2."
-
-#~ msgid "with GTK GUI."
-#~ msgstr "le GUI GTK."
-
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "le GUI X11-Motif."
-
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "le GUI X11-neXtaw."
-
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "le GUI X11-Athena."
-
-#~ msgid "with Photon GUI."
-#~ msgstr "le GUI Photon."
-
-#~ msgid "with GUI."
-#~ msgstr "le GUI."
-
-#~ msgid "with Carbon GUI."
-#~ msgstr "le GUI Carbon."
-
-#~ msgid "with Cocoa GUI."
-#~ msgstr "le GUI Cocoa."
-
-#~ msgid "with (classic) GUI."
-#~ msgstr "le GUI (clasaiceach)."
-
-#~ msgid " system gvimrc file: \""
-#~ msgstr " comhad gvimrc córais: \""
-
-#~ msgid " user gvimrc file: \""
-#~ msgstr " comhad gvimrc úsáideora: \""
-
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr "dara comhad gvimrc úsáideora: \""
-
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr "tríú comhad gvimrc úsáideora: \""
-
-#~ msgid " system menu file: \""
-#~ msgstr " comhad roghchláir an chórais: \""
-
-#~ msgid "Compiler: "
-#~ msgstr "Tiomsaitheoir: "
-
-# don't see where to localize "Help->Orphans"? --kps
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "roghchlár Help->Orphans chun eolas a fháil "
-
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "Á rith gan mhóid, ag ionsá an téacs atá iontráilte"
-
-# same problem --kps
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "roghchlár Edit->Global Settings->Toggle Insert Mode "
-
-#~ msgid " for two modes "
-#~ msgstr " do dhá mhód "
-
-# same problem --kps
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "roghchlár Edit->Global Settings->Toggle Vi Compatible"
-
-#~ msgid " for Vim defaults "
-#~ msgstr " le haghaidh réamhshocruithe Vim "
-
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "RABHADH: Braitheadh Windows 95/98/ME"
-
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr "clóscríobh :help windows95<Enter> chun eolas a fháil "
-
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: Níorbh fhéidir an leabharlann %s a oscailt"
-
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr ""
-#~ "Tá brón orm, níl an t-ordú seo le fáil: níorbh fhéidir an leabharlann "
-#~ "Perl a luchtú."
-
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr ""
-#~ "E299: Ní cheadaítear luacháil Perl i mbosca gainimh gan an modúl Safe"
-
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "Cuir in eagar le Vimeanna io&madúla"
-
-#~ msgid "Edit with single &Vim"
-#~ msgstr "Cuir in eagar le &Vim aonair"
-
-#~ msgid "Diff with Vim"
-#~ msgstr "Diff le Vim"
-
-#~ msgid "Edit with &Vim"
-#~ msgstr "Cuir in Eagar le &Vim"
-
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "Cuir in Eagar le Vim beo - "
-
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "Cuir an comhad roghnaithe in eagar le Vim"
-
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr ""
-#~ "Earráid agus próiseas á chruthú: Deimhnigh go bhfuil gvim i do chonair!"
-
-#~ msgid "gvimext.dll error"
-#~ msgstr "earráid gvimext.dll"
-
-#~ msgid "Path length too long!"
-#~ msgstr "Conair rófhada!"
-
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: Tacar cló anaithnid: %s"
-
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: Clófhoireann anaithnid: %s"
-
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: Ní cló aonleithid é \"%s\""
-
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: Ní féidir feidhm %s leabharlainne a luchtú"
-
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E26: Níl tacaíocht Eabhraise ar fáil: Níor cumasaíodh é ag am tiomsaithe\n"
-
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E27: Níl tacaíocht Pheirsise ar fáil: Níor cumasaíodh é ag am tiomsaithe\n"
-
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E800: Níl tacaíocht Araibise ar fáil: Níor cumasaíodh é ag am tiomsaithe\n"
-
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: níl aon fhreastalaí cláraithe leis an ainm \"%s\""
-
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: ní féidir an scáileán a oscailt"
-
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: Fuarthas slonn neamhbhailí"
-
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: Réigiún cosanta, ní féidir é a athrú"
-
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: Ní cheadaíonn NetBeans aon athrú i gcomhaid inléite amháin"
-
#~ msgid "E569: maximum number of cscope connections reached"
#~ msgstr "E569: ní cheadaítear níos mó ná an líon uasta nasc cscope"
@@ -8070,8 +7385,8 @@ msgstr "E446: Níl ainm comhaid faoin chúrsóir"
#~ msgstr ""
#~ "Ní mór do charachtar a úsáidtear ar SLASH a bheith ASCII; i %s líne %d: %s"
-#~ msgid "%<PRId64> changes"
-#~ msgstr "%<PRId64> athrú"
+#~ msgid "%ld changes"
+#~ msgstr "%ld athrú"
#~ msgid "with KDE GUI."
#~ msgstr "le GUI KDE."
diff --git a/src/nvim/po/it.po b/src/nvim/po/it.po
index 6c62262675..b8b119ade6 100644
--- a/src/nvim/po/it.po
+++ b/src/nvim/po/it.po
@@ -2541,7 +2541,7 @@ msgstr "E490: Non trovo alcuna piegatura"
#: ../fold.c:544
msgid "E350: Cannot create fold with current 'foldmethod'"
-msgstr "E350: Non posso create piegatura con il 'foldmethod' in uso"
+msgstr "E350: Non posso creare piegatura con il 'foldmethod' in uso"
#: ../fold.c:546
msgid "E351: Cannot delete fold with current 'foldmethod'"
diff --git a/src/nvim/po/ja.euc-jp.po b/src/nvim/po/ja.euc-jp.po
index c6425324b1..4b32096f1a 100644
--- a/src/nvim/po/ja.euc-jp.po
+++ b/src/nvim/po/ja.euc-jp.po
@@ -1,3 +1,4 @@
+
# Japanese translation for Vim
#
# Do ":help uganda" in Vim to read copying and usage conditions.
@@ -14,213 +15,176 @@ msgid ""
msgstr ""
"Project-Id-Version: Vim 7.4\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-02-01 09:02+0900\n"
-"PO-Revision-Date: 2016-02-01 09:08+0900\n"
+"POT-Creation-Date: 2016-09-10 21:10+0900\n"
+"PO-Revision-Date: 2016-09-10 21:20+0900\n"
"Last-Translator: MURAOKA Taro <koron.kaoriya@gmail.com>\n"
"Language-Team: vim-jp (https://github.com/vim-jp/lang-ja)\n"
"Language: Japanese\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=euc-jp\n"
"Content-Transfer-Encoding: 8-bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "¥ª¥×¥·¥ç¥ó¤ÎÃͤϼèÆÀ¤Ç¤­¤Þ¤»¤ó"
+msgid "E831: bf_key_init() called with empty password"
+msgstr "E831: bf_key_init() ¤¬¶õ¥Ñ¥¹¥ï¡¼¥É¤Ç¸Æ¤Ó½Ð¤µ¤ì¤Þ¤·¤¿"
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr "ÆâÉô¥¨¥é¡¼: ̤ÃΤΥª¥×¥·¥ç¥ó·¿¤Ç¤¹"
+msgid "E820: sizeof(uint32_t) != 4"
+msgstr "E820: sizeof(uint32_t) != 4"
+
+msgid "E817: Blowfish big/little endian use wrong"
+msgstr "E817: Blowfish°Å¹æ¤Î¥Ó¥Ã¥°/¥ê¥È¥ë¥¨¥ó¥Ç¥£¥¢¥ó¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
+
+msgid "E818: sha256 test failed"
+msgstr "E818: sha256¤Î¥Æ¥¹¥È¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "E819: Blowfish test failed"
+msgstr "E819: Blowfish°Å¹æ¤Î¥Æ¥¹¥È¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../buffer.c:92
msgid "[Location List]"
msgstr "[¥í¥±¡¼¥·¥ç¥ó¥ê¥¹¥È]"
-#: ../buffer.c:93
msgid "[Quickfix List]"
msgstr "[Quickfix¥ê¥¹¥È]"
-#: ../buffer.c:94
msgid "E855: Autocommands caused command to abort"
msgstr "E855: autocommand¤¬¥³¥Þ¥ó¥É¤ÎÄä»ß¤ò°ú¤­µ¯¤³¤·¤Þ¤·¤¿"
-#: ../buffer.c:135
msgid "E82: Cannot allocate any buffer, exiting..."
msgstr "E82: ¥Ð¥Ã¥Õ¥¡¤ò1¤Ä¤âºîÀ®¤Ç¤­¤Ê¤¤¤Î¤Ç, ½ªÎ»¤·¤Þ¤¹..."
-#: ../buffer.c:138
msgid "E83: Cannot allocate buffer, using other one..."
msgstr "E83: ¥Ð¥Ã¥Õ¥¡¤òºîÀ®¤Ç¤­¤Ê¤¤¤Î¤Ç, ¾¤Î¤ò»ÈÍѤ·¤Þ¤¹..."
-#: ../buffer.c:763
+msgid "E931: Buffer cannot be registered"
+msgstr "E931: ¥Ð¥Ã¥Õ¥¡¤òÅÐÏ¿¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E937: Attempt to delete a buffer that is in use"
+msgstr "E937: »ÈÍÑÃæ¤Î¥Ð¥Ã¥Õ¥¡¤òºï½ü¤·¤è¤¦¤È»î¤ß¤Þ¤·¤¿"
+
msgid "E515: No buffers were unloaded"
msgstr "E515: ²òÊü¤µ¤ì¤¿¥Ð¥Ã¥Õ¥¡¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../buffer.c:765
msgid "E516: No buffers were deleted"
msgstr "E516: ºï½ü¤µ¤ì¤¿¥Ð¥Ã¥Õ¥¡¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../buffer.c:767
msgid "E517: No buffers were wiped out"
msgstr "E517: ÇË´þ¤µ¤ì¤¿¥Ð¥Ã¥Õ¥¡¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../buffer.c:772
msgid "1 buffer unloaded"
msgstr "1 ¸Ä¤Î¥Ð¥Ã¥Õ¥¡¤¬²òÊü¤µ¤ì¤Þ¤·¤¿"
-#: ../buffer.c:774
#, c-format
msgid "%d buffers unloaded"
msgstr "%d ¸Ä¤Î¥Ð¥Ã¥Õ¥¡¤¬²òÊü¤µ¤ì¤Þ¤·¤¿"
-#: ../buffer.c:777
msgid "1 buffer deleted"
msgstr "1 ¸Ä¤Î¥Ð¥Ã¥Õ¥¡¤¬ºï½ü¤µ¤ì¤Þ¤·¤¿"
-#: ../buffer.c:779
#, c-format
msgid "%d buffers deleted"
msgstr "%d ¸Ä¤Î¥Ð¥Ã¥Õ¥¡¤¬ºï½ü¤µ¤ì¤Þ¤·¤¿"
-#: ../buffer.c:782
msgid "1 buffer wiped out"
msgstr "1 ¸Ä¤Î¥Ð¥Ã¥Õ¥¡¤¬ÇË´þ¤µ¤ì¤Þ¤·¤¿"
-#: ../buffer.c:784
#, c-format
msgid "%d buffers wiped out"
msgstr "%d ¸Ä¤Î¥Ð¥Ã¥Õ¥¡¤¬ÇË´þ¤µ¤ì¤Þ¤·¤¿"
-#: ../buffer.c:806
msgid "E90: Cannot unload last buffer"
msgstr "E90: ºÇ¸å¤Î¥Ð¥Ã¥Õ¥¡¤Ï²òÊü¤Ç¤­¤Þ¤»¤ó"
-#: ../buffer.c:874
msgid "E84: No modified buffer found"
msgstr "E84: Êѹ¹¤µ¤ì¤¿¥Ð¥Ã¥Õ¥¡¤Ï¤¢¤ê¤Þ¤»¤ó"
#. back where we started, didn't find anything.
-#: ../buffer.c:903
msgid "E85: There is no listed buffer"
msgstr "E85: ¥ê¥¹¥Èɽ¼¨¤µ¤ì¤ë¥Ð¥Ã¥Õ¥¡¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../buffer.c:913
-#, c-format
-msgid "E86: Buffer %<PRId64> does not exist"
-msgstr "E86: ¥Ð¥Ã¥Õ¥¡ %<PRId64> ¤Ï¤¢¤ê¤Þ¤»¤ó"
-
-#: ../buffer.c:915
msgid "E87: Cannot go beyond last buffer"
msgstr "E87: ºÇ¸å¤Î¥Ð¥Ã¥Õ¥¡¤ò±Û¤¨¤Æ°Üư¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../buffer.c:917
msgid "E88: Cannot go before first buffer"
msgstr "E88: ºÇ½é¤Î¥Ð¥Ã¥Õ¥¡¤è¤êÁ°¤Ø¤Ï°Üư¤Ç¤­¤Þ¤»¤ó"
-#: ../buffer.c:945
#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
-msgstr "E89: ¥Ð¥Ã¥Õ¥¡ %<PRId64> ¤ÎÊѹ¹¤ÏÊݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó (! ¤ÇÊѹ¹¤òÇË´þ)"
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr "E89: ¥Ð¥Ã¥Õ¥¡ %ld ¤ÎÊѹ¹¤ÏÊݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó (! ¤ÇÊѹ¹¤òÇË´þ)"
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
msgid "W14: Warning: List of file names overflow"
msgstr "W14: ·Ù¹ð: ¥Õ¥¡¥¤¥ë̾¤Î¥ê¥¹¥È¤¬Ä¹²á¤®¤Þ¤¹"
-#: ../buffer.c:1555 ../quickfix.c:3361
#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: ¥Ð¥Ã¥Õ¥¡ %<PRId64> ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+msgid "E92: Buffer %ld not found"
+msgstr "E92: ¥Ð¥Ã¥Õ¥¡ %ld ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../buffer.c:1798
#, c-format
msgid "E93: More than one match for %s"
msgstr "E93: %s ¤ËÊ£¿ô¤Î³ºÅö¤¬¤¢¤ê¤Þ¤·¤¿"
-#: ../buffer.c:1800
#, c-format
msgid "E94: No matching buffer for %s"
msgstr "E94: %s ¤Ë³ºÅö¤¹¤ë¥Ð¥Ã¥Õ¥¡¤Ï¤¢¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../buffer.c:2161
#, c-format
-msgid "line %<PRId64>"
-msgstr "¹Ô %<PRId64>"
+msgid "line %ld"
+msgstr "¹Ô %ld"
-#: ../buffer.c:2233
msgid "E95: Buffer with this name already exists"
msgstr "E95: ¤³¤Î̾Á°¤Î¥Ð¥Ã¥Õ¥¡¤Ï´û¤Ë¤¢¤ê¤Þ¤¹"
-#: ../buffer.c:2498
msgid " [Modified]"
msgstr " [Êѹ¹¤¢¤ê]"
-#: ../buffer.c:2501
msgid "[Not edited]"
msgstr "[̤ÊÔ½¸]"
-#: ../buffer.c:2504
msgid "[New file]"
msgstr "[¿·¥Õ¥¡¥¤¥ë]"
-#: ../buffer.c:2505
msgid "[Read errors]"
msgstr "[ÆÉ¹þ¥¨¥é¡¼]"
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
msgid "[RO]"
msgstr "[ÆÉÀì]"
-#: ../buffer.c:2507 ../fileio.c:1807
msgid "[readonly]"
msgstr "[ÆÉ¹þÀìÍÑ]"
-#: ../buffer.c:2524
#, c-format
msgid "1 line --%d%%--"
msgstr "1 ¹Ô --%d%%--"
-#: ../buffer.c:2526
#, c-format
-msgid "%<PRId64> lines --%d%%--"
-msgstr "%<PRId64> ¹Ô --%d%%--"
+msgid "%ld lines --%d%%--"
+msgstr "%ld ¹Ô --%d%%--"
-#: ../buffer.c:2530
#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "¹Ô %<PRId64> (Á´ÂÎ %<PRId64>) --%d%%-- col "
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "¹Ô %ld (Á´ÂÎ %ld) --%d%%-- col "
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
msgid "[No Name]"
msgstr "[̵̾]"
#. must be a help buffer
-#: ../buffer.c:2667
msgid "help"
msgstr "¥Ø¥ë¥×"
-#: ../buffer.c:3225 ../screen.c:4883
msgid "[Help]"
msgstr "[¥Ø¥ë¥×]"
-#: ../buffer.c:3254 ../screen.c:4887
msgid "[Preview]"
msgstr "[¥×¥ì¥Ó¥å¡¼]"
-#: ../buffer.c:3528
msgid "All"
msgstr "Á´¤Æ"
-#: ../buffer.c:3528
msgid "Bot"
msgstr "ËöÈø"
-#: ../buffer.c:3531
msgid "Top"
msgstr "ÀèÆ¬"
-#: ../buffer.c:4244
msgid ""
"\n"
"# Buffer list:\n"
@@ -228,11 +192,9 @@ msgstr ""
"\n"
"# ¥Ð¥Ã¥Õ¥¡¥ê¥¹¥È:\n"
-#: ../buffer.c:4289
msgid "[Scratch]"
msgstr "[²¼½ñ¤­]"
-#: ../buffer.c:4529
msgid ""
"\n"
"--- Signs ---"
@@ -240,200 +202,235 @@ msgstr ""
"\n"
"--- ¥µ¥¤¥ó ---"
-#: ../buffer.c:4538
#, c-format
msgid "Signs for %s:"
msgstr "%s ¤Î¥µ¥¤¥ó:"
-#: ../buffer.c:4543
#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " ¹Ô=%<PRId64> ¼±ÊÌ»Ò=%d ̾Á°=%s"
+msgid " line=%ld id=%d name=%s"
+msgstr " ¹Ô=%ld ¼±ÊÌ»Ò=%d ̾Á°=%s"
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: ¥³¥í¥ó¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "E902: Cannot connect to port"
+msgstr "E902: ¥Ý¡¼¥È¤ËÀܳ¤Ç¤­¤Þ¤»¤ó"
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: ÉÔÀµ¤Ê¥â¡¼¥É¤Ç¤¹"
+msgid "E901: gethostbyname() in channel_open()"
+msgstr "E901: channel_open() Æâ¤Î gethostbyname() ¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: ¿ôÃͤ¬É¬ÍפǤ¹"
+msgid "E898: socket() in channel_open()"
+msgstr "E898: channel_open() Æâ¤Î socket() ¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: ÉÔÀµ¤Ê¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸¤Ç¤¹"
+msgid "E903: received command with non-string argument"
+msgstr "E903: Èóʸ»úÎó¤Î°ú¿ô¤Î¥³¥Þ¥ó¥É¤ò¼õ¿®¤·¤Þ¤·¤¿"
+
+msgid "E904: last argument for expr/call must be a number"
+msgstr "E904: expr/call ¤ÎºÇ¸å¤Î°ú¿ô¤Ï¿ô»ú¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+
+msgid "E904: third argument for call must be a list"
+msgstr "E904: call ¤Î3ÈÖÌܤΰú¿ô¤Ï¥ê¥¹¥È·¿¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E905: received unknown command: %s"
+msgstr "E905: ̤ÃΤΥ³¥Þ¥ó¥É¤ò¼õ¿®¤·¤Þ¤·¤¿: %s"
+
+#, c-format
+msgid "E630: %s(): write while not connected"
+msgstr "E630: %s(): ÈóÀܳ¾õÂ֤ǽñ¤­¹þ¤ß¤Þ¤·¤¿"
+
+#, c-format
+msgid "E631: %s(): write failed"
+msgstr "E631: %s(): ½ñ¤­¹þ¤ß¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+#, c-format
+msgid "E917: Cannot use a callback with %s()"
+msgstr "E917: %s() ¤Ë¥³¡¼¥ë¥Ð¥Ã¥¯¤Ï»È¤¨¤Þ¤»¤ó"
+
+msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel"
+msgstr "E912: À¸¤ä nl ¥Á¥ã¥ó¥Í¥ë¤Ë ch_evalexpr()/ch_sendexpr ¤Ï»È¤¨¤Þ¤»¤ó"
+
+msgid "E906: not an open channel"
+msgstr "E906: ³«¤¤¤Æ¤¤¤Ê¤¤¥Á¥ã¥ó¥Í¥ë¤Ç¤¹"
+
+msgid "E920: _io file requires _name to be set"
+msgstr "E920: _io ¥Õ¥¡¥¤¥ë¤Ï _name ¤ÎÀßÄ꤬ɬÍפǤ¹"
+
+msgid "E915: in_io buffer requires in_buf or in_name to be set"
+msgstr "E915: in_io ¥Ð¥Ã¥Õ¥¡¤Ï in_buf ¤« in_name ¤ÎÀßÄ꤬ɬÍפǤ¹"
+
+#, c-format
+msgid "E918: buffer must be loaded: %s"
+msgstr "E918: ¥Ð¥Ã¥Õ¥¡¤¬¥í¡¼¥É¤µ¤ì¤Æ¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó: %s"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: ¥Õ¥¡¥¤¥ë¤¬Ì¤ÃΤÎÊýË¡¤Ç°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹"
+
+msgid "Warning: Using a weak encryption method; see :help 'cm'"
+msgstr "·Ù¹ð: ¼å¤¤°Å¹æÊýË¡¤ò»È¤Ã¤Æ¤¤¤Þ¤¹; :help 'cm' ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤"
+
+msgid "Enter encryption key: "
+msgstr "°Å¹æ²½ÍѤΥ­¡¼¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤: "
+
+msgid "Enter same key again: "
+msgstr "¤â¤¦°ìÅÙÆ±¤¸¥­¡¼¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤: "
+
+msgid "Keys don't match!"
+msgstr "¥­¡¼¤¬°ìÃפ·¤Þ¤»¤ó"
+
+msgid "[crypted]"
+msgstr "[°Å¹æ²½]"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: ¼­½ñ·¿¤Ë¥³¥í¥ó¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: ¼­½ñ·¿¤Ë½ÅÊ£¥­¡¼¤¬¤¢¤ê¤Þ¤¹: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: ¼­½ñ·¿¤Ë¥«¥ó¥Þ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: ¼­½ñ·¿¤ÎºÇ¸å¤Ë '}' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
+msgid "extend() argument"
+msgstr "extend() ¤Î°ú¿ô"
-#: ../diff.c:146
#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: %<PRId64> °Ê¾å¤Î¥Ð¥Ã¥Õ¥¡¤Ïdiff¤Ç¤­¤Þ¤»¤ó"
+msgid "E737: Key already exists: %s"
+msgstr "E737: ¥­¡¼¤Ï´û¤Ë¸ºß¤·¤Þ¤¹: %s"
+
+#, c-format
+msgid "E96: Cannot diff more than %ld buffers"
+msgstr "E96: %ld °Ê¾å¤Î¥Ð¥Ã¥Õ¥¡¤Ïdiff¤Ç¤­¤Þ¤»¤ó"
-#: ../diff.c:753
msgid "E810: Cannot read or write temp files"
msgstr "E810: °ì»þ¥Õ¥¡¥¤¥ë¤ÎÆÉ¹þ¤â¤·¤¯¤Ï½ñ¹þ¤¬¤Ç¤­¤Þ¤»¤ó"
-#: ../diff.c:755
msgid "E97: Cannot create diffs"
msgstr "E97: º¹Ê¬¤òºîÀ®¤Ç¤­¤Þ¤»¤ó"
-#: ../diff.c:966
+msgid "Patch file"
+msgstr "¥Ñ¥Ã¥Á¥Õ¥¡¥¤¥ë"
+
msgid "E816: Cannot read patch output"
msgstr "E816: patch¤Î½ÐÎϤòÆÉ¹þ¤á¤Þ¤»¤ó"
-#: ../diff.c:1220
msgid "E98: Cannot read diff output"
msgstr "E98: diff¤Î½ÐÎϤòÆÉ¹þ¤á¤Þ¤»¤ó"
-#: ../diff.c:2081
msgid "E99: Current buffer is not in diff mode"
msgstr "E99: ¸½ºß¤Î¥Ð¥Ã¥Õ¥¡¤Ïº¹Ê¬¥â¡¼¥É¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../diff.c:2100
msgid "E793: No other buffer in diff mode is modifiable"
msgstr "E793: º¹Ê¬¥â¡¼¥É¤Ç¤¢¤ë¾¤Î¥Ð¥Ã¥Õ¥¡¤ÏÊѹ¹¤Ç¤­¤Þ¤»¤ó"
-#: ../diff.c:2102
msgid "E100: No other buffer in diff mode"
msgstr "E100: º¹Ê¬¥â¡¼¥É¤Ç¤¢¤ë¾¤Î¥Ð¥Ã¥Õ¥¡¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../diff.c:2112
msgid "E101: More than two buffers in diff mode, don't know which one to use"
msgstr ""
"E101: º¹Ê¬¥â¡¼¥É¤Î¥Ð¥Ã¥Õ¥¡¤¬2¸Ä°Ê¾å¤¢¤ë¤Î¤Ç¡¢¤É¤ì¤ò»È¤¦¤«ÆÃÄê¤Ç¤­¤Þ¤»¤ó"
-#: ../diff.c:2141
#, c-format
msgid "E102: Can't find buffer \"%s\""
msgstr "E102: ¥Ð¥Ã¥Õ¥¡ \"%s\" ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../diff.c:2152
#, c-format
msgid "E103: Buffer \"%s\" is not in diff mode"
msgstr "E103: ¥Ð¥Ã¥Õ¥¡ \"%s\" ¤Ïº¹Ê¬¥â¡¼¥É¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../diff.c:2193
msgid "E787: Buffer changed unexpectedly"
msgstr "E787: ͽ´ü¤»¤º¥Ð¥Ã¥Õ¥¡¤¬Êѹ¹Êѹ¹¤µ¤ì¤Þ¤·¤¿"
-#: ../digraph.c:1598
msgid "E104: Escape not allowed in digraph"
msgstr "E104: ¹ç»ú¤ËEscape¤Ï»ÈÍѤǤ­¤Þ¤»¤ó"
-#: ../digraph.c:1760
msgid "E544: Keymap file not found"
msgstr "E544: ¥­¡¼¥Þ¥Ã¥×¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../digraph.c:1785
msgid "E105: Using :loadkeymap not in a sourced file"
msgstr "E105: :source ¤Ç¼è¹þ¤à¥Õ¥¡¥¤¥ë°Ê³°¤Ç¤Ï :loadkeymap ¤ò»È¤¨¤Þ¤»¤ó"
-#: ../digraph.c:1821
msgid "E791: Empty keymap entry"
msgstr "E791: ¶õ¤Î¥­¡¼¥Þ¥Ã¥×¥¨¥ó¥È¥ê"
-#: ../edit.c:82
msgid " Keyword completion (^N^P)"
msgstr " ¥­¡¼¥ï¡¼¥ÉÊä´° (^N^P)"
#. ctrl_x_mode == 0, ^P/^N compl.
-#: ../edit.c:83
msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
msgstr " ^X ¥â¡¼¥É (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
-#: ../edit.c:85
msgid " Whole line completion (^L^N^P)"
msgstr " ¹Ô(Á´ÂÎ)Êä´° (^L^N^P)"
-#: ../edit.c:86
msgid " File name completion (^F^N^P)"
msgstr " ¥Õ¥¡¥¤¥ë̾Êä´° (^F^N^P)"
-#: ../edit.c:87
msgid " Tag completion (^]^N^P)"
msgstr " ¥¿¥°Êä´° (^]^N^P)"
-#: ../edit.c:88
msgid " Path pattern completion (^N^P)"
msgstr " ¥Ñ¥¹¥Ñ¥¿¡¼¥óÊä´° (^N^P)"
-#: ../edit.c:89
msgid " Definition completion (^D^N^P)"
msgstr " ÄêµÁÊä´° (^D^N^P)"
-#: ../edit.c:91
msgid " Dictionary completion (^K^N^P)"
msgstr " ¼­½ñÊä´° (^K^N^P)"
-#: ../edit.c:92
msgid " Thesaurus completion (^T^N^P)"
msgstr " ¥·¥½¡¼¥é¥¹Êä´° (^T^N^P)"
-#: ../edit.c:93
msgid " Command-line completion (^V^N^P)"
msgstr " ¥³¥Þ¥ó¥É¥é¥¤¥óÊä´° (^V^N^P)"
-#: ../edit.c:94
msgid " User defined completion (^U^N^P)"
msgstr " ¥æ¡¼¥¶¡¼ÄêµÁÊä´° (^U^N^P)"
-#: ../edit.c:95
msgid " Omni completion (^O^N^P)"
msgstr " ¥ª¥à¥ËÊä´° (^O^N^P)"
-#: ../edit.c:96
msgid " Spelling suggestion (s^N^P)"
msgstr " Ä֤꽤Àµ¸õÊä (s^N^P)"
-#: ../edit.c:97
msgid " Keyword Local completion (^N^P)"
msgstr " ¶É½ê¥­¡¼¥ï¡¼¥ÉÊä´° (^N^P)"
-#: ../edit.c:100
msgid "Hit end of paragraph"
msgstr "ÃÊÍî¤ÎºÇ¸å¤Ë¥Ò¥Ã¥È"
-#: ../edit.c:101
msgid "E839: Completion function changed window"
msgstr "E839: Êä´Ö´Ø¿ô¤¬¥¦¥£¥ó¥É¥¦¤òÊѹ¹¤·¤Þ¤·¤¿"
-#: ../edit.c:102
msgid "E840: Completion function deleted text"
msgstr "E840: Êä´°´Ø¿ô¤¬¥Æ¥­¥¹¥È¤òºï½ü¤·¤Þ¤·¤¿"
-#: ../edit.c:1847
msgid "'dictionary' option is empty"
msgstr "'dictionary' ¥ª¥×¥·¥ç¥ó¤¬¶õ¤Ç¤¹"
-#: ../edit.c:1848
msgid "'thesaurus' option is empty"
msgstr "'thesaurus' ¥ª¥×¥·¥ç¥ó¤¬¶õ¤Ç¤¹"
-#: ../edit.c:2655
#, c-format
msgid "Scanning dictionary: %s"
msgstr "¼­½ñ¤ò¥¹¥­¥ã¥óÃæ: %s"
-#: ../edit.c:3079
msgid " (insert) Scroll (^E/^Y)"
msgstr " (ÁÞÆþ) ¥¹¥¯¥í¡¼¥ë(^E/^Y)"
-#: ../edit.c:3081
msgid " (replace) Scroll (^E/^Y)"
msgstr " (ÃÖ´¹) ¥¹¥¯¥í¡¼¥ë (^E/^Y)"
-#: ../edit.c:3587
#, c-format
msgid "Scanning: %s"
msgstr "¥¹¥­¥ã¥óÃæ: %s"
-#: ../edit.c:3614
msgid "Scanning tags."
msgstr "¥¿¥°¤ò¥¹¥­¥ã¥óÃæ."
-#: ../edit.c:4519
msgid " Adding"
msgstr " ÄɲÃÃæ"
@@ -441,431 +438,161 @@ msgstr " ÄɲÃÃæ"
#. * be called before line = ml_get(), or when this address is no
#. * longer needed. -- Acevedo.
#.
-#: ../edit.c:4562
msgid "-- Searching..."
msgstr "-- ¸¡º÷Ãæ..."
-#: ../edit.c:4618
msgid "Back at original"
msgstr "»Ï¤á¤ËÌá¤ë"
-#: ../edit.c:4621
msgid "Word from other line"
msgstr "¾¤Î¹Ô¤Îñ¸ì"
-#: ../edit.c:4624
msgid "The only match"
msgstr "Í£°ì¤Î³ºÅö"
-#: ../edit.c:4680
#, c-format
msgid "match %d of %d"
msgstr "%d ÈÖÌܤγºÅö (Á´³ºÅö %d ¸ÄÃæ)"
-#: ../edit.c:4684
#, c-format
msgid "match %d"
msgstr "%d ÈÖÌܤγºÅö"
-#: ../eval.c:137
+#. maximum nesting of lists and dicts
msgid "E18: Unexpected characters in :let"
msgstr "E18: ͽ´ü¤»¤Ìʸ»ú¤¬ :let ¤Ë¤¢¤ê¤Þ¤·¤¿"
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: ¥ê¥¹¥È¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤¬Èϰϳ°¤Ç¤¹: %<PRId64>"
-
-#: ../eval.c:139
#, c-format
msgid "E121: Undefined variable: %s"
msgstr "E121: ̤ÄêµÁ¤ÎÊÑ¿ô¤Ç¤¹: %s"
-#: ../eval.c:140
msgid "E111: Missing ']'"
msgstr "E111: ']' ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: %s ¤Î°ú¿ô¤Ï¥ê¥¹¥È·¿¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: %s ¤Î°ú¿ô¤Ï¥ê¥¹¥È·¿¤Þ¤¿¤Ï¼­½ñ·¿¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: ¼­½ñ·¿¤Ë¶õ¤Î¥­¡¼¤ò»È¤¦¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: ¥ê¥¹¥È·¿¤¬É¬ÍפǤ¹"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: ¼­½ñ·¿¤¬É¬ÍפǤ¹"
-
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: ´Ø¿ô¤Î°ú¿ô¤¬Â¿²á¤®¤Þ¤¹: %s"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: ¼­½ñ·¿¤Ë¥­¡¼¤¬Â¸ºß¤·¤Þ¤»¤ó: %s"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: ´Ø¿ô %s ¤ÏÄêµÁºÑ¤Ç¤¹, ºÆÄêµÁ¤¹¤ë¤Ë¤Ï ! ¤òÄɲ䷤Ƥ¯¤À¤µ¤¤"
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: ¼­½ñ·¿Æâ¤Ë¥¨¥ó¥È¥ê¤¬´û¤Ë¸ºß¤·¤Þ¤¹"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: ´Ø¿ô»²¾È·¿¤¬Í׵ᤵ¤ì¤Þ¤¹"
-
-#: ../eval.c:153
msgid "E719: Cannot use [:] with a Dictionary"
msgstr "E719: [:] ¤ò¼­½ñ·¿¤ÈÁȤ߹ç¤ï¤»¤Æ¤Ï»È¤¨¤Þ¤»¤ó"
-#: ../eval.c:154
#, c-format
msgid "E734: Wrong variable type for %s="
msgstr "E734: °Û¤Ê¤Ã¤¿·¿¤ÎÊÑ¿ô¤Ç¤¹ %s="
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: ̤ÃΤδؿô¤Ç¤¹: %s"
-
-#: ../eval.c:156
#, c-format
msgid "E461: Illegal variable name: %s"
msgstr "E461: ÉÔÀµ¤ÊÊÑ¿ô̾¤Ç¤¹: %s"
-#: ../eval.c:157
msgid "E806: using Float as a String"
msgstr "E806: ÉâÆ°¾®¿ôÅÀ¿ô¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:1830
msgid "E687: Less targets than List items"
msgstr "E687: ¥¿¡¼¥²¥Ã¥È¤¬¥ê¥¹¥È·¿Æâ¤ÎÍ×ÁǤè¤ê¤â¾¯¤Ê¤¤¤Ç¤¹"
-#: ../eval.c:1834
msgid "E688: More targets than List items"
msgstr "E688: ¥¿¡¼¥²¥Ã¥È¤¬¥ê¥¹¥È·¿Æâ¤ÎÍ×ÁǤè¤ê¤â¿¤¤¤Ç¤¹"
-#: ../eval.c:1906
msgid "Double ; in list of variables"
msgstr "¥ê¥¹¥È·¿¤ÎÃͤË2¤Ä°Ê¾å¤Î ; ¤¬¸¡½Ð¤µ¤ì¤Þ¤·¤¿"
-#: ../eval.c:2078
#, c-format
msgid "E738: Can't list variables for %s"
msgstr "E738: %s ¤ÎÃͤò°ìÍ÷ɽ¼¨¤Ç¤­¤Þ¤»¤ó"
-#: ../eval.c:2391
msgid "E689: Can only index a List or Dictionary"
msgstr "E689: ¥ê¥¹¥È·¿¤È¼­½ñ·¿°Ê³°¤Ï¥¤¥ó¥Ç¥Ã¥¯¥¹»ØÄê¤Ç¤­¤Þ¤»¤ó"
-#: ../eval.c:2396
msgid "E708: [:] must come last"
msgstr "E708: [:] ¤ÏºÇ¸å¤Ç¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó"
-#: ../eval.c:2439
msgid "E709: [:] requires a List value"
msgstr "E709: [:] ¤Ë¤Ï¥ê¥¹¥È·¿¤ÎÃͤ¬É¬ÍפǤ¹"
-#: ../eval.c:2674
msgid "E710: List value has more items than target"
msgstr "E710: ¥ê¥¹¥È·¿ÊÑ¿ô¤Ë¥¿¡¼¥²¥Ã¥È¤è¤ê¤â¿¤¤Í×ÁǤ¬¤¢¤ê¤Þ¤¹"
-#: ../eval.c:2678
msgid "E711: List value has not enough items"
msgstr "E711: ¥ê¥¹¥È·¿ÊÑ¿ô¤Ë½½Ê¬¤Ê¿ô¤ÎÍ×ÁǤ¬¤¢¤ê¤Þ¤»¤ó"
#
-#: ../eval.c:2867
msgid "E690: Missing \"in\" after :for"
msgstr "E690: :for ¤Î¸å¤Ë \"in\" ¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: ¥«¥Ã¥³ '(' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-
-#: ../eval.c:3263
#, c-format
msgid "E108: No such variable: \"%s\""
msgstr "E108: ¤½¤ÎÊÑ¿ô¤Ï¤¢¤ê¤Þ¤»¤ó: \"%s\""
-#: ../eval.c:3333
msgid "E743: variable nested too deep for (un)lock"
msgstr "E743: (¥¢¥ó)¥í¥Ã¥¯¤¹¤ë¤Ë¤ÏÊÑ¿ô¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
-#: ../eval.c:3630
msgid "E109: Missing ':' after '?'"
msgstr "E109: '?' ¤Î¸å¤Ë ':' ¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../eval.c:3893
msgid "E691: Can only compare List with List"
msgstr "E691: ¥ê¥¹¥È·¿¤Ï¥ê¥¹¥È·¿¤È¤·¤«Èæ³Ó¤Ç¤­¤Þ¤»¤ó"
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
+msgid "E692: Invalid operation for List"
msgstr "E692: ¥ê¥¹¥È·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹"
-#: ../eval.c:3915
msgid "E735: Can only compare Dictionary with Dictionary"
msgstr "E735: ¼­½ñ·¿¤Ï¼­½ñ·¿¤È¤·¤«Èæ³Ó¤Ç¤­¤Þ¤»¤ó"
-#: ../eval.c:3917
msgid "E736: Invalid operation for Dictionary"
msgstr "E736: ¼­½ñ·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹"
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: ´Ø¿ô»²¾È·¿¤Ï´Ø¿ô»²¾È·¿¤È¤·¤«Èæ³Ó¤Ç¤­¤Þ¤»¤ó"
-
-#: ../eval.c:3934
msgid "E694: Invalid operation for Funcrefs"
msgstr "E694: ´Ø¿ô»²¾È·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹"
-#: ../eval.c:4277
msgid "E804: Cannot use '%' with Float"
msgstr "E804: '%' ¤òÉâÆ°¾®¿ôÅÀ¿ô¤ÈÁȤ߹ç¤ï¤»¤Æ¤Ï»È¤¨¤Þ¤»¤ó"
-#: ../eval.c:4478
msgid "E110: Missing ')'"
msgstr "E110: ')' ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../eval.c:4609
msgid "E695: Cannot index a Funcref"
msgstr "E695: ´Ø¿ô»²¾È·¿¤Ï¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç¤­¤Þ¤»¤ó"
-#: ../eval.c:4839
+msgid "E909: Cannot index a special variable"
+msgstr "E909: ÆÃ¼ìÊÑ¿ô¤Ï¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç¤­¤Þ¤»¤ó"
+
#, c-format
msgid "E112: Option name missing: %s"
msgstr "E112: ¥ª¥×¥·¥ç¥ó̾¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../eval.c:4855
#, c-format
msgid "E113: Unknown option: %s"
msgstr "E113: ̤ÃΤΥª¥×¥·¥ç¥ó¤Ç¤¹: %s"
-#: ../eval.c:4904
#, c-format
msgid "E114: Missing quote: %s"
msgstr "E114: °úÍÑÉä (\") ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../eval.c:5020
#, c-format
msgid "E115: Missing quote: %s"
msgstr "E115: °úÍÑÉä (') ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: ¥ê¥¹¥È·¿¤Ë¥«¥ó¥Þ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: ¥ê¥¹¥È·¿¤ÎºÇ¸å¤Ë ']' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-
-#: ../eval.c:5807
msgid "Not enough memory to set references, garbage collection aborted!"
msgstr ""
"¥¬¡¼¥Ù¥Ã¥¸¥³¥ì¥¯¥·¥ç¥ó¤òÃæ»ß¤·¤Þ¤·¤¿! »²¾È¤òºîÀ®¤¹¤ë¤Î¤Ë¥á¥â¥ê¤¬ÉÔ­¤·¤Þ¤·¤¿"
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: ¼­½ñ·¿¤Ë¥³¥í¥ó¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: ¼­½ñ·¿¤Ë½ÅÊ£¥­¡¼¤¬¤¢¤ê¤Þ¤¹: \"%s\""
-
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: ¼­½ñ·¿¤Ë¥«¥ó¥Þ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: ¼­½ñ·¿¤ÎºÇ¸å¤Ë '}' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-
-#: ../eval.c:6555
msgid "E724: variable nested too deep for displaying"
msgstr "E724: ɽ¼¨¤¹¤ë¤Ë¤ÏÊÑ¿ô¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
-#: ../eval.c:7188
-#, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E740: ´Ø¿ô¤Î°ú¿ô¤¬Â¿²á¤®¤Þ¤¹: %s"
-
-#: ../eval.c:7190
-#, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E116: ´Ø¿ô¤Î̵¸ú¤Ê°ú¿ô¤Ç¤¹: %s"
-
-#: ../eval.c:7377
-#, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E117: ̤ÃΤδؿô¤Ç¤¹: %s"
-
-#: ../eval.c:7383
-#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: ´Ø¿ô¤Î°ú¿ô¤¬Â­¤ê¤Þ¤»¤ó: %s"
-
-#: ../eval.c:7387
-#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: ¥¹¥¯¥ê¥×¥È°Ê³°¤Ç<SID>¤¬»È¤ï¤ì¤Þ¤·¤¿: %s"
-
-#: ../eval.c:7391
-#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E725: ¼­½ñÍÑ´Ø¿ô¤¬¸Æ¤Ð¤ì¤Þ¤·¤¿¤¬¼­½ñ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-
-#: ../eval.c:7453
-msgid "E808: Number or Float required"
-msgstr "E808: ¿ôÃͤ«ÉâÆ°¾®¿ôÅÀ¿ô¤¬É¬ÍפǤ¹"
-
-#: ../eval.c:7503
-msgid "add() argument"
-msgstr "add() ¤Î°ú¿ô"
-
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: °ú¿ô¤¬Â¿²á¤®¤Þ¤¹"
-
-#: ../eval.c:8073
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete() ¤ÏÁÞÆþ¥â¡¼¥É¤Ç¤·¤«ÍøÍѤǤ­¤Þ¤»¤ó"
-
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "&Ok"
-
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: ¥­¡¼¤Ï´û¤Ë¸ºß¤·¤Þ¤¹: %s"
-
-#: ../eval.c:8692
-msgid "extend() argument"
-msgstr "extend() ¤Î°ú¿ô"
-
-#: ../eval.c:8915
-msgid "map() argument"
-msgstr "map() ¤Î°ú¿ô"
-
-#: ../eval.c:8916
-msgid "filter() argument"
-msgstr "filter() ¤Î°ú¿ô"
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld ¹Ô: "
-
-#: ../eval.c:9291
-#, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E700: ̤ÃΤδؿô¤Ç¤¹: %s"
-
-#: ../eval.c:10729
-msgid "called inputrestore() more often than inputsave()"
-msgstr "inputrestore() ¤¬ inputsave() ¤è¤ê¤â¿¤¯¸Æ¤Ð¤ì¤Þ¤·¤¿"
-
-#: ../eval.c:10771
-msgid "insert() argument"
-msgstr "insert() ¤Î°ú¿ô"
-
-#: ../eval.c:10841
-msgid "E786: Range not allowed"
-msgstr "E786: ÈϰϻØÄê¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-
-#: ../eval.c:11140
-msgid "E701: Invalid type for len()"
-msgstr "E701: len() ¤Ë¤Ï̵¸ú¤Ê·¿¤Ç¤¹"
-
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr "E726: ¥¹¥È¥é¥¤¥É(Á°¿ÊÎÌ)¤¬ 0 ¤Ç¤¹"
-
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr "E727: ³«»Ï°ÌÃÖ¤¬½ªÎ»°ÌÃÖ¤ò±Û¤¨¤Þ¤·¤¿"
-
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr "<¶õ>"
-
-#: ../eval.c:12282
-msgid "remove() argument"
-msgstr "remove() ¤Î°ú¿ô"
-
-# Added at 10-Mar-2004.
-#: ../eval.c:12466
-msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: ¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤¬Â¿²á¤®¤Þ¤¹ (½Û´Ä¤·¤Æ¤¤¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹)"
-
-#: ../eval.c:12593
-msgid "reverse() argument"
-msgstr "reverse() ¤Î°ú¿ô"
-
-#: ../eval.c:13721
-msgid "sort() argument"
-msgstr "sort() ¤Î°ú¿ô"
-
-#: ../eval.c:13721
-msgid "uniq() argument"
-msgstr "uniq() ¤Î°ú¿ô"
-
-#: ../eval.c:13776
-msgid "E702: Sort compare function failed"
-msgstr "E702: ¥½¡¼¥È¤ÎÈæ³Ó´Ø¿ô¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
-
-#: ../eval.c:13806
-msgid "E882: Uniq compare function failed"
-msgstr "E882: Uniq ¤ÎÈæ³Ó´Ø¿ô¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
-
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(̵¸ú)"
-
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: °ì»þ¥Õ¥¡¥¤¥ë½ñ¹þÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿"
-
-#: ../eval.c:16159
msgid "E805: Using a Float as a Number"
msgstr "E805: ÉâÆ°¾®¿ôÅÀ¿ô¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:16162
msgid "E703: Using a Funcref as a Number"
msgstr "E703: ´Ø¿ô»²¾È·¿¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹¡£"
-#: ../eval.c:16170
msgid "E745: Using a List as a Number"
msgstr "E745: ¥ê¥¹¥È·¿¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:16173
msgid "E728: Using a Dictionary as a Number"
msgstr "E728: ¼­½ñ·¿¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
+msgid "E910: Using a Job as a Number"
+msgstr "E910: ¥¸¥ç¥Ö¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
+
+msgid "E913: Using a Channel as a Number"
+msgstr "E913: ¥Á¥ã¥ó¥Í¥ë¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹¡£"
+
msgid "E891: Using a Funcref as a Float"
msgstr "E891: ´Ø¿ô»²¾È·¿¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹¡£"
@@ -878,265 +605,280 @@ msgstr "E893: ¥ê¥¹¥È·¿¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
msgid "E894: Using a Dictionary as a Float"
msgstr "E894: ¼­½ñ·¿¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:16259
+msgid "E907: Using a special value as a Float"
+msgstr "E907: ÆÃ¼ìÃͤòÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
+
+msgid "E911: Using a Job as a Float"
+msgstr "E911: ¥¸¥ç¥Ö¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
+
+msgid "E914: Using a Channel as a Float"
+msgstr "E914: ¥Á¥ã¥ó¥Í¥ë¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹¡£"
+
msgid "E729: using Funcref as a String"
msgstr "E729: ´Ø¿ô»²¾È·¿¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:16262
msgid "E730: using List as a String"
msgstr "E730: ¥ê¥¹¥È·¿¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:16265
msgid "E731: using Dictionary as a String"
msgstr "E731: ¼­½ñ·¿¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: ÊÑ¿ô¤Î·¿¤¬°ìÃפ·¤Þ¤»¤ó: %s"
+msgid "E908: using an invalid value as a String"
+msgstr "E908: ̵¸ú¤ÊÃͤòʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:16705
#, c-format
msgid "E795: Cannot delete variable %s"
msgstr "E795: ÊÑ¿ô %s ¤òºï½ü¤Ç¤­¤Þ¤»¤ó"
-#: ../eval.c:16724
#, c-format
msgid "E704: Funcref variable name must start with a capital: %s"
msgstr "E704: ´Ø¿ô»²¾È·¿ÊÑ¿ô̾¤ÏÂçʸ»ú¤Ç»Ï¤Þ¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó: %s"
-#: ../eval.c:16732
#, c-format
msgid "E705: Variable name conflicts with existing function: %s"
msgstr "E705: ÊÑ¿ô̾¤¬´û¸¤Î´Ø¿ô̾¤È¾×ÆÍ¤·¤Þ¤¹: %s"
-#: ../eval.c:16763
#, c-format
msgid "E741: Value is locked: %s"
msgstr "E741: Ãͤ¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤Þ¤¹: %s"
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
msgid "Unknown"
msgstr "ÉÔÌÀ"
-#: ../eval.c:16768
#, c-format
msgid "E742: Cannot change value of %s"
msgstr "E742: %s ¤ÎÃͤòÊѹ¹¤Ç¤­¤Þ¤»¤ó"
-#: ../eval.c:16838
msgid "E698: variable nested too deep for making a copy"
msgstr "E698: ¥³¥Ô¡¼¤ò¼è¤ë¤Ë¤ÏÊÑ¿ô¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: ̤ÄêµÁ¤Î´Ø¿ô¤Ç¤¹: %s"
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# ¥°¥í¡¼¥Ð¥ëÊÑ¿ô:\n"
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: '(' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tºÇ¸å¤Ë¥»¥Ã¥È¤·¤¿¥¹¥¯¥ê¥×¥È: "
-#: ../eval.c:17293
-msgid "E862: Cannot use g: here"
-msgstr "E862: ¤³¤³¤Ç¤Ï g: ¤Ï»È¤¨¤Þ¤»¤ó"
+msgid "map() argument"
+msgstr "map() ¤Î°ú¿ô"
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: ÉÔÀµ¤Ê°ú¿ô¤Ç¤¹: %s"
+msgid "filter() argument"
+msgstr "filter() ¤Î°ú¿ô"
-#: ../eval.c:17323
#, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E853: °ú¿ô̾¤¬½ÅÊ£¤·¤Æ¤¤¤Þ¤¹: %s"
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: %s ¤Î°ú¿ô¤Ï¥ê¥¹¥È·¿¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: :endfunction ¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "E928: String required"
+msgstr "E928: ʸ»úÎó¤¬É¬ÍפǤ¹"
-#: ../eval.c:17537
-#, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E707: ´Ø¿ô̾¤¬ÊÑ¿ô̾¤È¾×ÆÍ¤·¤Þ¤¹: %s"
+msgid "E808: Number or Float required"
+msgstr "E808: ¿ôÃͤ«ÉâÆ°¾®¿ôÅÀ¿ô¤¬É¬ÍפǤ¹"
-#: ../eval.c:17549
-#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: ´Ø¿ô %s ¤òºÆÄêµÁ¤Ç¤­¤Þ¤»¤ó: »ÈÍÑÃæ¤Ç¤¹"
+msgid "add() argument"
+msgstr "add() ¤Î°ú¿ô"
-#: ../eval.c:17604
-#, c-format
-msgid "E746: Function name does not match script file name: %s"
-msgstr "E746: ´Ø¿ô̾¤¬¥¹¥¯¥ê¥×¥È¤Î¥Õ¥¡¥¤¥ë̾¤È°ìÃפ·¤Þ¤»¤ó: %s"
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() ¤ÏÁÞÆþ¥â¡¼¥É¤Ç¤·¤«ÍøÍѤǤ­¤Þ¤»¤ó"
-#: ../eval.c:17716
-msgid "E129: Function name required"
-msgstr "E129: ´Ø¿ô̾¤¬Í׵ᤵ¤ì¤Þ¤¹"
+#.
+#. * Yes this is ugly, I don't particularly like it either. But doing it
+#. * this way has the compelling advantage that translations need not to
+#. * be touched at all. See below what 'ok' and 'ync' are used for.
+#.
+msgid "&Ok"
+msgstr "&Ok"
-#: ../eval.c:17824
#, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr "E128: ´Ø¿ô̾¤ÏÂçʸ»ú¤« \"s:\" ¤Ç»Ï¤Þ¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó: %s"
+msgid "+-%s%3ld line: "
+msgid_plural "+-%s%3ld lines: "
+msgstr[0] "+-%s%3ld ¹Ô: "
-#: ../eval.c:17833
#, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr "E884: ´Ø¿ô̾¤Ë¤Ï¥³¥í¥ó¤Ï´Þ¤á¤é¤ì¤Þ¤»¤ó: %s"
+msgid "E700: Unknown function: %s"
+msgstr "E700: ̤ÃΤδؿô¤Ç¤¹: %s"
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: ´Ø¿ô %s ¤òºï½ü¤Ç¤­¤Þ¤»¤ó: »ÈÍÑÃæ¤Ç¤¹"
+msgid "E922: expected a dict"
+msgstr "E922: ¼­½ñ¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: ´Ø¿ô¸Æ½Ð¤ÎÆþ¤ì»Ò¿ô¤¬ 'maxfuncdepth' ¤òͤ¨¤Þ¤·¤¿"
+msgid "E923: Second argument of function() must be a list or a dict"
+msgstr "E923: function() ¤ÎÂè 2 °ú¿ô¤Ï¥ê¥¹¥È·¿¤Þ¤¿¤Ï¼­½ñ·¿¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#: ../eval.c:18568
-#, c-format
-msgid "calling %s"
-msgstr "%s ¤ò¼Â¹ÔÃæ¤Ç¤¹"
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"·èÄê(&O)\n"
+"¥­¥ã¥ó¥»¥ë(&C)"
-#: ../eval.c:18651
-#, c-format
-msgid "%s aborted"
-msgstr "%s ¤¬ÃæÃǤµ¤ì¤Þ¤·¤¿"
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore() ¤¬ inputsave() ¤è¤ê¤â¿¤¯¸Æ¤Ð¤ì¤Þ¤·¤¿"
+
+msgid "insert() argument"
+msgstr "insert() ¤Î°ú¿ô"
+
+msgid "E786: Range not allowed"
+msgstr "E786: ÈϰϻØÄê¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+msgid "E916: not a valid job"
+msgstr "E916: Í­¸ú¤Ê¥¸¥ç¥Ö¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: len() ¤Ë¤Ï̵¸ú¤Ê·¿¤Ç¤¹"
-#: ../eval.c:18653
#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s ¤¬ #%<PRId64> ¤òÊÖ¤·¤Þ¤·¤¿"
+msgid "E798: ID is reserved for \":match\": %ld"
+msgstr "E798: ID ¤Ï \":match\" ¤Î¤¿¤á¤ËͽÌó¤µ¤ì¤Æ¤¤¤Þ¤¹: %ld"
+
+msgid "E726: Stride is zero"
+msgstr "E726: ¥¹¥È¥é¥¤¥É(Á°¿ÊÎÌ)¤¬ 0 ¤Ç¤¹"
+
+msgid "E727: Start past end"
+msgstr "E727: ³«»Ï°ÌÃÖ¤¬½ªÎ»°ÌÃÖ¤ò±Û¤¨¤Þ¤·¤¿"
+
+msgid "<empty>"
+msgstr "<¶õ>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Vim ¥µ¡¼¥Ð¡¼¤Ø¤ÎÀܳ¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../eval.c:18670
#, c-format
-msgid "%s returning %s"
-msgstr "%s ¤¬ %s ¤òÊÖ¤·¤Þ¤·¤¿"
+msgid "E241: Unable to send to %s"
+msgstr "E241: %s ¤ØÁ÷¤ë¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: ¥µ¡¼¥Ð¡¼¤Î±þÅú¤¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "remove() argument"
+msgstr "remove() ¤Î°ú¿ô"
+
+# Added at 10-Mar-2004.
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: ¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤¬Â¿²á¤®¤Þ¤¹ (½Û´Ä¤·¤Æ¤¤¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹)"
+
+msgid "reverse() argument"
+msgstr "reverse() ¤Î°ú¿ô"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: ¥¯¥é¥¤¥¢¥ó¥È¤ØÁ÷¤ë¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
-#: ../eval.c:18691 ../ex_cmds2.c:2695
#, c-format
-msgid "continuing in %s"
-msgstr "%s ¤Î¼Â¹Ô¤ò·ÑÂ³Ãæ¤Ç¤¹"
+msgid "E927: Invalid action: '%s'"
+msgstr "E927: ̵¸ú¤ÊÁàºî¤Ç¤¹: %s"
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: ´Ø¿ô³°¤Ë :return ¤¬¤¢¤ê¤Þ¤·¤¿"
+msgid "sort() argument"
+msgstr "sort() ¤Î°ú¿ô"
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# ¥°¥í¡¼¥Ð¥ëÊÑ¿ô:\n"
+msgid "uniq() argument"
+msgstr "uniq() ¤Î°ú¿ô"
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\tLast set from "
+msgid "E702: Sort compare function failed"
+msgstr "E702: ¥½¡¼¥È¤ÎÈæ³Ó´Ø¿ô¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../eval.c:19272
-msgid "No old files"
-msgstr "¸Å¤¤¥Õ¥¡¥¤¥ë¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "E882: Uniq compare function failed"
+msgstr "E882: Uniq ¤ÎÈæ³Ó´Ø¿ô¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "(Invalid)"
+msgstr "(̵¸ú)"
+
+#, c-format
+msgid "E935: invalid submatch number: %d"
+msgstr "E935: ̵¸ú¤Ê¥µ¥Ö¥Þ¥Ã¥ÁÈÖ¹æ: %d"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: °ì»þ¥Õ¥¡¥¤¥ë½ñ¹þÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿"
+
+msgid "E921: Invalid callback argument"
+msgstr "E921: ̵¸ú¤Ê¥³¡¼¥ë¥Ð¥Ã¥¯°ú¿ô¤Ç¤¹"
-#: ../ex_cmds.c:122
#, c-format
msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
msgstr "<%s>%s%s %d, 16¿Ê¿ô %02x, 8¿Ê¿ô %03o"
-#: ../ex_cmds.c:145
#, c-format
msgid "> %d, Hex %04x, Octal %o"
msgstr "> %d, 16¿Ê¿ô %04x, 8¿Ê¿ô %o"
-#: ../ex_cmds.c:146
#, c-format
msgid "> %d, Hex %08x, Octal %o"
msgstr "> %d, 16¿Ê¿ô %08x, 8¿Ê¿ô %o"
-#: ../ex_cmds.c:684
msgid "E134: Move lines into themselves"
msgstr "E134: ¹Ô¤ò¤½¤ì¼«¿È¤Ë¤Ï°Üư¤Ç¤­¤Þ¤»¤ó"
-#: ../ex_cmds.c:747
msgid "1 line moved"
msgstr "1 ¹Ô¤¬°Üư¤µ¤ì¤Þ¤·¤¿"
-#: ../ex_cmds.c:749
#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "%<PRId64> ¹Ô¤¬°Üư¤µ¤ì¤Þ¤·¤¿"
+msgid "%ld lines moved"
+msgstr "%ld ¹Ô¤¬°Üư¤µ¤ì¤Þ¤·¤¿"
-#: ../ex_cmds.c:1175
#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "%<PRId64> ¹Ô¤¬¥Õ¥£¥ë¥¿½èÍý¤µ¤ì¤Þ¤·¤¿"
+msgid "%ld lines filtered"
+msgstr "%ld ¹Ô¤¬¥Õ¥£¥ë¥¿½èÍý¤µ¤ì¤Þ¤·¤¿"
-#: ../ex_cmds.c:1194
msgid "E135: *Filter* Autocommands must not change current buffer"
msgstr "E135: *¥Õ¥£¥ë¥¿* autocommand¤Ï¸½ºß¤Î¥Ð¥Ã¥Õ¥¡¤òÊѹ¹¤·¤Æ¤Ï¤¤¤±¤Þ¤»¤ó"
-#: ../ex_cmds.c:1244
msgid "[No write since last change]\n"
msgstr "[ºÇ¸å¤ÎÊѹ¹¤¬Êݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó]\n"
-#: ../ex_cmds.c:1424
#, c-format
msgid "%sviminfo: %s in line: "
msgstr "%sviminfo: %s ¹ÔÌÜ: "
-#: ../ex_cmds.c:1431
msgid "E136: viminfo: Too many errors, skipping rest of file"
msgstr "E136: viminfo: ¥¨¥é¡¼¤¬Â¿²á¤®¤ë¤Î¤Ç, °Ê¹ß¤Ï¥¹¥­¥Ã¥×¤·¤Þ¤¹"
-#: ../ex_cmds.c:1458
#, c-format
msgid "Reading viminfo file \"%s\"%s%s%s"
msgstr "viminfo¥Õ¥¡¥¤¥ë \"%s\"%s%s%s ¤òÆÉ¹þ¤ßÃæ"
-#: ../ex_cmds.c:1460
msgid " info"
msgstr " ¾ðÊó"
-#: ../ex_cmds.c:1461
msgid " marks"
msgstr " ¥Þ¡¼¥¯"
-#: ../ex_cmds.c:1462
msgid " oldfiles"
msgstr " µì¥Õ¥¡¥¤¥ë·²"
-#: ../ex_cmds.c:1463
msgid " FAILED"
msgstr " ¼ºÇÔ"
#. avoid a wait_return for this message, it's annoying
-#: ../ex_cmds.c:1541
#, c-format
msgid "E137: Viminfo file is not writable: %s"
msgstr "E137: viminfo¥Õ¥¡¥¤¥ë¤¬½ñ¹þ¤ß¤Ç¤­¤Þ¤»¤ó: %s"
-#: ../ex_cmds.c:1626
+#, c-format
+msgid "E929: Too many viminfo temp files, like %s!"
+msgstr "E929: °ì»þviminfo¥Õ¥¡¥¤¥ë¤¬Â¿²á¤®¤Þ¤¹! Îã: %s"
+
#, c-format
msgid "E138: Can't write viminfo file %s!"
msgstr "E138: viminfo¥Õ¥¡¥¤¥ë %s ¤òÊݸ¤Ç¤­¤Þ¤»¤ó!"
-#: ../ex_cmds.c:1635
#, c-format
msgid "Writing viminfo file \"%s\""
msgstr "viminfo¥Õ¥¡¥¤¥ë \"%s\" ¤ò½ñ¹þ¤ßÃæ"
+#, c-format
+msgid "E886: Can't rename viminfo file to %s!"
+msgstr "E886: viminfo¥Õ¥¡¥¤¥ë¤ò %s ¤ØÌ¾Á°Êѹ¹¤Ç¤­¤Þ¤»¤ó!"
+
#. Write the info:
-#: ../ex_cmds.c:1720
#, c-format
msgid "# This viminfo file was generated by Vim %s.\n"
msgstr "# ¤³¤Î viminfo ¥Õ¥¡¥¤¥ë¤Ï Vim %s ¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Þ¤·¤¿.\n"
-#: ../ex_cmds.c:1722
msgid ""
"# You may edit it if you're careful!\n"
"\n"
@@ -1144,47 +886,47 @@ msgstr ""
"# Êѹ¹¤¹¤ëºÝ¤Ë¤Ï½½Ê¬Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤!\n"
"\n"
-#: ../ex_cmds.c:1723
msgid "# Value of 'encoding' when this file was written\n"
msgstr "# ¤³¤Î¥Õ¥¡¥¤¥ë¤¬½ñ¤«¤ì¤¿»þ¤Î 'encoding' ¤ÎÃÍ\n"
-#: ../ex_cmds.c:1800
msgid "Illegal starting char"
msgstr "ÉÔÀµ¤ÊÀèÆ¬Ê¸»ú¤Ç¤¹"
-#: ../ex_cmds.c:2162
+msgid ""
+"\n"
+"# Bar lines, copied verbatim:\n"
+msgstr ""
+"\n"
+"# '|' ¤Ç»Ï¤Þ¤ë¹Ô¤Î¡¢Ê¸»úÄ̤ê¤Î¥³¥Ô¡¼:\n"
+
+msgid "Save As"
+msgstr "ÊÌ̾¤ÇÊݸ"
+
msgid "Write partial file?"
msgstr "¥Õ¥¡¥¤¥ë¤òÉôʬŪ¤ËÊݸ¤·¤Þ¤¹¤«?"
-#: ../ex_cmds.c:2166
msgid "E140: Use ! to write partial buffer"
msgstr "E140: ¥Ð¥Ã¥Õ¥¡¤òÉôʬŪ¤ËÊݸ¤¹¤ë¤Ë¤Ï ! ¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤"
-#: ../ex_cmds.c:2281
#, c-format
msgid "Overwrite existing file \"%s\"?"
msgstr "´û¸¤Î¥Õ¥¡¥¤¥ë \"%s\" ¤ò¾å½ñ¤­¤·¤Þ¤¹¤«?"
-#: ../ex_cmds.c:2317
#, c-format
msgid "Swap file \"%s\" exists, overwrite anyway?"
msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë \"%s\" ¤¬Â¸ºß¤·¤Þ¤¹. ¾å½ñ¤­¤ò¶¯À©¤·¤Þ¤¹¤«?"
-#: ../ex_cmds.c:2326
#, c-format
msgid "E768: Swap file exists: %s (:silent! overrides)"
msgstr "E768: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤·¤Þ¤¹: %s (:silent! ¤òÄɲäǾå½ñ)"
-#: ../ex_cmds.c:2381
#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: ¥Ð¥Ã¥Õ¥¡ %<PRId64> ¤Ë¤Ï̾Á°¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: ¥Ð¥Ã¥Õ¥¡ %ld ¤Ë¤Ï̾Á°¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_cmds.c:2412
msgid "E142: File not written: Writing is disabled by 'write' option"
msgstr "E142: ¥Õ¥¡¥¤¥ë¤ÏÊݸ¤µ¤ì¤Þ¤»¤ó¤Ç¤·¤¿: 'write' ¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê̵¸ú¤Ç¤¹"
-#: ../ex_cmds.c:2434
#, c-format
msgid ""
"'readonly' option is set for \"%s\".\n"
@@ -1193,7 +935,6 @@ msgstr ""
"\"%s\" ¤Ë¤Ï 'readonly' ¥ª¥×¥·¥ç¥ó¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹.\n"
"¾å½ñ¤­¶¯À©¤ò¤·¤Þ¤¹¤«?"
-#: ../ex_cmds.c:2439
#, c-format
msgid ""
"File permissions of \"%s\" are read-only.\n"
@@ -1204,83 +945,68 @@ msgstr ""
"¤½¤ì¤Ç¤â¶²¤é¤¯½ñ¤­¹þ¤à¤³¤È¤Ï²Äǽ¤Ç¤¹.\n"
"·Ñ³¤·¤Þ¤¹¤«?"
-#: ../ex_cmds.c:2451
#, c-format
msgid "E505: \"%s\" is read-only (add ! to override)"
msgstr "E505: \"%s\" ¤ÏÆÉ¹þÀìÍѤǤ¹ (¶¯À©½ñ¹þ¤Ë¤Ï ! ¤òÄɲÃ)"
-#: ../ex_cmds.c:3120
+msgid "Edit File"
+msgstr "¥Õ¥¡¥¤¥ë¤òÊÔ½¸"
+
#, c-format
msgid "E143: Autocommands unexpectedly deleted new buffer %s"
msgstr "E143: autocommand¤¬Í½´ü¤»¤º¿·¤·¤¤¥Ð¥Ã¥Õ¥¡ %s ¤òºï½ü¤·¤Þ¤·¤¿"
-#: ../ex_cmds.c:3313
msgid "E144: non-numeric argument to :z"
msgstr "E144: ¿ô¤Ç¤Ï¤Ê¤¤°ú¿ô¤¬ :z ¤ËÅϤµ¤ì¤Þ¤·¤¿"
-#: ../ex_cmds.c:3404
msgid "E145: Shell commands not allowed in rvim"
msgstr "E145: rvim¤Ç¤Ï¥·¥§¥ë¥³¥Þ¥ó¥É¤ò»È¤¨¤Þ¤»¤ó"
-#: ../ex_cmds.c:3498
msgid "E146: Regular expressions can't be delimited by letters"
msgstr "E146: Àµµ¬É½¸½¤Ïʸ»ú¤Ç¶èÀڤ뤳¤È¤¬¤Ç¤­¤Þ¤»¤ó"
-#: ../ex_cmds.c:3964
#, c-format
msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
msgstr "%s ¤ËÃÖ´¹¤·¤Þ¤¹¤«? (y/n/a/q/l/^E/^Y)"
-#: ../ex_cmds.c:4379
msgid "(Interrupted) "
msgstr "(³ä¹þ¤Þ¤ì¤Þ¤·¤¿) "
-#: ../ex_cmds.c:4384
msgid "1 match"
msgstr "1 ²Õ½ê³ºÅö¤·¤Þ¤·¤¿"
-#: ../ex_cmds.c:4384
msgid "1 substitution"
msgstr "1 ²Õ½êÃÖ´¹¤·¤Þ¤·¤¿"
-#: ../ex_cmds.c:4387
#, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> ²Õ½ê³ºÅö¤·¤Þ¤·¤¿"
+msgid "%ld matches"
+msgstr "%ld ²Õ½ê³ºÅö¤·¤Þ¤·¤¿"
-#: ../ex_cmds.c:4388
#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> ²Õ½êÃÖ´¹¤·¤Þ¤·¤¿"
+msgid "%ld substitutions"
+msgstr "%ld ²Õ½êÃÖ´¹¤·¤Þ¤·¤¿"
-#: ../ex_cmds.c:4392
msgid " on 1 line"
msgstr " (·× 1 ¹ÔÆâ)"
-#: ../ex_cmds.c:4395
#, c-format
-msgid " on %<PRId64> lines"
-msgstr " (·× %<PRId64> ¹ÔÆâ)"
+msgid " on %ld lines"
+msgstr " (·× %ld ¹ÔÆâ)"
-#: ../ex_cmds.c:4438
msgid "E147: Cannot do :global recursive"
msgstr "E147: :global ¤òºÆµ¢Åª¤Ë¤Ï»È¤¨¤Þ¤»¤ó"
-#: ../ex_cmds.c:4467
msgid "E148: Regular expression missing from global"
msgstr "E148: global¥³¥Þ¥ó¥É¤ËÀµµ¬É½¸½¤¬»ØÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../ex_cmds.c:4508
#, c-format
msgid "Pattern found in every line: %s"
msgstr "¥Ñ¥¿¡¼¥ó¤¬Á´¤Æ¤Î¹Ô¤Ç¸«¤Ä¤«¤ê¤Þ¤·¤¿: %s"
-#: ../ex_cmds.c:4510
#, c-format
msgid "Pattern not found: %s"
msgstr "¥Ñ¥¿¡¼¥ó¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿: %s"
-#: ../ex_cmds.c:4587
msgid ""
"\n"
"# Last Substitute String:\n"
@@ -1290,110 +1016,102 @@ msgstr ""
"# ºÇ¸å¤ËÃÖ´¹¤µ¤ì¤¿Ê¸»úÎó:\n"
"$"
-#: ../ex_cmds.c:4679
msgid "E478: Don't panic!"
msgstr "E478: ¹²¤Æ¤Ê¤¤¤Ç¤¯¤À¤µ¤¤"
-#: ../ex_cmds.c:4717
#, c-format
msgid "E661: Sorry, no '%s' help for %s"
msgstr "E661: »Äǰ¤Ç¤¹¤¬ '%s' ¤Î¥Ø¥ë¥×¤¬ %s ¤Ë¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_cmds.c:4719
#, c-format
msgid "E149: Sorry, no help for %s"
msgstr "E149: »Äǰ¤Ç¤¹¤¬ %s ¤Ë¤Ï¥Ø¥ë¥×¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_cmds.c:4751
#, c-format
msgid "Sorry, help file \"%s\" not found"
msgstr "»Äǰ¤Ç¤¹¤¬¥Ø¥ë¥×¥Õ¥¡¥¤¥ë \"%s\" ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../ex_cmds.c:5323
#, c-format
-msgid "E150: Not a directory: %s"
-msgstr "E150: ¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
+msgid "E151: No match: %s"
+msgstr "E151: ¥Þ¥Ã¥Á¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../ex_cmds.c:5446
#, c-format
msgid "E152: Cannot open %s for writing"
msgstr "E152: ½ñ¹þ¤ßÍÑ¤Ë %s ¤ò³«¤±¤Þ¤»¤ó"
-#: ../ex_cmds.c:5471
#, c-format
msgid "E153: Unable to open %s for reading"
msgstr "E153: ÆÉ¹þÍÑ¤Ë %s ¤ò³«¤±¤Þ¤»¤ó"
# Added at 29-Apr-2004.
-#: ../ex_cmds.c:5500
#, c-format
msgid "E670: Mix of help file encodings within a language: %s"
msgstr "E670: 1¤Ä¤Î¸À¸ì¤Î¥Ø¥ë¥×¥Õ¥¡¥¤¥ë¤ËÊ£¿ô¤Î¥¨¥ó¥³¡¼¥É¤¬º®ºß¤·¤Æ¤¤¤Þ¤¹: %s"
-#: ../ex_cmds.c:5565
#, c-format
msgid "E154: Duplicate tag \"%s\" in file %s/%s"
msgstr "E154: ¥¿¥° \"%s\" ¤¬¥Õ¥¡¥¤¥ë %s/%s ¤Ë½ÅÊ£¤·¤Æ¤¤¤Þ¤¹"
-#: ../ex_cmds.c:5687
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: ¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
+
#, c-format
msgid "E160: Unknown sign command: %s"
msgstr "E160: ̤ÃΤÎsign¥³¥Þ¥ó¥É¤Ç¤¹: %s"
-#: ../ex_cmds.c:5704
msgid "E156: Missing sign name"
msgstr "E156: sign̾¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_cmds.c:5746
msgid "E612: Too many signs defined"
msgstr "E612: sign¤ÎÄêµÁ¤¬Â¿¿ô¸«¤Ä¤«¤ê¤Þ¤·¤¿"
-#: ../ex_cmds.c:5813
#, c-format
msgid "E239: Invalid sign text: %s"
msgstr "E239: ̵¸ú¤Êsign¤Î¥Æ¥­¥¹¥È¤Ç¤¹: %s"
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
#, c-format
msgid "E155: Unknown sign: %s"
msgstr "E155: ̤ÃΤÎsign¤Ç¤¹: %s"
-#: ../ex_cmds.c:5877
msgid "E159: Missing sign number"
msgstr "E159: sign¤ÎÈֹ椬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_cmds.c:5971
#, c-format
msgid "E158: Invalid buffer name: %s"
msgstr "E158: ̵¸ú¤Ê¥Ð¥Ã¥Õ¥¡Ì¾¤Ç¤¹: %s"
-#: ../ex_cmds.c:6008
+msgid "E934: Cannot jump to a buffer that does not have a name"
+msgstr "E934: ̾Á°¤Î̵¤¤¥Ð¥Ã¥Õ¥¡¤Ø¤Ï¥¸¥ã¥ó¥×¤Ç¤­¤Þ¤»¤ó"
+
#, c-format
-msgid "E157: Invalid sign ID: %<PRId64>"
-msgstr "E157: ̵¸ú¤Êsign¼±Ê̻ҤǤ¹: %<PRId64>"
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: ̵¸ú¤Êsign¼±Ê̻ҤǤ¹: %ld"
#, c-format
msgid "E885: Not possible to change sign %s"
msgstr "E885: Êѹ¹¤Ç¤­¤Ê¤¤ sign ¤Ç¤¹: %s"
-#: ../ex_cmds.c:6066
+# Added at 27-Jan-2004.
+msgid " (NOT FOUND)"
+msgstr " (¸«¤Ä¤«¤ê¤Þ¤»¤ó)"
+
msgid " (not supported)"
msgstr " (È󥵥ݡ¼¥È)"
-#: ../ex_cmds.c:6169
msgid "[Deleted]"
msgstr "[ºï½üºÑ]"
-#: ../ex_cmds2.c:139
+msgid "No old files"
+msgstr "¸Å¤¤¥Õ¥¡¥¤¥ë¤Ï¤¢¤ê¤Þ¤»¤ó"
+
msgid "Entering Debug mode. Type \"cont\" to continue."
msgstr "¥Ç¥Ð¥Ã¥°¥â¡¼¥É¤ËÆþ¤ê¤Þ¤¹. ³¤±¤ë¤Ë¤Ï \"cont\" ¤ÈÆþÎϤ·¤Æ¤¯¤À¤µ¤¤."
-#: ../ex_cmds2.c:143 ../ex_docmd.c:759
#, c-format
-msgid "line %<PRId64>: %s"
-msgstr "¹Ô %<PRId64>: %s"
+msgid "line %ld: %s"
+msgstr "¹Ô %ld: %s"
-#: ../ex_cmds2.c:145
#, c-format
msgid "cmd: %s"
msgstr "¥³¥Þ¥ó¥É: %s"
@@ -1405,232 +1123,184 @@ msgstr "¥Õ¥ì¡¼¥à¤¬ 0 ¤Ç¤¹"
msgid "frame at highest level: %d"
msgstr "ºÇ¹â¥ì¥Ù¥ë¤Î¥Õ¥ì¡¼¥à: %d"
-#: ../ex_cmds2.c:322
#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È \"%s%s\" ¹Ô %<PRId64>"
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È \"%s%s\" ¹Ô %ld"
-#: ../ex_cmds2.c:581
#, c-format
msgid "E161: Breakpoint not found: %s"
msgstr "E161: ¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s"
-#: ../ex_cmds2.c:611
msgid "No breakpoints defined"
msgstr "¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../ex_cmds2.c:617
#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s ¹Ô %<PRId64>"
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s ¹Ô %ld"
-#: ../ex_cmds2.c:942
msgid "E750: First use \":profile start {fname}\""
msgstr "E750: ½é¤á¤Ë \":profile start {fname}\" ¤ò¼Â¹Ô¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../ex_cmds2.c:1269
#, c-format
msgid "Save changes to \"%s\"?"
msgstr "Êѹ¹¤ò \"%s\" ¤ËÊݸ¤·¤Þ¤¹¤«?"
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
msgid "Untitled"
msgstr "̵Âê"
-#: ../ex_cmds2.c:1421
#, c-format
msgid "E162: No write since last change for buffer \"%s\""
msgstr "E162: ¥Ð¥Ã¥Õ¥¡ \"%s\" ¤ÎÊѹ¹¤ÏÊݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../ex_cmds2.c:1480
msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
msgstr "·Ù¹ð: ͽ´ü¤»¤ºÂ¾¥Ð¥Ã¥Õ¥¡¤Ø°Üư¤·¤Þ¤·¤¿ (autocommands ¤òÄ´¤Ù¤Æ¤¯¤À¤µ¤¤)"
-#: ../ex_cmds2.c:1826
msgid "E163: There is only one file to edit"
msgstr "E163: ÊÔ½¸¤¹¤ë¥Õ¥¡¥¤¥ë¤Ï1¤Ä¤·¤«¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_cmds2.c:1828
msgid "E164: Cannot go before first file"
msgstr "E164: ºÇ½é¤Î¥Õ¥¡¥¤¥ë¤è¤êÁ°¤Ë¤Ï¹Ô¤±¤Þ¤»¤ó"
-#: ../ex_cmds2.c:1830
msgid "E165: Cannot go beyond last file"
msgstr "E165: ºÇ¸å¤Î¥Õ¥¡¥¤¥ë¤ò±Û¤¨¤Æ¸å¤Ë¤Ï¹Ô¤±¤Þ¤»¤ó"
-#: ../ex_cmds2.c:2175
#, c-format
msgid "E666: compiler not supported: %s"
msgstr "E666: ¤½¤Î¥³¥ó¥Ñ¥¤¥é¤Ë¤ÏÂбþ¤·¤Æ¤¤¤Þ¤»¤ó: %s"
-#: ../ex_cmds2.c:2257
#, c-format
msgid "Searching for \"%s\" in \"%s\""
msgstr "\"%s\" ¤ò \"%s\" ¤«¤é¸¡º÷Ãæ"
-#: ../ex_cmds2.c:2284
#, c-format
msgid "Searching for \"%s\""
msgstr "\"%s\" ¤ò¸¡º÷Ãæ"
-#: ../ex_cmds2.c:2307
#, c-format
-msgid "not found in 'runtimepath': \"%s\""
-msgstr "'runtimepath' ¤ÎÃæ¤Ë¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó: \"%s\""
+msgid "not found in '%s': \"%s\""
+msgstr "'%s' ¤ÎÃæ¤Ë¤Ï¤¢¤ê¤Þ¤»¤ó: \"%s\""
+
+msgid "Source Vim script"
+msgstr "Vim¥¹¥¯¥ê¥×¥È¤Î¼è¹þ¤ß"
-#: ../ex_cmds2.c:2472
#, c-format
msgid "Cannot source a directory: \"%s\""
msgstr "¥Ç¥£¥ì¥¯¥È¥ê¤Ï¼è¹þ¤á¤Þ¤»¤ó: \"%s\""
-#: ../ex_cmds2.c:2518
#, c-format
msgid "could not source \"%s\""
msgstr "\"%s\" ¤ò¼è¹þ¤á¤Þ¤»¤ó"
-#: ../ex_cmds2.c:2520
#, c-format
-msgid "line %<PRId64>: could not source \"%s\""
-msgstr "¹Ô %<PRId64>: \"%s\" ¤ò¼è¹þ¤á¤Þ¤»¤ó"
+msgid "line %ld: could not source \"%s\""
+msgstr "¹Ô %ld: \"%s\" ¤ò¼è¹þ¤á¤Þ¤»¤ó"
-#: ../ex_cmds2.c:2535
#, c-format
msgid "sourcing \"%s\""
msgstr "\"%s\" ¤ò¼è¹þÃæ"
-#: ../ex_cmds2.c:2537
#, c-format
-msgid "line %<PRId64>: sourcing \"%s\""
-msgstr "¹Ô %<PRId64>: %s ¤ò¼è¹þÃæ"
+msgid "line %ld: sourcing \"%s\""
+msgstr "¹Ô %ld: %s ¤ò¼è¹þÃæ"
-#: ../ex_cmds2.c:2693
#, c-format
msgid "finished sourcing %s"
msgstr "%s ¤Î¼è¹þ¤ò´°Î»"
-#: ../ex_cmds2.c:2765
+#, c-format
+msgid "continuing in %s"
+msgstr "%s ¤Î¼Â¹Ô¤ò·ÑÂ³Ãæ¤Ç¤¹"
+
msgid "modeline"
msgstr "¥â¡¼¥É¹Ô"
-#: ../ex_cmds2.c:2767
msgid "--cmd argument"
msgstr "--cmd °ú¿ô"
-#: ../ex_cmds2.c:2769
msgid "-c argument"
msgstr "-c °ú¿ô"
-#: ../ex_cmds2.c:2771
msgid "environment variable"
msgstr "´Ä¶­ÊÑ¿ô"
-#: ../ex_cmds2.c:2773
msgid "error handler"
msgstr "¥¨¥é¡¼¥Ï¥ó¥É¥é"
-#: ../ex_cmds2.c:3020
msgid "W15: Warning: Wrong line separator, ^M may be missing"
msgstr "W15: ·Ù¹ð: ¹Ô¶èÀÚ¤¬ÉÔÀµ¤Ç¤¹. ^M ¤¬¤Ê¤¤¤Î¤Ç¤·¤ç¤¦"
-#: ../ex_cmds2.c:3139
msgid "E167: :scriptencoding used outside of a sourced file"
msgstr "E167: :scriptencoding ¤¬¼è¹þ¥¹¥¯¥ê¥×¥È°Ê³°¤Ç»ÈÍѤµ¤ì¤Þ¤·¤¿"
-#: ../ex_cmds2.c:3166
msgid "E168: :finish used outside of a sourced file"
msgstr "E168: :finish ¤¬¼è¹þ¥¹¥¯¥ê¥×¥È°Ê³°¤Ç»ÈÍѤµ¤ì¤Þ¤·¤¿"
-#: ../ex_cmds2.c:3389
#, c-format
msgid "Current %slanguage: \"%s\""
msgstr "¸½ºß¤Î %s¸À¸ì: \"%s\""
-#: ../ex_cmds2.c:3404
#, c-format
msgid "E197: Cannot set language to \"%s\""
msgstr "E197: ¸À¸ì¤ò \"%s\" ¤ËÀßÄê¤Ç¤­¤Þ¤»¤ó"
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
msgstr ""
"Ex¥â¡¼¥É¤ËÆþ¤ê¤Þ¤¹. ¥Î¡¼¥Þ¥ë¥â¡¼¥É¤ËÌá¤ë¤Ë¤Ï\"visual\"¤ÈÆþÎϤ·¤Æ¤¯¤À¤µ¤¤."
-#: ../ex_docmd.c:428
msgid "E501: At end-of-file"
msgstr "E501: ¥Õ¥¡¥¤¥ë¤Î½ªÎ»°ÌÃÖ"
-#: ../ex_docmd.c:513
msgid "E169: Command too recursive"
msgstr "E169: ¥³¥Þ¥ó¥É¤¬ºÆµ¢Åª²á¤®¤Þ¤¹"
-#: ../ex_docmd.c:1006
#, c-format
msgid "E605: Exception not caught: %s"
msgstr "E605: Îã³°¤¬Ê᪤µ¤ì¤Þ¤»¤ó¤Ç¤·¤¿: %s"
-#: ../ex_docmd.c:1085
msgid "End of sourced file"
msgstr "¼è¹þ¥Õ¥¡¥¤¥ë¤ÎºÇ¸å¤Ç¤¹"
-#: ../ex_docmd.c:1086
msgid "End of function"
msgstr "´Ø¿ô¤ÎºÇ¸å¤Ç¤¹"
-#: ../ex_docmd.c:1628
msgid "E464: Ambiguous use of user-defined command"
msgstr "E464: ¥æ¡¼¥¶¡¼ÄêµÁ¥³¥Þ¥ó¥É¤Î¤¢¤¤¤Þ¤¤¤Ê»ÈÍѤǤ¹"
-#: ../ex_docmd.c:1638
msgid "E492: Not an editor command"
msgstr "E492: ¥¨¥Ç¥£¥¿¤Î¥³¥Þ¥ó¥É¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:1729
msgid "E493: Backwards range given"
msgstr "E493: µÕ¤µ¤Þ¤ÎÈϰϤ¬»ØÄꤵ¤ì¤Þ¤·¤¿"
-#: ../ex_docmd.c:1733
msgid "Backwards range given, OK to swap"
msgstr "µÕ¤µ¤Þ¤ÎÈϰϤ¬»ØÄꤵ¤ì¤Þ¤·¤¿, ÆþÂØ¤¨¤Þ¤¹¤«?"
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
msgid "E494: Use w or w>>"
msgstr "E494: w ¤â¤·¤¯¤Ï w>> ¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤"
-#: ../ex_docmd.c:3454
-msgid "E319: The command is not available in this version"
+msgid "E319: Sorry, the command is not available in this version"
msgstr "E319: ¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï¤³¤Î¥³¥Þ¥ó¥É¤ÏÍøÍѤǤ­¤Þ¤»¤ó, ¤´¤á¤ó¤Ê¤µ¤¤"
-#: ../ex_docmd.c:3752
msgid "E172: Only one file name allowed"
msgstr "E172: ¥Õ¥¡¥¤¥ë̾¤Ï 1 ¤Ä¤Ë¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../ex_docmd.c:4238
msgid "1 more file to edit. Quit anyway?"
msgstr "ÊÔ½¸¤¹¤Ù¤­¥Õ¥¡¥¤¥ë¤¬ 1 ¸Ä¤¢¤ê¤Þ¤¹¤¬, ½ªÎ»¤·¤Þ¤¹¤«?"
-#: ../ex_docmd.c:4242
#, c-format
msgid "%d more files to edit. Quit anyway?"
msgstr "ÊÔ½¸¤¹¤Ù¤­¥Õ¥¡¥¤¥ë¤¬¤¢¤È %d ¸Ä¤¢¤ê¤Þ¤¹¤¬, ½ªÎ»¤·¤Þ¤¹¤«?"
-#: ../ex_docmd.c:4248
msgid "E173: 1 more file to edit"
msgstr "E173: ÊÔ½¸¤¹¤Ù¤­¥Õ¥¡¥¤¥ë¤¬ 1 ¸Ä¤¢¤ê¤Þ¤¹"
-#: ../ex_docmd.c:4250
#, c-format
-msgid "E173: %<PRId64> more files to edit"
-msgstr "E173: ÊÔ½¸¤¹¤Ù¤­¥Õ¥¡¥¤¥ë¤¬¤¢¤È %<PRId64> ¸Ä¤¢¤ê¤Þ¤¹"
+msgid "E173: %ld more files to edit"
+msgstr "E173: ÊÔ½¸¤¹¤Ù¤­¥Õ¥¡¥¤¥ë¤¬¤¢¤È %ld ¸Ä¤¢¤ê¤Þ¤¹"
-#: ../ex_docmd.c:4320
msgid "E174: Command already exists: add ! to replace it"
msgstr "E174: ¥³¥Þ¥ó¥É¤¬´û¤Ë¤¢¤ê¤Þ¤¹: ºÆÄêµÁ¤¹¤ë¤Ë¤Ï ! ¤òÄɲ䷤Ƥ¯¤À¤µ¤¤"
-#: ../ex_docmd.c:4432
msgid ""
"\n"
" Name Args Address Complete Definition"
@@ -1638,51 +1308,40 @@ msgstr ""
"\n"
" ̾Á° °ú¿ô ¥¢¥É¥ì¥¹ Êä´° ÄêµÁ"
-#: ../ex_docmd.c:4516
msgid "No user-defined commands found"
msgstr "¥æ¡¼¥¶¡¼ÄêµÁ¥³¥Þ¥ó¥É¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../ex_docmd.c:4538
msgid "E175: No attribute specified"
msgstr "E175: °À­¤ÏÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../ex_docmd.c:4583
msgid "E176: Invalid number of arguments"
msgstr "E176: °ú¿ô¤Î¿ô¤¬Ìµ¸ú¤Ç¤¹"
-#: ../ex_docmd.c:4594
msgid "E177: Count cannot be specified twice"
msgstr "E177: ¥«¥¦¥ó¥È¤ò2½Å»ØÄꤹ¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../ex_docmd.c:4603
msgid "E178: Invalid default value for count"
msgstr "E178: ¥«¥¦¥ó¥È¤Î¾ÊάÃͤ¬Ìµ¸ú¤Ç¤¹"
-#: ../ex_docmd.c:4625
msgid "E179: argument required for -complete"
msgstr "E179: -complete ¤Ë¤Ï°ú¿ô¤¬É¬ÍפǤ¹"
msgid "E179: argument required for -addr"
msgstr "E179: -addr ¤Ë¤Ï°ú¿ô¤¬É¬ÍפǤ¹"
-#: ../ex_docmd.c:4635
#, c-format
msgid "E181: Invalid attribute: %s"
msgstr "E181: ̵¸ú¤Ê°À­¤Ç¤¹: %s"
-#: ../ex_docmd.c:4678
msgid "E182: Invalid command name"
msgstr "E182: ̵¸ú¤Ê¥³¥Þ¥ó¥É̾¤Ç¤¹"
-#: ../ex_docmd.c:4691
msgid "E183: User defined commands must start with an uppercase letter"
-msgstr "E183: ¥æ¡¼¥¶ÄêµÁ¥³¥Þ¥ó¥É¤Ï±ÑÂçʸ»ú¤Ç»Ï¤Þ¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+msgstr "E183: ¥æ¡¼¥¶¡¼ÄêµÁ¥³¥Þ¥ó¥É¤Ï±ÑÂçʸ»ú¤Ç»Ï¤Þ¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:4696
msgid "E841: Reserved name, cannot be used for user defined command"
msgstr "E841: ͽÌó̾¤Ê¤Î¤Ç, ¥æ¡¼¥¶¡¼ÄêµÁ¥³¥Þ¥ó¥É¤ËÍøÍѤǤ­¤Þ¤»¤ó"
-#: ../ex_docmd.c:4751
#, c-format
msgid "E184: No such user-defined command: %s"
msgstr "E184: ¤½¤Î¥æ¡¼¥¶¡¼ÄêµÁ¥³¥Þ¥ó¥É¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
@@ -1691,293 +1350,261 @@ msgstr "E184: ¤½¤Î¥æ¡¼¥¶¡¼ÄêµÁ¥³¥Þ¥ó¥É¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
msgid "E180: Invalid address type value: %s"
msgstr "E180: ̵¸ú¤Ê¥¢¥É¥ì¥¹¥¿¥¤¥×ÃͤǤ¹: %s"
-#: ../ex_docmd.c:5219
#, c-format
msgid "E180: Invalid complete value: %s"
msgstr "E180: ̵¸ú¤ÊÊä´°»ØÄê¤Ç¤¹: %s"
-#: ../ex_docmd.c:5225
msgid "E468: Completion argument only allowed for custom completion"
msgstr "E468: Êä´°°ú¿ô¤Ï¥«¥¹¥¿¥àÊä´°¤Ç¤·¤«»ÈÍѤǤ­¤Þ¤»¤ó"
-#: ../ex_docmd.c:5231
msgid "E467: Custom completion requires a function argument"
msgstr "E467: ¥«¥¹¥¿¥àÊä´°¤Ë¤Ï°ú¿ô¤È¤·¤Æ´Ø¿ô¤¬É¬ÍפǤ¹"
-#: ../ex_docmd.c:5257
+msgid "unknown"
+msgstr "ÉÔÌÀ"
+
#, c-format
msgid "E185: Cannot find color scheme '%s'"
msgstr "E185: ¥«¥é¡¼¥¹¥­¡¼¥à '%s' ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:5263
msgid "Greetings, Vim user!"
msgstr "Vim »È¤¤¤µ¤ó¡¢¤ä¤¢!"
-#: ../ex_docmd.c:5431
msgid "E784: Cannot close last tab page"
msgstr "E784: ºÇ¸å¤Î¥¿¥Ö¥Ú¡¼¥¸¤òÊĤ¸¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../ex_docmd.c:5462
msgid "Already only one tab page"
msgstr "´û¤Ë¥¿¥Ö¥Ú¡¼¥¸¤Ï1¤Ä¤·¤«¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:6004
+msgid "Edit File in new window"
+msgstr "¿·¤·¤¤¥¦¥£¥ó¥É¥¦¤Ç¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Þ¤¹"
+
#, c-format
msgid "Tab page %d"
msgstr "¥¿¥Ö¥Ú¡¼¥¸ %d"
-#: ../ex_docmd.c:6295
msgid "No swap file"
msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:6478
+msgid "Append File"
+msgstr "Äɲåե¡¥¤¥ë"
+
msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
msgstr ""
"E747: ¥Ð¥Ã¥Õ¥¡¤¬½¤Àµ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ç, ¥Ç¥£¥ì¥¯¥È¥ê¤òÊѹ¹¤Ç¤­¤Þ¤»¤ó (! ¤òÄɲäÇ"
"¾å½ñ)"
-#: ../ex_docmd.c:6485
msgid "E186: No previous directory"
msgstr "E186: Á°¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:6530
msgid "E187: Unknown"
msgstr "E187: ̤ÃÎ"
-#: ../ex_docmd.c:6610
msgid "E465: :winsize requires two number arguments"
msgstr "E465: :winsize ¤Ë¤Ï2¤Ä¤Î¿ôÃͤΰú¿ô¤¬É¬ÍפǤ¹"
-#: ../ex_docmd.c:6655
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "¥¦¥£¥ó¥É¥¦°ÌÃÖ: X %d, Y %d"
+
msgid "E188: Obtaining window position not implemented for this platform"
msgstr ""
"E188: ¤³¤Î¥×¥é¥Ã¥È¥Û¡¼¥à¤Ë¤Ï¥¦¥£¥ó¥É¥¦°ÌÃ֤μèÆÀµ¡Ç½¤Ï¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../ex_docmd.c:6662
msgid "E466: :winpos requires two number arguments"
msgstr "E466: :winpos ¤Ë¤Ï2¤Ä¤Î¿ôÃͤΰú¿ô¤¬É¬ÍפǤ¹"
-#: ../ex_docmd.c:7241
+msgid "E930: Cannot use :redir inside execute()"
+msgstr "E930: execute() ¤ÎÃæ¤Ç¤Ï :redir ¤Ï»È¤¨¤Þ¤»¤ó"
+
+msgid "Save Redirection"
+msgstr "¥ê¥À¥¤¥ì¥¯¥È¤òÊݸ¤·¤Þ¤¹"
+
+msgid "Save View"
+msgstr "¥Ó¥å¡¼¤òÊݸ¤·¤Þ¤¹"
+
+msgid "Save Session"
+msgstr "¥»¥Ã¥·¥ç¥ó¾ðÊó¤òÊݸ¤·¤Þ¤¹"
+
+msgid "Save Setup"
+msgstr "ÀßÄê¤òÊݸ¤·¤Þ¤¹"
+
#, c-format
msgid "E739: Cannot create directory: %s"
msgstr "E739: ¥Ç¥£¥ì¥¯¥È¥ê¤òºîÀ®¤Ç¤­¤Þ¤»¤ó: %s"
-#: ../ex_docmd.c:7268
#, c-format
msgid "E189: \"%s\" exists (add ! to override)"
msgstr "E189: \"%s\" ¤¬Â¸ºß¤·¤Þ¤¹ (¾å½ñ¤¹¤ë¤Ë¤Ï ! ¤òÄɲ䷤Ƥ¯¤À¤µ¤¤)"
-#: ../ex_docmd.c:7273
#, c-format
msgid "E190: Cannot open \"%s\" for writing"
msgstr "E190: \"%s\" ¤ò½ñ¹þ¤ßÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó"
#. set mark
-#: ../ex_docmd.c:7294
msgid "E191: Argument must be a letter or forward/backward quote"
msgstr "E191: °ú¿ô¤Ï1ʸ»ú¤Î±Ñ»ú¤«°úÍÑÉä (' ¤« `) ¤Ç¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó"
-#: ../ex_docmd.c:7333
msgid "E192: Recursive use of :normal too deep"
msgstr "E192: :normal ¤ÎºÆµ¢ÍøÍѤ¬¿¼¤¯¤Ê¤ê²á¤®¤Þ¤·¤¿"
-#: ../ex_docmd.c:7807
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< ¤Ï +eval µ¡Ç½¤¬Ìµ¤¤¤ÈÍøÍѤǤ­¤Þ¤»¤ó"
+
msgid "E194: No alternate file name to substitute for '#'"
msgstr "E194: '#'¤òÃÖ¤­´¹¤¨¤ëÉû¥Õ¥¡¥¤¥ë¤Î̾Á°¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:7841
msgid "E495: no autocommand file name to substitute for \"<afile>\""
msgstr "E495: \"<afile>\"¤òÃÖ¤­´¹¤¨¤ëautocommand¤Î¥Õ¥¡¥¤¥ë̾¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:7850
msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
msgstr "E496: \"<abuf>\"¤òÃÖ¤­´¹¤¨¤ëautocommand¥Ð¥Ã¥Õ¥¡Èֹ椬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:7861
msgid "E497: no autocommand match name to substitute for \"<amatch>\""
msgstr "E497: \"<amatch>\"¤òÃÖ¤­´¹¤¨¤ëautocommand¤Î³ºÅö̾¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:7870
msgid "E498: no :source file name to substitute for \"<sfile>\""
msgstr "E498: \"<sfile>\"¤òÃÖ¤­´¹¤¨¤ë :source Âоݥե¡¥¤¥ë̾¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:7876
msgid "E842: no line number to use for \"<slnum>\""
msgstr "E842: \"<slnum>\"¤òÃÖ¤­´¹¤¨¤ë¹ÔÈֹ椬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
+#, no-c-format
msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
msgstr ""
"E499: '%' ¤ä '#' ¤¬ÌµÌ¾¥Õ¥¡¥¤¥ë¤Ê¤Î¤Ç \":p:h\" ¤òȼ¤ï¤Ê¤¤»È¤¤Êý¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../ex_docmd.c:7905
msgid "E500: Evaluates to an empty string"
msgstr "E500: ¶õʸ»úÎó¤È¤·¤ÆÉ¾²Á¤µ¤ì¤Þ¤·¤¿"
-#: ../ex_docmd.c:8838
msgid "E195: Cannot open viminfo file for reading"
msgstr "E195: viminfo¥Õ¥¡¥¤¥ë¤òÆÉ¹þÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó"
-#: ../ex_eval.c:464
+msgid "E196: No digraphs in this version"
+msgstr "E196: ¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ë¹ç»ú¤Ï¤¢¤ê¤Þ¤»¤ó"
+
msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
msgstr "E608: 'Vim' ¤Ç»Ï¤Þ¤ëÎã³°¤Ï :throw ¤Ç¤­¤Þ¤»¤ó"
#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
#, c-format
msgid "Exception thrown: %s"
msgstr "Îã³°¤¬È¯À¸¤·¤Þ¤·¤¿: %s"
-#: ../ex_eval.c:545
#, c-format
msgid "Exception finished: %s"
msgstr "Îã³°¤¬¼ý«¤·¤Þ¤·¤¿: %s"
-#: ../ex_eval.c:546
#, c-format
msgid "Exception discarded: %s"
msgstr "Îã³°¤¬ÇË´þ¤µ¤ì¤Þ¤·¤¿: %s"
-#: ../ex_eval.c:588 ../ex_eval.c:634
#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, ¹Ô %<PRId64>"
+msgid "%s, line %ld"
+msgstr "%s, ¹Ô %ld"
#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
#, c-format
msgid "Exception caught: %s"
msgstr "Îã³°¤¬Ê᪤µ¤ì¤Þ¤·¤¿: %s"
-#: ../ex_eval.c:676
#, c-format
msgid "%s made pending"
msgstr "%s ¤Ë¤è¤ê̤·èÄê¾õÂÖ¤¬À¸¤¸¤Þ¤·¤¿"
-#: ../ex_eval.c:679
#, c-format
msgid "%s resumed"
msgstr "%s ¤¬ºÆ³«¤·¤Þ¤·¤¿"
-#: ../ex_eval.c:683
#, c-format
msgid "%s discarded"
msgstr "%s ¤¬ÇË´þ¤µ¤ì¤Þ¤·¤¿"
-#: ../ex_eval.c:708
msgid "Exception"
msgstr "Îã³°"
-#: ../ex_eval.c:713
msgid "Error and interrupt"
msgstr "¥¨¥é¡¼¤È³ä¹þ¤ß"
-#: ../ex_eval.c:715
msgid "Error"
msgstr "¥¨¥é¡¼"
#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
msgid "Interrupt"
msgstr "³ä¹þ¤ß"
-#: ../ex_eval.c:795
msgid "E579: :if nesting too deep"
msgstr "E579: :if ¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
-#: ../ex_eval.c:830
msgid "E580: :endif without :if"
msgstr "E580: :if ¤Î¤Ê¤¤ :endif ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:873
msgid "E581: :else without :if"
msgstr "E581: :if ¤Î¤Ê¤¤ :else ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:876
msgid "E582: :elseif without :if"
msgstr "E582: :if ¤Î¤Ê¤¤ :elseif ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:880
msgid "E583: multiple :else"
msgstr "E583: Ê£¿ô¤Î :else ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:883
msgid "E584: :elseif after :else"
msgstr "E584: :else ¤Î¸å¤Ë :elseif ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:941
msgid "E585: :while/:for nesting too deep"
msgstr "E585: :while ¤ä :for ¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
-#: ../ex_eval.c:1028
msgid "E586: :continue without :while or :for"
msgstr "E586: :while ¤ä :for ¤Î¤Ê¤¤ :continue ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:1061
msgid "E587: :break without :while or :for"
msgstr "E587: :while ¤ä :for ¤Î¤Ê¤¤ :break ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:1102
msgid "E732: Using :endfor with :while"
msgstr "E732: :endfor ¤ò :while ¤ÈÁȤ߹ç¤ï¤»¤Æ¤¤¤Þ¤¹"
-#: ../ex_eval.c:1104
msgid "E733: Using :endwhile with :for"
msgstr "E733: :endwhile ¤ò :for ¤ÈÁȤ߹ç¤ï¤»¤Æ¤¤¤Þ¤¹"
-#: ../ex_eval.c:1247
msgid "E601: :try nesting too deep"
msgstr "E601: :try ¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
-#: ../ex_eval.c:1317
msgid "E603: :catch without :try"
msgstr "E603: :try ¤Î¤Ê¤¤ :catch ¤¬¤¢¤ê¤Þ¤¹"
#. Give up for a ":catch" after ":finally" and ignore it.
#. * Just parse.
-#: ../ex_eval.c:1332
msgid "E604: :catch after :finally"
msgstr "E604: :finally ¤Î¸å¤Ë :catch ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:1451
msgid "E606: :finally without :try"
msgstr "E606: :try ¤Î¤Ê¤¤ :finally ¤¬¤¢¤ê¤Þ¤¹"
#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
msgid "E607: multiple :finally"
msgstr "E607: Ê£¿ô¤Î :finally ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:1571
msgid "E602: :endtry without :try"
msgstr "E602: :try ¤Î¤Ê¤¤ :endtry ¤Ç¤¹"
-#: ../ex_eval.c:2026
msgid "E193: :endfunction not inside a function"
msgstr "E193: ´Ø¿ô¤Î³°¤Ë :endfunction ¤¬¤¢¤ê¤Þ¤·¤¿"
-#: ../ex_getln.c:1643
msgid "E788: Not allowed to edit another buffer now"
msgstr "E788: ¸½ºß¤Ï¾¤Î¥Ð¥Ã¥Õ¥¡¤òÊÔ½¸¤¹¤ë¤³¤È¤Ïµö¤µ¤ì¤Þ¤»¤ó"
-#: ../ex_getln.c:1656
msgid "E811: Not allowed to change buffer information now"
msgstr "E811: ¸½ºß¤Ï¥Ð¥Ã¥Õ¥¡¾ðÊó¤òÊѹ¹¤¹¤ë¤³¤È¤Ïµö¤µ¤ì¤Þ¤»¤ó"
-#: ../ex_getln.c:3178
msgid "tagname"
msgstr "¥¿¥°Ì¾"
-#: ../ex_getln.c:3181
msgid " kind file\n"
msgstr " ¥Õ¥¡¥¤¥ë¼ïÎà\n"
-#: ../ex_getln.c:4799
msgid "'history' option is zero"
msgstr "¥ª¥×¥·¥ç¥ó 'history' ¤¬¥¼¥í¤Ç¤¹"
-#: ../ex_getln.c:5046
#, c-format
msgid ""
"\n"
@@ -1986,303 +1613,224 @@ msgstr ""
"\n"
"# %s ¹àÌܤÎÍúÎò (¿·¤·¤¤¤â¤Î¤«¤é¸Å¤¤¤â¤Î¤Ø):\n"
-#: ../ex_getln.c:5047
msgid "Command Line"
msgstr "¥³¥Þ¥ó¥É¥é¥¤¥ó"
-#: ../ex_getln.c:5048
msgid "Search String"
msgstr "¸¡º÷ʸ»úÎó"
-#: ../ex_getln.c:5049
msgid "Expression"
msgstr "¼°"
-#: ../ex_getln.c:5050
msgid "Input Line"
msgstr "ÆþÎϹÔ"
-#: ../ex_getln.c:5117
+msgid "Debug Line"
+msgstr "¥Ç¥Ð¥Ã¥°¹Ô"
+
msgid "E198: cmd_pchar beyond the command length"
msgstr "E198: cmd_pchar ¤¬¥³¥Þ¥ó¥ÉŤòͤ¨¤Þ¤·¤¿"
-#: ../ex_getln.c:5279
msgid "E199: Active window or buffer deleted"
msgstr "E199: ¥¢¥¯¥Æ¥£¥Ö¤Ê¥¦¥£¥ó¥É¥¦¤«¥Ð¥Ã¥Õ¥¡¤¬ºï½ü¤µ¤ì¤Þ¤·¤¿"
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr "E854: ¥Ñ¥¹¤¬Ä¹²á¤®¤ÆÊä´°¤Ç¤­¤Þ¤»¤ó"
-
-#: ../file_search.c:446
-#, c-format
-msgid ""
-"E343: Invalid path: '**[number]' must be at the end of the path or be "
-"followed by '%s'."
-msgstr ""
-"E343: ̵¸ú¤Ê¥Ñ¥¹¤Ç¤¹: '**[¿ôÃÍ]' ¤Ïpath¤ÎºÇ¸å¤« '%s' ¤¬Â³¤¤¤Æ¤Ê¤¤¤È¤¤¤±¤Þ¤»"
-"¤ó."
-
-#: ../file_search.c:1505
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: cdpath¤Ë¤Ï \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: path¤Ë¤Ï \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: cdpath¤Ë¤Ï¤³¤ì°Ê¾å \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: ¥Ñ¥¹¤Ë¤Ï¤³¤ì°Ê¾å \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#: ../fileio.c:137
msgid "E812: Autocommands changed buffer or buffer name"
msgstr "E812: autocommand¤¬¥Ð¥Ã¥Õ¥¡¤«¥Ð¥Ã¥Õ¥¡Ì¾¤òÊѹ¹¤·¤Þ¤·¤¿"
-#: ../fileio.c:368
msgid "Illegal file name"
msgstr "ÉÔÀµ¤Ê¥Õ¥¡¥¤¥ë̾"
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
msgid "is a directory"
msgstr "¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹"
-#: ../fileio.c:397
msgid "is not a file"
msgstr "¤Ï¥Õ¥¡¥¤¥ë¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../fileio.c:508 ../fileio.c:3522
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "¤Ï¥Ç¥Ð¥¤¥¹¤Ç¤¹ ('opendevice' ¥ª¥×¥·¥ç¥ó¤Ç²óÈò¤Ç¤­¤Þ¤¹)"
+
msgid "[New File]"
msgstr "[¿·¥Õ¥¡¥¤¥ë]"
-#: ../fileio.c:511
msgid "[New DIRECTORY]"
msgstr "[¿·µ¬¥Ç¥£¥ì¥¯¥È¥ê]"
-#: ../fileio.c:529 ../fileio.c:532
msgid "[File too big]"
msgstr "[¥Õ¥¡¥¤¥ë²áÂç]"
-#: ../fileio.c:534
msgid "[Permission Denied]"
msgstr "[¸¢¸Â¤¬¤¢¤ê¤Þ¤»¤ó]"
-#: ../fileio.c:653
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr "E200: *ReadPre autocommand ¤¬¥Õ¥¡¥¤¥ë¤òÆÉ¹þÉԲĤˤ·¤Þ¤·¤¿"
-#: ../fileio.c:655
msgid "E201: *ReadPre autocommands must not change current buffer"
msgstr "E201: *ReadPre autocommand ¤Ï¸½ºß¤Î¥Ð¥Ã¥Õ¥¡¤òÊѤ¨¤é¤ì¤Þ¤»¤ó"
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
+msgid "Vim: Reading from stdin...\n"
msgstr "Vim: ɸ½àÆþÎϤ«¤éÆÉ¹þÃæ...\n"
+msgid "Reading from stdin..."
+msgstr "ɸ½àÆþÎϤ«¤éÆÉ¹þ¤ßÃæ..."
+
#. Re-opening the original file failed!
-#: ../fileio.c:909
msgid "E202: Conversion made file unreadable!"
msgstr "E202: ÊÑ´¹¤¬¥Õ¥¡¥¤¥ë¤òÆÉ¹þÉԲĤˤ·¤Þ¤·¤¿"
-#. fifo or socket
-#: ../fileio.c:1782
msgid "[fifo/socket]"
msgstr "[FIFO/¥½¥±¥Ã¥È]"
-#. fifo
-#: ../fileio.c:1788
msgid "[fifo]"
msgstr "[FIFO]"
-#. or socket
-#: ../fileio.c:1794
msgid "[socket]"
msgstr "[¥½¥±¥Ã¥È]"
-#. or character special
-#: ../fileio.c:1801
msgid "[character special]"
msgstr "[¥­¥ã¥é¥¯¥¿¡¦¥Ç¥Ð¥¤¥¹]"
-#: ../fileio.c:1815
msgid "[CR missing]"
msgstr "[CR̵]"
-#: ../fileio.c:1819
msgid "[long lines split]"
msgstr "[Ĺ¹Ôʬ³ä]"
-#: ../fileio.c:1823 ../fileio.c:3512
msgid "[NOT converted]"
msgstr "[̤ÊÑ´¹]"
-#: ../fileio.c:1826 ../fileio.c:3515
msgid "[converted]"
msgstr "[ÊÑ´¹ºÑ]"
-#: ../fileio.c:1831
#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[%<PRId64> ¹ÔÌܤÇÊÑ´¹¥¨¥é¡¼]"
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[%ld ¹ÔÌܤÇÊÑ´¹¥¨¥é¡¼]"
-#: ../fileio.c:1835
#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[%<PRId64> ¹ÔÌܤÎÉÔÀµ¤Ê¥Ð¥¤¥È]"
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[%ld ¹ÔÌܤÎÉÔÀµ¤Ê¥Ð¥¤¥È]"
-#: ../fileio.c:1838
msgid "[READ ERRORS]"
msgstr "[ÆÉ¹þ¥¨¥é¡¼]"
-#: ../fileio.c:2104
msgid "Can't find temp file for conversion"
msgstr "ÊÑ´¹¤ËɬÍפʰì»þ¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../fileio.c:2110
msgid "Conversion with 'charconvert' failed"
msgstr "'charconvert' ¤Ë¤è¤ëÊÑ´¹¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../fileio.c:2113
msgid "can't read output of 'charconvert'"
msgstr "'charconvert' ¤Î½ÐÎϤòÆÉ¹þ¤á¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../fileio.c:2437
msgid "E676: No matching autocommands for acwrite buffer"
msgstr "E676: acwrite¥Ð¥Ã¥Õ¥¡¤Î³ºÅö¤¹¤ëautocommand¤Ï¸ºß¤·¤Þ¤»¤ó"
-#: ../fileio.c:2466
msgid "E203: Autocommands deleted or unloaded buffer to be written"
msgstr "E203: Êݸ¤¹¤ë¥Ð¥Ã¥Õ¥¡¤òautocommand¤¬ºï½ü¤«²òÊü¤·¤Þ¤·¤¿"
-#: ../fileio.c:2486
msgid "E204: Autocommand changed number of lines in unexpected way"
msgstr "E204: autocommand¤¬Í½´ü¤»¤ÌÊýË¡¤Ç¹Ô¿ô¤òÊѹ¹¤·¤Þ¤·¤¿"
-#: ../fileio.c:2548 ../fileio.c:2565
+# Added at 19-Jan-2004.
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans¤Ï̤Êѹ¹¤Î¥Ð¥Ã¥Õ¥¡¤ò¾å½ñ¤¹¤ë¤³¤È¤Ïµö²Ä¤·¤Æ¤¤¤Þ¤»¤ó"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "NetBeans¥Ð¥Ã¥Õ¥¡¤Î°ìÉô¤ò½ñ¤­½Ð¤¹¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
+
msgid "is not a file or writable device"
msgstr "¤Ï¥Õ¥¡¥¤¥ë¤Ç¤â½ñ¹þ¤ß²Äǽ¥Ç¥Ð¥¤¥¹¤Ç¤â¤¢¤ê¤Þ¤»¤ó"
-#: ../fileio.c:2601
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "'opendevice' ¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê¥Ç¥Ð¥¤¥¹¤Ø¤Î½ñ¤­¹þ¤ß¤Ï¤Ç¤­¤Þ¤»¤ó"
+
msgid "is read-only (add ! to override)"
msgstr "¤ÏÆÉ¹þÀìÍѤǤ¹ (¶¯À©½ñ¹þ¤Ë¤Ï ! ¤òÄɲÃ)"
-#: ../fileio.c:2886
msgid "E506: Can't write to backup file (add ! to override)"
msgstr "E506: ¥Ð¥Ã¥¯¥¢¥Ã¥×¥Õ¥¡¥¤¥ë¤òÊݸ¤Ç¤­¤Þ¤»¤ó (! ¤òÄɲäǶ¯À©Êݸ)"
-#: ../fileio.c:2898
msgid "E507: Close error for backup file (add ! to override)"
msgstr ""
"E507: ¥Ð¥Ã¥¯¥¢¥Ã¥×¥Õ¥¡¥¤¥ë¤òÊĤ¸¤ëºÝ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿ (! ¤òÄɲäǶ¯À©)"
-#: ../fileio.c:2901
msgid "E508: Can't read file for backup (add ! to override)"
msgstr "E508: ¥Ð¥Ã¥¯¥¢¥Ã¥×ÍÑ¥Õ¥¡¥¤¥ë¤òÆÉ¹þ¤á¤Þ¤»¤ó (! ¤òÄɲäǶ¯À©ÆÉ¹þ)"
-#: ../fileio.c:2923
msgid "E509: Cannot create backup file (add ! to override)"
msgstr "E509: ¥Ð¥Ã¥¯¥¢¥Ã¥×¥Õ¥¡¥¤¥ë¤òºî¤ì¤Þ¤»¤ó (! ¤òÄɲäǶ¯À©ºîÀ®)"
-#: ../fileio.c:3008
msgid "E510: Can't make backup file (add ! to override)"
msgstr "E510: ¥Ð¥Ã¥¯¥¢¥Ã¥×¥Õ¥¡¥¤¥ë¤òºî¤ì¤Þ¤»¤ó (! ¤òÄɲäǶ¯À©ºîÀ®)"
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: ¥ê¥½¡¼¥¹¥Õ¥©¡¼¥¯¤¬¼º¤ï¤ì¤ë¤«¤â¤·¤ì¤Þ¤»¤ó (! ¤òÄɲäǶ¯À©)"
+
msgid "E214: Can't find temp file for writing"
msgstr "E214: ÊݸÍѰì»þ¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../fileio.c:3134
msgid "E213: Cannot convert (add ! to write without conversion)"
msgstr "E213: ÊÑ´¹¤Ç¤­¤Þ¤»¤ó (! ¤òÄɲäÇÊÑ´¹¤»¤º¤ËÊݸ)"
-#: ../fileio.c:3169
msgid "E166: Can't open linked file for writing"
msgstr "E166: ¥ê¥ó¥¯¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë½ñ¹þ¤á¤Þ¤»¤ó"
-#: ../fileio.c:3173
msgid "E212: Can't open file for writing"
msgstr "E212: ½ñ¹þ¤ßÍѤ˥ե¡¥¤¥ë¤ò³«¤±¤Þ¤»¤ó"
-#: ../fileio.c:3363
msgid "E667: Fsync failed"
msgstr "E667: fsync ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../fileio.c:3398
msgid "E512: Close failed"
msgstr "E512: ÊĤ¸¤ë¤³¤È¤Ë¼ºÇÔ"
-#: ../fileio.c:3436
msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
msgstr "E513: ½ñ¹þ¤ß¥¨¥é¡¼, ÊÑ´¹¼ºÇÔ (¾å½ñ¤¹¤ë¤Ë¤Ï 'fenc' ¤ò¶õ¤Ë¤·¤Æ¤¯¤À¤µ¤¤)"
-#: ../fileio.c:3441
#, c-format
msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
"override)"
msgstr ""
-"E513: ½ñ¹þ¤ß¥¨¥é¡¼, ÊÑ´¹¼ºÇÔ, ¹Ô¿ô %<PRId64> (¾å½ñ¤¹¤ë¤Ë¤Ï 'fenc' ¤ò¶õ¤Ë¤·¤Æ"
-"¤¯¤À¤µ¤¤)"
+"E513: ½ñ¹þ¤ß¥¨¥é¡¼, ÊÑ´¹¼ºÇÔ, ¹Ô¿ô %ld (¾å½ñ¤¹¤ë¤Ë¤Ï 'fenc' ¤ò¶õ¤Ë¤·¤Æ¤¯¤À¤µ"
+"¤¤)"
-#: ../fileio.c:3448
msgid "E514: write error (file system full?)"
msgstr "E514: ½ñ¹þ¤ß¥¨¥é¡¼, (¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤¬ËþÇÕ?)"
-#: ../fileio.c:3506
msgid " CONVERSION ERROR"
msgstr " ÊÑ´¹¥¨¥é¡¼"
-#: ../fileio.c:3509
#, c-format
-msgid " in line %<PRId64>;"
-msgstr " ¹Ô %<PRId64>;"
+msgid " in line %ld;"
+msgstr " ¹Ô %ld;"
-#: ../fileio.c:3519
msgid "[Device]"
msgstr "[¥Ç¥Ð¥¤¥¹]"
-#: ../fileio.c:3522
msgid "[New]"
msgstr "[¿·]"
-#: ../fileio.c:3535
msgid " [a]"
msgstr " [a]"
-#: ../fileio.c:3535
msgid " appended"
msgstr " ÄɲÃ"
-#: ../fileio.c:3537
msgid " [w]"
msgstr " [w]"
-#: ../fileio.c:3537
msgid " written"
msgstr " ½ñ¹þ¤ß"
-#: ../fileio.c:3579
msgid "E205: Patchmode: can't save original file"
msgstr "E205: patchmode: ¸¶ËÜ¥Õ¥¡¥¤¥ë¤òÊݸ¤Ç¤­¤Þ¤»¤ó"
-#: ../fileio.c:3602
msgid "E206: patchmode: can't touch empty original file"
msgstr "E206: patchmode: ¶õ¤Î¸¶ËÜ¥Õ¥¡¥¤¥ë¤òtouch¤Ç¤­¤Þ¤»¤ó"
-#: ../fileio.c:3616
msgid "E207: Can't delete backup file"
msgstr "E207: ¥Ð¥Ã¥¯¥¢¥Ã¥×¥Õ¥¡¥¤¥ë¤ò¾Ã¤»¤Þ¤»¤ó"
-#: ../fileio.c:3672
msgid ""
"\n"
"WARNING: Original file may be lost or damaged\n"
@@ -2290,134 +1838,105 @@ msgstr ""
"\n"
"·Ù¹ð: ¸¶ËÜ¥Õ¥¡¥¤¥ë¤¬¼º¤ï¤ì¤¿¤«Êѹ¹¤µ¤ì¤Þ¤·¤¿\n"
-#: ../fileio.c:3675
msgid "don't quit the editor until the file is successfully written!"
msgstr "¥Õ¥¡¥¤¥ë¤ÎÊݸ¤ËÀ®¸ù¤¹¤ë¤Þ¤Ç¥¨¥Ç¥£¥¿¤ò½ªÎ»¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤!"
-#: ../fileio.c:3795
msgid "[dos]"
msgstr "[dos]"
-#: ../fileio.c:3795
msgid "[dos format]"
msgstr "[dos¥Õ¥©¡¼¥Þ¥Ã¥È]"
-#: ../fileio.c:3801
msgid "[mac]"
msgstr "[mac]"
-#: ../fileio.c:3801
msgid "[mac format]"
msgstr "[mac¥Õ¥©¡¼¥Þ¥Ã¥È]"
-#: ../fileio.c:3807
msgid "[unix]"
msgstr "[unix]"
-#: ../fileio.c:3807
msgid "[unix format]"
msgstr "[unix¥Õ¥©¡¼¥Þ¥Ã¥È]"
-#: ../fileio.c:3831
msgid "1 line, "
msgstr "1 ¹Ô, "
-#: ../fileio.c:3833
#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> ¹Ô, "
+msgid "%ld lines, "
+msgstr "%ld ¹Ô, "
-#: ../fileio.c:3836
msgid "1 character"
msgstr "1 ʸ»ú"
-#: ../fileio.c:3838
#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> ʸ»ú"
+msgid "%lld characters"
+msgstr "%lld ʸ»ú"
-#: ../fileio.c:3849
msgid "[noeol]"
msgstr "[noeol]"
-#: ../fileio.c:3849
msgid "[Incomplete last line]"
msgstr "[ºÇ½ª¹Ô¤¬ÉÔ´°Á´]"
#. don't overwrite messages here
#. must give this prompt
#. don't use emsg() here, don't want to flush the buffers
-#: ../fileio.c:3865
msgid "WARNING: The file has been changed since reading it!!!"
msgstr "·Ù¹ð: ÆÉ¹þ¤ó¤À¸å¤Ë¥Õ¥¡¥¤¥ë¤ËÊѹ¹¤¬¤¢¤ê¤Þ¤·¤¿!!!"
-#: ../fileio.c:3867
msgid "Do you really want to write to it"
msgstr "ËÜÅö¤Ë¾å½ñ¤­¤·¤Þ¤¹¤«"
-#: ../fileio.c:4648
#, c-format
msgid "E208: Error writing to \"%s\""
msgstr "E208: \"%s\" ¤ò½ñ¹þ¤ßÃæ¤Î¥¨¥é¡¼¤Ç¤¹"
-#: ../fileio.c:4655
#, c-format
msgid "E209: Error closing \"%s\""
msgstr "E209: \"%s\" ¤òÊĤ¸¤ë»þ¤Ë¥¨¥é¡¼¤Ç¤¹"
-#: ../fileio.c:4657
#, c-format
msgid "E210: Error reading \"%s\""
msgstr "E210: \"%s\" ¤òÆÉ¹þÃæ¤Î¥¨¥é¡¼¤Ç¤¹"
-#: ../fileio.c:4883
msgid "E246: FileChangedShell autocommand deleted buffer"
msgstr "E246: autocommand ¤Î FileChangedShell ¤¬¥Ð¥Ã¥Õ¥¡¤òºï½ü¤·¤Þ¤·¤¿"
-#: ../fileio.c:4894
#, c-format
msgid "E211: File \"%s\" no longer available"
msgstr "E211: ¥Õ¥¡¥¤¥ë \"%s\" ¤Ï´û¤Ë¸ºß¤·¤Þ¤»¤ó"
-#: ../fileio.c:4906
#, c-format
msgid ""
"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
"well"
msgstr "W12: ·Ù¹ð: ¥Õ¥¡¥¤¥ë \"%s\" ¤¬Êѹ¹¤µ¤ìVim¤Î¥Ð¥Ã¥Õ¥¡¤âÊѹ¹¤µ¤ì¤Þ¤·¤¿"
-#: ../fileio.c:4907
msgid "See \":help W12\" for more info."
msgstr "¾ÜºÙ¤Ï \":help W12\" ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../fileio.c:4910
#, c-format
msgid "W11: Warning: File \"%s\" has changed since editing started"
msgstr "W11: ·Ù¹ð: ¥Õ¥¡¥¤¥ë \"%s\" ¤ÏÊÔ½¸³«»Ï¸å¤ËÊѹ¹¤µ¤ì¤Þ¤·¤¿"
-#: ../fileio.c:4911
msgid "See \":help W11\" for more info."
msgstr "¾ÜºÙ¤Ï \":help W11\" ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../fileio.c:4914
#, c-format
msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
msgstr "W16: ·Ù¹ð: ¥Õ¥¡¥¤¥ë \"%s\" ¤Î¥â¡¼¥É¤¬ÊÔ½¸³«»Ï¸å¤ËÊѹ¹¤µ¤ì¤Þ¤·¤¿"
-#: ../fileio.c:4915
msgid "See \":help W16\" for more info."
msgstr "¾ÜºÙ¤Ï \":help W16\" ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../fileio.c:4927
#, c-format
msgid "W13: Warning: File \"%s\" has been created after editing started"
msgstr "W13: ·Ù¹ð: ¥Õ¥¡¥¤¥ë \"%s\" ¤ÏÊÔ½¸³«»Ï¸å¤ËºîÀ®¤µ¤ì¤Þ¤·¤¿"
-#: ../fileio.c:4947
msgid "Warning"
msgstr "·Ù¹ð"
-#: ../fileio.c:4948
msgid ""
"&OK\n"
"&Load File"
@@ -2425,48 +1944,45 @@ msgstr ""
"&OK\n"
"¥Õ¥¡¥¤¥ëÆÉ¹þ(&L)"
-#: ../fileio.c:5065
#, c-format
msgid "E462: Could not prepare for reloading \"%s\""
msgstr "E462: \"%s\" ¤ò¥ê¥í¡¼¥É¤¹¤ë½àÈ÷¤¬¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../fileio.c:5078
#, c-format
msgid "E321: Could not reload \"%s\""
msgstr "E321: \"%s\" ¤Ï¥ê¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../fileio.c:5601
msgid "--Deleted--"
msgstr "--ºï½üºÑ--"
-#: ../fileio.c:5732
#, c-format
msgid "auto-removing autocommand: %s <buffer=%d>"
msgstr "autocommand: %s <¥Ð¥Ã¥Õ¥¡=%d> ¤¬¼«Æ°Åª¤Ëºï½ü¤µ¤ì¤Þ¤¹"
#. the group doesn't exist
-#: ../fileio.c:5772
#, c-format
msgid "E367: No such group: \"%s\""
msgstr "E367: ¤½¤Î¥°¥ë¡¼¥×¤Ï¤¢¤ê¤Þ¤»¤ó: \"%s\""
-#: ../fileio.c:5897
+msgid "E936: Cannot delete the current group"
+msgstr "E936: ¸½ºß¤Î¥°¥ë¡¼¥×¤Ïºï½ü¤Ç¤­¤Þ¤»¤ó"
+
+msgid "W19: Deleting augroup that is still in use"
+msgstr "W19: »ÈÍÑÃæ¤Î augroup ¤ò¾Ã¤½¤¦¤È¤·¤Æ¤¤¤Þ¤¹"
+
#, c-format
msgid "E215: Illegal character after *: %s"
msgstr "E215: * ¤Î¸å¤ËÉÔÀµ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤·¤¿: %s"
-#: ../fileio.c:5905
#, c-format
msgid "E216: No such event: %s"
msgstr "E216: ¤½¤Î¤è¤¦¤Ê¥¤¥Ù¥ó¥È¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../fileio.c:5907
#, c-format
msgid "E216: No such group or event: %s"
msgstr "E216: ¤½¤Î¤è¤¦¤Ê¥°¥ë¡¼¥×¤â¤·¤¯¤Ï¥¤¥Ù¥ó¥È¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
#. Highlight title
-#: ../fileio.c:6090
msgid ""
"\n"
"--- Auto-Commands ---"
@@ -2474,756 +1990,555 @@ msgstr ""
"\n"
"--- Auto-Commands ---"
-#: ../fileio.c:6293
#, c-format
msgid "E680: <buffer=%d>: invalid buffer number "
msgstr "E680: <¥Ð¥Ã¥Õ¥¡=%d>: ̵¸ú¤Ê¥Ð¥Ã¥Õ¥¡ÈÖ¹æ¤Ç¤¹ "
-#: ../fileio.c:6370
msgid "E217: Can't execute autocommands for ALL events"
msgstr "E217: Á´¤Æ¤Î¥¤¥Ù¥ó¥È¤ËÂФ·¤Æ¤Îautocommand¤Ï¼Â¹Ô¤Ç¤­¤Þ¤»¤ó"
-#: ../fileio.c:6393
msgid "No matching autocommands"
msgstr "³ºÅö¤¹¤ëautocommand¤Ï¸ºß¤·¤Þ¤»¤ó"
-#: ../fileio.c:6831
msgid "E218: autocommand nesting too deep"
msgstr "E218: autocommand¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
-#: ../fileio.c:7143
#, c-format
msgid "%s Auto commands for \"%s\""
msgstr "%s Auto commands for \"%s\""
-#: ../fileio.c:7149
#, c-format
msgid "Executing %s"
msgstr "%s ¤ò¼Â¹Ô¤·¤Æ¤¤¤Þ¤¹"
-#: ../fileio.c:7211
#, c-format
msgid "autocommand %s"
msgstr "autocommand %s"
-#: ../fileio.c:7795
msgid "E219: Missing {."
msgstr "E219: { ¤¬¤¢¤ê¤Þ¤»¤ó."
-#: ../fileio.c:7797
msgid "E220: Missing }."
msgstr "E220: } ¤¬¤¢¤ê¤Þ¤»¤ó."
-#: ../fold.c:93
msgid "E490: No fold found"
msgstr "E490: ÀÞ¾ö¤ß¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../fold.c:544
msgid "E350: Cannot create fold with current 'foldmethod'"
msgstr "E350: ¸½ºß¤Î 'foldmethod' ¤Ç¤ÏÀÞ¾ö¤ß¤òºîÀ®¤Ç¤­¤Þ¤»¤ó"
-#: ../fold.c:546
msgid "E351: Cannot delete fold with current 'foldmethod'"
msgstr "E351: ¸½ºß¤Î 'foldmethod' ¤Ç¤ÏÀÞ¾ö¤ß¤òºï½ü¤Ç¤­¤Þ¤»¤ó"
-#: ../fold.c:1784
#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld ¹Ô¤¬ÀÞ¾ö¤Þ¤ì¤Þ¤·¤¿ "
+msgid "+--%3ld line folded "
+msgid_plural "+--%3ld lines folded "
+msgstr[0] "+--%3ld ¹Ô¤¬ÀÞ¾ö¤Þ¤ì¤Þ¤·¤¿ "
-#. buffer has already been read
-#: ../getchar.c:273
msgid "E222: Add to read buffer"
msgstr "E222: ÆÉ¹þ¥Ð¥Ã¥Õ¥¡¤ØÄɲÃ"
-#: ../getchar.c:2040
msgid "E223: recursive mapping"
msgstr "E223: ºÆµ¢Åª¥Þ¥Ã¥Ô¥ó¥°"
-#: ../getchar.c:2849
#, c-format
msgid "E224: global abbreviation already exists for %s"
msgstr "E224: %s ¤È¤¤¤¦¥°¥í¡¼¥Ð¥ëû½ÌÆþÎϤϴû¤Ë¸ºß¤·¤Þ¤¹"
-#: ../getchar.c:2852
#, c-format
msgid "E225: global mapping already exists for %s"
msgstr "E225: %s ¤È¤¤¤¦¥°¥í¡¼¥Ð¥ë¥Þ¥Ã¥Ô¥ó¥°¤Ï´û¤Ë¸ºß¤·¤Þ¤¹"
-#: ../getchar.c:2952
#, c-format
msgid "E226: abbreviation already exists for %s"
msgstr "E226: %s ¤È¤¤¤¦Ã»½ÌÆþÎϤϴû¤Ë¸ºß¤·¤Þ¤¹"
-#: ../getchar.c:2955
#, c-format
msgid "E227: mapping already exists for %s"
msgstr "E227: %s ¤È¤¤¤¦¥Þ¥Ã¥Ô¥ó¥°¤Ï´û¤Ë¸ºß¤·¤Þ¤¹"
-#: ../getchar.c:3008
msgid "No abbreviation found"
msgstr "û½ÌÆþÎϤϸ«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../getchar.c:3010
msgid "No mapping found"
msgstr "¥Þ¥Ã¥Ô¥ó¥°¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../getchar.c:3974
msgid "E228: makemap: Illegal mode"
msgstr "E228: makemap: ÉÔÀµ¤Ê¥â¡¼¥É"
-#. key value of 'cedit' option
-#. type of cmdline window or 0
-#. result of cmdline window or 0
-#: ../globals.h:924
-msgid "--No lines in buffer--"
-msgstr "--¥Ð¥Ã¥Õ¥¡¤Ë¹Ô¤¬¤¢¤ê¤Þ¤»¤ó--"
+msgid "E851: Failed to create a new process for the GUI"
+msgstr "E851: GUIÍÑ¤Î¥×¥í¥»¥¹¤Îµ¯Æ°¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#.
-#. * The error messages that can be shared are included here.
-#. * Excluded are errors that are only used once and debugging messages.
-#.
-#: ../globals.h:996
-msgid "E470: Command aborted"
-msgstr "E470: ¥³¥Þ¥ó¥É¤¬ÃæÃǤµ¤ì¤Þ¤·¤¿"
+msgid "E852: The child process failed to start the GUI"
+msgstr "E852: »Ò¥×¥í¥»¥¹¤¬GUI¤Îµ¯Æ°¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: °ú¿ô¤¬É¬ÍפǤ¹"
+msgid "E229: Cannot start the GUI"
+msgstr "E229: GUI¤ò³«»Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: \\ ¤Î¸å¤Ï / ¤« ? ¤« & ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: \"%s\"¤«¤éÆÉ¹þ¤à¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr "E11: ¥³¥Þ¥ó¥É¥é¥¤¥ó¤Ç¤Ï̵¸ú¤Ç¤¹; <CR>¤Ç¼Â¹Ô, CTRL-C¤Ç¤ä¤á¤ë"
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr "E665: Í­¸ú¤Ê¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤¤¤Î¤Ç, GUI¤ò³«»Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
-msgstr ""
-"E12: ¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ä¥¿¥°¸¡º÷¤Ç¤Ïexrc/vimrc¤Î¥³¥Þ¥ó¥É¤Ïµö²Ä¤µ¤ì¤Þ¤»¤ó"
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' ¤¬Ìµ¸ú¤Ç¤¹"
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: :endif ¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: 'imactivatekey' ¤ËÀßÄꤵ¤ì¤¿Ãͤ¬Ìµ¸ú¤Ç¤¹"
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: :endtry ¤¬¤¢¤ê¤Þ¤»¤ó"
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: %s ¤Î¿§¤ò³ä¤êÅö¤Æ¤é¤ì¤Þ¤»¤ó"
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: :endwhile ¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "No match at cursor, finding next"
+msgstr "¥«¡¼¥½¥ë¤Î°ÌÃ֤˥ޥåÁ¤Ï¤¢¤ê¤Þ¤»¤ó, ¼¡¤ò¸¡º÷¤·¤Æ¤¤¤Þ¤¹"
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: :endfor ¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: :while ¤Î¤Ê¤¤ :endwhile ¤¬¤¢¤ê¤Þ¤¹"
+msgid "<cannot open> "
+msgstr "<³«¤±¤Þ¤»¤ó> "
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: :endfor ¤Î¤Ê¤¤ :for ¤¬¤¢¤ê¤Þ¤¹"
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: ¥Õ¥©¥ó¥È %s ¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: ¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤·¤Þ¤¹ (! ¤òÄɲäǾå½ñ)"
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: ¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ËÌá¤ì¤Þ¤»¤ó"
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: ¥³¥Þ¥ó¥É¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "Pathname:"
+msgstr "¥Ñ¥¹Ì¾:"
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: ÆâÉô¥¨¥é¡¼¤Ç¤¹"
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: ¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "³ä¹þ¤Þ¤ì¤Þ¤·¤¿"
+msgid "OK"
+msgstr "OK"
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: ̵¸ú¤Ê¥¢¥É¥ì¥¹¤Ç¤¹"
+msgid "Cancel"
+msgstr "¥­¥ã¥ó¥»¥ë"
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: ̵¸ú¤Ê°ú¿ô¤Ç¤¹"
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "¥¹¥¯¥í¡¼¥ë¥Ð¡¼: ²èÁü¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿."
-#: ../globals.h:1015
-#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: ̵¸ú¤Ê°ú¿ô¤Ç¤¹: %s"
+msgid "Vim dialog"
+msgstr "Vim ¥À¥¤¥¢¥í¥°"
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: ̵¸ú¤Ê¼°¤Ç¤¹: %s"
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: ¥á¥Ã¥»¡¼¥¸¤È¥³¡¼¥ë¥Ð¥Ã¥¯¤Î¤¢¤ë BalloonEval ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó"
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: ̵¸ú¤ÊÈϰϤǤ¹"
+msgid "_Cancel"
+msgstr "¥­¥ã¥ó¥»¥ë(_C)"
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: ̵¸ú¤Ê¥³¥Þ¥ó¥É¤Ç¤¹"
+msgid "_Save"
+msgstr "Êݸ(_S)"
-#: ../globals.h:1019
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: \"%s\" ¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹"
+msgid "_Open"
+msgstr "³«¤¯(_O)"
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: ̵¸ú¤Ê¥¹¥¯¥í¡¼¥ëÎ̤Ǥ¹"
+msgid "_OK"
+msgstr "_OK"
-#: ../globals.h:1021
-msgid "E901: Job table is full"
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
msgstr ""
+"¤Ï¤¤(&Y)\n"
+"¤¤¤¤¤¨(&N)\n"
+"¥­¥ã¥ó¥»¥ë(&C)"
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: \"%s\"() ¤Î¥é¥¤¥Ö¥é¥ê¸Æ½Ð¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "Yes"
+msgstr "¤Ï¤¤"
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: ¥Þ¡¼¥¯¤Ë̵¸ú¤Ê¹ÔÈֹ椬»ØÄꤵ¤ì¤Æ¤¤¤Þ¤·¤¿"
+msgid "No"
+msgstr "¤¤¤¤¤¨"
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: ¥Þ¡¼¥¯¤ÏÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "Input _Methods"
+msgstr "¥¤¥ó¥×¥Ã¥È¥á¥½¥Ã¥É"
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: 'modifiable' ¤¬¥ª¥Õ¤Ê¤Î¤Ç, Êѹ¹¤Ç¤­¤Þ¤»¤ó"
+msgid "VIM - Search and Replace..."
+msgstr "VIM - ¸¡º÷¤ÈÃÖ´¹..."
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: ¥¹¥¯¥ê¥×¥È¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
+msgid "VIM - Search..."
+msgstr "VIM - ¸¡º÷..."
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: Éû¥Õ¥¡¥¤¥ë¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "Find what:"
+msgstr "¸¡º÷ʸ»úÎó:"
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: ¤½¤Î¤è¤¦¤Êû½ÌÆþÎϤϤ¢¤ê¤Þ¤»¤ó"
+msgid "Replace with:"
+msgstr "ÃÖ´¹Ê¸»úÎó:"
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: ! ¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Àµ³Î¤Ë³ºÅö¤¹¤ë¤â¤Î¤À¤±"
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: GUI¤Ï»ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹"
+#. match case button
+msgid "Match case"
+msgstr "Âçʸ»ú/¾®Ê¸»ú¤ò¶èÊ̤¹¤ë"
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: ¤½¤Î¤è¤¦¤Ê̾¤Î¥Ï¥¤¥é¥¤¥È¥°¥ë¡¼¥×¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
+msgid "Direction"
+msgstr "Êý¸þ"
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: ¤Þ¤À¥Æ¥­¥¹¥È¤¬ÁÞÆþ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "¾å"
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: °ÊÁ°¤Ë¥³¥Þ¥ó¥É¹Ô¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "Down"
+msgstr "²¼"
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: ¤½¤Î¤è¤¦¤Ê¥Þ¥Ã¥Ô¥ó¥°¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "Find Next"
+msgstr "¼¡¤ò¸¡º÷"
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: ³ºÅö¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "Replace"
+msgstr "ÃÖ´¹"
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: ³ºÅö¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
+msgid "Replace All"
+msgstr "Á´¤ÆÃÖ´¹"
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: ¥Õ¥¡¥¤¥ë̾¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "_Close"
+msgstr "ÊĤ¸¤ë(_C)"
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: Àµµ¬É½¸½ÃÖ´¹¤¬¤Þ¤À¼Â¹Ô¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: ¥»¥Ã¥·¥ç¥ó¥Þ¥Í¡¼¥¸¥ã¤«¤é \"die\" Í×µá¤ò¼õ¤±¼è¤ê¤Þ¤·¤¿\n"
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: ¥³¥Þ¥ó¥É¤¬¤Þ¤À¼Â¹Ô¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "Close tab"
+msgstr "¥¿¥Ö¥Ú¡¼¥¸¤òÊĤ¸¤ë"
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: Àµµ¬É½¸½¤¬¤Þ¤À¼Â¹Ô¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "New tab"
+msgstr "¿·µ¬¥¿¥Ö¥Ú¡¼¥¸"
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: ÈϰϻØÄê¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "Open Tab..."
+msgstr "¥¿¥Ö¥Ú¡¼¥¸¤ò³«¤¯..."
-#: ../globals.h:1048
-msgid "E36: Not enough room"
-msgstr "E36: ¥¦¥£¥ó¥É¥¦¤Ë½½Ê¬¤Ê¹â¤µ¤â¤·¤¯¤ÏÉý¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: ¥á¥¤¥ó¥¦¥£¥ó¥É¥¦¤¬ÉÔ°Õ¤ËÇ˲õ¤µ¤ì¤Þ¤·¤¿\n"
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó"
+msgid "&Filter"
+msgstr "¥Õ¥£¥ë¥¿(&F)"
-#: ../globals.h:1050
-msgid "E483: Can't get temp file name"
-msgstr "E483: °ì»þ¥Õ¥¡¥¤¥ë¤Î̾Á°¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
+msgid "&Cancel"
+msgstr "¥­¥ã¥ó¥»¥ë(&C)"
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: ¥Õ¥¡¥¤¥ë \"%s\" ¤ò³«¤±¤Þ¤»¤ó"
+msgid "Directories"
+msgstr "¥Ç¥£¥ì¥¯¥È¥ê"
-#: ../globals.h:1052
-#, c-format
-msgid "E485: Can't read file %s"
-msgstr "E485: ¥Õ¥¡¥¤¥ë %s ¤òÆÉ¹þ¤á¤Þ¤»¤ó"
+msgid "Filter"
+msgstr "¥Õ¥£¥ë¥¿"
-#: ../globals.h:1054
-msgid "E37: No write since last change (add ! to override)"
-msgstr "E37: ºÇ¸å¤ÎÊѹ¹¤¬Êݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó (! ¤òÄɲäÇÊѹ¹¤òÇË´þ)"
+msgid "&Help"
+msgstr "¥Ø¥ë¥×(&H)"
-#: ../globals.h:1055
-msgid "E37: No write since last change"
-msgstr "E37: ºÇ¸å¤ÎÊѹ¹¤¬Êݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "Files"
+msgstr "¥Õ¥¡¥¤¥ë"
-#: ../globals.h:1056
-msgid "E38: Null argument"
-msgstr "E38: °ú¿ô¤¬¶õ¤Ç¤¹"
+msgid "&OK"
+msgstr "&OK"
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: ¿ôÃͤ¬Í׵ᤵ¤ì¤Æ¤¤¤Þ¤¹"
+msgid "Selection"
+msgstr "ÁªÂò"
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: ¥¨¥é¡¼¥Õ¥¡¥¤¥ë %s ¤ò³«¤±¤Þ¤»¤ó"
+msgid "Find &Next"
+msgstr "¼¡¤ò¸¡º÷(&N)"
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: ¥á¥â¥ê¤¬¿Ô¤­²Ì¤Æ¤Þ¤·¤¿!"
+msgid "&Replace"
+msgstr "ÃÖ´¹(&R)"
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "¥Ñ¥¿¡¼¥ó¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
+msgid "Replace &All"
+msgstr "Á´¤ÆÃÖ´¹(&A)"
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: ¥Ñ¥¿¡¼¥ó¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿: %s"
+msgid "&Undo"
+msgstr "¥¢¥ó¥É¥¥(&U)"
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: °ú¿ô¤ÏÀµ¤ÎÃͤǤʤ±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+msgid "Open tab..."
+msgstr "¥¿¥Ö¥Ú¡¼¥¸¤ò³«¤¯"
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: Á°¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ËÌá¤ì¤Þ¤»¤ó"
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "¸¡º÷ʸ»úÎó ('\\' ¤ò¸¡º÷¤¹¤ë¤Ë¤Ï '\\\\')"
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: ¥¨¥é¡¼¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "¸¡º÷¡¦ÃÖ´¹ ('\\' ¤ò¸¡º÷¤¹¤ë¤Ë¤Ï '\\\\')"
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: ¥í¥±¡¼¥·¥ç¥ó¥ê¥¹¥È¤Ï¤¢¤ê¤Þ¤»¤ó"
-
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: ³ºÅöʸ»úÎó¤¬ÇË»¤·¤Æ¤¤¤Þ¤¹"
+#. 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 "»È¤ï¤ì¤Þ¤»¤ó"
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: ÉÔÀµ¤ÊÀµµ¬É½¸½¥×¥í¥°¥é¥à¤Ç¤¹"
+msgid "Directory\t*.nothing\n"
+msgstr "¥Ç¥£¥ì¥¯¥È¥ê\t*.nothing\n"
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: 'readonly' ¥ª¥×¥·¥ç¥ó¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹ (! ¤òÄɲäǾå½ñ¤­)"
-
-#: ../globals.h:1073
#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: ÆÉ¼èÀìÍÑÊÑ¿ô \"%s\" ¤Ë¤ÏÃͤòÀßÄê¤Ç¤­¤Þ¤»¤ó"
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: ¥¿¥¤¥È¥ë¤¬ \"%s\" ¤Î¥¦¥£¥ó¥É¥¦¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../globals.h:1075
#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E794: ¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤ÏÊÑ¿ô \"%s\" ¤ËÃͤòÀßÄê¤Ç¤­¤Þ¤»¤ó"
-
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: ¥¨¥é¡¼¥Õ¥¡¥¤¥ë¤ÎÆÉ¹þÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿"
-
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: ¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤Ïµö¤µ¤ì¤Þ¤»¤ó"
-
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: ¤³¤³¤Ç¤Ïµö²Ä¤µ¤ì¤Þ¤»¤ó"
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: °ú¿ô¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤»¤ó: \"-%s\"; OLEÈǤò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤."
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: ¥¹¥¯¥ê¡¼¥ó¥â¡¼¥É¤ÎÀßÄê¤Ë¤ÏÂбþ¤·¤Æ¤¤¤Þ¤»¤ó"
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: MDI¥¢¥×¥ê¤ÎÃæ¤Ç¤Ï¥¦¥£¥ó¥É¥¦¤ò³«¤±¤Þ¤»¤ó"
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: ̵¸ú¤Ê¥¹¥¯¥í¡¼¥ëÎ̤Ǥ¹"
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr "Vim E458: ¿§»ØÄ꤬Àµ¤·¤¯¤Ê¤¤¤Î¤Ç¥¨¥ó¥È¥ê¤ò³ä¤êÅö¤Æ¤é¤ì¤Þ¤»¤ó"
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: 'shell' ¥ª¥×¥·¥ç¥ó¤¬¶õ¤Ç¤¹"
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: °Ê²¼¤Îʸ»ú¥»¥Ã¥È¤Î¥Õ¥©¥ó¥È¤¬¤¢¤ê¤Þ¤»¤ó %s:"
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: sign ¤Î¥Ç¡¼¥¿¤òÆÉ¹þ¤á¤Þ¤»¤ó¤Ç¤·¤¿"
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: ¥Õ¥©¥ó¥È¥»¥Ã¥È̾: %s"
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î¥¯¥í¡¼¥º»þ¥¨¥é¡¼¤Ç¤¹"
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "¥Õ¥©¥ó¥È '%s' ¤Ï¸ÇÄêÉý¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: ¥¿¥°¥¹¥¿¥Ã¥¯¤¬¶õ¤Ç¤¹"
+#, c-format
+msgid "E253: Fontset name: %s"
+msgstr "E253: ¥Õ¥©¥ó¥È¥»¥Ã¥È̾: %s"
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: ¥³¥Þ¥ó¥É¤¬Ê£»¨²á¤®¤Þ¤¹"
+#, c-format
+msgid "Font0: %s"
+msgstr "¥Õ¥©¥ó¥È0: %s"
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: ̾Á°¤¬Ä¹²á¤®¤Þ¤¹"
+#, c-format
+msgid "Font1: %s"
+msgstr "¥Õ¥©¥ó¥È1: %s"
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: [ ¤¬Â¿²á¤®¤Þ¤¹"
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "¥Õ¥©¥ó¥È%ld ¤ÎÉý¤¬¥Õ¥©¥ó¥È0¤Î2ÇܤǤϤ¢¤ê¤Þ¤»¤ó"
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: ¥Õ¥¡¥¤¥ë̾¤¬Â¿²á¤®¤Þ¤¹"
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "¥Õ¥©¥ó¥È0¤ÎÉý: %ld"
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: ;ʬ¤Êʸ»ú¤¬¸å¤í¤Ë¤¢¤ê¤Þ¤¹"
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "¥Õ¥©¥ó¥È1¤ÎÉý: %ld"
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: ̤ÃΤΥޡ¼¥¯"
+msgid "Invalid font specification"
+msgstr "̵¸ú¤Ê¥Õ¥©¥ó¥È»ØÄê¤Ç¤¹"
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: ¥ï¥¤¥ë¥É¥«¡¼¥É¤òŸ³«¤Ç¤­¤Þ¤»¤ó"
+msgid "&Dismiss"
+msgstr "µÑ²¼¤¹¤ë(&D)"
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: 'winheight' ¤Ï 'winminheight' ¤è¤ê¾®¤µ¤¯¤Ç¤­¤Þ¤»¤ó"
+msgid "no specific match"
+msgstr "¥Þ¥Ã¥Á¤¹¤ë¤â¤Î¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: 'winwidth' ¤Ï 'winminwidth' ¤è¤ê¾®¤µ¤¯¤Ç¤­¤Þ¤»¤ó"
+msgid "Vim - Font Selector"
+msgstr "Vim - ¥Õ¥©¥ó¥ÈÁªÂò"
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: ½ñ¹þ¤ßÃæ¤Î¥¨¥é¡¼"
+msgid "Name:"
+msgstr "̾Á°:"
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "¥¼¥í¥«¥¦¥ó¥È"
+#. create toggle button
+msgid "Show size in Points"
+msgstr "¥µ¥¤¥º¤ò¥Ý¥¤¥ó¥È¤Çɽ¼¨¤¹¤ë"
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: ¥¹¥¯¥ê¥×¥È°Ê³°¤Ç<SID>¤¬»È¤ï¤ì¤Þ¤·¤¿"
+msgid "Encoding:"
+msgstr "¥¨¥ó¥³¡¼¥É:"
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: ÆâÉô¥¨¥é¡¼¤Ç¤¹: %s"
+msgid "Font:"
+msgstr "¥Õ¥©¥ó¥È:"
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: ¥Ñ¥¿¡¼¥ó¤¬ 'maxmempattern' °Ê¾å¤Î¥á¥â¥ê¤ò»ÈÍѤ·¤Þ¤¹"
+msgid "Style:"
+msgstr "¥¹¥¿¥¤¥ë:"
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: ¥Ð¥Ã¥Õ¥¡¤¬¶õ¤Ç¤¹"
+msgid "Size:"
+msgstr "¥µ¥¤¥º:"
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: ¸¡º÷¥Ñ¥¿¡¼¥ó¤«¶èÀڤ국¹æ¤¬ÉÔÀµ¤Ç¤¹"
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: ¥Ï¥ó¥°¥ë¥ª¡¼¥È¥Þ¥È¥ó¥¨¥é¡¼"
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: Ʊ¤¸Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¾¤Î¥Ð¥Ã¥Õ¥¡¤ÇÆÉ¹þ¤Þ¤ì¤Æ¤¤¤Þ¤¹"
-
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: ¥ª¥×¥·¥ç¥ó '%s' ¤ÏÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-
-#: ../globals.h:1111
-msgid "E850: Invalid register name"
-msgstr "E850: ̵¸ú¤Ê¥ì¥¸¥¹¥¿Ì¾¤Ç¤¹"
-
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "¾å¤Þ¤Ç¸¡º÷¤·¤¿¤Î¤Ç²¼¤ËÌá¤ê¤Þ¤¹"
-
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "²¼¤Þ¤Ç¸¡º÷¤·¤¿¤Î¤Ç¾å¤ËÌá¤ê¤Þ¤¹"
-
-#: ../hardcopy.c:240
msgid "E550: Missing colon"
msgstr "E550: ¥³¥í¥ó¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../hardcopy.c:252
msgid "E551: Illegal component"
msgstr "E551: ÉÔÀµ¤Ê¹½Ê¸Í×ÁǤǤ¹"
-#: ../hardcopy.c:259
msgid "E552: digit expected"
msgstr "E552: ¿ôÃͤ¬É¬ÍפǤ¹"
-#: ../hardcopy.c:473
#, c-format
msgid "Page %d"
msgstr "%d ¥Ú¡¼¥¸"
-#: ../hardcopy.c:597
msgid "No text to be printed"
msgstr "°õºþ¤¹¤ë¥Æ¥­¥¹¥È¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../hardcopy.c:668
#, c-format
msgid "Printing page %d (%d%%)"
msgstr "°õºþÃæ: ¥Ú¡¼¥¸ %d (%d%%)"
-#: ../hardcopy.c:680
#, c-format
msgid " Copy %d of %d"
msgstr " ¥³¥Ô¡¼ %d (Á´ %d Ãæ)"
-#: ../hardcopy.c:733
#, c-format
msgid "Printed: %s"
msgstr "°õºþ¤·¤Þ¤·¤¿: %s"
-#: ../hardcopy.c:740
msgid "Printing aborted"
msgstr "°õºþ¤¬Ãæ»ß¤µ¤ì¤Þ¤·¤¿"
-#: ../hardcopy.c:1365
msgid "E455: Error writing to PostScript output file"
msgstr "E455: PostScript½ÐÎÏ¥Õ¥¡¥¤¥ë¤Î½ñ¹þ¤ß¥¨¥é¡¼¤Ç¤¹"
-#: ../hardcopy.c:1747
#, c-format
msgid "E624: Can't open file \"%s\""
msgstr "E624: ¥Õ¥¡¥¤¥ë \"%s\" ¤ò³«¤±¤Þ¤»¤ó"
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
#, c-format
msgid "E457: Can't read PostScript resource file \"%s\""
msgstr "E457: PostScript¤Î¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë \"%s\" ¤òÆÉ¹þ¤á¤Þ¤»¤ó"
-#: ../hardcopy.c:1772
#, c-format
msgid "E618: file \"%s\" is not a PostScript resource file"
msgstr "E618: ¥Õ¥¡¥¤¥ë \"%s\" ¤Ï PostScript ¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844
#, c-format
msgid "E619: file \"%s\" is not a supported PostScript resource file"
msgstr "E619: ¥Õ¥¡¥¤¥ë \"%s\" ¤ÏÂбþ¤·¤Æ¤¤¤Ê¤¤ PostScript ¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤Ç¤¹"
-#: ../hardcopy.c:1856
#, c-format
msgid "E621: \"%s\" resource file has wrong version"
msgstr "E621: ¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë \"%s\" ¤Ï¥Ð¡¼¥¸¥ç¥ó¤¬°Û¤Ê¤ê¤Þ¤¹"
-#: ../hardcopy.c:2225
msgid "E673: Incompatible multi-byte encoding and character set."
msgstr "E673: ¸ß´¹À­¤Î̵¤¤¥Þ¥ë¥Á¥Ð¥¤¥È¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Èʸ»ú¥»¥Ã¥È¤Ç¤¹"
-#: ../hardcopy.c:2238
msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
msgstr "E674: ¥Þ¥ë¥Á¥Ð¥¤¥È¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Ç¤Ï printmbcharset ¤ò¶õ¤Ë¤Ç¤­¤Þ¤»¤ó"
-#: ../hardcopy.c:2254
msgid "E675: No default font specified for multi-byte printing."
msgstr ""
"E675: ¥Þ¥ë¥Á¥Ð¥¤¥Èʸ»ú¤ò°õºþ¤¹¤ë¤¿¤á¤Î¥Ç¥Õ¥©¥ë¥È¥Õ¥©¥ó¥È¤¬»ØÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../hardcopy.c:2426
msgid "E324: Can't open PostScript output file"
msgstr "E324: PostScript½ÐÎÏÍѤΥե¡¥¤¥ë¤ò³«¤±¤Þ¤»¤ó"
-#: ../hardcopy.c:2458
#, c-format
msgid "E456: Can't open file \"%s\""
msgstr "E456: ¥Õ¥¡¥¤¥ë \"%s\" ¤ò³«¤±¤Þ¤»¤ó"
-#: ../hardcopy.c:2583
msgid "E456: Can't find PostScript resource file \"prolog.ps\""
msgstr "E456: PostScript¤Î¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë \"prolog.ps\" ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../hardcopy.c:2593
msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
msgstr "E456: PostScript¤Î¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë \"cidfont.ps\" ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
#, c-format
msgid "E456: Can't find PostScript resource file \"%s.ps\""
msgstr "E456: PostScript¤Î¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë \"%s.ps\" ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../hardcopy.c:2654
#, c-format
msgid "E620: Unable to convert to print encoding \"%s\""
msgstr "E620: °õºþ¥¨¥ó¥³¡¼¥É \"%s\" ¤ØÊÑ´¹¤Ç¤­¤Þ¤»¤ó"
-#: ../hardcopy.c:2877
msgid "Sending to printer..."
msgstr "¥×¥ê¥ó¥¿¤ËÁ÷¿®Ãæ..."
-#: ../hardcopy.c:2881
msgid "E365: Failed to print PostScript file"
msgstr "E365: PostScript¥Õ¥¡¥¤¥ë¤Î°õºþ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../hardcopy.c:2883
msgid "Print job sent."
msgstr "°õºþ¥¸¥ç¥Ö¤òÁ÷¿®¤·¤Þ¤·¤¿."
-#: ../if_cscope.c:85
msgid "Add a new database"
msgstr "¿·¥Ç¡¼¥¿¥Ù¡¼¥¹¤òÄɲÃ"
-#: ../if_cscope.c:87
msgid "Query for a pattern"
msgstr "¥Ñ¥¿¡¼¥ó¤Î¥¯¥¨¥ê¡¼¤òÄɲÃ"
-#: ../if_cscope.c:89
msgid "Show this message"
msgstr "¤³¤Î¥á¥Ã¥»¡¼¥¸¤òɽ¼¨¤¹¤ë"
-#: ../if_cscope.c:91
msgid "Kill a connection"
msgstr "Àܳ¤ò½ªÎ»¤¹¤ë"
-#: ../if_cscope.c:93
msgid "Reinit all connections"
msgstr "Á´¤Æ¤ÎÀܳ¤òºÆ½é´ü²½¤¹¤ë"
-#: ../if_cscope.c:95
msgid "Show connections"
msgstr "Àܳ¤òɽ¼¨¤¹¤ë"
-#: ../if_cscope.c:101
#, c-format
msgid "E560: Usage: cs[cope] %s"
msgstr "E560: »ÈÍÑÊýË¡: cs[cope] %s"
-#: ../if_cscope.c:225
msgid "This cscope command does not support splitting the window.\n"
msgstr "¤³¤Îcscope¥³¥Þ¥ó¥É¤Ïʬ³ä¥¦¥£¥ó¥É¥¦¤Ç¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤»¤ó.\n"
-#: ../if_cscope.c:266
msgid "E562: Usage: cstag <ident>"
msgstr "E562: »ÈÍÑË¡: cstag <ident>"
-#: ../if_cscope.c:313
msgid "E257: cstag: tag not found"
msgstr "E257: cstag: ¥¿¥°¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../if_cscope.c:461
#, c-format
msgid "E563: stat(%s) error: %d"
msgstr "E563: stat(%s) ¥¨¥é¡¼: %d"
-#: ../if_cscope.c:551
+msgid "E563: stat error"
+msgstr "E563: stat ¥¨¥é¡¼"
+
#, c-format
msgid "E564: %s is not a directory or a valid cscope database"
msgstr "E564: %s ¤Ï¥Ç¥£¥ì¥¯¥È¥êµÚ¤ÓÍ­¸ú¤Êcscope¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../if_cscope.c:566
#, c-format
msgid "Added cscope database %s"
msgstr "cscope¥Ç¡¼¥¿¥Ù¡¼¥¹ %s ¤òÄɲÃ"
-#: ../if_cscope.c:616
#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: cscope¤ÎÀܳ %<PRId64> ¤òÆÉ¹þ¤ßÃæ¤Î¥¨¥é¡¼¤Ç¤¹"
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: cscope¤ÎÀܳ %ld ¤òÆÉ¹þ¤ßÃæ¤Î¥¨¥é¡¼¤Ç¤¹"
-#: ../if_cscope.c:711
msgid "E561: unknown cscope search type"
msgstr "E561: ̤ÃΤÎcscope¸¡º÷·¿¤Ç¤¹"
-#: ../if_cscope.c:752 ../if_cscope.c:789
msgid "E566: Could not create cscope pipes"
msgstr "E566: cscope¥Ñ¥¤¥×¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../if_cscope.c:767
msgid "E622: Could not fork for cscope"
msgstr "E622: cscope¤Îµ¯Æ°½àÈ÷(fork)¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../if_cscope.c:849
msgid "cs_create_connection setpgid failed"
msgstr "cs_create_connection ¤Ø¤Î setpgid ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../if_cscope.c:853 ../if_cscope.c:889
msgid "cs_create_connection exec failed"
msgstr "cs_create_connection ¤Î¼Â¹Ô¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../if_cscope.c:863 ../if_cscope.c:902
msgid "cs_create_connection: fdopen for to_fp failed"
msgstr "cs_create_connection: to_fp ¤Î fdopen ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../if_cscope.c:865 ../if_cscope.c:906
msgid "cs_create_connection: fdopen for fr_fp failed"
msgstr "cs_create_connection: fr_fp ¤Î fdopen ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../if_cscope.c:890
msgid "E623: Could not spawn cscope process"
msgstr "E623: cscope¥×¥í¥»¥¹¤òµ¯Æ°¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../if_cscope.c:932
msgid "E567: no cscope connections"
msgstr "E567: cscopeÀܳ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../if_cscope.c:1009
#, c-format
msgid "E469: invalid cscopequickfix flag %c for %c"
msgstr "E469: ̵¸ú¤Ê cscopequickfix ¥Õ¥é¥° %c ¤Î %c ¤Ç¤¹"
-#: ../if_cscope.c:1058
#, c-format
msgid "E259: no matches found for cscope query %s of %s"
msgstr "E259: cscope¥¯¥¨¥ê¡¼ %s of %s ¤Ë³ºÅö¤¬¤¢¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../if_cscope.c:1142
msgid "cscope commands:\n"
msgstr "cscope¥³¥Þ¥ó¥É:\n"
-#: ../if_cscope.c:1150
#, c-format
msgid "%-5s: %s%*s (Usage: %s)"
msgstr "%-5s: %s%*s (»ÈÍÑË¡: %s)"
-#: ../if_cscope.c:1155
msgid ""
"\n"
+" a: Find assignments to this symbol\n"
" c: Find functions calling this function\n"
" d: Find functions called by this function\n"
" e: Find this egrep pattern\n"
@@ -3234,6 +2549,7 @@ msgid ""
" t: Find this text string\n"
msgstr ""
"\n"
+" a: ¤³¤Î¥·¥ó¥Ü¥ë¤ËÂФ¹¤ëÂåÆþ¤òõ¤¹\n"
" c: ¤³¤Î´Ø¿ô¤ò¸Æ¤ó¤Ç¤¤¤ë´Ø¿ô¤òõ¤¹\n"
" d: ¤³¤Î´Ø¿ô¤«¤é¸Æ¤ó¤Ç¤¤¤ë´Ø¿ô¤òõ¤¹\n"
" e: ¤³¤Îegrep¥Ñ¥¿¡¼¥ó¤òõ¤¹\n"
@@ -3243,31 +2559,32 @@ msgstr ""
" s: ¤³¤ÎC¥·¥ó¥Ü¥ë¤òõ¤¹\n"
" t: ¤³¤Î¥Æ¥­¥¹¥Èʸ»úÎó¤òõ¤¹\n"
-#: ../if_cscope.c:1226
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: cscope¥Ç¡¼¥¿¥Ù¡¼¥¹: %s ¤ò³«¤¯¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: cscope¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¾ðÊó¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
+
msgid "E568: duplicate cscope database not added"
msgstr "E568: ½ÅÊ£¤¹¤ëcscope¥Ç¡¼¥¿¥Ù¡¼¥¹¤ÏÄɲ䵤ì¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../if_cscope.c:1335
#, c-format
msgid "E261: cscope connection %s not found"
msgstr "E261: cscopeÀܳ %s ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../if_cscope.c:1364
#, c-format
msgid "cscope connection %s closed"
msgstr "cscopeÀܳ %s ¤¬ÊĤ¸¤é¤ì¤Þ¤·¤¿"
#. should not reach here
-#: ../if_cscope.c:1486
msgid "E570: fatal error in cs_manage_matches"
msgstr "E570: cs_manage_matches ¤ÇÃ×̿Ū¤Ê¥¨¥é¡¼¤Ç¤¹"
-#: ../if_cscope.c:1693
#, c-format
msgid "Cscope tag: %s"
msgstr "Cscope ¥¿¥°: %s"
-#: ../if_cscope.c:1711
msgid ""
"\n"
" # line"
@@ -3275,87 +2592,300 @@ msgstr ""
"\n"
" # ¹ÔÈÖ¹æ"
-#: ../if_cscope.c:1713
msgid "filename / context / line\n"
msgstr "¥Õ¥¡¥¤¥ë̾ / ʸ̮ / ¹Ô\n"
-#: ../if_cscope.c:1809
#, c-format
msgid "E609: Cscope error: %s"
msgstr "E609: cscope¥¨¥é¡¼: %s"
-#: ../if_cscope.c:2053
msgid "All cscope databases reset"
msgstr "Á´¤Æ¤Îcscope¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò¥ê¥»¥Ã¥È¤·¤Þ¤¹"
-#: ../if_cscope.c:2123
msgid "no cscope connections\n"
msgstr "cscopeÀܳ¤¬¤¢¤ê¤Þ¤»¤ó\n"
-#: ../if_cscope.c:2126
msgid " # pid database name prepend path\n"
msgstr " # pid ¥Ç¡¼¥¿¥Ù¡¼¥¹Ì¾ prepend ¥Ñ¥¹\n"
-#: ../main.c:144
+msgid "Lua library cannot be loaded."
+msgstr "Lua¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó."
+
+msgid "cannot save undo information"
+msgstr "¥¢¥ó¥É¥¥¾ðÊó¤¬Êݸ¤Ç¤­¤Þ¤»¤ó"
+
+msgid ""
+"E815: Sorry, this command is disabled, the MzScheme libraries could not be "
+"loaded."
+msgstr "E815: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹. MzScheme ¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó."
+
+msgid ""
+"E895: Sorry, this command is disabled, the MzScheme's racket/base module "
+"could not be loaded."
+msgstr ""
+"E895: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹,¤´¤á¤ó¤Ê¤µ¤¤. MzScheme ¤Î racket/base ¥â¥¸¥å¡¼¥ë"
+"¤¬¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿."
+
+msgid "invalid expression"
+msgstr "̵¸ú¤Ê¼°¤Ç¤¹"
+
+msgid "expressions disabled at compile time"
+msgstr "¼°¤Ï¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹"
+
+msgid "hidden option"
+msgstr "±£¤·¥ª¥×¥·¥ç¥ó"
+
+msgid "unknown option"
+msgstr "̤ÃΤΥª¥×¥·¥ç¥ó¤Ç¤¹"
+
+msgid "window index is out of range"
+msgstr "Èϰϳ°¤Î¥¦¥£¥ó¥É¥¦ÈÖ¹æ¤Ç¤¹"
+
+msgid "couldn't open buffer"
+msgstr "¥Ð¥Ã¥Õ¥¡¤ò³«¤±¤Þ¤»¤ó"
+
+msgid "cannot delete line"
+msgstr "¹Ô¤ò¾Ã¤»¤Þ¤»¤ó"
+
+msgid "cannot replace line"
+msgstr "¹Ô¤òÃÖ´¹¤Ç¤­¤Þ¤»¤ó"
+
+msgid "cannot insert line"
+msgstr "¹Ô¤òÁÞÆþ¤Ç¤­¤Þ¤»¤ó"
+
+msgid "string cannot contain newlines"
+msgstr "ʸ»úÎó¤Ë¤Ï²þ¹Ôʸ»ú¤ò´Þ¤á¤é¤ì¤Þ¤»¤ó"
+
+msgid "error converting Scheme values to Vim"
+msgstr "SchemeÃͤÎVim¤Ø¤ÎÊÑ´¹¥¨¥é¡¼"
+
+msgid "Vim error: ~a"
+msgstr "Vim ¥¨¥é¡¼: ~a"
+
+msgid "Vim error"
+msgstr "Vim ¥¨¥é¡¼"
+
+msgid "buffer is invalid"
+msgstr "¥Ð¥Ã¥Õ¥¡¤Ï̵¸ú¤Ç¤¹"
+
+msgid "window is invalid"
+msgstr "¥¦¥£¥ó¥É¥¦¤Ï̵¸ú¤Ç¤¹"
+
+msgid "linenr out of range"
+msgstr "Èϰϳ°¤Î¹ÔÈÖ¹æ¤Ç¤¹"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤Ïµö¤µ¤ì¤Þ¤»¤ó"
+
+msgid "E836: This Vim cannot execute :python after using :py3"
+msgstr "E836: ¤³¤ÎVim¤Ç¤Ï :py3 ¤ò»È¤Ã¤¿¸å¤Ë :python ¤ò»È¤¨¤Þ¤»¤ó"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹,¤´¤á¤ó¤Ê¤µ¤¤: Python¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó"
+"¤Ç¤·¤¿."
+
+msgid ""
+"E887: Sorry, this command is disabled, the Python's site module could not be "
+"loaded."
+msgstr ""
+"E887: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹,¤´¤á¤ó¤Ê¤µ¤¤. Python ¤Î site ¥â¥¸¥å¡¼¥ë¤ò¥í¡¼¥É"
+"¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿."
+
+# Added at 07-Feb-2004.
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Python ¤òºÆµ¢Åª¤Ë¼Â¹Ô¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E837: This Vim cannot execute :py3 after using :python"
+msgstr "E837: ¤³¤ÎVim¤Ç¤Ï :python ¤ò»È¤Ã¤¿¸å¤Ë :py3 ¤ò»È¤¨¤Þ¤»¤ó"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: $_ ¤Ïʸ»úÎó¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹,¤´¤á¤ó¤Ê¤µ¤¤: Ruby¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç"
+"¤·¤¿."
+
+msgid "E267: unexpected return"
+msgstr "E267: ͽ´ü¤»¤Ì return ¤Ç¤¹"
+
+msgid "E268: unexpected next"
+msgstr "E268: ͽ´ü¤»¤Ì next ¤Ç¤¹"
+
+msgid "E269: unexpected break"
+msgstr "E269: ͽ´ü¤»¤Ì break ¤Ç¤¹"
+
+msgid "E270: unexpected redo"
+msgstr "E270: ͽ´ü¤»¤Ì redo ¤Ç¤¹"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: rescue ¤Î³°¤Î retry ¤Ç¤¹"
+
+msgid "E272: unhandled exception"
+msgstr "E272: ¼è¤ê°·¤ï¤ì¤Ê¤«¤Ã¤¿Îã³°¤¬¤¢¤ê¤Þ¤¹"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: ̤ÃΤÎlongjmp¾õÂÖ: %d"
+
+msgid "invalid buffer number"
+msgstr "̵¸ú¤Ê¥Ð¥Ã¥Õ¥¡ÈÖ¹æ¤Ç¤¹"
+
+msgid "not implemented yet"
+msgstr "¤Þ¤À¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "¹Ô¤òÀßÄê¤Ç¤­¤Þ¤»¤ó"
+
+msgid "invalid mark name"
+msgstr "̵¸ú¤Ê¥Þ¡¼¥¯Ì¾¤Ç¤¹"
+
+msgid "mark not set"
+msgstr "¥Þ¡¼¥¯¤ÏÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "¹Ô %d Îó %d"
+
+msgid "cannot insert/append line"
+msgstr "¹Ô¤ÎÁÞÆþ/Äɲäò¤Ç¤­¤Þ¤»¤ó"
+
+msgid "line number out of range"
+msgstr "Èϰϳ°¤Î¹ÔÈÖ¹æ¤Ç¤¹"
+
+msgid "unknown flag: "
+msgstr "̤ÃΤΥե饰: "
+
+msgid "unknown vimOption"
+msgstr "̤ÃΤΠvimOption ¤Ç¤¹"
+
+msgid "keyboard interrupt"
+msgstr "¥­¡¼¥Ü¡¼¥É³ä¹þ¤ß"
+
+msgid "vim error"
+msgstr "vim ¥¨¥é¡¼"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr ""
+"¥Ð¥Ã¥Õ¥¡/¥¦¥£¥ó¥É¥¦ºîÀ®¥³¥Þ¥ó¥É¤òºîÀ®¤Ç¤­¤Þ¤»¤ó: ¥ª¥Ö¥¸¥§¥¯¥È¤¬¾Ãµî¤µ¤ì¤Æ¤¤¤Þ"
+"¤·¤¿"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥É¤òÅÐÏ¿¤Ç¤­¤Þ¤»¤ó: ¥Ð¥Ã¥Õ¥¡/¥¦¥£¥ó¥É¥¦¤¬´û¤Ë¾Ãµî¤µ¤ì¤Þ¤·¤¿"
+
+#. 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 ¼ÂÂΤÎÅÐÏ¿¥×¥í¥Ñ¥Æ¥£¤¬ÉÔÀµ¤Ç¤¹. ¾Ãµî¤·¤Þ¤·¤¿!"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: ¥ê¥¹¥È·¿¤Ë¥«¥ó¥Þ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: ¥ê¥¹¥È·¿¤ÎºÇ¸å¤Ë ']' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
msgid "Unknown option argument"
msgstr "̤ÃΤΥª¥×¥·¥ç¥ó°ú¿ô¤Ç¤¹"
-#: ../main.c:146
msgid "Too many edit arguments"
msgstr "ÊÔ½¸°ú¿ô¤¬Â¿²á¤®¤Þ¤¹"
-#: ../main.c:148
msgid "Argument missing after"
msgstr "°ú¿ô¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../main.c:150
msgid "Garbage after option argument"
msgstr "¥ª¥×¥·¥ç¥ó°ú¿ô¤Î¸å¤Ë¥´¥ß¤¬¤¢¤ê¤Þ¤¹"
-#: ../main.c:152
msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
msgstr "\"+command\", \"-c command\", \"--cmd command\" ¤Î°ú¿ô¤¬Â¿²á¤®¤Þ¤¹"
-#: ../main.c:154
msgid "Invalid argument for"
msgstr "̵¸ú¤Ê°ú¿ô¤Ç¤¹: "
-#: ../main.c:294
#, c-format
msgid "%d files to edit\n"
msgstr "%d ¸Ä¤Î¥Õ¥¡¥¤¥ë¤¬ÊÔ½¸¤ò¹µ¤¨¤Æ¤¤¤Þ¤¹\n"
-#: ../main.c:1342
+msgid "netbeans is not supported with this GUI\n"
+msgstr "netbeans ¤Ï¤³¤ÎGUI¤Ç¤ÏÍøÍѤǤ­¤Þ¤»¤ó\n"
+
+msgid "'-nb' cannot be used: not enabled at compile time\n"
+msgstr "'-nb' »ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "¤³¤ÎVim¤Ë¤Ïdiffµ¡Ç½¤¬¤¢¤ê¤Þ¤»¤ó(¥³¥ó¥Ñ¥¤¥ë»þÀßÄê)."
+
msgid "Attempt to open script file again: \""
msgstr "¥¹¥¯¥ê¥×¥È¥Õ¥¡¥¤¥ë¤òºÆ¤Ó³«¤¤¤Æ¤ß¤Þ¤¹: \""
-#: ../main.c:1350
msgid "Cannot open for reading: \""
msgstr "ÆÉ¹þÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó"
-#: ../main.c:1393
msgid "Cannot open for script output: \""
msgstr "¥¹¥¯¥ê¥×¥È½ÐÎÏÍѤò³«¤±¤Þ¤»¤ó"
-#: ../main.c:1622
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: ¥¨¥é¡¼: NetBeans¤«¤égvim¤ò¥¹¥¿¡¼¥È¤Ç¤­¤Þ¤»¤ó\n"
+
+msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n"
+msgstr "Vim: ¥¨¥é¡¼: ¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤ÎVim¤ÏCygwinüËö¤Ç¤Ïưºî¤·¤Þ¤»¤ó\n"
+
msgid "Vim: Warning: Output is not to a terminal\n"
msgstr "Vim: ·Ù¹ð: üËö¤Ø¤Î½ÐÎϤǤϤ¢¤ê¤Þ¤»¤ó\n"
-#: ../main.c:1624
msgid "Vim: Warning: Input is not from a terminal\n"
msgstr "Vim: ·Ù¹ð: üËö¤«¤é¤ÎÆþÎϤǤϤ¢¤ê¤Þ¤»¤ó\n"
#. just in case..
-#: ../main.c:1891
msgid "pre-vimrc command line"
msgstr "vimrcÁ°¤Î¥³¥Þ¥ó¥É¥é¥¤¥ó"
-#: ../main.c:1964
#, c-format
msgid "E282: Cannot read from \"%s\""
msgstr "E282: \"%s\"¤«¤éÆÉ¹þ¤à¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
-#: ../main.c:2149
msgid ""
"\n"
"More info with: \"vim -h\"\n"
@@ -3363,23 +2893,18 @@ msgstr ""
"\n"
"¤è¤ê¾ÜºÙ¤Ê¾ðÊó¤Ï: \"vim -h\"\n"
-#: ../main.c:2178
msgid "[file ..] edit specified file(s)"
msgstr "[¥Õ¥¡¥¤¥ë..] ¤¢¤ë¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤¹¤ë"
-#: ../main.c:2179
msgid "- read text from stdin"
msgstr "- ɸ½àÆþÎϤ«¤é¥Æ¥­¥¹¥È¤òÆÉ¹þ¤à"
-#: ../main.c:2180
msgid "-t tag edit file where tag is defined"
msgstr "-t ¥¿¥° ¥¿¥°¤¬ÄêµÁ¤µ¤ì¤¿¤È¤³¤í¤«¤éÊÔ½¸¤¹¤ë"
-#: ../main.c:2181
msgid "-q [errorfile] edit file with first error"
msgstr "-q [errorfile] ºÇ½é¤Î¥¨¥é¡¼¤ÇÊÔ½¸¤¹¤ë"
-#: ../main.c:2187
msgid ""
"\n"
"\n"
@@ -3389,11 +2914,9 @@ msgstr ""
"\n"
"»ÈÍÑË¡:"
-#: ../main.c:2189
msgid " vim [arguments] "
msgstr " vim [°ú¿ô] "
-#: ../main.c:2193
msgid ""
"\n"
" or:"
@@ -3401,7 +2924,13 @@ msgstr ""
"\n"
" ¤â¤·¤¯¤Ï:"
-#: ../main.c:2196
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"Â羮ʸ»ú¤¬Ìµ»ë¤µ¤ì¤ë¾ì¹ç¤ÏÂçʸ»ú¤Ë¤¹¤ë¤¿¤á¤Ë / ¤òÁ°ÃÖ¤·¤Æ¤¯¤À¤µ¤¤"
+
msgid ""
"\n"
"\n"
@@ -3411,189 +2940,319 @@ msgstr ""
"\n"
"°ú¿ô:\n"
-#: ../main.c:2197
msgid "--\t\t\tOnly file names after this"
msgstr "--\t\t\t¤³¤Î¤¢¤È¤Ë¤Ï¥Õ¥¡¥¤¥ë̾¤À¤±"
-#: ../main.c:2199
msgid "--literal\t\tDon't expand wildcards"
msgstr "--literal\t\t¥ï¥¤¥ë¥É¥«¡¼¥É¤òŸ³«¤·¤Ê¤¤"
-#: ../main.c:2201
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\t¤³¤Îgvim¤òOLE¤È¤·¤ÆÅÐÏ¿¤¹¤ë"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tgvim¤ÎOLEÅÐÏ¿¤ò²ò½ü¤¹¤ë"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tGUI¤Çµ¯Æ°¤¹¤ë (\"gvim\" ¤ÈƱ¤¸)"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f or --nofork\t¥Õ¥©¥¢¥°¥é¥¦¥ó¥É: GUI¤ò»Ï¤á¤ë¤È¤­¤Ëfork¤·¤Ê¤¤"
+
msgid "-v\t\t\tVi mode (like \"vi\")"
msgstr "-v\t\t\tVi¥â¡¼¥É (\"vi\" ¤ÈƱ¤¸)"
-#: ../main.c:2202
msgid "-e\t\t\tEx mode (like \"ex\")"
msgstr "-e\t\t\tEx¥â¡¼¥É (\"ex\" ¤ÈƱ¤¸)"
-#: ../main.c:2203
msgid "-E\t\t\tImproved Ex mode"
msgstr "-E\t\t\t²þÎÉEx¥â¡¼¥É"
-#: ../main.c:2204
msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
msgstr "-s\t\t\t¥µ¥¤¥ì¥ó¥È(¥Ð¥Ã¥Á)¥â¡¼¥É (\"ex\" ÀìÍÑ)"
-#: ../main.c:2205
msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
msgstr "-d\t\t\tº¹Ê¬¥â¡¼¥É (\"vidiff\" ¤ÈƱ¤¸)"
-#: ../main.c:2206
msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
msgstr "-y\t\t\t¥¤¡¼¥¸¡¼¥â¡¼¥É (\"evim\" ¤ÈƱ¤¸, ¥â¡¼¥É̵)"
-#: ../main.c:2207
msgid "-R\t\t\tReadonly mode (like \"view\")"
msgstr "-R\t\t\tÆÉ¹þÀìÍѥ⡼¥É (\"view\" ¤ÈƱ¤¸)"
-#: ../main.c:2208
msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
msgstr "-Z\t\t\tÀ©¸Â¥â¡¼¥É (\"rvim\" ¤ÈƱ¤¸)"
-#: ../main.c:2209
msgid "-m\t\t\tModifications (writing files) not allowed"
msgstr "-m\t\t\tÊѹ¹ (¥Õ¥¡¥¤¥ëÊݸ»þ) ¤ò¤Ç¤­¤Ê¤¤¤è¤¦¤Ë¤¹¤ë"
-#: ../main.c:2210
msgid "-M\t\t\tModifications in text not allowed"
msgstr "-M\t\t\t¥Æ¥­¥¹¥È¤ÎÊÔ½¸¤ò¹Ô¤Ê¤¨¤Ê¤¤¤è¤¦¤Ë¤¹¤ë"
-#: ../main.c:2211
msgid "-b\t\t\tBinary mode"
msgstr "-b\t\t\t¥Ð¥¤¥Ê¥ê¥â¡¼¥É"
-#: ../main.c:2212
msgid "-l\t\t\tLisp mode"
msgstr "-l\t\t\tLisp¥â¡¼¥É"
-#: ../main.c:2213
msgid "-C\t\t\tCompatible with Vi: 'compatible'"
msgstr "-C\t\t\tVi¸ß´¹¥â¡¼¥É: 'compatible'"
-#: ../main.c:2214
msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
msgstr "-N\t\t\tViÈó¸ß´¹¥â¡¼¥É: 'nocompatible"
-#: ../main.c:2215
msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
msgstr "-V[N][fname]\t\t¥í¥°½ÐÎÏÀßÄê [¥ì¥Ù¥ë N] [¥í¥°¥Õ¥¡¥¤¥ë̾ fname]"
-#: ../main.c:2216
msgid "-D\t\t\tDebugging mode"
msgstr "-D\t\t\t¥Ç¥Ð¥Ã¥°¥â¡¼¥É"
-#: ../main.c:2217
msgid "-n\t\t\tNo swap file, use memory only"
msgstr "-n\t\t\t¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ò»ÈÍѤ»¤º¥á¥â¥ê¤À¤±"
-#: ../main.c:2218
msgid "-r\t\t\tList swap files and exit"
msgstr "-r\t\t\t¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤òÎóµó¤·½ªÎ»"
-#: ../main.c:2219
msgid "-r (with file name)\tRecover crashed session"
msgstr "-r (¥Õ¥¡¥¤¥ë̾)\t¥¯¥é¥Ã¥·¥å¤·¤¿¥»¥Ã¥·¥ç¥ó¤òÉüµ¢"
-#: ../main.c:2220
msgid "-L\t\t\tSame as -r"
msgstr "-L\t\t\t-r¤ÈƱ¤¸"
-#: ../main.c:2221
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\t¥¦¥£¥ó¥É¥¦¤ò³«¤¯¤Î¤Ë newcli ¤ò»ÈÍѤ·¤Ê¤¤"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <device>\t\tI/O¤Ë <device> ¤ò»ÈÍѤ¹¤ë"
+
msgid "-A\t\t\tstart in Arabic mode"
msgstr "-A\t\t\t¥¢¥é¥Ó¥¢¸ì¥â¡¼¥É¤Çµ¯Æ°¤¹¤ë"
-#: ../main.c:2222
msgid "-H\t\t\tStart in Hebrew mode"
msgstr "-H\t\t\t¥Ø¥Ö¥é¥¤¸ì¥â¡¼¥É¤Çµ¯Æ°¤¹¤ë"
-#: ../main.c:2223
msgid "-F\t\t\tStart in Farsi mode"
msgstr "-F\t\t\t¥Ú¥ë¥·¥¢¸ì¥â¡¼¥É¤Çµ¯Æ°¤¹¤ë"
-#: ../main.c:2224
msgid "-T <terminal>\tSet terminal type to <terminal>"
msgstr "-T <terminal>\tüËö¤ò <terminal> ¤ËÀßÄꤹ¤ë"
-#: ../main.c:2225
+msgid "--not-a-term\t\tSkip warning for input/output not being a terminal"
+msgstr "--not-a-term\t\tÆþ½ÐÎϤ¬Ã¼Ëö¤Ç¤Ê¤¤¤È¤Î·Ù¹ð¤ò¥¹¥­¥Ã¥×¤¹¤ë"
+
msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
msgstr "-u <vimrc>\t\t.vimrc¤ÎÂå¤ï¤ê¤Ë <vimrc> ¤ò»È¤¦"
-#: ../main.c:2226
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\t.gvimrc¤ÎÂå¤ï¤ê¤Ë <gvimrc> ¤ò»È¤¦"
+
msgid "--noplugin\t\tDon't load plugin scripts"
msgstr "--noplugin\t\t¥×¥é¥°¥¤¥ó¥¹¥¯¥ê¥×¥È¤ò¥í¡¼¥É¤·¤Ê¤¤"
-#: ../main.c:2227
msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
msgstr "-p[N]\t\tN ¸Ä¥¿¥Ö¥Ú¡¼¥¸¤ò³«¤¯(¾ÊάÃÍ: ¥Õ¥¡¥¤¥ë¤Ë¤Ä¤­1¸Ä)"
-#: ../main.c:2228
msgid "-o[N]\t\tOpen N windows (default: one for each file)"
msgstr "-o[N]\t\tN ¸Ä¥¦¥£¥ó¥É¥¦¤ò³«¤¯(¾ÊάÃÍ: ¥Õ¥¡¥¤¥ë¤Ë¤Ä¤­1¸Ä)"
-#: ../main.c:2229
msgid "-O[N]\t\tLike -o but split vertically"
msgstr "-O[N]\t\t-o¤ÈƱ¤¸¤À¤¬¿âľʬ³ä"
-#: ../main.c:2230
msgid "+\t\t\tStart at end of file"
msgstr "+\t\t\t¥Õ¥¡¥¤¥ë¤ÎºÇ¸å¤«¤é¤Ï¤¸¤á¤ë"
-#: ../main.c:2231
msgid "+<lnum>\t\tStart at line <lnum>"
msgstr "+<lnum>\t\t<lnum> ¹Ô¤«¤é¤Ï¤¸¤á¤ë"
-#: ../main.c:2232
msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
msgstr "--cmd <command>\tvimrc¤ò¥í¡¼¥É¤¹¤ëÁ°¤Ë <command> ¤ò¼Â¹Ô¤¹¤ë"
-#: ../main.c:2233
msgid "-c <command>\t\tExecute <command> after loading the first file"
msgstr "-c <command>\t\tºÇ½é¤Î¥Õ¥¡¥¤¥ë¤ò¥í¡¼¥É¸å <command> ¤ò¼Â¹Ô¤¹¤ë"
-#: ../main.c:2235
msgid "-S <session>\t\tSource file <session> after loading the first file"
msgstr "-S <session>\t\tºÇ½é¤Î¥Õ¥¡¥¤¥ë¤ò¥í¡¼¥É¸å¥Õ¥¡¥¤¥ë <session> ¤ò¼è¹þ¤à"
-#: ../main.c:2236
msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
msgstr "-s <scriptin>\t¥Õ¥¡¥¤¥ë <scriptin> ¤«¤é¥Î¡¼¥Þ¥ë¥³¥Þ¥ó¥É¤òÆÉ¹þ¤à"
-#: ../main.c:2237
msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
msgstr "-w <scriptout>\tÆþÎϤ·¤¿Á´¥³¥Þ¥ó¥É¤ò¥Õ¥¡¥¤¥ë <scriptout> ¤ËÄɲ乤ë"
-#: ../main.c:2238
msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
msgstr "-W <scriptout>\tÆþÎϤ·¤¿Á´¥³¥Þ¥ó¥É¤ò¥Õ¥¡¥¤¥ë <scriptout> ¤ËÊݸ¤¹¤ë"
-#: ../main.c:2240
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\t°Å¹æ²½¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤¹¤ë"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <display>\tvim¤ò»ØÄꤷ¤¿ X ¥µ¡¼¥Ð¡¼¤ËÀܳ¤¹¤ë"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tX¥µ¡¼¥Ð¡¼¤ËÀܳ¤·¤Ê¤¤"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <files>\t²Äǽ¤Ê¤é¤ÐVim¥µ¡¼¥Ð¡¼¤Ç <files> ¤òÊÔ½¸¤¹¤ë"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-silent <files> Ʊ¾å, ¥µ¡¼¥Ð¡¼¤¬Ìµ¤¯¤Æ¤â·Ù¹ðʸ¤ò½ÐÎϤ·¤Ê¤¤"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr "--remote-wait <files>\t--remote¸å ¥Õ¥¡¥¤¥ë¤ÎÊÔ½¸¤¬½ª¤ï¤ë¤Î¤òÂÔ¤Ä"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-wait-silent <files> Ʊ¾å, ¥µ¡¼¥Ð¡¼¤¬Ìµ¤¯¤Æ¤â·Ù¹ðʸ¤ò½ÐÎϤ·¤Ê¤¤"
+
+msgid ""
+"--remote-tab[-wait][-silent] <files> As --remote but use tab page per file"
+msgstr ""
+"--remote-tab[-wait][-silent] <files> --remote¤Ç¥Õ¥¡¥¤¥ë1¤Ä¤Ë¤Ä¤­1¤Ä¤Î¥¿¥Ö"
+"¥Ú¡¼¥¸¤ò³«¤¯"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <keys>\tVim¥µ¡¼¥Ð¡¼¤Ë <keys> ¤òÁ÷¿®¤·¤Æ½ªÎ»¤¹¤ë"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr "--remote-expr <expr>\t¥µ¡¼¥Ð¡¼¤Ç <expr> ¤ò¼Â¹Ô¤·¤Æ·ë²Ì¤òɽ¼¨¤¹¤ë"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tVim¥µ¡¼¥Ð¡¼Ì¾¤Î°ìÍ÷¤òɽ¼¨¤·¤Æ½ªÎ»¤¹¤ë"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <name>\tVim¥µ¡¼¥Ð¡¼ <name> ¤ËÁ÷¿®/̾Á°ÀßÄꤹ¤ë"
+
msgid "--startuptime <file>\tWrite startup timing messages to <file>"
msgstr "--startuptime <file>\tµ¯Æ°¤Ë¤«¤«¤Ã¤¿»þ´Ö¤Î¾ÜºÙ¤ò <file> ¤Ø½ÐÎϤ¹¤ë"
-#: ../main.c:2242
msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
msgstr "-i <viminfo>\t\t.viminfo¤ÎÂå¤ï¤ê¤Ë <viminfo> ¤ò»È¤¦"
-#: ../main.c:2243
msgid "-h or --help\tPrint Help (this message) and exit"
msgstr "-h or --help\t¥Ø¥ë¥×(¤³¤Î¥á¥Ã¥»¡¼¥¸)¤òɽ¼¨¤·½ªÎ»¤¹¤ë"
-#: ../main.c:2244
msgid "--version\t\tPrint version information and exit"
msgstr "--version\t\t¥Ð¡¼¥¸¥ç¥ó¾ðÊó¤òɽ¼¨¤·½ªÎ»¤¹¤ë"
-#: ../mark.c:676
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"gvim¤Ë¤è¤Ã¤Æ²ò¼á¤µ¤ì¤ë°ú¿ô(Motif¥Ð¡¼¥¸¥ç¥ó):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"gvim¤Ë¤è¤Ã¤Æ²ò¼á¤µ¤ì¤ë°ú¿ô(neXtaw¥Ð¡¼¥¸¥ç¥ó):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"gvim¤Ë¤è¤Ã¤Æ²ò¼á¤µ¤ì¤ë°ú¿ô(Athena¥Ð¡¼¥¸¥ç¥ó):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <display>\t<display> ¤Çvim¤ò¼Â¹Ô¤¹¤ë"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tºÇ¾®²½¤·¤¿¾õÂÖ¤Çvim¤òµ¯Æ°¤¹¤ë"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <color>\tÇØ·Ê¿§¤Ë <color> ¤ò»È¤¦(ƱµÁ: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <color>\tÁ°·Ê¿§¤Ë <color> ¤ò»È¤¦(ƱµÁ: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <font>\t\t¥Æ¥­¥¹¥Èɽ¼¨¤Ë <font> ¤ò»È¤¦(ƱµÁ: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <font>\tÂÀ»ú¤Ë <font> ¤ò»È¤¦"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <for>\t¼ÐÂλú¤Ë <font> ¤ò»È¤¦"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <geom>\t½é´üÇÛÃÖ¤Ë <geom> ¤ò»È¤¦(ƱµÁ: -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <width>\t¶­³¦¤ÎÉý¤ò <width> ¤Ë¤¹¤ë(ƱµÁ: -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <width> ¥¹¥¯¥í¡¼¥ë¥Ð¡¼¤ÎÉý¤ò <width> ¤Ë¤¹¤ë(ƱµÁ: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr "-menuheight <height>\t¥á¥Ë¥å¡¼¥Ð¡¼¤Î¹â¤µ¤ò <height> ¤Ë¤¹¤ë(ƱµÁ: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tȿž±ÇÁü¤ò»ÈÍѤ¹¤ë(ƱµÁ: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tȿž±ÇÁü¤ò»ÈÍѤ·¤Ê¤¤(ƱµÁ: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <resource>\tÆÃÄê¤Î¥ê¥½¡¼¥¹¤ò»ÈÍѤ¹¤ë"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"gvim¤Ë¤è¤Ã¤Æ²ò¼á¤µ¤ì¤ë°ú¿ô(GTK+¥Ð¡¼¥¸¥ç¥ó):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <display>\t<display> ¤Çvim¤ò¼Â¹Ô¤¹¤ë(ƱµÁ: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "--role <role>\t¥á¥¤¥ó¥¦¥£¥ó¥É¥¦¤ò¼±Ê̤¹¤ë°ì°Õ¤ÊÌò³ä(role)¤òÀßÄꤹ¤ë"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\t°Û¤Ê¤ëGTK widget¤ÇVim¤ò³«¤¯"
+
+msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
+msgstr "--echo-wid\t\t¥¦¥£¥ó¥É¥¦ID¤òɸ½à½ÐÎϤ˽ÐÎϤ¹¤ë"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <¿Æ¤Î¥¿¥¤¥È¥ë>\tVim¤ò¿Æ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÎÃæ¤Çµ¯Æ°¤¹¤ë"
+
+msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
+msgstr "--windowid <HWND>\t°Û¤Ê¤ëWin32 widget¤ÎÆâÉô¤ËVim¤ò³«¤¯"
+
+msgid "No display"
+msgstr "¥Ç¥£¥¹¥×¥ì¥¤¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+
+#. 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 "¥Þ¡¼¥¯¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../mark.c:678
#, c-format
msgid "E283: No marks matching \"%s\""
msgstr "E283: \"%s\" ¤Ë³ºÅö¤¹¤ë¥Þ¡¼¥¯¤¬¤¢¤ê¤Þ¤»¤ó"
#. Highlight title
-#: ../mark.c:687
msgid ""
"\n"
"mark line col file/text"
@@ -3602,7 +3261,6 @@ msgstr ""
"mark ¹Ô Îó ¥Õ¥¡¥¤¥ë/¥Æ¥­¥¹¥È"
#. Highlight title
-#: ../mark.c:789
msgid ""
"\n"
" jump line col file/text"
@@ -3611,7 +3269,6 @@ msgstr ""
" jump ¹Ô Îó ¥Õ¥¡¥¤¥ë/¥Æ¥­¥¹¥È"
#. Highlight title
-#: ../mark.c:831
msgid ""
"\n"
"change line col text"
@@ -3619,7 +3276,6 @@ msgstr ""
"\n"
"Êѹ¹ ¹Ô Îó ¥Æ¥­¥¹¥È"
-#: ../mark.c:1238
msgid ""
"\n"
"# File marks:\n"
@@ -3628,7 +3284,6 @@ msgstr ""
"# ¥Õ¥¡¥¤¥ë¥Þ¡¼¥¯:\n"
#. Write the jumplist with -'
-#: ../mark.c:1271
msgid ""
"\n"
"# Jumplist (newest first):\n"
@@ -3636,7 +3291,6 @@ msgstr ""
"\n"
"# ¥¸¥ã¥ó¥×¥ê¥¹¥È (¿·¤·¤¤¤â¤Î¤¬Àè):\n"
-#: ../mark.c:1352
msgid ""
"\n"
"# History of marks within files (newest to oldest):\n"
@@ -3644,84 +3298,88 @@ msgstr ""
"\n"
"# ¥Õ¥¡¥¤¥ëÆâ¥Þ¡¼¥¯¤ÎÍúÎò (¿·¤·¤¤¤â¤Î¤«¤é¸Å¤¤¤â¤Î):\n"
-#: ../mark.c:1431
msgid "Missing '>'"
msgstr "'>' ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../memfile.c:426
+msgid "E543: Not a valid codepage"
+msgstr "E543: ̵¸ú¤Ê¥³¡¼¥É¥Ú¡¼¥¸¤Ç¤¹"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: IC¤ÎÃͤòÀßÄê¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: ¥¤¥ó¥×¥Ã¥È¥³¥ó¥Æ¥­¥¹¥È¤ÎºîÀ®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: ¥¤¥ó¥×¥Ã¥È¥á¥½¥Ã¥É¤Î¥ª¡¼¥×¥ó¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: ·Ù¹ð: IM¤ÎÇ˲õ¥³¡¼¥ë¥Ð¥Ã¥¯¤òÀßÄê¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: ¥¤¥ó¥×¥Ã¥È¥á¥½¥Ã¥É¤Ï¤É¤ó¤Ê¥¹¥¿¥¤¥ë¤â¥µ¥Ý¡¼¥È¤·¤Þ¤»¤ó"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: ¥¤¥ó¥×¥Ã¥È¥á¥½¥Ã¥É¤Ï my preedit type ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤»¤ó"
+
msgid "E293: block was not locked"
msgstr "E293: ¥Ö¥í¥Ã¥¯¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../memfile.c:799
msgid "E294: Seek error in swap file read"
msgstr "E294: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ëÆÉ¹þ»þ¤Ë¥·¡¼¥¯¥¨¥é¡¼¤Ç¤¹"
-#: ../memfile.c:803
msgid "E295: Read error in swap file"
msgstr "E295: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ÎÆÉ¹þ¤ß¥¨¥é¡¼¤Ç¤¹"
-#: ../memfile.c:849
msgid "E296: Seek error in swap file write"
msgstr "E296: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë½ñ¹þ¤ß»þ¤Ë¥·¡¼¥¯¥¨¥é¡¼¤Ç¤¹"
-#: ../memfile.c:865
msgid "E297: Write error in swap file"
msgstr "E297: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î½ñ¹þ¤ß¥¨¥é¡¼¤Ç¤¹"
-#: ../memfile.c:1036
msgid "E300: Swap file already exists (symlink attack?)"
msgstr "E300: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬´û¤Ë¸ºß¤·¤Þ¤¹ (symlink¤Ë¤è¤ë¹¶·â?)"
-#: ../memline.c:318
msgid "E298: Didn't get block nr 0?"
msgstr "E298: ¥Ö¥í¥Ã¥¯ 0 ¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó?"
-#: ../memline.c:361
msgid "E298: Didn't get block nr 1?"
msgstr "E298: ¥Ö¥í¥Ã¥¯ 1 ¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó?"
-#: ../memline.c:377
msgid "E298: Didn't get block nr 2?"
msgstr "E298: ¥Ö¥í¥Ã¥¯ 2 ¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó?"
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î°Å¹æ¤ò¹¹¿·Ãæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿"
+
#. could not (re)open the swap file, what can we do????
-#: ../memline.c:465
msgid "E301: Oops, lost the swap file!!!"
msgstr "E301: ¤ª¤Ã¤È, ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬¼º¤ï¤ì¤Þ¤·¤¿!!!"
-#: ../memline.c:477
msgid "E302: Could not rename swap file"
msgstr "E302: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÊѤ¨¤é¤ì¤Þ¤»¤ó"
-#: ../memline.c:554
#, c-format
msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
msgstr "E303: \"%s\" ¤Î¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ò³«¤±¤Ê¤¤¤Î¤Ç¥ê¥«¥Ð¥ê¤ÏÉÔ²Äǽ¤Ç¤¹"
-#: ../memline.c:666
msgid "E304: ml_upd_block0(): Didn't get block 0??"
msgstr "E304: ml_upd_block0(): ¥Ö¥í¥Ã¥¯ 0 ¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿??"
-#. no swap files found
-#: ../memline.c:830
#, c-format
msgid "E305: No swap file found for %s"
msgstr "E305: %s ¤Ë¤Ï¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../memline.c:839
msgid "Enter number of swap file to use (0 to quit): "
msgstr "»ÈÍѤ¹¤ë¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ÎÈÖ¹æ¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤(0 ¤Ç½ªÎ»): "
-#: ../memline.c:879
#, c-format
msgid "E306: Cannot open %s"
msgstr "E306: %s ¤ò³«¤±¤Þ¤»¤ó"
-#: ../memline.c:897
msgid "Unable to read block 0 from "
msgstr "¥Ö¥í¥Ã¥¯ 0 ¤òÆÉ¹þ¤á¤Þ¤»¤ó "
-#: ../memline.c:900
msgid ""
"\n"
"Maybe no changes were made or Vim did not update the swap file."
@@ -3729,28 +3387,22 @@ msgstr ""
"\n"
"¶²¤é¤¯Êѹ¹¤¬¤µ¤ì¤Æ¤¤¤Ê¤¤¤«Vim¤¬¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ò¹¹¿·¤·¤Æ¤¤¤Þ¤»¤ó."
-#: ../memline.c:909
msgid " cannot be used with this version of Vim.\n"
msgstr " Vim¤Î¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï»ÈÍѤǤ­¤Þ¤»¤ó.\n"
-#: ../memline.c:911
msgid "Use Vim version 3.0.\n"
msgstr "Vim¤Î¥Ð¡¼¥¸¥ç¥ó3.0¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤.\n"
-#: ../memline.c:916
#, c-format
msgid "E307: %s does not look like a Vim swap file"
msgstr "E307: %s ¤ÏVim¤Î¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Ç¤Ï¤Ê¤¤¤è¤¦¤Ç¤¹"
-#: ../memline.c:922
msgid " cannot be used on this computer.\n"
msgstr " ¤³¤Î¥³¥ó¥Ô¥å¡¼¥¿¤Ç¤Ï»ÈÍѤǤ­¤Þ¤»¤ó.\n"
-#: ../memline.c:924
msgid "The file was created on "
msgstr "¤³¤Î¥Õ¥¡¥¤¥ë¤Ï¼¡¤Î¾ì½ê¤Çºî¤é¤ì¤Þ¤·¤¿ "
-#: ../memline.c:928
msgid ""
",\n"
"or the file has been damaged."
@@ -3758,85 +3410,104 @@ msgstr ""
",\n"
"¤â¤·¤¯¤Ï¥Õ¥¡¥¤¥ë¤¬Â»½ý¤·¤Æ¤¤¤Þ¤¹."
-#: ../memline.c:945
+#, c-format
+msgid ""
+"E833: %s is encrypted and this version of Vim does not support encryption"
+msgstr ""
+"E833: %s ¤Ï¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤ÎVim¤Ç¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤·Á¼°¤Ç°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹"
+
msgid " has been damaged (page size is smaller than minimum value).\n"
msgstr " ¤Ï»½ý¤·¤Æ¤¤¤Þ¤¹ (¥Ú¡¼¥¸¥µ¥¤¥º¤¬ºÇ¾®Ãͤò²¼²ó¤Ã¤Æ¤¤¤Þ¤¹).\n"
-#: ../memline.c:974
#, c-format
msgid "Using swap file \"%s\""
msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë \"%s\" ¤ò»ÈÍÑÃæ"
-#: ../memline.c:980
#, c-format
msgid "Original file \"%s\""
msgstr "¸¶ËÜ¥Õ¥¡¥¤¥ë \"%s\""
-#: ../memline.c:995
msgid "E308: Warning: Original file may have been changed"
msgstr "E308: ·Ù¹ð: ¸¶ËÜ¥Õ¥¡¥¤¥ë¤¬Êѹ¹¤µ¤ì¤Æ¤¤¤Þ¤¹"
-#: ../memline.c:1061
+#, c-format
+msgid "Swap file is encrypted: \"%s\""
+msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Ï°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹: \"%s\""
+
+msgid ""
+"\n"
+"If you entered a new crypt key but did not write the text file,"
+msgstr ""
+"\n"
+"¿·¤·¤¤°Å¹æ¥­¡¼¤òÆþÎϤ·¤¿¤¢¤È¤Ë¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤òÊݸ¤·¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï,"
+
+msgid ""
+"\n"
+"enter the new crypt key."
+msgstr ""
+"\n"
+"¿·¤·¤¤°Å¹æ¥­¡¼¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤."
+
+msgid ""
+"\n"
+"If you wrote the text file after changing the crypt key press enter"
+msgstr ""
+"\n"
+"°Å¹æ¥­¡¼¤òÊѤ¨¤¿¤¢¤È¤Ë¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤òÊݸ¤·¤¿¾ì¹ç¤Ï, ¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤È"
+
+msgid ""
+"\n"
+"to use the same key for text file and swap file"
+msgstr ""
+"\n"
+"¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ËƱ¤¸°Å¹æ¥­¡¼¤ò»È¤¦¤¿¤á¤Ëenter¤À¤±¤ò²¡¤·¤Æ¤¯¤À¤µ¤¤."
+
#, c-format
msgid "E309: Unable to read block 1 from %s"
msgstr "E309: %s ¤«¤é¥Ö¥í¥Ã¥¯ 1 ¤òÆÉ¹þ¤á¤Þ¤»¤ó"
-#: ../memline.c:1065
msgid "???MANY LINES MISSING"
msgstr "???¿¤¯¤Î¹Ô¤¬¼º¤ï¤ì¤Æ¤¤¤Þ¤¹"
-#: ../memline.c:1076
msgid "???LINE COUNT WRONG"
msgstr "???¹Ô¿ô¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../memline.c:1082
msgid "???EMPTY BLOCK"
msgstr "???¥Ö¥í¥Ã¥¯¤¬¶õ¤Ç¤¹"
-#: ../memline.c:1103
msgid "???LINES MISSING"
msgstr "???¹Ô¤¬¼º¤ï¤ì¤Æ¤¤¤Þ¤¹"
-#: ../memline.c:1128
#, c-format
msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
msgstr "E310: ¥Ö¥í¥Ã¥¯ 1 ¤ÎID¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹(%s ¤¬.swp¥Õ¥¡¥¤¥ë¤Ç¤Ê¤¤?)"
-#: ../memline.c:1133
msgid "???BLOCK MISSING"
msgstr "???¥Ö¥í¥Ã¥¯¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../memline.c:1147
msgid "??? from here until ???END lines may be messed up"
msgstr "??? ¤³¤³¤«¤é ???END ¤Þ¤Ç¤Î¹Ô¤¬Ç˲õ¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ç¤¹"
-#: ../memline.c:1164
msgid "??? from here until ???END lines may have been inserted/deleted"
msgstr "??? ¤³¤³¤«¤é ???END ¤Þ¤Ç¤Î¹Ô¤¬ÁÞÆþ¤«ºï½ü¤µ¤ì¤¿¤è¤¦¤Ç¤¹"
-#: ../memline.c:1181
msgid "???END"
msgstr "???END"
-#: ../memline.c:1238
msgid "E311: Recovery Interrupted"
msgstr "E311: ¥ê¥«¥Ð¥ê¤¬³ä¹þ¤Þ¤ì¤Þ¤·¤¿"
-#: ../memline.c:1243
msgid ""
"E312: Errors detected while recovering; look for lines starting with ???"
msgstr ""
"E312: ¥ê¥«¥Ð¥ê¤ÎºÇÃæ¤Ë¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤Þ¤·¤¿; ???¤Ç»Ï¤Þ¤ë¹Ô¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../memline.c:1245
msgid "See \":help E312\" for more information."
msgstr "¾ÜºÙ¤Ï \":help E312\" ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../memline.c:1249
msgid "Recovery completed. You should check if everything is OK."
msgstr "¥ê¥«¥Ð¥ê¤¬½ªÎ»¤·¤Þ¤·¤¿. Á´¤Æ¤¬Àµ¤·¤¤¤«¥Á¥§¥Ã¥¯¤·¤Æ¤¯¤À¤µ¤¤."
-#: ../memline.c:1251
msgid ""
"\n"
"(You might want to write out this file under another name\n"
@@ -3844,15 +3515,12 @@ msgstr ""
"\n"
"(Êѹ¹¤ò¥Á¥§¥Ã¥¯¤¹¤ë¤¿¤á¤Ë, ¤³¤Î¥Õ¥¡¥¤¥ë¤òÊ̤Î̾Á°¤ÇÊݸ¤·¤¿¾å¤Ç\n"
-#: ../memline.c:1252
msgid "and run diff with the original file to check for changes)"
msgstr "¸¶ËÜ¥Õ¥¡¥¤¥ë¤È¤Î diff ¤ò¼Â¹Ô¤¹¤ë¤ÈÎɤ¤¤Ç¤·¤ç¤¦)"
-#: ../memline.c:1254
msgid "Recovery completed. Buffer contents equals file contents."
msgstr "Éü¸µ´°Î». ¥Ð¥Ã¥Õ¥¡¤ÎÆâÍÆ¤Ï¥Õ¥¡¥¤¥ë¤ÈƱ¤¸¤Ë¤Ê¤ê¤Þ¤·¤¿."
-#: ../memline.c:1255
msgid ""
"\n"
"You may want to delete the .swp file now.\n"
@@ -3862,52 +3530,43 @@ msgstr ""
"¸µ¤Î.swp¥Õ¥¡¥¤¥ë¤Ïºï½ü¤·¤Æ¤â¹½¤¤¤Þ¤»¤ó\n"
"\n"
+msgid "Using crypt key from swap file for the text file.\n"
+msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤«¤é¼èÆÀ¤·¤¿°Å¹æ¥­¡¼¤ò¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤Ë»È¤¤¤Þ¤¹.\n"
+
#. use msg() to start the scrolling properly
-#: ../memline.c:1327
msgid "Swap files found:"
msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬Ê£¿ô¸«¤Ä¤«¤ê¤Þ¤·¤¿:"
-#: ../memline.c:1446
msgid " In current directory:\n"
msgstr " ¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê:\n"
-#: ../memline.c:1448
msgid " Using specified name:\n"
msgstr " °Ê²¼¤Î̾Á°¤ò»ÈÍÑÃæ:\n"
-#: ../memline.c:1450
msgid " In directory "
msgstr " ¥Ç¥£¥ì¥¯¥È¥ê "
-#: ../memline.c:1465
msgid " -- none --\n"
msgstr " -- ¤Ê¤· --\n"
-#: ../memline.c:1527
msgid " owned by: "
msgstr " ½êÍ­¼Ô: "
-#: ../memline.c:1529
msgid " dated: "
msgstr " ÆüÉÕ: "
-#: ../memline.c:1532 ../memline.c:3231
msgid " dated: "
msgstr " ÆüÉÕ: "
-#: ../memline.c:1548
msgid " [from Vim version 3.0]"
msgstr " [from Vim version 3.0]"
-#: ../memline.c:1550
msgid " [does not look like a Vim swap file]"
msgstr " [Vim¤Î¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Ç¤Ï¤Ê¤¤¤è¤¦¤Ç¤¹]"
-#: ../memline.c:1552
msgid " file name: "
msgstr " ¥Õ¥¡¥¤¥ë̾: "
-#: ../memline.c:1558
msgid ""
"\n"
" modified: "
@@ -3915,15 +3574,12 @@ msgstr ""
"\n"
" Êѹ¹¾õÂÖ: "
-#: ../memline.c:1559
msgid "YES"
msgstr "¤¢¤ê"
-#: ../memline.c:1559
msgid "no"
msgstr "¤Ê¤·"
-#: ../memline.c:1562
msgid ""
"\n"
" user name: "
@@ -3931,11 +3587,9 @@ msgstr ""
"\n"
" ¥æ¡¼¥¶¡¼Ì¾: "
-#: ../memline.c:1568
msgid " host name: "
msgstr " ¥Û¥¹¥È̾: "
-#: ../memline.c:1570
msgid ""
"\n"
" host name: "
@@ -3943,7 +3597,6 @@ msgstr ""
"\n"
" ¥Û¥¹¥È̾: "
-#: ../memline.c:1575
msgid ""
"\n"
" process ID: "
@@ -3951,11 +3604,16 @@ msgstr ""
"\n"
" ¥×¥í¥»¥¹ID: "
-#: ../memline.c:1579
msgid " (still running)"
msgstr " (¤Þ¤À¼Â¹ÔÃæ)"
-#: ../memline.c:1586
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [¤³¤ÎVim¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï»ÈÍѤǤ­¤Þ¤»¤ó]"
+
msgid ""
"\n"
" [not usable on this computer]"
@@ -3963,97 +3621,75 @@ msgstr ""
"\n"
" [¤³¤Î¥³¥ó¥Ô¥å¡¼¥¿¤Ç¤Ï»ÈÍѤǤ­¤Þ¤»¤ó]"
-#: ../memline.c:1590
msgid " [cannot be read]"
msgstr " [ÆÉ¹þ¤á¤Þ¤»¤ó]"
-#: ../memline.c:1593
msgid " [cannot be opened]"
msgstr " [³«¤±¤Þ¤»¤ó]"
-#: ../memline.c:1698
msgid "E313: Cannot preserve, there is no swap file"
msgstr "E313: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬Ìµ¤¤¤Î¤Ç°Ý»ý¤Ç¤­¤Þ¤»¤ó"
-#: ../memline.c:1747
msgid "File preserved"
msgstr "¥Õ¥¡¥¤¥ë¤¬°Ý»ý¤µ¤ì¤Þ¤¹"
-#: ../memline.c:1749
msgid "E314: Preserve failed"
msgstr "E314: °Ý»ý¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../memline.c:1819
#, c-format
-msgid "E315: ml_get: invalid lnum: %<PRId64>"
-msgstr "E315: ml_get: ̵¸ú¤Êlnum¤Ç¤¹: %<PRId64>"
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: ̵¸ú¤Êlnum¤Ç¤¹: %ld"
-#: ../memline.c:1851
#, c-format
-msgid "E316: ml_get: cannot find line %<PRId64>"
-msgstr "E316: ml_get: ¹Ô %<PRId64> ¤ò¸«¤Ä¤±¤é¤ì¤Þ¤»¤ó"
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: ¹Ô %ld ¤ò¸«¤Ä¤±¤é¤ì¤Þ¤»¤ó"
-#: ../memline.c:2236
msgid "E317: pointer block id wrong 3"
msgstr "E317: ¥Ý¥¤¥ó¥¿¥Ö¥í¥Ã¥¯¤ÎID¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹ 3"
-#: ../memline.c:2311
msgid "stack_idx should be 0"
msgstr "stack_idx ¤Ï 0 ¤Ç¤¢¤ë¤Ù¤­¤Ç¤¹"
-#: ../memline.c:2369
msgid "E318: Updated too many blocks?"
msgstr "E318: ¹¹¿·¤µ¤ì¤¿¥Ö¥í¥Ã¥¯¤¬Â¿²á¤®¤ë¤«¤â?"
-#: ../memline.c:2511
msgid "E317: pointer block id wrong 4"
msgstr "E317: ¥Ý¥¤¥ó¥¿¥Ö¥í¥Ã¥¯¤ÎID¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹ 4"
-#: ../memline.c:2536
msgid "deleted block 1?"
msgstr "¥Ö¥í¥Ã¥¯ 1 ¤Ï¾Ã¤µ¤ì¤¿?"
-#: ../memline.c:2707
#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: ¹Ô %<PRId64> ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+msgid "E320: Cannot find line %ld"
+msgstr "E320: ¹Ô %ld ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../memline.c:2916
msgid "E317: pointer block id wrong"
msgstr "E317: ¥Ý¥¤¥ó¥¿¥Ö¥í¥Ã¥¯¤ÎID¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../memline.c:2930
msgid "pe_line_count is zero"
msgstr "pe_line_count ¤¬¥¼¥í¤Ç¤¹"
-#: ../memline.c:2955
#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: ¹ÔÈֹ椬Èϰϳ°¤Ç¤¹: %<PRId64> ͤ¨¤Æ¤¤¤Þ¤¹"
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: ¹ÔÈֹ椬Èϰϳ°¤Ç¤¹: %ld ͤ¨¤Æ¤¤¤Þ¤¹"
-#: ../memline.c:2959
#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: ¥Ö¥í¥Ã¥¯ %<PRId64> ¤Î¹Ô¥«¥¦¥ó¥È¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: ¥Ö¥í¥Ã¥¯ %ld ¤Î¹Ô¥«¥¦¥ó¥È¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../memline.c:2999
msgid "Stack size increases"
msgstr "¥¹¥¿¥Ã¥¯¥µ¥¤¥º¤¬Áý¤¨¤Þ¤¹"
-#: ../memline.c:3038
msgid "E317: pointer block id wrong 2"
msgstr "E317: ¥Ý¥¤¥ó¥¿¥Ö¥í¥Ã¥¯¤ÎID¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹ 2"
-#: ../memline.c:3070
#, c-format
msgid "E773: Symlink loop for \"%s\""
msgstr "E773: \"%s\" ¤Î¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤¬¥ë¡¼¥×¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../memline.c:3221
msgid "E325: ATTENTION"
msgstr "E325: Ãí°Õ"
-#: ../memline.c:3222
msgid ""
"\n"
"Found a swap file by the name \""
@@ -4061,39 +3697,32 @@ msgstr ""
"\n"
"¼¡¤Î̾Á°¤Ç¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ò¸«¤Ä¤±¤Þ¤·¤¿ \""
-#: ../memline.c:3226
msgid "While opening file \""
msgstr "¼¡¤Î¥Õ¥¡¥¤¥ë¤ò³«¤¤¤Æ¤¤¤ëºÇÃæ \""
-#: ../memline.c:3239
msgid " NEWER than swap file!\n"
msgstr " ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤è¤ê¤â¿·¤·¤¤¤Ç¤¹!\n"
-#: ../memline.c:3244
+#. Some of these messages are long to allow translation to
+#. * other languages.
msgid ""
"\n"
"(1) Another program may be editing the same file. If this is the case,\n"
" be careful not to end up with two different instances of the same\n"
-" file when making changes."
+" file when making changes. Quit, or continue with caution.\n"
msgstr ""
"\n"
"(1) ÊÌ¤Î¥×¥í¥°¥é¥à¤¬Æ±¤¸¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Æ¤¤¤ë¤«¤â¤·¤ì¤Þ¤»¤ó.\n"
" ¤³¤Î¾ì¹ç¤Ë¤Ï, Êѹ¹¤ò¤·¤Æ¤·¤Þ¤¦¤È1¤Ä¤Î¥Õ¥¡¥¤¥ë¤ËÂФ·¤Æ°Û¤Ê¤ë2¤Ä¤Î\n"
-" ¥¤¥ó¥¹¥¿¥ó¥¹¤¬¤Ç¤­¤Æ¤·¤Þ¤¦¤Î¤Ç, ¤½¤¦¤·¤Ê¤¤¤è¤¦¤Ëµ¤¤ò¤Ä¤±¤Æ¤¯¤À¤µ¤¤."
-
-#: ../memline.c:3245
-msgid " Quit, or continue with caution.\n"
-msgstr " ½ªÎ»¤¹¤ë¤«, Ãí°Õ¤·¤Ê¤¬¤é³¤±¤Æ¤¯¤À¤µ¤¤.\n"
+" ¥¤¥ó¥¹¥¿¥ó¥¹¤¬¤Ç¤­¤Æ¤·¤Þ¤¦¤Î¤Ç, ¤½¤¦¤·¤Ê¤¤¤è¤¦¤Ëµ¤¤ò¤Ä¤±¤Æ¤¯¤À¤µ¤¤.\n"
+" ½ªÎ»¤¹¤ë¤«, Ãí°Õ¤·¤Ê¤¬¤é³¤±¤Æ¤¯¤À¤µ¤¤.\n"
-#: ../memline.c:3246
msgid "(2) An edit session for this file crashed.\n"
msgstr "(2) ¤³¤Î¥Õ¥¡¥¤¥ë¤ÎÊÔ½¸¥»¥Ã¥·¥ç¥ó¤¬¥¯¥é¥Ã¥·¥å¤·¤¿.\n"
-#: ../memline.c:3247
msgid " If this is the case, use \":recover\" or \"vim -r "
msgstr " ¤³¤Î¾ì¹ç¤Ë¤Ï \":recover\" ¤« \"vim -r "
-#: ../memline.c:3249
msgid ""
"\"\n"
" to recover the changes (see \":help recovery\").\n"
@@ -4101,11 +3730,9 @@ msgstr ""
"\"\n"
" ¤ò»ÈÍѤ·¤ÆÊѹ¹¤ò¥ê¥«¥Ð¡¼¤·¤Þ¤¹(\":help recovery\" ¤ò»²¾È).\n"
-#: ../memline.c:3250
msgid " If you did this already, delete the swap file \""
msgstr " ´û¤Ë¤³¤ì¤ò¹Ô¤Ê¤Ã¤¿¤Î¤Ê¤é¤Ð, ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë \""
-#: ../memline.c:3252
msgid ""
"\"\n"
" to avoid this message.\n"
@@ -4113,23 +3740,18 @@ msgstr ""
"\"\n"
" ¤ò¾Ã¤»¤Ð¤³¤Î¥á¥Ã¥»¡¼¥¸¤ò²óÈò¤Ç¤­¤Þ¤¹.\n"
-#: ../memline.c:3450 ../memline.c:3452
msgid "Swap file \""
msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë \""
-#: ../memline.c:3451 ../memline.c:3455
msgid "\" already exists!"
msgstr "\" ¤¬´û¤Ë¤¢¤ê¤Þ¤¹!"
-#: ../memline.c:3457
msgid "VIM - ATTENTION"
msgstr "VIM - Ãí°Õ"
-#: ../memline.c:3459
msgid "Swap file already exists!"
msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬´û¤Ë¸ºß¤·¤Þ¤¹!"
-#: ../memline.c:3464
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4143,7 +3765,6 @@ msgstr ""
"½ªÎ»¤¹¤ë(&Q)\n"
"Ãæ»ß¤¹¤ë(&A)"
-#: ../memline.c:3467
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4159,56 +3780,34 @@ msgstr ""
"½ªÎ»¤¹¤ë(&Q)\n"
"Ãæ»ß¤¹¤ë(&A)"
-#.
-#. * Change the ".swp" extension to find another file that can be used.
-#. * First decrement the last char: ".swo", ".swn", etc.
-#. * If that still isn't enough decrement the last but one char: ".svz"
-#. * Can happen when editing many "No Name" buffers.
-#.
-#. ".s?a"
-#. ".saa": tried enough, give up
-#: ../memline.c:3528
msgid "E326: Too many swap files found"
msgstr "E326: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬Â¿¿ô¸«¤Ä¤«¤ê¤Þ¤·¤¿"
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: ¥á¥â¥ê¤¬Â­¤ê¤Þ¤»¤ó! (%<PRIu64> ¥Ð¥¤¥È¤ò³äÅöÍ×µá)"
-
-#: ../menu.c:62
msgid "E327: Part of menu-item path is not sub-menu"
msgstr "E327: ¥á¥Ë¥å¡¼¥¢¥¤¥Æ¥à¤Î¥Ñ¥¹¤ÎÉôʬ¤¬¥µ¥Ö¥á¥Ë¥å¡¼¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../menu.c:63
msgid "E328: Menu only exists in another mode"
msgstr "E328: ¥á¥Ë¥å¡¼¤Ï¾¤Î¥â¡¼¥É¤Ë¤À¤±¤¢¤ê¤Þ¤¹"
-#: ../menu.c:64
#, c-format
msgid "E329: No menu \"%s\""
msgstr "E329: \"%s\" ¤È¤¤¤¦¥á¥Ë¥å¡¼¤Ï¤¢¤ê¤Þ¤»¤ó"
#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
msgid "E792: Empty menu name"
msgstr "E792: ¥á¥Ë¥å¡¼Ì¾¤¬¶õ¤Ç¤¹"
-#: ../menu.c:340
msgid "E330: Menu path must not lead to a sub-menu"
msgstr "E330: ¥á¥Ë¥å¡¼¥Ñ¥¹¤Ï¥µ¥Ö¥á¥Ë¥å¡¼¤òÀ¸¤¸¤ë¤Ù¤­¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../menu.c:365
msgid "E331: Must not add menu items directly to menu bar"
msgstr "E331: ¥á¥Ë¥å¡¼¥Ð¡¼¤Ë¤ÏľÀÜ¥á¥Ë¥å¡¼¥¢¥¤¥Æ¥à¤òÄɲäǤ­¤Þ¤»¤ó"
-#: ../menu.c:370
msgid "E332: Separator cannot be part of a menu path"
msgstr "E332: ¶èÀÚ¤ê¤Ï¥á¥Ë¥å¡¼¥Ñ¥¹¤Î°ìÉô¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
#. Now we have found the matching menu, and we list the mappings
#. Highlight title
-#: ../menu.c:762
msgid ""
"\n"
"--- Menus ---"
@@ -4216,69 +3815,60 @@ msgstr ""
"\n"
"--- ¥á¥Ë¥å¡¼ ---"
-#: ../menu.c:1313
+msgid "Tear off this menu"
+msgstr "¤³¤Î¥á¥Ë¥å¡¼¤òÀÚ¤ê¼è¤ë"
+
msgid "E333: Menu path must lead to a menu item"
msgstr "E333: ¥á¥Ë¥å¡¼¥Ñ¥¹¤Ï¥á¥Ë¥å¡¼¥¢¥¤¥Æ¥à¤òÀ¸¤¸¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó"
-#: ../menu.c:1330
#, c-format
msgid "E334: Menu not found: %s"
msgstr "E334: ¥á¥Ë¥å¡¼¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s"
-#: ../menu.c:1396
#, c-format
msgid "E335: Menu not defined for %s mode"
msgstr "E335: %s ¤Ë¤Ï¥á¥Ë¥å¡¼¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../menu.c:1426
msgid "E336: Menu path must lead to a sub-menu"
msgstr "E336: ¥á¥Ë¥å¡¼¥Ñ¥¹¤Ï¥µ¥Ö¥á¥Ë¥å¡¼¤òÀ¸¤¸¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó"
-#: ../menu.c:1447
msgid "E337: Menu not found - check menu names"
msgstr "E337: ¥á¥Ë¥å¡¼¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó - ¥á¥Ë¥å¡¼Ì¾¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../message.c:423
#, c-format
msgid "Error detected while processing %s:"
msgstr "%s ¤Î½èÍýÃæ¤Ë¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤Þ¤·¤¿:"
-#: ../message.c:445
#, c-format
msgid "line %4ld:"
msgstr "¹Ô %4ld:"
-#: ../message.c:617
#, c-format
msgid "E354: Invalid register name: '%s'"
msgstr "E354: ̵¸ú¤Ê¥ì¥¸¥¹¥¿Ì¾: '%s'"
-#: ../message.c:986
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "ÆüËܸì¥á¥Ã¥»¡¼¥¸ËÝÌõ/´Æ½¤: ¼²¬ ÂÀϺ <koron.kaoriya@gmail.com>"
+
msgid "Interrupt: "
msgstr "³ä¹þ¤ß: "
-#: ../message.c:988
msgid "Press ENTER or type command to continue"
msgstr "³¤±¤ë¤Ë¤ÏENTER¤ò²¡¤¹¤«¥³¥Þ¥ó¥É¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤"
-#: ../message.c:1843
#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s ¹Ô %<PRId64>"
+msgid "%s line %ld"
+msgstr "%s ¹Ô %ld"
-#: ../message.c:2392
msgid "-- More --"
msgstr "-- ·Ñ³ --"
-#: ../message.c:2398
msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
msgstr " SPACE/d/j: ²èÌÌ/¥Ú¡¼¥¸/¹Ô ²¼, b/u/k: ¾å, q: ½ªÎ» "
-#: ../message.c:3021 ../message.c:3031
msgid "Question"
msgstr "¼ÁÌä"
-#: ../message.c:3023
msgid ""
"&Yes\n"
"&No"
@@ -4286,17 +3876,6 @@ msgstr ""
"¤Ï¤¤(&Y)\n"
"¤¤¤¤¤¨(&N)"
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"¤Ï¤¤(&Y)\n"
-"¤¤¤¤¤¨(&N)\n"
-"¥­¥ã¥ó¥»¥ë(&C)"
-
-#: ../message.c:3045
msgid ""
"&Yes\n"
"&No\n"
@@ -4310,175 +3889,247 @@ msgstr ""
"Á´¤ÆÊü´þ(&D)\n"
"¥­¥ã¥ó¥»¥ë(&C)"
-#: ../message.c:3058
+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() ¤Î°ú¿ô¤¬ÉÔ½½Ê¬¤Ç¤¹"
-#: ../message.c:3119
msgid "E807: Expected Float argument for printf()"
msgstr "E807: printf() ¤Î°ú¿ô¤Ë¤ÏÉâÆ°¾¯¿ôÅÀ¿ô¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤Þ¤¹"
-#: ../message.c:3873
msgid "E767: Too many arguments to printf()"
msgstr "E767: printf() ¤Î°ú¿ô¤¬Â¿²á¤®¤Þ¤¹"
-#: ../misc1.c:2256
msgid "W10: Warning: Changing a readonly file"
msgstr "W10: ·Ù¹ð: ÆÉ¹þÀìÍÑ¥Õ¥¡¥¤¥ë¤òÊѹ¹¤·¤Þ¤¹"
-#: ../misc1.c:2537
msgid "Type number and <Enter> or click with mouse (empty cancels): "
msgstr ""
"ÈÖ¹æ¤È<Enter>¤òÆþÎϤ¹¤ë¤«¥Þ¥¦¥¹¤Ç¥¯¥ê¥Ã¥¯¤·¤Æ¤¯¤À¤µ¤¤ (¶õ¤Ç¥­¥ã¥ó¥»¥ë): "
-#: ../misc1.c:2539
msgid "Type number and <Enter> (empty cancels): "
msgstr "ÈÖ¹æ¤È<Enter>¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤ (¶õ¤Ç¥­¥ã¥ó¥»¥ë): "
-#: ../misc1.c:2585
msgid "1 more line"
msgstr "1 ¹Ô Äɲä·¤Þ¤·¤¿"
-#: ../misc1.c:2588
msgid "1 line less"
msgstr "1 ¹Ô ºï½ü¤·¤Þ¤·¤¿"
-#: ../misc1.c:2593
#, c-format
-msgid "%<PRId64> more lines"
-msgstr "%<PRId64> ¹Ô Äɲä·¤Þ¤·¤¿"
+msgid "%ld more lines"
+msgstr "%ld ¹Ô Äɲä·¤Þ¤·¤¿"
-#: ../misc1.c:2596
#, c-format
-msgid "%<PRId64> fewer lines"
-msgstr "%<PRId64> ¹Ô ºï½ü¤·¤Þ¤·¤¿"
+msgid "%ld fewer lines"
+msgstr "%ld ¹Ô ºï½ü¤·¤Þ¤·¤¿"
-#: ../misc1.c:2599
msgid " (Interrupted)"
msgstr " (³ä¹þ¤Þ¤ì¤Þ¤·¤¿)"
-#: ../misc1.c:2635
msgid "Beep!"
msgstr "¥Ó¡¼¥Ã!"
-#: ../misc2.c:738
+msgid "ERROR: "
+msgstr "¥¨¥é¡¼: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[¥á¥â¥ê(¥Ð¥¤¥È)] Áí³äÅö-²òÊüÎÌ %lu-%lu, »ÈÍÑÎÌ %lu, ¥Ô¡¼¥¯»þ %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[¸Æ½Ð] Áí re/malloc() ²ó¿ô %lu, Áí free() ²ó¿ô %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: ¹Ô¤¬Ä¹¤¯¤Ê¤ê²á¤®¤Þ¤·¤¿"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: ÆâÉô¥¨¥é¡¼: lalloc(%ld,)"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: ¥á¥â¥ê¤¬Â­¤ê¤Þ¤»¤ó! (%lu ¥Ð¥¤¥È¤ò³äÅöÍ×µá)"
+
#, c-format
msgid "Calling shell to execute: \"%s\""
msgstr "¼Â¹Ô¤Î¤¿¤á¤Ë¥·¥§¥ë¤ò¸Æ½Ð¤·Ãæ: \"%s\""
-#: ../normal.c:183
+msgid "E545: Missing colon"
+msgstr "E545: ¥³¥í¥ó¤¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E546: Illegal mode"
+msgstr "E546: ÉÔÀµ¤Ê¥â¡¼¥É¤Ç¤¹"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: ÉÔÀµ¤Ê 'mouseshape' ¤Ç¤¹"
+
+msgid "E548: digit expected"
+msgstr "E548: ¿ôÃͤ¬É¬ÍפǤ¹"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: ÉÔÀµ¤Ê¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸¤Ç¤¹"
+
+msgid "E854: path too long for completion"
+msgstr "E854: ¥Ñ¥¹¤¬Ä¹²á¤®¤ÆÊä´°¤Ç¤­¤Þ¤»¤ó"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: ̵¸ú¤Ê¥Ñ¥¹¤Ç¤¹: '**[¿ôÃÍ]' ¤Ïpath¤ÎºÇ¸å¤« '%s' ¤¬Â³¤¤¤Æ¤Ê¤¤¤È¤¤¤±¤Þ¤»"
+"¤ó."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: cdpath¤Ë¤Ï \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: path¤Ë¤Ï \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: cdpath¤Ë¤Ï¤³¤ì°Ê¾å \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: ¥Ñ¥¹¤Ë¤Ï¤³¤ì°Ê¾å \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: NetBeans¤ÎÀܳ¾ðÊó¥Õ¥¡¥¤¥ë¤Î¥¢¥¯¥»¥¹¥â¡¼¥É¤ËÌäÂ꤬¤¢¤ê¤Þ¤¹: \"%s\""
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: ¥Ð¥Ã¥Õ¥¡ %ld ¤Î NetBeans Àܳ¤¬¼º¤ï¤ì¤Þ¤·¤¿"
+
+msgid "E838: netbeans is not supported with this GUI"
+msgstr "E838: NetBeans¤Ï¤³¤ÎGUI¤Ë¤ÏÂбþ¤·¤Æ¤¤¤Þ¤»¤ó"
+
+msgid "E511: netbeans already connected"
+msgstr "E511: NetBeans¤Ï´û¤ËÀܳ¤·¤Æ¤¤¤Þ¤¹"
+
+#, c-format
+msgid "E505: %s is read-only (add ! to override)"
+msgstr "E505: %s ¤ÏÆÉ¹þÀìÍѤǤ¹ (¶¯À©½ñ¹þ¤Ë¤Ï ! ¤òÄɲÃ)"
+
msgid "E349: No identifier under cursor"
msgstr "E349: ¥«¡¼¥½¥ë¤Î°ÌÃ֤ˤϼ±Ê̻Ҥ¬¤¢¤ê¤Þ¤»¤ó"
-#: ../normal.c:1866
msgid "E774: 'operatorfunc' is empty"
msgstr "E774: 'operatorfunc' ¥ª¥×¥·¥ç¥ó¤¬¶õ¤Ç¤¹"
-#: ../normal.c:2637
+msgid "E775: Eval feature not available"
+msgstr "E775: ¼°É¾²Áµ¡Ç½¤¬Ìµ¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹"
+
msgid "Warning: terminal cannot highlight"
msgstr "·Ù¹ð: »ÈÍѤ·¤Æ¤¤¤ëüËö¤Ï¥Ï¥¤¥é¥¤¥È¤Ç¤­¤Þ¤»¤ó"
-#: ../normal.c:2807
msgid "E348: No string under cursor"
msgstr "E348: ¥«¡¼¥½¥ë¤Î°ÌÃ֤ˤÏʸ»úÎ󤬤¢¤ê¤Þ¤»¤ó"
-#: ../normal.c:3937
msgid "E352: Cannot erase folds with current 'foldmethod'"
msgstr "E352: ¸½ºß¤Î 'foldmethod' ¤Ç¤ÏÀÞ¾ö¤ß¤ò¾Ãµî¤Ç¤­¤Þ¤»¤ó"
-#: ../normal.c:5897
msgid "E664: changelist is empty"
msgstr "E664: Êѹ¹¥ê¥¹¥È¤¬¶õ¤Ç¤¹"
-#: ../normal.c:5899
msgid "E662: At start of changelist"
msgstr "E662: Êѹ¹¥ê¥¹¥È¤ÎÀèÆ¬"
-#: ../normal.c:5901
msgid "E663: At end of changelist"
msgstr "E663: Êѹ¹¥ê¥¹¥È¤ÎËöÈø"
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
+msgid "Type :quit<Enter> to exit Vim"
msgstr "Vim¤ò½ªÎ»¤¹¤ë¤Ë¤Ï :quit<Enter> ¤ÈÆþÎϤ·¤Æ¤¯¤À¤µ¤¤"
-#: ../ops.c:248
#, c-format
msgid "1 line %sed 1 time"
msgstr "1 ¹Ô¤¬ %s ¤Ç 1 ²ó½èÍý¤µ¤ì¤Þ¤·¤¿"
-#: ../ops.c:250
#, c-format
msgid "1 line %sed %d times"
msgstr "1 ¹Ô¤¬ %s ¤Ç %d ²ó½èÍý¤µ¤ì¤Þ¤·¤¿"
-#: ../ops.c:253
#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> ¹Ô¤¬ %s ¤Ç 1 ²ó½èÍý¤µ¤ì¤Þ¤·¤¿"
+msgid "%ld lines %sed 1 time"
+msgstr "%ld ¹Ô¤¬ %s ¤Ç 1 ²ó½èÍý¤µ¤ì¤Þ¤·¤¿"
-#: ../ops.c:256
#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> ¹Ô¤¬ %s ¤Ç %d ²ó½èÍý¤µ¤ì¤Þ¤·¤¿"
+msgid "%ld lines %sed %d times"
+msgstr "%ld ¹Ô¤¬ %s ¤Ç %d ²ó½èÍý¤µ¤ì¤Þ¤·¤¿"
-#: ../ops.c:592
#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "%<PRId64> ¹Ô¤¬¥¤¥ó¥Ç¥ó¥È¤µ¤ì¤Þ¤¹... "
+msgid "%ld lines to indent... "
+msgstr "%ld ¹Ô¤¬¥¤¥ó¥Ç¥ó¥È¤µ¤ì¤Þ¤¹... "
-#: ../ops.c:634
msgid "1 line indented "
msgstr "1 ¹Ô¤ò¥¤¥ó¥Ç¥ó¥È¤·¤Þ¤·¤¿ "
-#: ../ops.c:636
#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "%<PRId64> ¹Ô¤ò¥¤¥ó¥Ç¥ó¥È¤·¤Þ¤·¤¿ "
+msgid "%ld lines indented "
+msgstr "%ld ¹Ô¤ò¥¤¥ó¥Ç¥ó¥È¤·¤Þ¤·¤¿ "
-#: ../ops.c:938
msgid "E748: No previously used register"
msgstr "E748: ¤Þ¤À¥ì¥¸¥¹¥¿¤ò»ÈÍѤ·¤Æ¤¤¤Þ¤»¤ó"
#. must display the prompt
-#: ../ops.c:1433
msgid "cannot yank; delete anyway"
msgstr "¥ä¥ó¥¯¤Ç¤­¤Þ¤»¤ó; ¤È¤Ë¤«¤¯¾Ãµî"
-#: ../ops.c:1929
msgid "1 line changed"
msgstr "1 ¹Ô¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿"
-#: ../ops.c:1931
#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "%<PRId64> ¹Ô¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿"
+msgid "%ld lines changed"
+msgstr "%ld ¹Ô¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "%ld ¹Ô¤ò²òÊüÃæ"
-#: ../ops.c:2521
msgid "block of 1 line yanked"
msgstr "1 ¹Ô¤Î¥Ö¥í¥Ã¥¯¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
-#: ../ops.c:2523
msgid "1 line yanked"
msgstr "1 ¹Ô¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
-#: ../ops.c:2525
#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "%<PRId64> ¹Ô¤Î¥Ö¥í¥Ã¥¯¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
+msgid "block of %ld lines yanked"
+msgstr "%ld ¹Ô¤Î¥Ö¥í¥Ã¥¯¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
-#: ../ops.c:2528
#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "%<PRId64> ¹Ô¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
+msgid "%ld lines yanked"
+msgstr "%ld ¹Ô¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
-#: ../ops.c:2710
#, c-format
msgid "E353: Nothing in register %s"
msgstr "E353: ¥ì¥¸¥¹¥¿ %s ¤Ë¤Ï²¿¤â¤¢¤ê¤Þ¤»¤ó"
#. Highlight title
-#: ../ops.c:3185
msgid ""
"\n"
"--- Registers ---"
@@ -4486,11 +4137,9 @@ msgstr ""
"\n"
"--- ¥ì¥¸¥¹¥¿ ---"
-#: ../ops.c:4455
msgid "Illegal register name"
msgstr "ÉÔÀµ¤Ê¥ì¥¸¥¹¥¿Ì¾"
-#: ../ops.c:4533
msgid ""
"\n"
"# Registers:\n"
@@ -4498,7 +4147,6 @@ msgstr ""
"\n"
"# ¥ì¥¸¥¹¥¿:\n"
-#: ../ops.c:4575
#, c-format
msgid "E574: Unknown register type %d"
msgstr "E574: ̤ÃΤΥ쥸¥¹¥¿·¿ %d ¤Ç¤¹"
@@ -4508,86 +4156,61 @@ msgid ""
"lines"
msgstr "E883: ¸¡º÷¥Ñ¥¿¡¼¥ó¤È¼°¥ì¥¸¥¹¥¿¤Ë¤Ï2¹Ô°Ê¾å¤ò´Þ¤á¤é¤ì¤Þ¤»¤ó"
-#: ../ops.c:5089
#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> Îó; "
+msgid "%ld Cols; "
+msgstr "%ld Îó; "
-#: ../ops.c:5097
#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"ÁªÂò %s%<PRId64> / %<PRId64> ¹Ô; %<PRId64> / %<PRId64> ñ¸ì; %<PRId64> / "
-"%<PRId64> ¥Ð¥¤¥È"
+msgid "Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes"
+msgstr "ÁªÂò %s%ld / %ld ¹Ô; %lld / %lld ñ¸ì; %lld / %lld ¥Ð¥¤¥È"
-#: ../ops.c:5105
#, c-format
msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
+"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of "
+"%lld Bytes"
msgstr ""
-"ÁªÂò %s%<PRId64> / %<PRId64> ¹Ô; %<PRId64> / %<PRId64> ñ¸ì; %<PRId64> / "
-"%<PRId64> ʸ»ú; %<PRId64> / %<PRId64> ¥Ð¥¤¥È"
+"ÁªÂò %s%ld / %ld ¹Ô; %lld / %lld ñ¸ì; %lld / %lld ʸ»ú; %lld / %lld ¥Ð¥¤¥È"
-#: ../ops.c:5123
#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
-msgstr ""
-"Îó %s / %s; ¹Ô %<PRId64> of %<PRId64>; ñ¸ì %<PRId64> / %<PRId64>; ¥Ð¥¤¥È "
-"%<PRId64> / %<PRId64>"
+msgid "Col %s of %s; Line %ld of %ld; Word %lld of %lld; Byte %lld of %lld"
+msgstr "Îó %s / %s; ¹Ô %ld of %ld; ñ¸ì %lld / %lld; ¥Ð¥¤¥È %lld / %lld"
-#: ../ops.c:5133
#, c-format
msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
+"Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte "
+"%lld of %lld"
msgstr ""
-"Îó %s / %s; ¹Ô %<PRId64> / %<PRId64>; ñ¸ì %<PRId64> / %<PRId64>; ʸ»ú "
-"%<PRId64> / %<PRId64>; ¥Ð¥¤¥È %<PRId64> of %<PRId64>"
+"Îó %s / %s; ¹Ô %ld / %ld; ñ¸ì %lld / %lld; ʸ»ú %lld / %lld; ¥Ð¥¤¥È %lld of "
+"%lld"
-#: ../ops.c:5146
#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> for BOM)"
+msgid "(+%ld for BOM)"
+msgstr "(+%ld for BOM)"
-#: ../option.c:1238
msgid "%<%f%h%m%=Page %N"
msgstr "%<%f%h%m%=%N ¥Ú¡¼¥¸"
-#: ../option.c:1574
msgid "Thanks for flying Vim"
msgstr "Vim ¤ò»È¤Ã¤Æ¤¯¤ì¤Æ¤¢¤ê¤¬¤È¤¦"
-#. found a mismatch: skip
-#: ../option.c:2698
msgid "E518: Unknown option"
msgstr "E518: ̤ÃΤΥª¥×¥·¥ç¥ó¤Ç¤¹"
-#: ../option.c:2709
msgid "E519: Option not supported"
msgstr "E519: ¥ª¥×¥·¥ç¥ó¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../option.c:2740
msgid "E520: Not allowed in a modeline"
msgstr "E520: modeline ¤Ç¤Ïµö²Ä¤µ¤ì¤Þ¤»¤ó"
-#: ../option.c:2815
msgid "E846: Key code not set"
msgstr "E846: ¥­¡¼¥³¡¼¥É¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../option.c:2924
msgid "E521: Number required after ="
msgstr "E521: = ¤Î¸å¤Ë¤Ï¿ô»ú¤¬É¬ÍפǤ¹"
-#: ../option.c:3226 ../option.c:3864
msgid "E522: Not found in termcap"
msgstr "E522: termcap Æâ¤Ë¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../option.c:3335
#, c-format
msgid "E539: Illegal character <%s>"
msgstr "E539: ÉÔÀµ¤Êʸ»ú¤Ç¤¹ <%s>"
@@ -4596,93 +4219,99 @@ msgstr "E539: ÉÔÀµ¤Êʸ»ú¤Ç¤¹ <%s>"
msgid "For option %s"
msgstr "¥ª¥×¥·¥ç¥ó: %s"
-#: ../option.c:3862
msgid "E529: Cannot set 'term' to empty string"
msgstr "E529: 'term' ¤Ë¤Ï¶õʸ»úÎó¤òÀßÄê¤Ç¤­¤Þ¤»¤ó"
-#: ../option.c:3885
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: GUI¤Ç¤Ï 'term' ¤òÊѹ¹¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: GUI¤ò¥¹¥¿¡¼¥È¤¹¤ë¤Ë¤Ï \":gui\" ¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤"
+
msgid "E589: 'backupext' and 'patchmode' are equal"
msgstr "E589: 'backupext' ¤È 'patchmode' ¤¬Æ±¤¸¤Ç¤¹"
-#: ../option.c:3964
msgid "E834: Conflicts with value of 'listchars'"
msgstr "E834: 'listchars'¤ÎÃͤËÌ·½â¤¬¤¢¤ê¤Þ¤¹"
-#: ../option.c:3966
msgid "E835: Conflicts with value of 'fillchars'"
msgstr "E835: 'fillchars'¤ÎÃͤËÌ·½â¤¬¤¢¤ê¤Þ¤¹"
-#: ../option.c:4163
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: GTK+2 GUI¤Ç¤ÏÊѹ¹¤Ç¤­¤Þ¤»¤ó"
+
msgid "E524: Missing colon"
msgstr "E524: ¥³¥í¥ó¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../option.c:4165
msgid "E525: Zero length string"
msgstr "E525: ʸ»úÎó¤ÎŤµ¤¬¥¼¥í¤Ç¤¹"
-#: ../option.c:4220
#, c-format
msgid "E526: Missing number after <%s>"
msgstr "E526: <%s> ¤Î¸å¤Ë¿ô»ú¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../option.c:4232
msgid "E527: Missing comma"
msgstr "E527: ¥«¥ó¥Þ¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../option.c:4239
msgid "E528: Must specify a ' value"
msgstr "E528: ' ¤ÎÃͤò»ØÄꤷ¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#: ../option.c:4271
msgid "E595: contains unprintable or wide character"
msgstr "E595: ɽ¼¨¤Ç¤­¤Ê¤¤Ê¸»ú¤«¥ï¥¤¥Éʸ»ú¤ò´Þ¤ó¤Ç¤¤¤Þ¤¹"
-#: ../option.c:4469
+msgid "E596: Invalid font(s)"
+msgstr "E596: ̵¸ú¤Ê¥Õ¥©¥ó¥È¤Ç¤¹"
+
+msgid "E597: can't select fontset"
+msgstr "E597: ¥Õ¥©¥ó¥È¥»¥Ã¥È¤òÁªÂò¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: ̵¸ú¤Ê¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ç¤¹"
+
+msgid "E533: can't select wide font"
+msgstr "E533: ¥ï¥¤¥É¥Õ¥©¥ó¥È¤òÁªÂò¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: ̵¸ú¤Ê¥ï¥¤¥É¥Õ¥©¥ó¥È¤Ç¤¹"
+
#, c-format
msgid "E535: Illegal character after <%c>"
msgstr "E535: <%c> ¤Î¸å¤ËÉÔÀµ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤¹"
-#: ../option.c:4534
msgid "E536: comma required"
msgstr "E536: ¥«¥ó¥Þ¤¬É¬ÍפǤ¹"
-#: ../option.c:4543
#, c-format
msgid "E537: 'commentstring' must be empty or contain %s"
msgstr "E537: 'commentstring' ¤Ï¶õ¤Ç¤¢¤ë¤« %s ¤ò´Þ¤àɬÍפ¬¤¢¤ê¤Þ¤¹"
-#: ../option.c:4928
+msgid "E538: No mouse support"
+msgstr "E538: ¥Þ¥¦¥¹¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤»¤ó"
+
msgid "E540: Unclosed expression sequence"
msgstr "E540: ¼°¤¬½ªÎ»¤·¤Æ¤¤¤Þ¤»¤ó"
-#: ../option.c:4932
msgid "E541: too many items"
msgstr "E541: Í×ÁǤ¬Â¿²á¤®¤Þ¤¹"
-#: ../option.c:4934
msgid "E542: unbalanced groups"
msgstr "E542: ¥°¥ë¡¼¥×¤¬Äà¹ç¤¤¤Þ¤»¤ó"
-#: ../option.c:5148
msgid "E590: A preview window already exists"
msgstr "E590: ¥×¥ì¥Ó¥å¡¼¥¦¥£¥ó¥É¥¦¤¬´û¤Ë¸ºß¤·¤Þ¤¹"
-#: ../option.c:5311
msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
msgstr ""
"W17: ¥¢¥é¥Ó¥¢Ê¸»ú¤Ë¤ÏUTF-8¤¬É¬ÍפʤΤÇ, ':set encoding=utf-8' ¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../option.c:5623
#, c-format
msgid "E593: Need at least %d lines"
msgstr "E593: ºÇÄã %d ¤Î¹Ô¿ô¤¬É¬ÍפǤ¹"
-#: ../option.c:5631
#, c-format
msgid "E594: Need at least %d columns"
msgstr "E594: ºÇÄã %d ¤Î¥«¥é¥àÉý¤¬É¬ÍפǤ¹"
-#: ../option.c:6011
#, c-format
msgid "E355: Unknown option: %s"
msgstr "E355: ̤ÃΤΥª¥×¥·¥ç¥ó¤Ç¤¹: %s"
@@ -4690,12 +4319,10 @@ msgstr "E355: ̤ÃΤΥª¥×¥·¥ç¥ó¤Ç¤¹: %s"
#. There's another character after zeros or the string
#. * is empty. In both cases, we are trying to set a
#. * num option using a string.
-#: ../option.c:6037
#, c-format
msgid "E521: Number required: &%s = '%s'"
msgstr "E521: ¿ô»ú¤¬É¬ÍפǤ¹: &%s = '%s'"
-#: ../option.c:6149
msgid ""
"\n"
"--- Terminal codes ---"
@@ -4703,7 +4330,6 @@ msgstr ""
"\n"
"--- üËö¥³¡¼¥É ---"
-#: ../option.c:6151
msgid ""
"\n"
"--- Global option values ---"
@@ -4711,7 +4337,6 @@ msgstr ""
"\n"
"--- ¥°¥í¡¼¥Ð¥ë¥ª¥×¥·¥ç¥óÃÍ ---"
-#: ../option.c:6153
msgid ""
"\n"
"--- Local option values ---"
@@ -4719,7 +4344,6 @@ msgstr ""
"\n"
"--- ¥í¡¼¥«¥ë¥ª¥×¥·¥ç¥óÃÍ ---"
-#: ../option.c:6155
msgid ""
"\n"
"--- Options ---"
@@ -4727,37 +4351,119 @@ msgstr ""
"\n"
"--- ¥ª¥×¥·¥ç¥ó ---"
-#: ../option.c:6816
msgid "E356: get_varp ERROR"
msgstr "E356: get_varp ¥¨¥é¡¼"
-#: ../option.c:7696
#, c-format
msgid "E357: 'langmap': Matching character missing for %s"
msgstr "E357: 'langmap': %s ¤ËÂбþ¤¹¤ëʸ»ú¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../option.c:7715
#, c-format
msgid "E358: 'langmap': Extra characters after semicolon: %s"
msgstr "E358: 'langmap': ¥»¥ß¥³¥í¥ó¤Î¸å¤Ë;ʬ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤¹: %s"
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"¥·¥§¥ë¤ò¼Â¹Ô¤Ç¤­¤Þ¤»¤ó "
+msgid "cannot open "
+msgstr "³«¤±¤Þ¤»¤ó "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: ¥¦¥£¥ó¥É¥¦¤ò³«¤±¤Þ¤»¤ó!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Amigados¤Î¥Ð¡¼¥¸¥ç¥ó 2.04¤«¤½¤ì°Ê¹ß¤¬É¬ÍפǤ¹\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "%s ¤Î¥Ð¡¼¥¸¥ç¥ó %ld ¤¬É¬ÍפǤ¹\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "NIL¤ò³«¤±¤Þ¤»¤ó:\n"
+
+msgid "Cannot create "
+msgstr "ºîÀ®¤Ç¤­¤Þ¤»¤ó "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim¤Ï %d ¤Ç½ªÎ»¤·¤Þ¤¹\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "¥³¥ó¥½¡¼¥ë¥â¡¼¥É¤òÊѹ¹¤Ç¤­¤Þ¤»¤ó?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: ¥³¥ó¥½¡¼¥ë¤Ç¤Ï¤Ê¤¤??\n"
+
+#. 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 "E244: Illegal quality name \"%s\" in font name \"%s\""
+msgstr "E244: ÉʼÁ̾ \"%s\" ¤ÏÉÔÀµ¤Ç¤¹ (¥Õ¥©¥ó¥È̾ \"%s\")"
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: '%c' ¤ÏÉÔÀµ¤Êʸ»ú¤Ç¤¹ (¥Õ¥©¥ó¥È̾ \"%s\")"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "X¥µ¡¼¥Ð¡¼¤Ø¤ÎÀܳ¤Ë %ld ¥ß¥êÉ䫤«¤ê¤Þ¤·¤¿"
-#: ../os/shell.c:439
msgid ""
"\n"
-"shell returned "
+"Vim: Got X error\n"
msgstr ""
"\n"
-"¥·¥§¥ë¤¬ÃͤòÊÖ¤·¤Þ¤·¤¿ "
+"Vim: X ¤Î¥¨¥é¡¼¤ò¸¡½Ð¤·¤Þ¤·¤¿r\n"
+
+msgid "Testing the X display failed"
+msgstr "X display ¤Î¥Á¥§¥Ã¥¯¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "Opening the X display timed out"
+msgstr "X display ¤Î open ¤¬¥¿¥¤¥à¥¢¥¦¥È¤·¤Þ¤·¤¿"
-#: ../os_unix.c:465 ../os_unix.c:471
msgid ""
"\n"
"Could not get security context for "
@@ -4765,7 +4471,6 @@ msgstr ""
"\n"
"¥»¥­¥å¥ê¥Æ¥£¥³¥ó¥Æ¥­¥¹¥È¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó "
-#: ../os_unix.c:479
msgid ""
"\n"
"Could not set security context for "
@@ -4781,223 +4486,293 @@ msgstr "¥»¥­¥å¥ê¥Æ¥£¥³¥ó¥Æ¥­¥¹¥È %s ¤ò %s ¤ËÀßÄê¤Ç¤­¤Þ¤»¤ó"
msgid "Could not get security context %s for %s. Removing it!"
msgstr "¥»¥­¥å¥ê¥Æ¥£¥³¥ó¥Æ¥­¥¹¥È %s ¤ò %s ¤«¤é¼èÆÀ¤Ç¤­¤Þ¤»¤ó. ºï½ü¤·¤Þ¤¹!"
-#: ../os_unix.c:1558 ../os_unix.c:1647
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"sh ¥·¥§¥ë¤ò¼Â¹Ô¤Ç¤­¤Þ¤»¤ó\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"¥·¥§¥ë¤¬ÃͤòÊÖ¤·¤Þ¤·¤¿ "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"¥Ñ¥¤¥×¤òºîÀ®¤Ç¤­¤Þ¤»¤ó\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"fork ¤Ç¤­¤Þ¤»¤ó\n"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"¥·¥§¥ë¤ò¼Â¹Ô¤Ç¤­¤Þ¤»¤ó "
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"¥³¥Þ¥ó¥É¤òÃæÃǤ·¤Þ¤·¤¿\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP ¤¬ICEÀܳ¤ò¼º¤¤¤Þ¤·¤¿"
+
#, c-format
msgid "dlerror = \"%s\""
msgstr "dlerror = \"%s\""
-#: ../path.c:1449
+msgid "Opening the X display failed"
+msgstr "X display ¤Î open ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP ¤¬save-yourselfÍ×µá¤ò½èÍý¤·¤Æ¤¤¤Þ¤¹"
+
+msgid "XSMP opening connection"
+msgstr "XSMP ¤¬Àܳ¤ò³«»Ï¤·¤Æ¤¤¤Þ¤¹"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP ICEÀܳ¤¬¼ºÇÔ¤·¤¿¤è¤¦¤Ç¤¹"
+
#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: path¤Ë¤Ï \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP SmcOpenConnection¤¬¼ºÇÔ¤·¤Þ¤·¤¿: %s"
+
+msgid "At line"
+msgstr "¹Ô"
+
+msgid "Could not load vim32.dll!"
+msgstr "vim32.dll ¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
+
+msgid "VIM Error"
+msgstr "VIM¥¨¥é¡¼"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "DLL¤«¤é´Ø¿ô¥Ý¥¤¥ó¥¿¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: ¥¤¥Ù¥ó¥È %s ¤ò¸¡ÃÎ\n"
+
+msgid "close"
+msgstr "ÊĤ¸¤ë"
+
+msgid "logoff"
+msgstr "¥í¥°¥ª¥Õ"
+
+msgid "shutdown"
+msgstr "¥·¥ã¥Ã¥È¥À¥¦¥ó"
+
+msgid "E371: Command not found"
+msgstr "E371: ¥³¥Þ¥ó¥É¤¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid ""
+"VIMRUN.EXE not found in your $PATH.\n"
+"External commands will not pause after completion.\n"
+"See :help win32-vimrun for more information."
+msgstr ""
+"VIMRUN.EXE¤¬ $PATH ¤ÎÃæ¤Ë¸«¤Ä¤«¤ê¤Þ¤»¤ó.\n"
+"³°Éô¥³¥Þ¥ó¥É¤Î½ªÎ»¸å¤Ë°ì»þÄä»ß¤ò¤·¤Þ¤»¤ó.\n"
+"¾ÜºÙ¤Ï :help win32-vimrun ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤."
+
+msgid "Vim Warning"
+msgstr "Vim¤Î·Ù¹ð"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "¥·¥§¥ë¤¬¥³¡¼¥É %d ¤Ç½ªÎ»¤·¤Þ¤·¤¿"
-#: ../quickfix.c:359
#, c-format
msgid "E372: Too many %%%c in format string"
msgstr "E372: ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ë %%%c ¤¬Â¿²á¤®¤Þ¤¹"
-#: ../quickfix.c:371
#, c-format
msgid "E373: Unexpected %%%c in format string"
msgstr "E373: ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ëͽ´ü¤»¤Ì %%%c ¤¬¤¢¤ê¤Þ¤·¤¿"
-#: ../quickfix.c:420
msgid "E374: Missing ] in format string"
msgstr "E374: ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ë ] ¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../quickfix.c:431
#, c-format
msgid "E375: Unsupported %%%c in format string"
msgstr "E375: ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ç¤Ï %%%c ¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤»¤ó"
-#: ../quickfix.c:448
#, c-format
msgid "E376: Invalid %%%c in format string prefix"
msgstr "E376: ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤ÎÁ°ÃÖ¤Ë̵¸ú¤Ê %%%c ¤¬¤¢¤ê¤Þ¤¹"
-#: ../quickfix.c:454
#, c-format
msgid "E377: Invalid %%%c in format string"
msgstr "E377: ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ë̵¸ú¤Ê %%%c ¤¬¤¢¤ê¤Þ¤¹"
#. nothing found
-#: ../quickfix.c:477
msgid "E378: 'errorformat' contains no pattern"
msgstr "E378: 'errorformat' ¤Ë¥Ñ¥¿¡¼¥ó¤¬»ØÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../quickfix.c:695
msgid "E379: Missing or empty directory name"
msgstr "E379: ¥Ç¥£¥ì¥¯¥È¥ê̾¤¬Ìµ¤¤¤«¶õ¤Ç¤¹"
-#: ../quickfix.c:1305
msgid "E553: No more items"
msgstr "E553: Í×ÁǤ¬¤â¤¦¤¢¤ê¤Þ¤»¤ó"
-#: ../quickfix.c:1674
+msgid "E924: Current window was closed"
+msgstr "E924: ¸½ºß¤Î¥¦¥£¥ó¥É¥¦¤¬ÊĤ¸¤é¤ì¤Þ¤·¤¿"
+
+msgid "E925: Current quickfix was changed"
+msgstr "E925: ¸½ºß¤Î quickfix ¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿"
+
+msgid "E926: Current location list was changed"
+msgstr "E926: ¸½ºß¤Î¥í¥±¡¼¥·¥ç¥ó¥ê¥¹¥È¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿"
+
#, c-format
msgid "(%d of %d)%s%s: "
msgstr "(%d of %d)%s%s: "
-#: ../quickfix.c:1676
msgid " (line deleted)"
msgstr " (¹Ô¤¬ºï½ü¤µ¤ì¤Þ¤·¤¿)"
-#: ../quickfix.c:1863
+#, c-format
+msgid "%serror list %d of %d; %d errors "
+msgstr "%s ¥¨¥é¡¼°ìÍ÷ %d of %d; %d ¸Ä¥¨¥é¡¼"
+
msgid "E380: At bottom of quickfix stack"
msgstr "E380: quickfix ¥¹¥¿¥Ã¥¯¤ÎËöÈø¤Ç¤¹"
-#: ../quickfix.c:1869
msgid "E381: At top of quickfix stack"
msgstr "E381: quickfix ¥¹¥¿¥Ã¥¯¤ÎÀèÆ¬¤Ç¤¹"
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "¥¨¥é¡¼°ìÍ÷ %d of %d; %d ¸Ä¥¨¥é¡¼"
+msgid "No entries"
+msgstr "¥¨¥ó¥È¥ê¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../quickfix.c:2427
msgid "E382: Cannot write, 'buftype' option is set"
msgstr "E382: 'buftype' ¥ª¥×¥·¥ç¥ó¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¤Î¤Ç½ñ¹þ¤ß¤Þ¤»¤ó"
-#: ../quickfix.c:2812
+msgid "Error file"
+msgstr "¥¨¥é¡¼¥Õ¥¡¥¤¥ë"
+
msgid "E683: File name missing or invalid pattern"
msgstr "E683: ¥Õ¥¡¥¤¥ë̾¤¬Ìµ¤¤¤«Ìµ¸ú¤Ê¥Ñ¥¿¡¼¥ó¤Ç¤¹"
-#: ../quickfix.c:2911
#, c-format
msgid "Cannot open file \"%s\""
msgstr "¥Õ¥¡¥¤¥ë \"%s\" ¤ò³«¤±¤Þ¤»¤ó"
-#: ../quickfix.c:3429
msgid "E681: Buffer is not loaded"
msgstr "E681: ¥Ð¥Ã¥Õ¥¡¤ÏÆÉ¤ß¹þ¤Þ¤ì¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../quickfix.c:3487
msgid "E777: String or List expected"
msgstr "E777: ʸ»úÎ󤫥ꥹ¥È¤¬É¬ÍפǤ¹"
-#: ../regexp.c:359
#, c-format
msgid "E369: invalid item in %s%%[]"
msgstr "E369: ̵¸ú¤Ê¹àÌܤǤ¹: %s%%[]"
#
-#: ../regexp.c:374
#, c-format
msgid "E769: Missing ] after %s["
msgstr "E769: %s[ ¤Î¸å¤Ë ] ¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../regexp.c:375
#, c-format
msgid "E53: Unmatched %s%%("
msgstr "E53: %s%%( ¤¬Äà¤ê¹ç¤Ã¤Æ¤¤¤Þ¤»¤ó"
-#: ../regexp.c:376
#, c-format
msgid "E54: Unmatched %s("
msgstr "E54: %s( ¤¬Äà¤ê¹ç¤Ã¤Æ¤¤¤Þ¤»¤ó"
-#: ../regexp.c:377
#, c-format
msgid "E55: Unmatched %s)"
msgstr "E55: %s) ¤¬Äà¤ê¹ç¤Ã¤Æ¤¤¤Þ¤»¤ó"
#
-#: ../regexp.c:378
msgid "E66: \\z( not allowed here"
msgstr "E66: \\z( ¤Ï¥³¥³¤Ç¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
#
-#: ../regexp.c:379
msgid "E67: \\z1 et al. not allowed here"
msgstr "E67: \\z1 ¤½¤Î¾¤Ï¥³¥³¤Ç¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
#
-#: ../regexp.c:380
#, c-format
msgid "E69: Missing ] after %s%%["
msgstr "E69: %s%%[ ¤Î¸å¤Ë ] ¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../regexp.c:381
#, c-format
msgid "E70: Empty %s%%[]"
msgstr "E70: %s%%[] ¤¬¶õ¤Ç¤¹"
-#: ../regexp.c:1209 ../regexp.c:1224
msgid "E339: Pattern too long"
msgstr "E339: ¥Ñ¥¿¡¼¥ó¤¬Ä¹²á¤®¤Þ¤¹"
-#: ../regexp.c:1371
msgid "E50: Too many \\z("
msgstr "E50: \\z( ¤¬Â¿²á¤®¤Þ¤¹"
-#: ../regexp.c:1378
#, c-format
msgid "E51: Too many %s("
msgstr "E51: %s( ¤¬Â¿²á¤®¤Þ¤¹"
-#: ../regexp.c:1427
msgid "E52: Unmatched \\z("
msgstr "E52: \\z( ¤¬Äà¤ê¹ç¤Ã¤Æ¤¤¤Þ¤»¤ó"
-#: ../regexp.c:1637
#, c-format
msgid "E59: invalid character after %s@"
msgstr "E59: %s@ ¤Î¸å¤ËÉÔÀµ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤·¤¿"
-#: ../regexp.c:1672
#, c-format
msgid "E60: Too many complex %s{...}s"
msgstr "E60: Ê£»¨¤Ê %s{...} ¤¬Â¿²á¤®¤Þ¤¹"
-#: ../regexp.c:1687
#, c-format
msgid "E61: Nested %s*"
msgstr "E61:%s* ¤¬Æþ¤ì»Ò¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../regexp.c:1690
#, c-format
msgid "E62: Nested %s%c"
msgstr "E62:%s%c ¤¬Æþ¤ì»Ò¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹"
#
-#: ../regexp.c:1800
msgid "E63: invalid use of \\_"
msgstr "E63: \\_ ¤Î̵¸ú¤Ê»ÈÍÑÊýË¡¤Ç¤¹"
-#: ../regexp.c:1850
#, c-format
msgid "E64: %s%c follows nothing"
msgstr "E64:%s%c ¤Î¸å¤Ë¤Ê¤Ë¤â¤¢¤ê¤Þ¤»¤ó"
#
-#: ../regexp.c:1902
msgid "E65: Illegal back reference"
msgstr "E65: ÉÔÀµ¤Ê¸åÊý»²¾È¤Ç¤¹"
#
-#: ../regexp.c:1943
msgid "E68: Invalid character after \\z"
msgstr "E68: \\z ¤Î¸å¤ËÉÔÀµ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤·¤¿"
#
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
#, c-format
msgid "E678: Invalid character after %s%%[dxouU]"
msgstr "E678: %s%%[dxouU] ¤Î¸å¤ËÉÔÀµ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤·¤¿"
#
-#: ../regexp.c:2107
#, c-format
msgid "E71: Invalid character after %s%%"
msgstr "E71: %s%% ¤Î¸å¤ËÉÔÀµ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤·¤¿"
-#: ../regexp.c:3017
#, c-format
msgid "E554: Syntax error in %s{...}"
msgstr "E554: %s{...} Æâ¤Ëʸˡ¥¨¥é¡¼¤¬¤¢¤ê¤Þ¤¹"
-#: ../regexp.c:3805
msgid "External submatches:\n"
msgstr "³°Éô¤ÎÉôʬ³ºÅö:\n"
@@ -5005,7 +4780,6 @@ msgstr "³°Éô¤ÎÉôʬ³ºÅö:\n"
msgid "E888: (NFA regexp) cannot repeat %s"
msgstr "E888: (NFA Àµµ¬É½¸½) ·«¤êÊÖ¤»¤Þ¤»¤ó %s"
-#: ../regexp.c:7022
msgid ""
"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
"used "
@@ -5016,62 +4790,54 @@ msgstr ""
msgid "Switching to backtracking RE engine for pattern: "
msgstr "¼¡¤Î¥Ñ¥¿¡¼¥ó¤Ë¥Ð¥Ã¥¯¥È¥é¥Ã¥­¥ó¥° RE ¥¨¥ó¥¸¥ó¤òŬÍѤ·¤Þ¤¹: "
-#: ../regexp_nfa.c:239
msgid "E865: (NFA) Regexp end encountered prematurely"
msgstr "E865: (NFA) ´üÂÔ¤è¤êÁ᤯Àµµ¬É½¸½¤Î½ªÃ¼¤ËÅþ㤷¤Þ¤·¤¿"
-#: ../regexp_nfa.c:240
#, c-format
msgid "E866: (NFA regexp) Misplaced %c"
msgstr "E866: (NFA Àµµ¬É½¸½) °ÌÃÖ¤¬¸í¤Ã¤Æ¤¤¤Þ¤¹: %c"
-#: ../regexp_nfa.c:242
+#
#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr "E877: (NFA Àµµ¬É½¸½) ̵¸ú¤Êʸ»ú¥¯¥é¥¹: %<PRId64>"
+msgid "E877: (NFA regexp) Invalid character class: %ld"
+msgstr "E877: (NFA Àµµ¬É½¸½) ̵¸ú¤Êʸ»ú¥¯¥é¥¹: %ld"
-#: ../regexp_nfa.c:1261
#, c-format
msgid "E867: (NFA) Unknown operator '\\z%c'"
msgstr "E867: (NFA) ̤ÃΤΥª¥Ú¥ì¡¼¥¿¤Ç¤¹: '\\z%c'"
-#: ../regexp_nfa.c:1387
#, c-format
msgid "E867: (NFA) Unknown operator '\\%%%c'"
msgstr "E867: (NFA) ̤ÃΤΥª¥Ú¥ì¡¼¥¿¤Ç¤¹: '\\%%%c'"
-#: ../regexp_nfa.c:1802
+#. 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'"
-#: ../regexp_nfa.c:1831
msgid "E870: (NFA regexp) Error reading repetition limits"
msgstr "E870: (NFA Àµµ¬É½¸½) ·«¤êÊÖ¤·¤ÎÀ©¸Â²ó¿ô¤òÆÉ¹þÃæ¤Ë¥¨¥é¡¼"
#. Can't have a multi follow a multi.
-#: ../regexp_nfa.c:1895
msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
msgstr "E871: (NFA Àµµ¬É½¸½) ·«¤êÊÖ¤· ¤Î¸å¤Ë ·«¤êÊÖ¤· ¤Ï¤Ç¤­¤Þ¤»¤ó!"
#. Too many `('
-#: ../regexp_nfa.c:2037
msgid "E872: (NFA regexp) Too many '('"
msgstr "E872: (NFA Àµµ¬É½¸½) '(' ¤¬Â¿²á¤®¤Þ¤¹"
-#: ../regexp_nfa.c:2042
msgid "E879: (NFA regexp) Too many \\z("
msgstr "E879: (NFA Àµµ¬É½¸½) \\z( ¤¬Â¿²á¤®¤Þ¤¹"
-#: ../regexp_nfa.c:2066
msgid "E873: (NFA regexp) proper termination error"
msgstr "E873: (NFA Àµµ¬É½¸½) ½ªÃ¼µ­¹æ¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../regexp_nfa.c:2599
msgid "E874: (NFA) Could not pop the stack !"
msgstr "E874: (NFA) ¥¹¥¿¥Ã¥¯¤ò¥Ý¥Ã¥×¤Ç¤­¤Þ¤»¤ó!"
-#: ../regexp_nfa.c:3298
msgid ""
"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
"left on stack"
@@ -5079,177 +4845,136 @@ msgstr ""
"E875: (NFA Àµµ¬É½¸½) (¸åÃÖʸ»úÎó¤òNFA¤ËÊÑ´¹Ãæ¤Ë) ¥¹¥¿¥Ã¥¯¤Ë»Ä¤µ¤ì¤¿¥¹¥Æ¡¼¥È¤¬"
"¿²á¤®¤Þ¤¹"
-#: ../regexp_nfa.c:3302
msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
msgstr "E876: (NFA Àµµ¬É½¸½) NFAÁ´ÂΤòÊݸ¤¹¤ë¤Ë¤Ï¶õ¤­¥¹¥Ú¡¼¥¹¤¬Â­¤ê¤Þ¤»¤ó"
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
+msgid "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Àµµ¬É½¸½¥¨¥ó¥¸¥óÍÑ¤Î¥í¥°¥Õ¥¡¥¤¥ë¤ò½ñ¹þÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó¡£¥í¥°¤Ïɸ½à½ÐÎϤË"
"½ÐÎϤ·¤Þ¤¹¡£"
-#: ../regexp_nfa.c:4840
#, c-format
msgid "(NFA) COULD NOT OPEN %s !"
msgstr "(NFA) ¥í¥°¥Õ¥¡¥¤¥ë %s ¤ò³«¤±¤Þ¤»¤ó!"
-#: ../regexp_nfa.c:6049
msgid "Could not open temporary log file for writing "
msgstr "NFAÀµµ¬É½¸½¥¨¥ó¥¸¥óÍÑ¤Î¥í¥°¥Õ¥¡¥¤¥ë¤ò½ñ¹þÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó¡£"
-#: ../screen.c:7435
msgid " VREPLACE"
msgstr " ²¾ÁÛÃÖ´¹"
-#: ../screen.c:7437
msgid " REPLACE"
msgstr " ÃÖ´¹"
-#: ../screen.c:7440
msgid " REVERSE"
msgstr " ȿž"
-#: ../screen.c:7441
msgid " INSERT"
msgstr " ÁÞÆþ"
-#: ../screen.c:7443
msgid " (insert)"
msgstr " (ÁÞÆþ)"
-#: ../screen.c:7445
msgid " (replace)"
msgstr " (ÃÖ´¹)"
-#: ../screen.c:7447
msgid " (vreplace)"
msgstr " (²¾ÁÛÃÖ´¹)"
-#: ../screen.c:7449
msgid " Hebrew"
msgstr " ¥Ø¥Ö¥é¥¤"
-#: ../screen.c:7454
msgid " Arabic"
msgstr " ¥¢¥é¥Ó¥¢"
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (¸À¸ì)"
-
-#: ../screen.c:7459
msgid " (paste)"
msgstr " (ޤêÉÕ¤±)"
-#: ../screen.c:7469
msgid " VISUAL"
msgstr " ¥Ó¥¸¥å¥¢¥ë"
-#: ../screen.c:7470
msgid " VISUAL LINE"
msgstr " ¥Ó¥¸¥å¥¢¥ë ¹Ô"
-#: ../screen.c:7471
msgid " VISUAL BLOCK"
msgstr " ¥Ó¥¸¥å¥¢¥ë ¶ë·Á"
-#: ../screen.c:7472
msgid " SELECT"
msgstr " ¥»¥ì¥¯¥È"
-#: ../screen.c:7473
msgid " SELECT LINE"
msgstr " ¹Ô»Ø¸þÁªÂò"
-#: ../screen.c:7474
msgid " SELECT BLOCK"
msgstr " ¶ë·ÁÁªÂò"
-#: ../screen.c:7486 ../screen.c:7541
msgid "recording"
msgstr "µ­Ï¿Ãæ"
-#: ../search.c:487
#, c-format
msgid "E383: Invalid search string: %s"
msgstr "E383: ̵¸ú¤Ê¸¡º÷ʸ»úÎó¤Ç¤¹: %s"
-#: ../search.c:832
#, c-format
msgid "E384: search hit TOP without match for: %s"
msgstr "E384: ¾å¤Þ¤Ç¸¡º÷¤·¤Þ¤·¤¿¤¬³ºÅö²Õ½ê¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../search.c:835
#, c-format
msgid "E385: search hit BOTTOM without match for: %s"
msgstr "E385: ²¼¤Þ¤Ç¸¡º÷¤·¤Þ¤·¤¿¤¬³ºÅö²Õ½ê¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../search.c:1200
msgid "E386: Expected '?' or '/' after ';'"
msgstr "E386: ';' ¤Î¤¢¤È¤Ë¤Ï '?' ¤« '/' ¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë"
-#: ../search.c:4085
msgid " (includes previously listed match)"
msgstr " (Á°¤ËÎóµó¤·¤¿³ºÅö²Õ½ê¤ò´Þ¤à)"
#. cursor at status line
-#: ../search.c:4104
msgid "--- Included files "
msgstr "--- ¥¤¥ó¥¯¥ë¡¼¥É¤µ¤ì¤¿¥Õ¥¡¥¤¥ë "
-#: ../search.c:4106
msgid "not found "
msgstr "¸«¤Ä¤«¤ê¤Þ¤»¤ó "
-#: ../search.c:4107
msgid "in path ---\n"
msgstr "¥Ñ¥¹¤Ë ----\n"
-#: ../search.c:4168
msgid " (Already listed)"
msgstr " (´û¤ËÎóµó)"
-#: ../search.c:4170
msgid " NOT FOUND"
msgstr " ¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../search.c:4211
#, c-format
msgid "Scanning included file: %s"
msgstr "¥¤¥ó¥¯¥ë¡¼¥É¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤ò¥¹¥­¥ã¥óÃæ: %s"
-#: ../search.c:4216
#, c-format
msgid "Searching included file %s"
msgstr "¥¤¥ó¥¯¥ë¡¼¥É¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤ò¥¹¥­¥ã¥óÃæ %s"
-#: ../search.c:4405
msgid "E387: Match is on current line"
msgstr "E387: ¸½ºß¹Ô¤Ë³ºÅö¤¬¤¢¤ê¤Þ¤¹"
-#: ../search.c:4517
msgid "All included files were found"
msgstr "Á´¤Æ¤Î¥¤¥ó¥¯¥ë¡¼¥É¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤·¤¿"
-#: ../search.c:4519
msgid "No included files"
msgstr "¥¤¥ó¥¯¥ë¡¼¥É¥Õ¥¡¥¤¥ë¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../search.c:4527
msgid "E388: Couldn't find definition"
msgstr "E388: ÄêµÁ¤ò¸«¤Ä¤±¤é¤ì¤Þ¤»¤ó"
-#: ../search.c:4529
msgid "E389: Couldn't find pattern"
msgstr "E389: ¥Ñ¥¿¡¼¥ó¤ò¸«¤Ä¤±¤é¤ì¤Þ¤»¤ó"
-#: ../search.c:4668
msgid "Substitute "
msgstr "Substitute "
-#: ../search.c:4681
#, c-format
msgid ""
"\n"
@@ -5260,99 +4985,131 @@ msgstr ""
"# ºÇ¸å¤Î %s¸¡º÷¥Ñ¥¿¡¼¥ó:\n"
"~"
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: ¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤Î½ñ¼°¥¨¥é¡¼¤Ç¤¹"
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: ¥¹¥Ú¥ë¥Á¥§¥Ã¥¯¤Ï̵¸ú²½¤µ¤ì¤Æ¤¤¤Þ¤¹"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
+msgstr ""
+"·Ù¹ð: ñ¸ì¥ê¥¹¥È \"%s_%s.spl\" ¤ª¤è¤Ó \"%s_ascii.spl\" ¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr ""
+"·Ù¹ð: ñ¸ì¥ê¥¹¥È \"%s.%s.spl\" ¤ª¤è¤Ó \"%s.ascii.spl\" ¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+
+msgid "E797: SpellFileMissing autocommand deleted buffer"
+msgstr "E797: autocommand ¤Î SpellFileMissing ¤¬¥Ð¥Ã¥Õ¥¡¤òºï½ü¤·¤Þ¤·¤¿"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "·Ù¹ð9: %s ¤È¤¤¤¦ÈϰϤϥµ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+msgid "Sorry, no suggestions"
+msgstr "»Äǰ¤Ç¤¹¤¬, ½¤Àµ¸õÊä¤Ï¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "»Äǰ¤Ç¤¹¤¬, ½¤Àµ¸õÊä¤Ï %ld ¸Ä¤·¤«¤¢¤ê¤Þ¤»¤ó"
+
+#. 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"
-#: ../spell.c:952
msgid "E758: Truncated spell file"
msgstr "E758: ¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤¬ÀÚ¼è¤é¤ì¤Æ¤¤¤ë¤è¤¦¤Ç¤¹"
-#: ../spell.c:953
#, c-format
msgid "Trailing text in %s line %d: %s"
msgstr "%s (%d ¹ÔÌÜ) ¤Ë³¤¯¥Æ¥­¥¹¥È: %s"
-#: ../spell.c:954
#, c-format
msgid "Affix name too long in %s line %d: %s"
msgstr "%s (%d ¹ÔÌÜ) ¤Î affix ̾¤¬Ä¹²á¤®¤Þ¤¹: %s"
-#: ../spell.c:955
msgid "E761: Format error in affix file FOL, LOW or UPP"
msgstr ""
"E761: affix¥Õ¥¡¥¤¥ë¤Î FOL, LOW ¤â¤·¤¯¤Ï UPP ¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤Ë¥¨¥é¡¼¤¬¤¢¤ê¤Þ¤¹"
-#: ../spell.c:957
msgid "E762: Character in FOL, LOW or UPP is out of range"
msgstr "E762: FOL, LOW ¤â¤·¤¯¤Ï UPP ¤Îʸ»ú¤¬Èϰϳ°¤Ç¤¹"
-#: ../spell.c:958
msgid "Compressing word tree..."
msgstr "ñ¸ì¥Ä¥ê¡¼¤ò°µ½Ì¤·¤Æ¤¤¤Þ¤¹..."
-#: ../spell.c:1951
-msgid "E756: Spell checking is not enabled"
-msgstr "E756: ¥¹¥Ú¥ë¥Á¥§¥Ã¥¯¤Ï̵¸ú²½¤µ¤ì¤Æ¤¤¤Þ¤¹"
-
-#: ../spell.c:2249
-#, c-format
-msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
-msgstr ""
-"·Ù¹ð: ñ¸ì¥ê¥¹¥È \"%s.%s.spl\" ¤ª¤è¤Ó \"%s.ascii.spl\" ¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-
-#: ../spell.c:2473
#, c-format
msgid "Reading spell file \"%s\""
msgstr "¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë \"%s\" ¤òÆÉ¹þÃæ"
-#: ../spell.c:2496
msgid "E757: This does not look like a spell file"
msgstr "E757: ¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤Ç¤Ï¤Ê¤¤¤è¤¦¤Ç¤¹"
-#: ../spell.c:2501
msgid "E771: Old spell file, needs to be updated"
msgstr "E771: ¸Å¤¤¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤Ê¤Î¤Ç, ¥¢¥Ã¥×¥Ç¡¼¥È¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../spell.c:2504
msgid "E772: Spell file is for newer version of Vim"
msgstr "E772: ¤è¤ê¿·¤·¤¤¥Ð¡¼¥¸¥ç¥ó¤Î Vim ÍѤΥ¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤Ç¤¹"
-#: ../spell.c:2602
msgid "E770: Unsupported section in spell file"
msgstr "E770: ¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤Ë¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤¥»¥¯¥·¥ç¥ó¤¬¤¢¤ê¤Þ¤¹"
-#: ../spell.c:3762
#, c-format
-msgid "Warning: region %s not supported"
-msgstr "·Ù¹ð9: %s ¤È¤¤¤¦ÈϰϤϥµ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: .sug ¥Õ¥¡¥¤¥ë¤Ç¤Ï¤Ê¤¤¤è¤¦¤Ç¤¹: %s"
+
+#, 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"
-#: ../spell.c:4550
#, c-format
msgid "Reading affix file %s ..."
msgstr "affix ¥Õ¥¡¥¤¥ë %s ¤òÆÉ¹þÃæ..."
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
msgid "Conversion failure for word in %s line %d: %s"
msgstr "%s (%d ¹ÔÌÜ) ¤Îñ¸ì¤òÊÑ´¹¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿: %s"
-#: ../spell.c:4630 ../spell.c:6170
#, c-format
msgid "Conversion in %s not supported: from %s to %s"
msgstr "%s Æâ¤Î¼¡¤ÎÊÑ´¹¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó: %s ¤«¤é %s ¤Ø"
-#: ../spell.c:4642
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "%s Æâ¤ÎÊÑ´¹¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
#, c-format
msgid "Invalid value for FLAG in %s line %d: %s"
msgstr "%s Æâ¤Î %d ¹ÔÌܤΠFLAG ¤Ë̵¸ú¤ÊÃͤ¬¤¢¤ê¤Þ¤¹: %s"
-#: ../spell.c:4655
#, c-format
msgid "FLAG after using flags in %s line %d: %s"
msgstr "%s Æâ¤Î %d ¹ÔÌܤ˥ե饰¤ÎÆó½Å»ÈÍѤ¬¤¢¤ê¤Þ¤¹: %s"
-#: ../spell.c:4723
#, c-format
msgid ""
"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
@@ -5361,7 +5118,6 @@ msgstr ""
"%s ¤Î %d ¹ÔÌܤΠPFX ¹àÌܤθå¤Î COMPOUNDFORBIDFLAG ¤ÎÄêµÁ¤Ï¸í¤Ã¤¿·ë²Ì¤òÀ¸¤¸¤ë"
"¤³¤È¤¬¤¢¤ê¤Þ¤¹"
-#: ../spell.c:4731
#, c-format
msgid ""
"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
@@ -5370,43 +5126,35 @@ msgstr ""
"%s ¤Î %d ¹ÔÌܤΠPFX ¹àÌܤθå¤Î COMPOUNDPERMITFLAG ¤ÎÄêµÁ¤Ï¸í¤Ã¤¿·ë²Ì¤òÀ¸¤¸¤ë"
"¤³¤È¤¬¤¢¤ê¤Þ¤¹"
-#: ../spell.c:4747
#, c-format
msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
msgstr "COMPOUNDRULES ¤ÎÃͤ˸í¤ê¤¬¤¢¤ê¤Þ¤¹. ¥Õ¥¡¥¤¥ë %s ¤Î %d ¹ÔÌÜ: %s"
-#: ../spell.c:4771
#, c-format
msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠCOMPOUNDWORDMAX ¤ÎÃͤ˸í¤ê¤¬¤¢¤ê¤Þ¤¹: %s"
-#: ../spell.c:4777
#, c-format
msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠCOMPOUNDMIN ¤ÎÃͤ˸í¤ê¤¬¤¢¤ê¤Þ¤¹: %s"
-#: ../spell.c:4783
#, c-format
msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠCOMPOUNDSYLMAX ¤ÎÃͤ˸í¤ê¤¬¤¢¤ê¤Þ¤¹: %s"
-#: ../spell.c:4795
#, c-format
msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠCHECKCOMPOUNDPATTERN ¤ÎÃͤ˸í¤ê¤¬¤¢¤ê¤Þ¤¹: %s"
-#: ../spell.c:4847
#, c-format
msgid "Different combining flag in continued affix block in %s line %d: %s"
msgstr ""
"%s ¤Î %d ¹ÔÌܤΠϢ³ affix ¥Ö¥í¥Ã¥¯¤Î¥Õ¥é¥°¤ÎÁȹ礻¤Ë°ã¤¤¤¬¤¢¤ê¤Þ¤¹: %s"
-#: ../spell.c:4850
#, c-format
msgid "Duplicate affix in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌÜ¤Ë ½ÅÊ£¤·¤¿ affix ¤ò¸¡½Ð¤·¤Þ¤·¤¿: %s"
-#: ../spell.c:4871
#, c-format
msgid ""
"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
@@ -5415,308 +5163,206 @@ msgstr ""
"%s ¤Î %d ¹ÔÌܤΠaffix ¤Ï BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST "
"¤Ë»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤: %s"
-#: ../spell.c:4893
#, c-format
msgid "Expected Y or N in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌÜ¤Ç¤Ï Y ¤« N ¤¬É¬ÍפǤ¹: %s"
-#: ../spell.c:4968
#, c-format
msgid "Broken condition in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠ¾ò·ï¤Ï²õ¤ì¤Æ¤¤¤Þ¤¹: %s"
-#: ../spell.c:5091
#, c-format
msgid "Expected REP(SAL) count in %s line %d"
msgstr "%s ¤Î %d ¹ÔÌÜ¤Ë¤Ï REP(SAL) ¤Î²ó¿ô¤¬É¬ÍפǤ¹"
-#: ../spell.c:5120
#, c-format
msgid "Expected MAP count in %s line %d"
msgstr "%s ¤Î %d ¹ÔÌÜ¤Ë¤Ï MAP ¤Î²ó¿ô¤¬É¬ÍפǤ¹"
-#: ../spell.c:5132
#, c-format
msgid "Duplicate character in MAP in %s line %d"
msgstr "%s ¤Î %d ¹ÔÌܤΠMAP ¤Ë½ÅÊ£¤·¤¿Ê¸»ú¤¬¤¢¤ê¤Þ¤¹"
-#: ../spell.c:5176
#, c-format
msgid "Unrecognized or duplicate item in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌÜ¤Ë Ç§¼±¤Ç¤­¤Ê¤¤¤«½ÅÊ£¤·¤¿¹àÌܤ¬¤¢¤ê¤Þ¤¹: %s"
-#: ../spell.c:5197
#, c-format
msgid "Missing FOL/LOW/UPP line in %s"
msgstr "%s ¹ÔÌÜ¤Ë FOL/LOW/UPP ¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../spell.c:5220
msgid "COMPOUNDSYLMAX used without SYLLABLE"
msgstr "SYLLABLE ¤¬»ØÄꤵ¤ì¤Ê¤¤ COMPOUNDSYLMAX"
-#: ../spell.c:5236
msgid "Too many postponed prefixes"
msgstr "ÃÙ±ä¸åÃÖ»Ò¤¬Â¿²á¤®¤Þ¤¹"
-#: ../spell.c:5238
msgid "Too many compound flags"
msgstr "Ê£¹ç¥Õ¥é¥°¤¬Â¿²á¤®¤Þ¤¹"
-#: ../spell.c:5240
msgid "Too many postponed prefixes and/or compound flags"
msgstr "ÃÙ±ä¸åÃÖ»Ò ¤È/¤â¤·¤¯¤Ï Ê£¹ç¥Õ¥é¥°¤¬Â¿²á¤®¤Þ¤¹"
-#: ../spell.c:5250
#, c-format
msgid "Missing SOFO%s line in %s"
msgstr "SOFO%s ¹Ô¤¬ %s ¤Ë¤¢¤ê¤Þ¤»¤ó"
-#: ../spell.c:5253
#, c-format
msgid "Both SAL and SOFO lines in %s"
msgstr "SAL¹Ô ¤È SOFO¹Ô ¤¬ %s ¤ÇξÊý»ØÄꤵ¤ì¤Æ¤¤¤Þ¤¹"
-#: ../spell.c:5331
#, c-format
msgid "Flag is not a number in %s line %d: %s"
msgstr "%s ¤Î %d ¹Ô¤Î ¥Õ¥é¥°¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó: %s"
-#: ../spell.c:5334
#, c-format
msgid "Illegal flag in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠ¥Õ¥é¥°¤¬ÉÔÀµ¤Ç¤¹: %s"
-#: ../spell.c:5493 ../spell.c:5501
#, c-format
msgid "%s value differs from what is used in another .aff file"
msgstr "ÃÍ %s ¤Ï¾¤Î .aff ¥Õ¥¡¥¤¥ë¤Ç»ÈÍѤµ¤ì¤¿¤Î¤È°Û¤Ê¤ê¤Þ¤¹"
-#: ../spell.c:5602
#, c-format
msgid "Reading dictionary file %s ..."
msgstr "¼­½ñ¥Õ¥¡¥¤¥ë %s ¤ò¥¹¥­¥ã¥óÃæ..."
-#: ../spell.c:5611
#, c-format
msgid "E760: No word count in %s"
msgstr "E760: %s ¤Ë¤Ïñ¸ì¿ô¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../spell.c:5669
#, c-format
msgid "line %6d, word %6d - %s"
msgstr "¹Ô %6d, ñ¸ì %6d - %s"
-#: ../spell.c:5691
#, c-format
msgid "Duplicate word in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌÜ¤Ç ½Åʣñ¸ì¤¬¸«¤Ä¤«¤ê¤Þ¤·¤¿: %s"
-#: ../spell.c:5694
#, c-format
msgid "First duplicate word in %s line %d: %s"
msgstr "½ÅÊ£¤Î¤¦¤ÁºÇ½é¤Îñ¸ì¤Ï %s ¤Î %d ¹ÔÌܤǤ¹: %s"
-#: ../spell.c:5746
#, c-format
msgid "%d duplicate word(s) in %s"
msgstr "%d ¸Ä¤Îñ¸ì¤¬¸«¤Ä¤«¤ê¤Þ¤·¤¿ (%s Æâ)"
-#: ../spell.c:5748
#, c-format
msgid "Ignored %d word(s) with non-ASCII characters in %s"
msgstr "ÈóASCIIʸ»ú¤ò´Þ¤à %d ¸Ä¤Îñ¸ì¤ò̵»ë¤·¤Þ¤·¤¿ (%s Æâ)"
-#: ../spell.c:6115
#, c-format
msgid "Reading word file %s ..."
msgstr "ɸ½àÆþÎϤ«¤éÆÉ¹þ¤ßÃæ %s ..."
-#: ../spell.c:6155
#, c-format
msgid "Duplicate /encoding= line ignored in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠ½ÅÊ£¤·¤¿ /encoding= ¹Ô¤ò̵»ë¤·¤Þ¤·¤¿: %s"
-#: ../spell.c:6159
#, c-format
msgid "/encoding= line after word ignored in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠñ¸ì¤Î¸å¤Î /encoding= ¹Ô¤ò̵»ë¤·¤Þ¤·¤¿: %s"
-#: ../spell.c:6180
#, c-format
msgid "Duplicate /regions= line ignored in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠ½ÅÊ£¤·¤¿ /regions= ¹Ô¤ò̵»ë¤·¤Þ¤·¤¿: %s"
-#: ../spell.c:6185
#, c-format
msgid "Too many regions in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌÜ, ÈϰϻØÄ꤬¿²á¤®¤Þ¤¹: %s"
-#: ../spell.c:6198
#, c-format
msgid "/ line ignored in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠ½ÅÊ£¤·¤¿ / ¹Ô¤ò̵»ë¤·¤Þ¤·¤¿: %s"
-#: ../spell.c:6224
#, c-format
msgid "Invalid region nr in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌÜ Ìµ¸ú¤Ê nr Îΰè¤Ç¤¹: %s"
-#: ../spell.c:6230
#, c-format
msgid "Unrecognized flags in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌÜ Ç§¼±ÉÔǽ¤Ê¥Õ¥é¥°¤Ç¤¹: %s"
-#: ../spell.c:6257
#, c-format
msgid "Ignored %d words with non-ASCII characters"
msgstr "ÈóASCIIʸ»ú¤ò´Þ¤à %d ¸Ä¤Îñ¸ì¤ò̵»ë¤·¤Þ¤·¤¿"
-#: ../spell.c:6656
+msgid "E845: Insufficient memory, word list will be incomplete"
+msgstr "E845: ¥á¥â¥ê¤¬Â­¤ê¤Ê¤¤¤Î¤Ç¡¢Ã±¸ì¥ê¥¹¥È¤ÏÉÔ´°Á´¤Ç¤¹"
+
#, c-format
msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
msgstr "¥Î¡¼¥É %d ¸Ä(Á´ %d ¸ÄÃæ) ¤ò°µ½Ì¤·¤Þ¤·¤¿; »Ä¤ê %d (%d%%)"
-#: ../spell.c:7340
msgid "Reading back spell file..."
msgstr "¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤òµÕÆÉ¹þÃæ"
-#. Go through the trie of good words, soundfold each word and add it to
-#. the soundfold trie.
-#: ../spell.c:7357
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
msgid "Performing soundfolding..."
msgstr "²»À¼¾ö¹þ¤ß¤ò¼Â¹ÔÃæ..."
-#: ../spell.c:7368
#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "²»À¼¾ö¹þ¤ß¸å¤ÎÁíñ¸ì¿ô: %<PRId64>"
+msgid "Number of words after soundfolding: %ld"
+msgstr "²»À¼¾ö¹þ¤ß¸å¤ÎÁíñ¸ì¿ô: %ld"
-#: ../spell.c:7476
#, c-format
msgid "Total number of words: %d"
msgstr "Áíñ¸ì¿ô: %d"
-#: ../spell.c:7655
#, c-format
msgid "Writing suggestion file %s ..."
msgstr "½¤Àµ¸õÊä¥Õ¥¡¥¤¥ë \"%s\" ¤ò½ñ¹þ¤ßÃæ..."
-#: ../spell.c:7707 ../spell.c:7927
#, c-format
msgid "Estimated runtime memory use: %d bytes"
msgstr "¿äÄê¥á¥â¥ê»ÈÍÑÎÌ: %d ¥Ð¥¤¥È"
-#: ../spell.c:7820
msgid "E751: Output file name must not have region name"
msgstr "E751: ½ÐÎÏ¥Õ¥¡¥¤¥ë̾¤Ë¤ÏÈϰÏ̾¤ò´Þ¤á¤é¤ì¤Þ¤»¤ó"
-#: ../spell.c:7822
msgid "E754: Only up to 8 regions supported"
msgstr "E754: ÈÏ°Ï¤Ï 8 ¸Ä¤Þ¤Ç¤·¤«¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../spell.c:7846
#, c-format
msgid "E755: Invalid region in %s"
msgstr "E755: ̵¸ú¤ÊÈϰϤǤ¹: %s"
-#: ../spell.c:7907
msgid "Warning: both compounding and NOBREAK specified"
msgstr "·Ù¹ð: Ê£¹ç¥Õ¥é¥°¤È NOBREAK ¤¬Î¾Êý¤È¤â»ØÄꤵ¤ì¤Þ¤·¤¿"
-#: ../spell.c:7920
#, c-format
msgid "Writing spell file %s ..."
msgstr "¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë %s ¤ò½ñ¹þ¤ßÃæ..."
-#: ../spell.c:7925
msgid "Done!"
msgstr "¼Â¹Ô¤·¤Þ¤·¤¿!"
-#: ../spell.c:8034
#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: 'spellfile' ¤Ë¤Ï %<PRId64> ¸Ä¤Î¥¨¥ó¥È¥ê¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' ¤Ë¤Ï %ld ¸Ä¤Î¥¨¥ó¥È¥ê¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../spell.c:8074
#, c-format
msgid "Word '%.*s' removed from %s"
msgstr "ñ¸ì '%.*s' ¤¬ %s ¤«¤éºï½ü¤µ¤ì¤Þ¤·¤¿"
-#: ../spell.c:8117
#, c-format
msgid "Word '%.*s' added to %s"
msgstr "ñ¸ì '%.*s' ¤¬ %s ¤ØÄɲ䵤ì¤Þ¤·¤¿"
-#: ../spell.c:8381
msgid "E763: Word characters differ between spell files"
msgstr "E763: ñ¸ì¤Îʸ»ú¤¬¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤È°Û¤Ê¤ê¤Þ¤¹"
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "»Äǰ¤Ç¤¹¤¬, ½¤Àµ¸õÊä¤Ï¤¢¤ê¤Þ¤»¤ó"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "»Äǰ¤Ç¤¹¤¬, ½¤Àµ¸õÊä¤Ï %<PRId64> ¸Ä¤·¤«¤¢¤ê¤Þ¤»¤ó"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "\"%.*s\" ¤ò¼¡¤ØÊÑ´¹:"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < \"%.*s\""
-
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: ¥¹¥Ú¥ëÃÖ´¹¤¬¤Þ¤À¼Â¹Ô¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: ¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s"
-
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: .sug ¥Õ¥¡¥¤¥ë¤Ç¤Ï¤Ê¤¤¤è¤¦¤Ç¤¹: %s"
-
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: ¸Å¤¤ .sug ¥Õ¥¡¥¤¥ë¤Ê¤Î¤Ç, ¥¢¥Ã¥×¥Ç¡¼¥È¤·¤Æ¤¯¤À¤µ¤¤: %s"
-
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: ¤è¤ê¿·¤·¤¤¥Ð¡¼¥¸¥ç¥ó¤Î Vim ÍѤΠ.sug ¥Õ¥¡¥¤¥ë¤Ç¤¹: %s"
-
-#: ../spell.c:9295
-#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr "E781: .sug ¥Õ¥¡¥¤¥ë¤¬ .spl ¥Õ¥¡¥¤¥ë¤È°ìÃפ·¤Þ¤»¤ó: %s"
-
-#: ../spell.c:9305
-#, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E782: .sug ¥Õ¥¡¥¤¥ë¤ÎÆÉ¹þÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿: %s"
-
#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
+#. * file.
msgid "E783: duplicate char in MAP entry"
msgstr "E783: MAP ¥¨¥ó¥È¥ê¤Ë½Åʣʸ»ú¤¬Â¸ºß¤·¤Þ¤¹"
-#: ../syntax.c:266
msgid "No Syntax items defined for this buffer"
msgstr "¤³¤Î¥Ð¥Ã¥Õ¥¡¤ËÄêµÁ¤µ¤ì¤¿¹½Ê¸Í×ÁǤϤ¢¤ê¤Þ¤»¤ó"
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
#, c-format
msgid "E390: Illegal argument: %s"
msgstr "E390: ÉÔÀµ¤Ê°ú¿ô¤Ç¤¹: %s"
@@ -5724,28 +5370,22 @@ msgstr "E390: ÉÔÀµ¤Ê°ú¿ô¤Ç¤¹: %s"
msgid "syntax iskeyword "
msgstr "¥·¥ó¥¿¥Ã¥¯¥¹ÍÑ iskeyword "
-#: ../syntax.c:3299
#, c-format
msgid "E391: No such syntax cluster: %s"
msgstr "E391: ¤½¤Î¤è¤¦¤Ê¹½Ê¸¥¯¥é¥¹¥¿¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../syntax.c:3433
msgid "syncing on C-style comments"
msgstr "C¸À¸ìÉ÷¥³¥á¥ó¥È¤«¤éƱ´üÃæ"
-#: ../syntax.c:3439
msgid "no syncing"
msgstr "È󯱴ü"
-#: ../syntax.c:3441
msgid "syncing starts "
msgstr "Ʊ´ü³«»Ï "
-#: ../syntax.c:3443 ../syntax.c:3506
msgid " lines before top line"
msgstr " ¹ÔÁ°(¥È¥Ã¥×¹Ô¤è¤ê¤â)"
-#: ../syntax.c:3448
msgid ""
"\n"
"--- Syntax sync items ---"
@@ -5753,7 +5393,6 @@ msgstr ""
"\n"
"--- ¹½Ê¸Æ±´üÍ×ÁÇ ---"
-#: ../syntax.c:3452
msgid ""
"\n"
"syncing on items"
@@ -5761,7 +5400,6 @@ msgstr ""
"\n"
"Í×ÁǾå¤ÇƱ´üÃæ"
-#: ../syntax.c:3457
msgid ""
"\n"
"--- Syntax items ---"
@@ -5769,53 +5407,41 @@ msgstr ""
"\n"
"--- ¹½Ê¸Í×ÁÇ ---"
-#: ../syntax.c:3475
#, c-format
msgid "E392: No such syntax cluster: %s"
msgstr "E392: ¤½¤Î¤è¤¦¤Ê¹½Ê¸¥¯¥é¥¹¥¿¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../syntax.c:3497
msgid "minimal "
msgstr "minimal "
-#: ../syntax.c:3503
msgid "maximal "
msgstr "maximal "
-#: ../syntax.c:3513
msgid "; match "
msgstr "; ³ºÅö "
-#: ../syntax.c:3515
msgid " line breaks"
msgstr " ¸Ä¤Î²þ¹Ô"
-#: ../syntax.c:4076
msgid "E395: contains argument not accepted here"
msgstr "E395: ¤³¤Î¾ì½ê¤Ç¤Ï°ú¿ôcontains¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../syntax.c:4096
msgid "E844: invalid cchar value"
msgstr "E844: ̵¸ú¤Êcchar¤ÎÃͤǤ¹"
-#: ../syntax.c:4107
msgid "E393: group[t]here not accepted here"
msgstr "E393: ¤³¤³¤Ç¤Ï¥°¥ë¡¼¥×¤Ïµö²Ä¤µ¤ì¤Þ¤»¤ó"
-#: ../syntax.c:4126
#, c-format
msgid "E394: Didn't find region item for %s"
msgstr "E394: %s ¤ÎÈϰÏÍ×ÁǤ¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../syntax.c:4188
msgid "E397: Filename required"
msgstr "E397: ¥Õ¥¡¥¤¥ë̾¤¬É¬ÍפǤ¹"
-#: ../syntax.c:4221
msgid "E847: Too many syntax includes"
msgstr "E847: ¹½Ê¸¤Î¼è¤ê¹þ¤ß(include)¤¬Â¿²á¤®¤Þ¤¹"
-#: ../syntax.c:4303
#, c-format
msgid "E789: Missing ']': %s"
msgstr "E789: ']' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
@@ -5824,221 +5450,173 @@ msgstr "E789: ']' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
msgid "E890: trailing char after ']': %s]%s"
msgstr "E890: ']' ¤Î¸å¤í¤Ë;ʬ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤¹: %s]%s"
-#: ../syntax.c:4531
#, c-format
msgid "E398: Missing '=': %s"
msgstr "E398: '=' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../syntax.c:4666
#, c-format
msgid "E399: Not enough arguments: syntax region %s"
msgstr "E399: °ú¿ô¤¬Â­¤ê¤Þ¤»¤ó: ¹½Ê¸ÈÏ°Ï %s"
-#: ../syntax.c:4870
msgid "E848: Too many syntax clusters"
msgstr "E848: ¹½Ê¸¥¯¥é¥¹¥¿¤¬Â¿²á¤®¤Þ¤¹"
-#: ../syntax.c:4954
msgid "E400: No cluster specified"
msgstr "E400: ¥¯¥é¥¹¥¿¤¬»ØÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#. end delimiter not found
-#: ../syntax.c:4986
#, c-format
msgid "E401: Pattern delimiter not found: %s"
msgstr "E401: ¥Ñ¥¿¡¼¥ó¶èÀڤ꤬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s"
-#: ../syntax.c:5049
#, c-format
msgid "E402: Garbage after pattern: %s"
msgstr "E402: ¥Ñ¥¿¡¼¥ó¤Î¤¢¤È¤Ë¥´¥ß¤¬¤¢¤ê¤Þ¤¹: %s"
-#: ../syntax.c:5120
msgid "E403: syntax sync: line continuations pattern specified twice"
msgstr "E403: ¹½Ê¸Æ±´ü: Ϣ³¹Ô¥Ñ¥¿¡¼¥ó¤¬2ÅÙ»ØÄꤵ¤ì¤Þ¤·¤¿"
-#: ../syntax.c:5169
#, c-format
msgid "E404: Illegal arguments: %s"
msgstr "E404: ÉÔÀµ¤Ê°ú¿ô¤Ç¤¹: %s"
-#: ../syntax.c:5217
#, c-format
msgid "E405: Missing equal sign: %s"
msgstr "E405: Åù¹æ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../syntax.c:5222
#, c-format
msgid "E406: Empty argument: %s"
msgstr "E406: ¶õ¤Î°ú¿ô: %s"
-#: ../syntax.c:5240
#, c-format
msgid "E407: %s not allowed here"
msgstr "E407: %s ¤Ï¥³¥³¤Ç¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../syntax.c:5246
#, c-format
msgid "E408: %s must be first in contains list"
msgstr "E408: %s ¤ÏÆâÍÆ¥ê¥¹¥È¤ÎÀèÆ¬¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤"
-#: ../syntax.c:5304
#, c-format
msgid "E409: Unknown group name: %s"
msgstr "E409: ̤ÃΤΥ°¥ë¡¼¥×̾: %s"
-#: ../syntax.c:5512
#, c-format
msgid "E410: Invalid :syntax subcommand: %s"
msgstr "E410: ̵¸ú¤Ê :syntax ¤Î¥µ¥Ö¥³¥Þ¥ó¥É: %s"
-#: ../syntax.c:5854
msgid ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
msgstr ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
-#: ../syntax.c:6146
msgid "E679: recursive loop loading syncolor.vim"
msgstr "E679: syncolor.vim ¤ÎºÆµ¢¸Æ¤Ó½Ð¤·¤ò¸¡½Ð¤·¤Þ¤·¤¿"
-#: ../syntax.c:6256
#, c-format
msgid "E411: highlight group not found: %s"
msgstr "E411: ¥Ï¥¤¥é¥¤¥È¥°¥ë¡¼¥×¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s"
-#: ../syntax.c:6278
#, c-format
msgid "E412: Not enough arguments: \":highlight link %s\""
msgstr "E412: °ú¿ô¤¬½¼Ê¬¤Ç¤Ï¤Ê¤¤: \":highlight link %s\""
-#: ../syntax.c:6284
#, c-format
msgid "E413: Too many arguments: \":highlight link %s\""
msgstr "E413: °ú¿ô¤¬Â¿²á¤®¤Þ¤¹: \":highlight link %s\""
-#: ../syntax.c:6302
msgid "E414: group has settings, highlight link ignored"
msgstr "E414: ¥°¥ë¡¼¥×¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¤Î¤Ç¥Ï¥¤¥é¥¤¥È¥ê¥ó¥¯¤Ï̵»ë¤µ¤ì¤Þ¤¹"
-#: ../syntax.c:6367
#, c-format
msgid "E415: unexpected equal sign: %s"
msgstr "E415: ͽ´ü¤»¤ÌÅù¹æ¤Ç¤¹: %s"
-#: ../syntax.c:6395
#, c-format
msgid "E416: missing equal sign: %s"
msgstr "E416: Åù¹æ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../syntax.c:6418
#, c-format
msgid "E417: missing argument: %s"
msgstr "E417: °ú¿ô¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../syntax.c:6446
#, c-format
msgid "E418: Illegal value: %s"
msgstr "E418: ÉÔÀµ¤ÊÃͤǤ¹: %s"
-#: ../syntax.c:6496
msgid "E419: FG color unknown"
msgstr "E419: ̤ÃΤÎÁ°·Ê¿§¤Ç¤¹"
-#: ../syntax.c:6504
msgid "E420: BG color unknown"
msgstr "E420: ̤ÃΤÎÇØ·Ê¿§¤Ç¤¹"
-#: ../syntax.c:6564
#, c-format
msgid "E421: Color name or number not recognized: %s"
msgstr "E421: ¥«¥é¡¼Ì¾¤äÈÖ¹æ¤òǧ¼±¤Ç¤­¤Þ¤»¤ó: %s"
-#: ../syntax.c:6714
#, c-format
msgid "E422: terminal code too long: %s"
msgstr "E422: ½ªÃ¼¥³¡¼¥É¤¬Ä¹²á¤®¤Þ¤¹: %s"
-#: ../syntax.c:6753
#, c-format
msgid "E423: Illegal argument: %s"
msgstr "E423: ÉÔÀµ¤Ê°ú¿ô¤Ç¤¹: %s"
-#: ../syntax.c:6925
msgid "E424: Too many different highlighting attributes in use"
msgstr "E424: ¿¤¯¤Î°Û¤Ê¤ë¥Ï¥¤¥é¥¤¥È°À­¤¬»È¤ï¤ì²á¤®¤Æ¤¤¤Þ¤¹"
-#: ../syntax.c:7427
msgid "E669: Unprintable character in group name"
msgstr "E669: ¥°¥ë¡¼¥×̾¤Ë°õºþÉÔ²Äǽ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤¹"
-#: ../syntax.c:7434
msgid "W18: Invalid character in group name"
msgstr "W18: ¥°¥ë¡¼¥×̾¤ËÉÔÀµ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤¹"
-#: ../syntax.c:7448
msgid "E849: Too many highlight and syntax groups"
msgstr "E849: ¥Ï¥¤¥é¥¤¥È¤È¹½Ê¸¥°¥ë¡¼¥×¤¬Â¿²á¤®¤Þ¤¹"
-#: ../tag.c:104
msgid "E555: at bottom of tag stack"
msgstr "E555: ¥¿¥°¥¹¥¿¥Ã¥¯¤ÎËöÈø¤Ç¤¹"
-#: ../tag.c:105
msgid "E556: at top of tag stack"
msgstr "E556: ¥¿¥°¥¹¥¿¥Ã¥¯¤ÎÀèÆ¬¤Ç¤¹"
-#: ../tag.c:380
msgid "E425: Cannot go before first matching tag"
msgstr "E425: ºÇ½é¤Î³ºÅö¥¿¥°¤òͤ¨¤ÆÌá¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../tag.c:504
#, c-format
msgid "E426: tag not found: %s"
msgstr "E426: ¥¿¥°¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s"
-#: ../tag.c:528
msgid " # pri kind tag"
msgstr " # pri kind tag"
-#: ../tag.c:531
msgid "file\n"
msgstr "¥Õ¥¡¥¤¥ë\n"
-#: ../tag.c:829
msgid "E427: There is only one matching tag"
msgstr "E427: ³ºÅö¥¿¥°¤¬1¤Ä¤À¤±¤·¤«¤¢¤ê¤Þ¤»¤ó"
-#: ../tag.c:831
msgid "E428: Cannot go beyond last matching tag"
msgstr "E428: ºÇ¸å¤Ë³ºÅö¤¹¤ë¥¿¥°¤òͤ¨¤Æ¿Ê¤à¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../tag.c:850
#, c-format
msgid "File \"%s\" does not exist"
msgstr "¥Õ¥¡¥¤¥ë \"%s\" ¤¬¤¢¤ê¤Þ¤»¤ó"
#. Give an indication of the number of matching tags
-#: ../tag.c:859
#, c-format
msgid "tag %d of %d%s"
msgstr "¥¿¥° %d (Á´%d%s)"
-#: ../tag.c:862
msgid " or more"
msgstr " ¤«¤½¤ì°Ê¾å"
-#: ../tag.c:864
msgid " Using tag with different case!"
msgstr " ¥¿¥°¤ò°Û¤Ê¤ëcase¤Ç»ÈÍѤ·¤Þ¤¹!"
-#: ../tag.c:909
#, c-format
msgid "E429: File \"%s\" does not exist"
msgstr "E429: ¥Õ¥¡¥¤¥ë \"%s\" ¤¬¤¢¤ê¤Þ¤»¤ó"
#. Highlight title
-#: ../tag.c:960
msgid ""
"\n"
" # TO tag FROM line in file/text"
@@ -6046,79 +5624,66 @@ msgstr ""
"\n"
" # TO ¥¿¥° FROM ¹Ô in file/text"
-#: ../tag.c:1303
#, c-format
msgid "Searching tags file %s"
msgstr "¥¿¥°¥Õ¥¡¥¤¥ë %s ¤ò¸¡º÷Ãæ"
-#: ../tag.c:1545
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: ¥¿¥°¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤¬ %s ¤ËÀÚ¤ê¼Î¤Æ¤é¤ì¤Þ¤·¤¿\n"
+
msgid "Ignoring long line in tags file"
msgstr "¥¿¥°¥Õ¥¡¥¤¥ëÆâ¤ÎŤ¤¹Ô¤ò̵»ë¤·¤Þ¤¹"
-#: ../tag.c:1915
#, c-format
msgid "E431: Format error in tags file \"%s\""
msgstr "E431: ¥¿¥°¥Õ¥¡¥¤¥ë \"%s\" ¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤Ë¥¨¥é¡¼¤¬¤¢¤ê¤Þ¤¹"
-#: ../tag.c:1917
#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "ľÁ°¤Î %<PRId64> ¥Ð¥¤¥È"
+msgid "Before byte %ld"
+msgstr "ľÁ°¤Î %ld ¥Ð¥¤¥È"
-#: ../tag.c:1929
#, c-format
msgid "E432: Tags file not sorted: %s"
msgstr "E432: ¥¿¥°¥Õ¥¡¥¤¥ë¤¬¥½¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó: %s"
#. never opened any tags file
-#: ../tag.c:1960
msgid "E433: No tags file"
msgstr "E433: ¥¿¥°¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../tag.c:2536
msgid "E434: Can't find tag pattern"
msgstr "E434: ¥¿¥°¥Ñ¥¿¡¼¥ó¤ò¸«¤Ä¤±¤é¤ì¤Þ¤»¤ó"
-#: ../tag.c:2544
msgid "E435: Couldn't find tag, just guessing!"
msgstr "E435: ¥¿¥°¤ò¸«¤Ä¤±¤é¤ì¤Ê¤¤¤Î¤Çñ¤Ë¿ä¬¤·¤Þ¤¹!"
-#: ../tag.c:2797
#, c-format
msgid "Duplicate field name: %s"
msgstr "½ÅÊ£¤·¤¿¥Õ¥£¡¼¥ë¥É̾: %s"
-#: ../term.c:1442
msgid "' not known. Available builtin terminals are:"
msgstr "' ¤Ï̤ÃΤǤ¹. ¸½¹Ô¤ÎÁȤ߹þ¤ßüËö¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹:"
-#: ../term.c:1463
msgid "defaulting to '"
msgstr "¾ÊάÃͤò¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Þ¤¹ '"
-#: ../term.c:1731
msgid "E557: Cannot open termcap file"
msgstr "E557: termcap¥Õ¥¡¥¤¥ë¤ò³«¤±¤Þ¤»¤ó"
-#: ../term.c:1735
msgid "E558: Terminal entry not found in terminfo"
msgstr "E558: terminfo¤ËüËö¥¨¥ó¥È¥ê¤ò¸«¤Ä¤±¤é¤ì¤Þ¤»¤ó"
-#: ../term.c:1737
msgid "E559: Terminal entry not found in termcap"
msgstr "E559: termcap¤ËüËö¥¨¥ó¥È¥ê¤ò¸«¤Ä¤±¤é¤ì¤Þ¤»¤ó"
-#: ../term.c:1878
#, c-format
msgid "E436: No \"%s\" entry in termcap"
msgstr "E436: termcap¤Ë \"%s\" ¤Î¥¨¥ó¥È¥ê¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../term.c:2249
msgid "E437: terminal capability \"cm\" required"
msgstr "E437: üËö¤Ë \"cm\" µ¡Ç½¤¬É¬ÍפǤ¹"
#. Highlight title
-#: ../term.c:4376
msgid ""
"\n"
"--- Terminal keys ---"
@@ -6126,168 +5691,347 @@ msgstr ""
"\n"
"--- üËö¥­¡¼ ---"
-#: ../ui.c:481
+msgid "Cannot open $VIMRUNTIME/rgb.txt"
+msgstr "$VIMRUNTIME/rgb.txt¤ò³«¤±¤Þ¤»¤ó"
+
+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.
-#: ../undo.c:379
msgid "E881: Line count changed unexpectedly"
msgstr "E881: ͽ´ü¤»¤º¹Ô¥«¥¦¥ó¥È¤¬ÊѤï¤ê¤Þ¤·¤¿"
-#: ../undo.c:627
+#. 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"
-#: ../undo.c:717
#, c-format
msgid "E825: Corrupted undo file (%s): %s"
msgstr "E825: ¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤¬²õ¤ì¤Æ¤¤¤Þ¤¹ (%s): %s"
-#: ../undo.c:1039
msgid "Cannot write undo file in any directory in 'undodir'"
msgstr "'undodir'¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤ò½ñ¤­¹þ¤á¤Þ¤»¤ó"
-#: ../undo.c:1074
#, c-format
msgid "Will not overwrite with undo file, cannot read: %s"
msgstr "¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤È¤·¤ÆÆÉ¤ß¹þ¤á¤Ê¤¤¤Î¤Ç¾å½ñ¤­¤·¤Þ¤»¤ó: %s"
-#: ../undo.c:1092
#, c-format
msgid "Will not overwrite, this is not an undo file: %s"
msgstr "¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤Ç¤Ï¤Ê¤¤¤Î¤Ç¾å½ñ¤­¤·¤Þ¤»¤ó: %s"
-#: ../undo.c:1108
msgid "Skipping undo file write, nothing to undo"
msgstr "Âоݤ¬¤Ê¤¤¤Î¤Ç¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤Î½ñ¤­¹þ¤ß¤ò¥¹¥­¥Ã¥×¤·¤Þ¤¹"
-#: ../undo.c:1121
#, c-format
msgid "Writing undo file: %s"
msgstr "¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë½ñ¤­¹þ¤ßÃæ: %s"
-#: ../undo.c:1213
#, c-format
msgid "E829: write error in undo file: %s"
msgstr "E829: ¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤Î½ñ¤­¹þ¤ß¥¨¥é¡¼¤Ç¤¹: %s"
-#: ../undo.c:1280
#, c-format
msgid "Not reading undo file, owner differs: %s"
msgstr "¥ª¡¼¥Ê¡¼¤¬°Û¤Ê¤ë¤Î¤Ç¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤òÆÉ¤ß¹þ¤ß¤Þ¤»¤ó: %s"
-#: ../undo.c:1292
#, c-format
msgid "Reading undo file: %s"
msgstr "¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ëÆÉ¹þÃæ: %s"
-#: ../undo.c:1299
#, c-format
msgid "E822: Cannot open undo file for reading: %s"
msgstr "E822: ¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤òÆÉ¹þÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó: %s"
-#: ../undo.c:1308
#, c-format
msgid "E823: Not an undo file: %s"
msgstr "E823: ¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../undo.c:1313
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: Èó°Å¹æ²½¥Õ¥¡¥¤¥ë¤¬°Å¹æ²½¤µ¤ì¤¿¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤ò»È¤Ã¤Æ¤Þ¤¹: %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: °Å¹æ²½¤µ¤ì¤¿¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤Î²òÆÉ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: ¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤¬°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹: %s"
+
#, c-format
msgid "E824: Incompatible undo file: %s"
msgstr "E824: ¸ß´¹À­¤Î̵¤¤¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤Ç¤¹: %s"
-#: ../undo.c:1328
msgid "File contents changed, cannot use undo info"
msgstr "¥Õ¥¡¥¤¥ë¤ÎÆâÍÆ¤¬ÊѤï¤Ã¤Æ¤¤¤ë¤¿¤á¡¢¥¢¥ó¥É¥¥¾ðÊó¤òÍøÍѤǤ­¤Þ¤»¤ó"
-#: ../undo.c:1497
#, c-format
msgid "Finished reading undo file %s"
msgstr "¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë %s ¤Î¼è¹þ¤ò´°Î»"
-#: ../undo.c:1586 ../undo.c:1812
msgid "Already at oldest change"
msgstr "´û¤Ë°ìÈָŤ¤Êѹ¹¤Ç¤¹"
-#: ../undo.c:1597 ../undo.c:1814
msgid "Already at newest change"
msgstr "´û¤Ë°ìÈÖ¿·¤·¤¤Êѹ¹¤Ç¤¹"
-#: ../undo.c:1806
#, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E830: ¥¢¥ó¥É¥¥ÈÖ¹æ %<PRId64> ¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+msgid "E830: Undo number %ld not found"
+msgstr "E830: ¥¢¥ó¥É¥¥ÈÖ¹æ %ld ¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../undo.c:1979
msgid "E438: u_undo: line numbers wrong"
msgstr "E438: u_undo: ¹ÔÈֹ椬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../undo.c:2183
msgid "more line"
msgstr "¹Ô Äɲä·¤Þ¤·¤¿"
-#: ../undo.c:2185
msgid "more lines"
msgstr "¹Ô Äɲä·¤Þ¤·¤¿"
-#: ../undo.c:2187
msgid "line less"
msgstr "¹Ô ºï½ü¤·¤Þ¤·¤¿"
-#: ../undo.c:2189
msgid "fewer lines"
msgstr "¹Ô ºï½ü¤·¤Þ¤·¤¿"
-#: ../undo.c:2193
msgid "change"
msgstr "²Õ½êÊѹ¹¤·¤Þ¤·¤¿"
-#: ../undo.c:2195
msgid "changes"
msgstr "²Õ½êÊѹ¹¤·¤Þ¤·¤¿"
-#: ../undo.c:2225
#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s; %s #%<PRId64> %s"
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
-#: ../undo.c:2228
msgid "before"
msgstr "Á°Êý"
-#: ../undo.c:2228
msgid "after"
msgstr "¸åÊý"
-#: ../undo.c:2325
msgid "Nothing to undo"
msgstr "¥¢¥ó¥É¥¥Âоݤ¬¤¢¤ê¤Þ¤»¤ó"
-#: ../undo.c:2330
msgid "number changes when saved"
msgstr "ÄÌÈÖ Êѹ¹¿ô Êѹ¹»þ´ü ÊݸºÑ"
-#: ../undo.c:2360
#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> É÷вᤷ¤Æ¤¤¤Þ¤¹"
+msgid "%ld seconds ago"
+msgstr "%ld É÷вᤷ¤Æ¤¤¤Þ¤¹"
-#: ../undo.c:2372
msgid "E790: undojoin is not allowed after undo"
msgstr "E790: undo ¤Îľ¸å¤Ë undojoin ¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../undo.c:2466
msgid "E439: undo list corrupt"
msgstr "E439: ¥¢¥ó¥É¥¥¥ê¥¹¥È¤¬²õ¤ì¤Æ¤¤¤Þ¤¹"
-#: ../undo.c:2495
msgid "E440: undo line missing"
msgstr "E440: ¥¢¥ó¥É¥¥¹Ô¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../version.c:600
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: ´Ø¿ô %s ¤ÏÄêµÁºÑ¤Ç¤¹, ºÆÄêµÁ¤¹¤ë¤Ë¤Ï ! ¤òÄɲ䷤Ƥ¯¤À¤µ¤¤"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: ¼­½ñ·¿Æâ¤Ë¥¨¥ó¥È¥ê¤¬´û¤Ë¸ºß¤·¤Þ¤¹"
+
+msgid "E718: Funcref required"
+msgstr "E718: ´Ø¿ô»²¾È·¿¤¬Í׵ᤵ¤ì¤Þ¤¹"
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: ̤ÃΤδؿô¤Ç¤¹: %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: ÉÔÀµ¤Ê°ú¿ô¤Ç¤¹: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: °ú¿ô̾¤¬½ÅÊ£¤·¤Æ¤¤¤Þ¤¹: %s"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: ´Ø¿ô¤Î°ú¿ô¤¬Â¿²á¤®¤Þ¤¹: %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: ´Ø¿ô¤Î̵¸ú¤Ê°ú¿ô¤Ç¤¹: %s"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: ´Ø¿ô¸Æ½Ð¤ÎÆþ¤ì»Ò¿ô¤¬ 'maxfuncdepth' ¤òͤ¨¤Þ¤·¤¿"
+
+#, c-format
+msgid "calling %s"
+msgstr "%s ¤ò¼Â¹ÔÃæ¤Ç¤¹"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s ¤¬ÃæÃǤµ¤ì¤Þ¤·¤¿"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s ¤¬ #%ld ¤òÊÖ¤·¤Þ¤·¤¿"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s ¤¬ %s ¤òÊÖ¤·¤Þ¤·¤¿"
+
+msgid "E699: Too many arguments"
+msgstr "E699: °ú¿ô¤¬Â¿²á¤®¤Þ¤¹"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: ̤ÃΤδؿô¤Ç¤¹: %s"
+
+#, c-format
+msgid "E933: Function was deleted: %s"
+msgstr "E933: ´Ø¿ô¤Ïºï½ü¤µ¤ì¤Þ¤·¤¿: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: ´Ø¿ô¤Î°ú¿ô¤¬Â­¤ê¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: ¥¹¥¯¥ê¥×¥È°Ê³°¤Ç<SID>¤¬»È¤ï¤ì¤Þ¤·¤¿: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: ¼­½ñÍÑ´Ø¿ô¤¬¸Æ¤Ð¤ì¤Þ¤·¤¿¤¬¼­½ñ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: ´Ø¿ô̾¤¬Í׵ᤵ¤ì¤Þ¤¹"
+
+#, c-format
+msgid "E128: Function name must start with a capital or \"s:\": %s"
+msgstr "E128: ´Ø¿ô̾¤ÏÂçʸ»ú¤« \"s:\" ¤Ç»Ï¤Þ¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E884: Function name cannot contain a colon: %s"
+msgstr "E884: ´Ø¿ô̾¤Ë¤Ï¥³¥í¥ó¤Ï´Þ¤á¤é¤ì¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: ̤ÄêµÁ¤Î´Ø¿ô¤Ç¤¹: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: '(' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
+msgid "E862: Cannot use g: here"
+msgstr "E862: ¤³¤³¤Ç¤Ï g: ¤Ï»È¤¨¤Þ¤»¤ó"
+
+#, c-format
+msgid "E932: Closure function should not be at top level: %s"
+msgstr "E932: ¥¯¥í¡¼¥¸¥ã¡¼´Ø¿ô¤Ï¥È¥Ã¥×¥ì¥Ù¥ë¤Ëµ­½Ò¤Ç¤­¤Þ¤»¤ó: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: :endfunction ¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: ´Ø¿ô̾¤¬ÊÑ¿ô̾¤È¾×ÆÍ¤·¤Þ¤¹: %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: ´Ø¿ô %s ¤òºÆÄêµÁ¤Ç¤­¤Þ¤»¤ó: »ÈÍÑÃæ¤Ç¤¹"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: ´Ø¿ô̾¤¬¥¹¥¯¥ê¥×¥È¤Î¥Õ¥¡¥¤¥ë̾¤È°ìÃפ·¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: ´Ø¿ô %s ¤òºï½ü¤Ç¤­¤Þ¤»¤ó: »ÈÍÑÃæ¤Ç¤¹"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: ´Ø¿ô³°¤Ë :return ¤¬¤¢¤ê¤Þ¤·¤¿"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: ¥«¥Ã¥³ '(' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
+#. 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 " with OLE support"
+msgstr " with OLE ¥µ¥Ý¡¼¥È"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 64 ¥Ó¥Ã¥È ¥³¥ó¥½¡¼¥ë ÈÇ"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 32 ¥Ó¥Ã¥È ¥³¥ó¥½¡¼¥ë ÈÇ"
+
+msgid ""
+"\n"
+"MacOS 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: "
@@ -6295,7 +6039,6 @@ msgstr ""
"\n"
"ŬÍѺѥѥåÁ: "
-#: ../version.c:627
msgid ""
"\n"
"Extra patches: "
@@ -6303,11 +6046,9 @@ msgstr ""
"\n"
"ÄɲóÈÄ¥¥Ñ¥Ã¥Á: "
-#: ../version.c:639 ../version.c:864
msgid "Modified by "
msgstr "Modified by "
-#: ../version.c:646
msgid ""
"\n"
"Compiled "
@@ -6315,11 +6056,9 @@ msgstr ""
"\n"
"Compiled "
-#: ../version.c:649
msgid "by "
msgstr "by "
-#: ../version.c:660
msgid ""
"\n"
"Huge version "
@@ -6327,1886 +6066,926 @@ msgstr ""
"\n"
"Huge ÈÇ "
-#: ../version.c:661
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Big ÈÇ "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Ä̾ï ÈÇ "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Small ÈÇ "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Tiny ÈÇ "
+
msgid "without GUI."
msgstr "without GUI."
-#: ../version.c:662
+msgid "with GTK3 GUI."
+msgstr "with GTK3 GUI."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "with GTK2-GNOME GUI."
+
+msgid "with GTK2 GUI."
+msgstr "with GTK2 GUI."
+
+msgid "with X11-Motif GUI."
+msgstr "with X11-Motif GUI."
+
+msgid "with X11-neXtaw GUI."
+msgstr "with X11-neXtaw GUI."
+
+msgid "with X11-Athena GUI."
+msgstr "with X11-Athena GUI."
+
+msgid "with Photon GUI."
+msgstr "with Photon GUI."
+
+msgid "with GUI."
+msgstr "with GUI."
+
+msgid "with Carbon GUI."
+msgstr "with Carbon GUI."
+
+msgid "with Cocoa GUI."
+msgstr "with Cocoa GUI."
+
+msgid "with (classic) GUI."
+msgstr "with (¥¯¥é¥·¥Ã¥¯) GUI."
+
msgid " Features included (+) or not (-):\n"
msgstr " µ¡Ç½¤Î°ìÍ÷ Í­¸ú(+)/̵¸ú(-)\n"
-#: ../version.c:667
msgid " system vimrc file: \""
msgstr " ¥·¥¹¥Æ¥à vimrc: \""
-#: ../version.c:672
msgid " user vimrc file: \""
msgstr " ¥æ¡¼¥¶¡¼ vimrc: \""
-#: ../version.c:677
msgid " 2nd user vimrc file: \""
msgstr " Âè2¥æ¡¼¥¶¡¼ vimrc: \""
-#: ../version.c:682
msgid " 3rd user vimrc file: \""
msgstr " Âè3¥æ¡¼¥¶¡¼ vimrc: \""
-#: ../version.c:687
msgid " user exrc file: \""
msgstr " ¥æ¡¼¥¶¡¼ exrc: \""
-#: ../version.c:692
msgid " 2nd user exrc file: \""
msgstr " Âè2¥æ¡¼¥¶¡¼ exrc: \""
-#: ../version.c:699
+msgid " system gvimrc file: \""
+msgstr " ¥·¥¹¥Æ¥à gvimrc: \""
+
+msgid " user gvimrc file: \""
+msgstr " ¥æ¡¼¥¶¡¼ gvimrc: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr " Âè2¥æ¡¼¥¶¡¼ gvimrc: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr " Âè3¥æ¡¼¥¶¡¼ gvimrc: \""
+
+msgid " defaults file: \""
+msgstr " ¥Ç¥Õ¥©¥ë¥È¥Õ¥¡¥¤¥ë: \""
+
+msgid " system menu file: \""
+msgstr " ¥·¥¹¥Æ¥à¥á¥Ë¥å¡¼: \""
+
msgid " fall-back for $VIM: \""
msgstr " ¾Êά»þ¤Î $VIM: \""
-#: ../version.c:705
msgid " f-b for $VIMRUNTIME: \""
msgstr "¾Êά»þ¤Î $VIMRUNTIME: \""
-#: ../version.c:709
msgid "Compilation: "
msgstr "¥³¥ó¥Ñ¥¤¥ë: "
-#: ../version.c:712
+msgid "Compiler: "
+msgstr "¥³¥ó¥Ñ¥¤¥é: "
+
msgid "Linking: "
msgstr "¥ê¥ó¥¯: "
-#: ../version.c:717
msgid " DEBUG BUILD"
msgstr "¥Ç¥Ð¥Ã¥°¥Ó¥ë¥É"
-#: ../version.c:767
msgid "VIM - Vi IMproved"
msgstr "VIM - Vi IMproved"
-#: ../version.c:769
msgid "version "
msgstr "version "
-#: ../version.c:770
msgid "by Bram Moolenaar et al."
msgstr "by Bram Moolenaar ¾."
-#: ../version.c:774
msgid "Vim is open source and freely distributable"
msgstr "Vim ¤Ï¥ª¡¼¥×¥ó¥½¡¼¥¹¤Ç¤¢¤ê¼«Í³¤ËÇÛÉÛ²Äǽ¤Ç¤¹"
-#: ../version.c:776
msgid "Help poor children in Uganda!"
msgstr "¥¦¥¬¥ó¥À¤Î·Ã¤Þ¤ì¤Ê¤¤»Ò¶¡¤¿¤Á¤Ë±ç½õ¤ò!"
-#: ../version.c:777
msgid "type :help iccf<Enter> for information "
msgstr "¾ÜºÙ¤Ê¾ðÊó¤Ï :help iccf<Enter> "
-#: ../version.c:779
msgid "type :q<Enter> to exit "
msgstr "½ªÎ»¤¹¤ë¤Ë¤Ï :q<Enter> "
-#: ../version.c:780
msgid "type :help<Enter> or <F1> for on-line help"
msgstr "¥ª¥ó¥é¥¤¥ó¥Ø¥ë¥×¤Ï :help<Enter> ¤« <F1> "
-#: ../version.c:781
-msgid "type :help version7<Enter> for version info"
-msgstr "¥Ð¡¼¥¸¥ç¥ó¾ðÊó¤Ï :help version7<Enter> "
+msgid "type :help version8<Enter> for version info"
+msgstr "¥Ð¡¼¥¸¥ç¥ó¾ðÊó¤Ï :help version8<Enter> "
-#: ../version.c:784
msgid "Running in Vi compatible mode"
msgstr "Vi¸ß´¹¥â¡¼¥É¤ÇưºîÃæ"
-#: ../version.c:785
msgid "type :set nocp<Enter> for Vim defaults"
msgstr "Vim¿ä¾©Ãͤˤ¹¤ë¤Ë¤Ï :set nocp<Enter> "
-#: ../version.c:786
msgid "type :help cp-default<Enter> for info on this"
msgstr "¾ÜºÙ¤Ê¾ðÊó¤Ï :help cp-default<Enter>"
-#: ../version.c:827
+msgid "menu Help->Orphans for information "
+msgstr "¾ÜºÙ¤Ï¥á¥Ë¥å¡¼¤Î ¥Ø¥ë¥×->¸É»ù ¤ò»²¾È¤·¤Æ²¼¤µ¤¤ "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "¥â¡¼¥É̵¤Ç¼Â¹ÔÃæ, ¥¿¥¤¥×¤·¤¿Ê¸»ú¤¬ÁÞÆþ¤µ¤ì¤Þ¤¹"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "¥á¥Ë¥å¡¼¤Î ÊÔ½¸->Á´ÂÎÀßÄê->ÁÞÆþ(½é¿´¼Ô)¥â¡¼¥ÉÀÚÂØ "
+
+msgid " for two modes "
+msgstr " ¤Ç¥â¡¼¥ÉÍ­¤Ë "
+
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "¥á¥Ë¥å¡¼¤Î ÊÔ½¸->Á´ÂÎÀßÄê->Vi¸ß´¹¥â¡¼¥ÉÀÚÂØ "
+
+msgid " for Vim defaults "
+msgstr " ¤ÇVim¤È¤·¤ÆÆ°ºî "
+
msgid "Sponsor Vim development!"
msgstr "Vim¤Î³«È¯¤ò±þ±ç¤·¤Æ¤¯¤À¤µ¤¤!"
-#: ../version.c:828
msgid "Become a registered Vim user!"
msgstr "Vim¤ÎÅÐÏ¿¥æ¡¼¥¶¡¼¤Ë¤Ê¤Ã¤Æ¤¯¤À¤µ¤¤!"
-#: ../version.c:831
msgid "type :help sponsor<Enter> for information "
msgstr "¾ÜºÙ¤Ê¾ðÊó¤Ï :help sponsor<Enter> "
-#: ../version.c:832
msgid "type :help register<Enter> for information "
msgstr "¾ÜºÙ¤Ê¾ðÊó¤Ï :help register<Enter> "
-#: ../version.c:834
msgid "menu Help->Sponsor/Register for information "
msgstr "¾ÜºÙ¤Ï¥á¥Ë¥å¡¼¤Î ¥Ø¥ë¥×->¥¹¥Ý¥ó¥µ¡¼/ÅÐÏ¿ ¤ò»²¾È¤·¤Æ²¼¤µ¤¤"
-#: ../window.c:119
+msgid "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¤Ä¤·¤«¤¢¤ê¤Þ¤»¤ó"
-#: ../window.c:224
msgid "E441: There is no preview window"
msgstr "E441: ¥×¥ì¥Ó¥å¡¼¥¦¥£¥ó¥É¥¦¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../window.c:559
msgid "E442: Can't split topleft and botright at the same time"
msgstr "E442: º¸¾å¤È±¦²¼¤òƱ»þ¤Ëʬ³ä¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../window.c:1228
msgid "E443: Cannot rotate when another window is split"
msgstr "E443: ¾¤Î¥¦¥£¥ó¥É¥¦¤¬Ê¬³ä¤µ¤ì¤Æ¤¤¤ë»þ¤Ë¤Ï½ç²ó¤Ç¤­¤Þ¤»¤ó"
-#: ../window.c:1803
msgid "E444: Cannot close last window"
msgstr "E444: ºÇ¸å¤Î¥¦¥£¥ó¥É¥¦¤òÊĤ¸¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../window.c:1810
msgid "E813: Cannot close autocmd window"
msgstr "E813: autocmd¥¦¥£¥ó¥É¥¦¤ÏÊĤ¸¤é¤ì¤Þ¤»¤ó"
-#: ../window.c:1814
msgid "E814: Cannot close window, only autocmd window would remain"
msgstr "E814: autocmd¥¦¥£¥ó¥É¥¦¤·¤«»Ä¤é¤Ê¤¤¤¿¤á¡¢¥¦¥£¥ó¥É¥¦¤ÏÊĤ¸¤é¤ì¤Þ¤»¤ó"
-#: ../window.c:2717
msgid "E445: Other window contains changes"
msgstr "E445: ¾¤Î¥¦¥£¥ó¥É¥¦¤Ë¤ÏÊѹ¹¤¬¤¢¤ê¤Þ¤¹"
-#: ../window.c:4805
msgid "E446: No file name under cursor"
msgstr "E446: ¥«¡¼¥½¥ë¤Î²¼¤Ë¥Õ¥¡¥¤¥ë̾¤¬¤¢¤ê¤Þ¤»¤ó"
-msgid "List or number required"
-msgstr "¥ê¥¹¥È¤«¿ôÃͤ¬É¬ÍפǤ¹"
-
-#~ msgid "E831: bf_key_init() called with empty password"
-#~ msgstr "E831: bf_key_init() ¤¬¶õ¥Ñ¥¹¥ï¡¼¥É¤Ç¸Æ¤Ó½Ð¤µ¤ì¤Þ¤·¤¿"
-
-#~ msgid "E820: sizeof(uint32_t) != 4"
-#~ msgstr "E820: sizeof(uint32_t) != 4"
-
-#~ msgid "E817: Blowfish big/little endian use wrong"
-#~ msgstr "E817: Blowfish°Å¹æ¤Î¥Ó¥Ã¥°/¥ê¥È¥ë¥¨¥ó¥Ç¥£¥¢¥ó¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
-
-#~ msgid "E818: sha256 test failed"
-#~ msgstr "E818: sha256¤Î¥Æ¥¹¥È¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-
-#~ msgid "E819: Blowfish test failed"
-#~ msgstr "E819: Blowfish°Å¹æ¤Î¥Æ¥¹¥È¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-
-#~ msgid "Patch file"
-#~ msgstr "¥Ñ¥Ã¥Á¥Õ¥¡¥¤¥ë"
-
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "·èÄê(&O)\n"
-#~ "¥­¥ã¥ó¥»¥ë(&C)"
-
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Vim ¥µ¡¼¥Ð¤Ø¤ÎÀܳ¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: %s ¤ØÁ÷¤ë¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: ¥µ¡¼¥Ð¤Î±þÅú¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: ¥¯¥é¥¤¥¢¥ó¥È¤ØÁ÷¤ë¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "Save As"
-#~ msgstr "ÊÌ̾¤ÇÊݸ"
-
-#~ msgid "Edit File"
-#~ msgstr "¥Õ¥¡¥¤¥ë¤òÊÔ½¸"
-
-# Added at 27-Jan-2004.
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (¸«¤Ä¤«¤ê¤Þ¤»¤ó)"
-
-#~ msgid "Source Vim script"
-#~ msgstr "Vim¥¹¥¯¥ê¥×¥È¤Î¼è¹þ¤ß"
-
-#~ msgid "unknown"
-#~ msgstr "ÉÔÌÀ"
-
-#~ msgid "Edit File in new window"
-#~ msgstr "¿·¤·¤¤¥¦¥£¥ó¥É¥¦¤Ç¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Þ¤¹"
-
-#~ msgid "Append File"
-#~ msgstr "Äɲåե¡¥¤¥ë"
-
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "¥¦¥£¥ó¥É¥¦°ÌÃÖ: X %d, Y %d"
-
-#~ msgid "Save Redirection"
-#~ msgstr "¥ê¥À¥¤¥ì¥¯¥È¤òÊݸ¤·¤Þ¤¹"
-
-#~ msgid "Save View"
-#~ msgstr "¥Ó¥å¡¼¤òÊݸ¤·¤Þ¤¹"
-
-#~ msgid "Save Session"
-#~ msgstr "¥»¥Ã¥·¥ç¥ó¾ðÊó¤òÊݸ¤·¤Þ¤¹"
-
-#~ msgid "Save Setup"
-#~ msgstr "ÀßÄê¤òÊݸ¤·¤Þ¤¹"
-
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: #< ¤Ï +eval µ¡Ç½¤¬Ìµ¤¤¤ÈÍøÍѤǤ­¤Þ¤»¤ó"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: ¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ë¹ç»ú¤Ï¤¢¤ê¤Þ¤»¤ó"
-
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr " ¤Ï¥Ç¥Ð¥¤¥¹¤Ç¤¹ ('opendevice' ¥ª¥×¥·¥ç¥ó¤Ç²óÈò¤Ç¤­¤Þ¤¹)"
-
-#~ msgid "Reading from stdin..."
-#~ msgstr "ɸ½àÆþÎϤ«¤éÆÉ¹þ¤ßÃæ..."
-
-#~ msgid "[blowfish]"
-#~ msgstr "[blowfish°Å¹æ²½]"
-
-#~ msgid "[crypted]"
-#~ msgstr "[°Å¹æ²½]"
-
-#~ msgid "E821: File is encrypted with unknown method"
-#~ msgstr "E821: ¥Õ¥¡¥¤¥ë¤¬Ì¤ÃΤÎÊýË¡¤Ç°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹"
-
-# Added at 19-Jan-2004.
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans¤Ï̤Êѹ¹¤Î¥Ð¥Ã¥Õ¥¡¤ò¾å½ñ¤¹¤ë¤³¤È¤Ïµö²Ä¤·¤Æ¤¤¤Þ¤»¤ó"
-
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "NetBeans¥Ð¥Ã¥Õ¥¡¤Î°ìÉô¤ò½ñ¤­½Ð¤¹¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "'opendevice' ¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê¥Ç¥Ð¥¤¥¹¤Ø¤Î½ñ¤­¹þ¤ß¤Ï¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: ¥ê¥½¡¼¥¹¥Õ¥©¡¼¥¯¤¬¼º¤ï¤ì¤ë¤«¤â¤·¤ì¤Þ¤»¤ó (! ¤òÄɲäǶ¯À©)"
-
-#~ msgid "E851: Failed to create a new process for the GUI"
-#~ msgstr "E851: GUIÍÑ¤Î¥×¥í¥»¥¹¤Îµ¯Æ°¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-
-#~ msgid "E852: The child process failed to start the GUI"
-#~ msgstr "E852: »Ò¥×¥í¥»¥¹¤¬GUI¤Îµ¯Æ°¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: GUI¤ò³«»Ï¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: \"%s\"¤«¤éÆÉ¹þ¤à¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr "E665: Í­¸ú¤Ê¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤¤¤Î¤Ç, GUI¤ò³«»Ï¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: 'guifontwide' ¤¬Ìµ¸ú¤Ç¤¹"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: 'imactivatekey' ¤ËÀßÄꤵ¤ì¤¿Ãͤ¬Ìµ¸ú¤Ç¤¹"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: %s ¤Î¿§¤ò³ä¤êÅö¤Æ¤é¤ì¤Þ¤»¤ó"
-
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "¥«¡¼¥½¥ë¤Î°ÌÃ֤˥ޥåÁ¤Ï¤¢¤ê¤Þ¤»¤ó, ¼¡¤ò¸¡º÷¤·¤Æ¤¤¤Þ¤¹"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<³«¤±¤Þ¤»¤ó> "
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: ¥Õ¥©¥ó¥È %s ¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: ¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ËÌá¤ì¤Þ¤»¤ó"
-
-#~ msgid "Pathname:"
-#~ msgstr "¥Ñ¥¹Ì¾:"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: ¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "OK"
-#~ msgstr "OK"
-
-#~ msgid "Cancel"
-#~ msgstr "¥­¥ã¥ó¥»¥ë"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr "¥¹¥¯¥í¡¼¥ë¥Ð¡¼: ²èÁü¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿."
-
-#~ msgid "Vim dialog"
-#~ msgstr "Vim ¥À¥¤¥¢¥í¥°"
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: ¥á¥Ã¥»¡¼¥¸¤È¥³¡¼¥ë¥Ð¥Ã¥¯¤Î¤¢¤ë BalloonEval ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "Input _Methods"
-#~ msgstr "¥¤¥ó¥×¥Ã¥È¥á¥½¥Ã¥É"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - ¸¡º÷¤ÈÃÖ´¹..."
-
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - ¸¡º÷..."
-
-#~ msgid "Find what:"
-#~ msgstr "¸¡º÷ʸ»úÎó:"
-
-#~ msgid "Replace with:"
-#~ msgstr "ÃÖ´¹Ê¸»úÎó:"
-
-#~ msgid "Match whole word only"
-#~ msgstr "Àµ³Î¤Ë³ºÅö¤¹¤ë¤â¤Î¤À¤±"
-
-#~ msgid "Match case"
-#~ msgstr "Âçʸ»ú/¾®Ê¸»ú¤ò¶èÊ̤¹¤ë"
-
-#~ msgid "Direction"
-#~ msgstr "Êý¸þ"
-
-#~ msgid "Up"
-#~ msgstr "¾å"
-
-#~ msgid "Down"
-#~ msgstr "²¼"
-
-#~ msgid "Find Next"
-#~ msgstr "¼¡¤ò¸¡º÷"
-
-#~ msgid "Replace"
-#~ msgstr "ÃÖ´¹"
-
-#~ msgid "Replace All"
-#~ msgstr "Á´¤ÆÃÖ´¹"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: ¥»¥Ã¥·¥ç¥ó¥Þ¥Í¡¼¥¸¥ã¤«¤é \"die\" Í×µá¤ò¼õ¤±¼è¤ê¤Þ¤·¤¿\n"
-
-#~ msgid "Close"
-#~ msgstr "ÊĤ¸¤ë"
-
-#~ msgid "New tab"
-#~ msgstr "¿·µ¬¥¿¥Ö¥Ú¡¼¥¸"
-
-#~ msgid "Open Tab..."
-#~ msgstr "¥¿¥Ö¥Ú¡¼¥¸¤ò³«¤¯..."
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: ¥á¥¤¥ó¥¦¥£¥ó¥É¥¦¤¬ÉÔ°Õ¤ËÇ˲õ¤µ¤ì¤Þ¤·¤¿\n"
-
-#~ msgid "&Filter"
-#~ msgstr "¥Õ¥£¥ë¥¿(&F)"
-
-#~ msgid "&Cancel"
-#~ msgstr "¥­¥ã¥ó¥»¥ë(&C)"
-
-#~ msgid "Directories"
-#~ msgstr "¥Ç¥£¥ì¥¯¥È¥ê"
-
-#~ msgid "Filter"
-#~ msgstr "¥Õ¥£¥ë¥¿"
-
-#~ msgid "&Help"
-#~ msgstr "¥Ø¥ë¥×(&H)"
-
-#~ msgid "Files"
-#~ msgstr "¥Õ¥¡¥¤¥ë"
-
-#~ msgid "&OK"
-#~ msgstr "&OK"
-
-#~ msgid "Selection"
-#~ msgstr "ÁªÂò"
-
-#~ msgid "Find &Next"
-#~ msgstr "¼¡¤ò¸¡º÷(&N)"
-
-#~ msgid "&Replace"
-#~ msgstr "ÃÖ´¹(&R)"
-
-#~ msgid "Replace &All"
-#~ msgstr "Á´¤ÆÃÖ´¹(&A)"
-
-#~ msgid "&Undo"
-#~ msgstr "¥¢¥ó¥É¥¥(&U)"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: ¥¿¥¤¥È¥ë¤¬ \"%s\" ¤Î¥¦¥£¥ó¥É¥¦¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: °ú¿ô¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤»¤ó: \"-%s\"; OLEÈǤò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤."
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: MDI¥¢¥×¥ê¤ÎÃæ¤Ç¤Ï¥¦¥£¥ó¥É¥¦¤ò³«¤±¤Þ¤»¤ó"
-
-#~ msgid "Close tab"
-#~ msgstr "¥¿¥Ö¥Ú¡¼¥¸¤òÊĤ¸¤ë"
-
-#~ msgid "Open tab..."
-#~ msgstr "¥¿¥Ö¥Ú¡¼¥¸¤ò³«¤¯"
-
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "¸¡º÷ʸ»úÎó ('\\' ¤ò¸¡º÷¤¹¤ë¤Ë¤Ï '\\\\')"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "¸¡º÷¡¦ÃÖ´¹ ('\\' ¤ò¸¡º÷¤¹¤ë¤Ë¤Ï '\\\\')"
-
-#~ msgid "Not Used"
-#~ msgstr "»È¤ï¤ì¤Þ¤»¤ó"
-
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "¥Ç¥£¥ì¥¯¥È¥ê\t*.nothing\n"
-
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr "Vim E458: ¿§»ØÄ꤬Àµ¤·¤¯¤Ê¤¤¤Î¤Ç¥¨¥ó¥È¥ê¤ò³ä¤êÅö¤Æ¤é¤ì¤Þ¤»¤ó"
-
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr "E250: °Ê²¼¤Îʸ»ú¥»¥Ã¥È¤Î¥Õ¥©¥ó¥È¤¬¤¢¤ê¤Þ¤»¤ó %s:"
-
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: ¥Õ¥©¥ó¥È¥»¥Ã¥È̾: %s"
-
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "¥Õ¥©¥ó¥È '%s' ¤Ï¸ÇÄêÉý¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-
-#~ msgid "E253: Fontset name: %s"
-#~ msgstr "E253: ¥Õ¥©¥ó¥È¥»¥Ã¥È̾: %s"
-
-#~ msgid "Font0: %s"
-#~ msgstr "¥Õ¥©¥ó¥È0: %s"
-
-#~ msgid "Font1: %s"
-#~ msgstr "¥Õ¥©¥ó¥È1: %s"
-
-#~ msgid "Font%<PRId64> width is not twice that of font0"
-#~ msgstr "¥Õ¥©¥ó¥È%<PRId64> ¤ÎÉý¤¬¥Õ¥©¥ó¥È0¤Î2ÇܤǤϤ¢¤ê¤Þ¤»¤ó"
-
-#~ msgid "Font0 width: %<PRId64>"
-#~ msgstr "¥Õ¥©¥ó¥È0¤ÎÉý: %<PRId64>"
-
-#~ msgid "Font1 width: %<PRId64>"
-#~ msgstr "¥Õ¥©¥ó¥È1¤ÎÉý: %<PRId64>"
-
-#~ msgid "Invalid font specification"
-#~ msgstr "̵¸ú¤Ê¥Õ¥©¥ó¥È»ØÄê¤Ç¤¹"
-
-#~ msgid "&Dismiss"
-#~ msgstr "µÑ²¼¤¹¤ë(&D)"
-
-#~ msgid "no specific match"
-#~ msgstr "¥Þ¥Ã¥Á¤¹¤ë¤â¤Î¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - ¥Õ¥©¥ó¥ÈÁªÂò"
-
-#~ msgid "Name:"
-#~ msgstr "̾Á°:"
-
-#~ msgid "Show size in Points"
-#~ msgstr "¥µ¥¤¥º¤ò¥Ý¥¤¥ó¥È¤Çɽ¼¨¤¹¤ë"
-
-#~ msgid "Encoding:"
-#~ msgstr "¥¨¥ó¥³¡¼¥É:"
-
-#~ msgid "Font:"
-#~ msgstr "¥Õ¥©¥ó¥È:"
-
-#~ msgid "Style:"
-#~ msgstr "¥¹¥¿¥¤¥ë:"
-
-#~ msgid "Size:"
-#~ msgstr "¥µ¥¤¥º:"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: ¥Ï¥ó¥°¥ë¥ª¡¼¥È¥Þ¥È¥ó¥¨¥é¡¼"
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: stat ¥¨¥é¡¼"
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: cscope¥Ç¡¼¥¿¥Ù¡¼¥¹: %s ¤ò³«¤¯¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: cscope¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¾ðÊó¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "Lua library cannot be loaded."
-#~ msgstr "Lua¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó."
-
-#~ msgid "cannot save undo information"
-#~ msgstr "¥¢¥ó¥É¥¥¾ðÊó¤¬Êݸ¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr ""
-#~ "E815: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹. MzScheme ¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó."
-
-#~ msgid "invalid expression"
-#~ msgstr "̵¸ú¤Ê¼°¤Ç¤¹"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "¼°¤Ï¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹"
-
-#~ msgid "hidden option"
-#~ msgstr "±£¤·¥ª¥×¥·¥ç¥ó"
-
-#~ msgid "unknown option"
-#~ msgstr "̤ÃΤΥª¥×¥·¥ç¥ó¤Ç¤¹"
-
-#~ msgid "window index is out of range"
-#~ msgstr "Èϰϳ°¤Î¥¦¥£¥ó¥É¥¦ÈÖ¹æ¤Ç¤¹"
-
-#~ msgid "couldn't open buffer"
-#~ msgstr "¥Ð¥Ã¥Õ¥¡¤ò³«¤±¤Þ¤»¤ó"
-
-#~ msgid "cannot delete line"
-#~ msgstr "¹Ô¤ò¾Ã¤»¤Þ¤»¤ó"
-
-#~ msgid "cannot replace line"
-#~ msgstr "¹Ô¤òÃÖ´¹¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "cannot insert line"
-#~ msgstr "¹Ô¤òÁÞÆþ¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "ʸ»úÎó¤Ë¤Ï²þ¹Ôʸ»ú¤ò´Þ¤á¤é¤ì¤Þ¤»¤ó"
-
-#~ msgid "error converting Scheme values to Vim"
-#~ msgstr "SchemeÃͤÎVim¤Ø¤ÎÊÑ´¹¥¨¥é¡¼"
-
-#~ msgid "Vim error: ~a"
-#~ msgstr "Vim ¥¨¥é¡¼: ~a"
-
-#~ msgid "Vim error"
-#~ msgstr "Vim ¥¨¥é¡¼"
-
-#~ msgid "buffer is invalid"
-#~ msgstr "¥Ð¥Ã¥Õ¥¡¤Ï̵¸ú¤Ç¤¹"
-
-#~ msgid "window is invalid"
-#~ msgstr "¥¦¥£¥ó¥É¥¦¤Ï̵¸ú¤Ç¤¹"
-
-#~ msgid "linenr out of range"
-#~ msgstr "Èϰϳ°¤Î¹ÔÈÖ¹æ¤Ç¤¹"
-
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤Ïµö¤µ¤ì¤Þ¤»¤ó"
-
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: ¥é¥¤¥Ö¥é¥ê %s ¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
-
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr ""
-#~ "¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹, ¤´¤á¤ó¤Ê¤µ¤¤: Perl¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·"
-#~ "¤¿."
-
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr ""
-#~ "E299: ¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤Ï Safe ¥â¥¸¥å¡¼¥ë¤ò»ÈÍѤ·¤Ê¤¤Perl¥¹¥¯¥ê¥×¥È¤Ï¶Ø¤¸¤é"
-#~ "¤ì¤Æ¤¤¤Þ¤¹"
-
-#~ msgid "E836: This Vim cannot execute :python after using :py3"
-#~ msgstr "E836: ¤³¤ÎVim¤Ç¤Ï :py3 ¤ò»È¤Ã¤¿¸å¤Ë :python ¤ò»È¤¨¤Þ¤»¤ó"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E263: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹,¤´¤á¤ó¤Ê¤µ¤¤: Python¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ"
-#~ "¤»¤ó¤Ç¤·¤¿."
-
-# Added at 07-Feb-2004.
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Python ¤òºÆµ¢Åª¤Ë¼Â¹Ô¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E837: This Vim cannot execute :py3 after using :python"
-#~ msgstr "E837: ¤³¤ÎVim¤Ç¤Ï :python ¤ò»È¤Ã¤¿¸å¤Ë :py3 ¤ò»È¤¨¤Þ¤»¤ó"
-
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: $_ ¤Ïʸ»úÎó¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E266: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹,¤´¤á¤ó¤Ê¤µ¤¤: Ruby¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»"
-#~ "¤ó¤Ç¤·¤¿."
-
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: ͽ´ü¤»¤Ì return ¤Ç¤¹"
-
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: ͽ´ü¤»¤Ì next ¤Ç¤¹"
-
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: ͽ´ü¤»¤Ì break ¤Ç¤¹"
-
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: ͽ´ü¤»¤Ì redo ¤Ç¤¹"
-
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: rescue ¤Î³°¤Î retry ¤Ç¤¹"
-
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: ¼è¤ê°·¤ï¤ì¤Ê¤«¤Ã¤¿Îã³°¤¬¤¢¤ê¤Þ¤¹"
-
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: ̤ÃΤÎlongjmp¾õÂÖ: %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "¼ÂÁõ¤ÈÄêµÁ¤òÀÚ¤êÂØ¤¨¤ë"
-
-#~ msgid "Show base class of"
-#~ msgstr "¼¡¤Î¥¯¥é¥¹¤Î´ðÄì¤òɽ¼¨"
-
-#~ msgid "Show overridden member function"
-#~ msgstr "¥ª¡¼¥Ð¡¼¥é¥¤¥É¤µ¤ì¤¿¥á¥ó¥Ð´Ø¿ô¤òɽ¼¨"
-
-#~ msgid "Retrieve from file"
-#~ msgstr "¥Õ¥¡¥¤¥ë¤«¤é²óÉü¤¹¤ë"
-
-#~ msgid "Retrieve from project"
-#~ msgstr "¥×¥í¥¸¥§¥¯¥È¤«¤é²óÉü¤¹¤ë"
-
-#~ msgid "Retrieve from all projects"
-#~ msgstr "Á´¤Æ¤Î¥×¥í¥¸¥§¥¯¥È¤«¤é²óÉü¤¹¤ë"
-
-#~ msgid "Retrieve"
-#~ msgstr "²óÉü"
-
-#~ msgid "Show source of"
-#~ msgstr "¼¡¤Î¥½¡¼¥¹¤òɽ¼¨¤¹¤ë"
-
-#~ msgid "Find symbol"
-#~ msgstr "¸«¤Ä¤±¤¿¥·¥ó¥Ü¥ë"
-
-#~ msgid "Browse class"
-#~ msgstr "¥¯¥é¥¹¤ò»²¾È"
-
-#~ msgid "Show class in hierarchy"
-#~ msgstr "³¬Áؤǥ¯¥é¥¹¤òɽ¼¨"
-
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "¸ÂÄꤵ¤ì¤¿³¬Áؤǥ¯¥é¥¹¤òɽ¼¨"
-
-#~ msgid "Xref refers to"
-#~ msgstr "Xref ¤Î»²¾ÈÀè"
-
-#~ msgid "Xref referred by"
-#~ msgstr "Xref ¤¬»²¾È¤µ¤ì¤ë"
-
-#~ msgid "Xref has a"
-#~ msgstr "Xref ¤¬¼¡¤Î¤â¤Î¤ò¤â¤Ã¤Æ¤¤¤Þ¤¹"
-
-#~ msgid "Xref used by"
-#~ msgstr "Xref ¤¬»ÈÍѤµ¤ì¤ë"
-
-#~ msgid "Show docu of"
-#~ msgstr "¼¡¤Îʸ¾Ï¤òɽ¼¨"
-
-#~ msgid "Generate docu for"
-#~ msgstr "¼¡¤Îʸ¾Ï¤òÀ¸À®"
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "SNiFF+¤ËÀܳ¤Ç¤­¤Þ¤»¤ó. ´Ä¶­¤ò¥Á¥§¥Ã¥¯¤·¤Æ¤¯¤À¤µ¤¤(sniffemacs ¤¬ $PATH ¤Ë"
-#~ "¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó).\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: ÆÉ¹þÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿. ÀÚÃǤ·¤Þ¤·¤¿"
-
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "¸½ºßSNiFF+ ¤Î¾õÂ֤ϡÖ"
-
-#~ msgid "not "
-#~ msgstr "̤"
-
-#~ msgid "connected"
-#~ msgstr "Àܳ¡×¤Ç¤¹"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: ̤ÃΤΠSNiFF+ ¥ê¥¯¥¨¥¹¥È¤Ç¤¹: %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: SNiFF+ ¤Ø¤ÎÀÜÂ³Ãæ¤Î¥¨¥é¡¼¤Ç¤¹"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SNiFF+ ¤ËÀܳ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: SNiFF+ ¥Ð¥Ã¥Õ¥¡¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: ½ñ¹þ¤ßÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤¿¤Î¤ÇÀÚÃǤ·¤Þ¤·¤¿"
-
-#~ msgid "invalid buffer number"
-#~ msgstr "̵¸ú¤Ê¥Ð¥Ã¥Õ¥¡ÈÖ¹æ¤Ç¤¹"
-
-#~ msgid "not implemented yet"
-#~ msgstr "¤Þ¤À¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "¹Ô¤òÀßÄê¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "invalid mark name"
-#~ msgstr "̵¸ú¤Ê¥Þ¡¼¥¯Ì¾¤Ç¤¹"
-
-#~ msgid "mark not set"
-#~ msgstr "¥Þ¡¼¥¯¤ÏÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-
-#~ msgid "row %d column %d"
-#~ msgstr "¹Ô %d Îó %d"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "¹Ô¤ÎÁÞÆþ/Äɲäò¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "line number out of range"
-#~ msgstr "Èϰϳ°¤Î¹ÔÈÖ¹æ¤Ç¤¹"
-
-#~ msgid "unknown flag: "
-#~ msgstr "̤ÃΤΥե饰: "
-
-#~ msgid "unknown vimOption"
-#~ msgstr "̤ÃΤΠvimOption ¤Ç¤¹"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "¥­¡¼¥Ü¡¼¥É³ä¹þ¤ß"
-
-#~ msgid "vim error"
-#~ msgstr "vim ¥¨¥é¡¼"
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr ""
-#~ "¥Ð¥Ã¥Õ¥¡/¥¦¥£¥ó¥É¥¦ºîÀ®¥³¥Þ¥ó¥É¤òºîÀ®¤Ç¤­¤Þ¤»¤ó: ¥ª¥Ö¥¸¥§¥¯¥È¤¬¾Ãµî¤µ¤ì¤Æ"
-#~ "¤¤¤Þ¤·¤¿"
-
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr ""
-#~ "¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥É¤òÅÐÏ¿¤Ç¤­¤Þ¤»¤ó: ¥Ð¥Ã¥Õ¥¡/¥¦¥£¥ó¥É¥¦¤¬´û¤Ë¾Ãµî¤µ¤ì¤Þ"
-#~ "¤·¤¿"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr ""
-#~ "E280: TCL Ã×̿Ū¥¨¥é¡¼: reflist ±øÀ÷!? vim-dev@vim.org ¤ËÊó¹ð¤·¤Æ¤¯¤À¤µ¤¤"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr ""
-#~ "¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥É¤òÅÐÏ¿¤Ç¤­¤Þ¤»¤ó: ¥Ð¥Ã¥Õ¥¡/¥¦¥£¥ó¥É¥¦¤Î»²¾È¤¬¸«¤Ä¤«¤ê"
-#~ "¤Þ¤»¤ó"
-
-#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E571: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹,¤´¤á¤ó¤Ê¤µ¤¤: Tcl¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó"
-#~ "¤Ç¤·¤¿."
-
-#~ msgid "E572: exit code %d"
-#~ msgstr "E572: ½ªÎ»¥³¡¼¥É %d"
-
-#~ msgid "cannot get line"
-#~ msgstr "¹Ô¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "Unable to register a command server name"
-#~ msgstr "Ì¿Î᥵¡¼¥Ð¤Î̾Á°¤òÅÐÏ¿¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: ÌÜŪ¤Î¥×¥í¥°¥é¥à¤Ø¤Î¥³¥Þ¥ó¥ÉÁ÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: ̵¸ú¤Ê¥µ¡¼¥ÐID¤¬»È¤ï¤ì¤Þ¤·¤¿: %s"
-
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr "E251: VIM ¼ÂÂΤÎÅÐÏ¿¥×¥í¥Ñ¥Æ¥£¤¬ÉÔÀµ¤Ç¤¹. ¾Ãµî¤·¤Þ¤·¤¿!"
-
-#~ msgid "netbeans is not supported with this GUI\n"
-#~ msgstr "netbeans ¤Ï¤³¤ÎGUI¤Ç¤ÏÍøÍѤǤ­¤Þ¤»¤ó\n"
-
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "¤³¤ÎVim¤Ë¤Ïdiffµ¡Ç½¤¬¤¢¤ê¤Þ¤»¤ó(¥³¥ó¥Ñ¥¤¥ë»þÀßÄê)."
-
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "'-nb' »ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹\n"
-
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: ¥¨¥é¡¼: NetBeans¤«¤égvim¤ò¥¹¥¿¡¼¥È¤Ç¤­¤Þ¤»¤ó\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
-#~ msgstr ""
-#~ "\n"
-#~ "Â羮ʸ»ú¤¬Ìµ»ë¤µ¤ì¤ë¾ì¹ç¤ÏÂçʸ»ú¤Ë¤¹¤ë¤¿¤á¤Ë / ¤òÁ°ÃÖ¤·¤Æ¤¯¤À¤µ¤¤"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\t¤³¤Îgvim¤òOLE¤È¤·¤ÆÅÐÏ¿¤¹¤ë"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tgvim¤ÎOLEÅÐÏ¿¤ò²ò½ü¤¹¤ë"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tGUI¤Çµ¯Æ°¤¹¤ë (\"gvim\" ¤ÈƱ¤¸)"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f or --nofork\t¥Õ¥©¥¢¥°¥é¥¦¥ó¥É: GUI¤ò»Ï¤á¤ë¤È¤­¤Ëfork¤·¤Ê¤¤"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\t¥¦¥£¥ó¥É¥¦¤ò³«¤¯¤Î¤Ë newcli ¤ò»ÈÍѤ·¤Ê¤¤"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <device>\t\tI/O¤Ë <device> ¤ò»ÈÍѤ¹¤ë"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\t.gvimrc¤ÎÂå¤ï¤ê¤Ë <gvimrc> ¤ò»È¤¦"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\t°Å¹æ²½¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤¹¤ë"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <display>\tvim¤ò»ØÄꤷ¤¿ X ¥µ¡¼¥Ð¤ËÀܳ¤¹¤ë"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tX¥µ¡¼¥Ð¤ËÀܳ¤·¤Ê¤¤"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr "--remote <files>\t²Äǽ¤Ê¤é¤ÐVim¥µ¡¼¥Ð¤Ç <files> ¤òÊÔ½¸¤¹¤ë"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr "--remote-silent <files> Ʊ¾å, ¥µ¡¼¥Ð¤¬Ìµ¤¯¤Æ¤â·Ù¹ðʸ¤ò½ÐÎϤ·¤Ê¤¤"
-
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr "--remote-wait <files>\t--remote¸å ¥Õ¥¡¥¤¥ë¤ÎÊÔ½¸¤¬½ª¤ï¤ë¤Î¤òÂÔ¤Ä"
-
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-wait-silent <files> Ʊ¾å, ¥µ¡¼¥Ð¤¬Ìµ¤¯¤Æ¤â·Ù¹ðʸ¤ò½ÐÎϤ·¤Ê¤¤"
-
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <files> --remote¤Ç¥Õ¥¡¥¤¥ë1¤Ä¤Ë¤Ä¤­1¤Ä¤Î¥¿¥Ö"
-#~ "¥Ú¡¼¥¸¤ò³«¤¯"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr "--remote-send <keys>\tVim¥µ¡¼¥Ð¤Ë <keys> ¤òÁ÷¿®¤·¤Æ½ªÎ»¤¹¤ë"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr "--remote-expr <expr>\t¥µ¡¼¥Ð¤Ç <expr> ¤ò¼Â¹Ô¤·¤Æ·ë²Ì¤òɽ¼¨¤¹¤ë"
-
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr "--serverlist\t\tVim¥µ¡¼¥Ð̾¤Î°ìÍ÷¤òɽ¼¨¤·¤Æ½ªÎ»¤¹¤ë"
-
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <name>\tVim¥µ¡¼¥Ð <name> ¤ËÁ÷¿®/̾Á°ÀßÄꤹ¤ë"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim¤Ë¤è¤Ã¤Æ²ò¼á¤µ¤ì¤ë°ú¿ô(Motif¥Ð¡¼¥¸¥ç¥ó):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim¤Ë¤è¤Ã¤Æ²ò¼á¤µ¤ì¤ë°ú¿ô(neXtaw¥Ð¡¼¥¸¥ç¥ó):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim¤Ë¤è¤Ã¤Æ²ò¼á¤µ¤ì¤ë°ú¿ô(Athena¥Ð¡¼¥¸¥ç¥ó):\n"
-
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <display>\t<display> ¤Çvim¤ò¼Â¹Ô¤¹¤ë"
-
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tºÇ¾®²½¤·¤¿¾õÂÖ¤Çvim¤òµ¯Æ°¤¹¤ë"
-
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <color>\tÇØ·Ê¿§¤Ë <color> ¤ò»È¤¦(ƱµÁ: -bg)"
-
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr "-foreground <color>\tÁ°·Ê¿§¤Ë <color> ¤ò»È¤¦(ƱµÁ: -fg)"
-
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <font>\t\t¥Æ¥­¥¹¥Èɽ¼¨¤Ë <font> ¤ò»È¤¦(ƱµÁ: -fn)"
-
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <font>\tÂÀ»ú¤Ë <font> ¤ò»È¤¦"
-
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <for>\t¼ÐÂλú¤Ë <font> ¤ò»È¤¦"
-
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr "-geometry <geom>\t½é´üÇÛÃÖ¤Ë <geom> ¤ò»È¤¦(ƱµÁ: -geom)"
-
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <width>\t¶­³¦¤ÎÉý¤ò <width> ¤Ë¤¹¤ë(ƱµÁ: -bw)"
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <width> ¥¹¥¯¥í¡¼¥ë¥Ð¡¼¤ÎÉý¤ò <width> ¤Ë¤¹¤ë(ƱµÁ: -sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr ""
-#~ "-menuheight <height>\t¥á¥Ë¥å¡¼¥Ð¡¼¤Î¹â¤µ¤ò <height> ¤Ë¤¹¤ë(ƱµÁ: -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tȿž±ÇÁü¤ò»ÈÍѤ¹¤ë(ƱµÁ: -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tȿž±ÇÁü¤ò»ÈÍѤ·¤Ê¤¤(ƱµÁ: +rv)"
-
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <resource>\tÆÃÄê¤Î¥ê¥½¡¼¥¹¤ò»ÈÍѤ¹¤ë"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim¤Ë¤è¤Ã¤Æ²ò¼á¤µ¤ì¤ë°ú¿ô(GTK+¥Ð¡¼¥¸¥ç¥ó):\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <display>\t<display> ¤Çvim¤ò¼Â¹Ô¤¹¤ë(ƱµÁ: --display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr "--role <role>\t¥á¥¤¥ó¥¦¥£¥ó¥É¥¦¤ò¼±Ê̤¹¤ë°ì°Õ¤ÊÌò³ä(role)¤òÀßÄꤹ¤ë"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\t°Û¤Ê¤ëGTK widget¤ÇVim¤ò³«¤¯"
-
-#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
-#~ msgstr "--echo-wid\t\t¥¦¥£¥ó¥É¥¦ID¤òɸ½à½ÐÎϤ˽ÐÎϤ¹¤ë"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <¿Æ¤Î¥¿¥¤¥È¥ë>\tVim¤ò¿Æ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÎÃæ¤Çµ¯Æ°¤¹¤ë"
-
-#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
-#~ msgstr "--windowid <HWND>\t°Û¤Ê¤ëWin32 widget¤ÎÆâÉô¤ËVim¤ò³«¤¯"
-
-#~ msgid "No display"
-#~ msgstr "¥Ç¥£¥¹¥×¥ì¥¤¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr ": Á÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿.\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": Á÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿. ¥í¡¼¥«¥ë¤Ç¤Î¼Â¹Ô¤ò»î¤ß¤Æ¤¤¤Þ¤¹\n"
-
-#~ msgid "%d of %d edited"
-#~ msgstr "%d ¸Ä (%d ¸ÄÃæ) ¤Î¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Þ¤·¤¿"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "¥Ç¥£¥¹¥×¥ì¥¤¤¬¤¢¤ê¤Þ¤»¤ó: ¼°¤ÎÁ÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿.\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": ¼°¤ÎÁ÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿.\n"
-
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: ̵¸ú¤Ê¥³¡¼¥É¥Ú¡¼¥¸¤Ç¤¹"
-
-#~ msgid "E284: Cannot set IC values"
-#~ msgstr "E284: IC¤ÎÃͤòÀßÄê¤Ç¤­¤Þ¤»¤ó"
-
-#~ 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 ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤»¤ó"
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: path¤Ë¤Ï \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "E843: Error while updating swap file crypt"
-#~ msgstr "E843: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î°Å¹æ¤ò¹¹¿·Ãæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿"
+#, c-format
+msgid "E799: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E799: ̵¸ú¤Ê ID: %ld (1 °Ê¾å¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó)"
-#~ msgid ""
-#~ "E833: %s is encrypted and this version of Vim does not support encryption"
-#~ msgstr ""
-#~ "E833: %s ¤Ï¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤ÎVim¤Ç¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤·Á¼°¤Ç°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹"
+#, c-format
+msgid "E801: ID already taken: %ld"
+msgstr "E801: ID ¤Ï¤¹¤Ç¤ËÍøÍÑÃæ¤Ç¤¹: %ld"
-#~ msgid "Swap file is encrypted: \"%s\""
-#~ msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Ï°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹: \"%s\""
+msgid "List or number required"
+msgstr "¥ê¥¹¥È¤«¿ôÃͤ¬É¬ÍפǤ¹"
-#~ msgid ""
-#~ "\n"
-#~ "If you entered a new crypt key but did not write the text file,"
-#~ msgstr ""
-#~ "\n"
-#~ "¿·¤·¤¤°Å¹æ¥­¡¼¤òÆþÎϤ·¤¿¤¢¤È¤Ë¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤òÊݸ¤·¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï,"
+#, c-format
+msgid "E802: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E802: ̵¸ú¤Ê ID: %ld (1 °Ê¾å¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó)"
-#~ msgid ""
-#~ "\n"
-#~ "enter the new crypt key."
-#~ msgstr ""
-#~ "\n"
-#~ "¿·¤·¤¤°Å¹æ¥­¡¼¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤."
+#, c-format
+msgid "E803: ID not found: %ld"
+msgstr "E803: ID ¤Ï¤¢¤ê¤Þ¤»¤ó: %ld"
-#~ msgid ""
-#~ "\n"
-#~ "If you wrote the text file after changing the crypt key press enter"
-#~ msgstr ""
-#~ "\n"
-#~ "°Å¹æ¥­¡¼¤òÊѤ¨¤¿¤¢¤È¤Ë¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤òÊݸ¤·¤¿¾ì¹ç¤Ï, ¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤È"
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: ¥é¥¤¥Ö¥é¥ê %s ¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
-#~ msgid ""
-#~ "\n"
-#~ "to use the same key for text file and swap file"
-#~ msgstr ""
-#~ "\n"
-#~ "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ËƱ¤¸°Å¹æ¥­¡¼¤ò»È¤¦¤¿¤á¤Ëenter¤À¤±¤ò²¡¤·¤Æ¤¯¤À¤µ¤¤."
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr ""
+"¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹, ¤´¤á¤ó¤Ê¤µ¤¤: Perl¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿."
-#~ msgid "Using crypt key from swap file for the text file.\n"
-#~ msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤«¤é¼èÆÀ¤·¤¿°Å¹æ¥­¡¼¤ò¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤Ë»È¤¤¤Þ¤¹.\n"
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr ""
+"E299: ¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤Ï Safe ¥â¥¸¥å¡¼¥ë¤ò»ÈÍѤ·¤Ê¤¤Perl¥¹¥¯¥ê¥×¥È¤Ï¶Ø¤¸¤é¤ì"
+"¤Æ¤¤¤Þ¤¹"
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [¤³¤ÎVim¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï»ÈÍѤǤ­¤Þ¤»¤ó]"
+msgid "Edit with &multiple Vims"
+msgstr "Ê£¿ô¤ÎVim¤ÇÊÔ½¸¤¹¤ë (&M)"
-#~ msgid "Tear off this menu"
-#~ msgstr "¤³¤Î¥á¥Ë¥å¡¼¤òÀÚ¤ê¼è¤ë"
+msgid "Edit with single &Vim"
+msgstr "1¤Ä¤ÎVim¤ÇÊÔ½¸¤¹¤ë (&V)"
-#~ msgid "Select Directory dialog"
-#~ msgstr "¥Ç¥£¥ì¥¯¥È¥êÁªÂò¥À¥¤¥¢¥í¥°"
+msgid "Diff with Vim"
+msgstr "Vim¤Çº¹Ê¬¤òɽ¼¨¤¹¤ë"
-#~ msgid "Save File dialog"
-#~ msgstr "¥Õ¥¡¥¤¥ëÊݸ¥À¥¤¥¢¥í¥°"
+msgid "Edit with &Vim"
+msgstr "Vim¤ÇÊÔ½¸¤¹¤ë (&V)"
-#~ msgid "Open File dialog"
-#~ msgstr "¥Õ¥¡¥¤¥ëÆÉ¹þ¥À¥¤¥¢¥í¥°"
+#. Now concatenate
+msgid "Edit with existing Vim - "
+msgstr "µ¯Æ°ºÑ¤ÎVim¤ÇÊÔ½¸¤¹¤ë - "
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr ""
-#~ "E338: ¥³¥ó¥½¡¼¥ë¥â¡¼¥É¤Ç¤Ï¥Õ¥¡¥¤¥ë¥Ö¥é¥¦¥¶¤ò»È¤¨¤Þ¤»¤ó, ¤´¤á¤ó¤Ê¤µ¤¤"
+msgid "Edits the selected file(s) with Vim"
+msgstr "ÁªÂò¤·¤¿¥Õ¥¡¥¤¥ë¤òVim¤ÇÊÔ½¸¤¹¤ë"
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "Vim: ¥Õ¥¡¥¤¥ë¤òÊÝÂ¸Ãæ...\n"
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "¥×¥í¥»¥¹¤ÎºîÀ®¤Ë¼ºÇÔ: gvim¤¬´Ä¶­ÊÑ¿ôPATH¾å¤Ë¤¢¤ë¤«³Îǧ¤·¤Æ¤¯¤À¤µ¤¤!"
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "Vim: ½ªÎ»¤·¤Þ¤·¤¿.\n"
+msgid "gvimext.dll error"
+msgstr "gvimext.dll ¥¨¥é¡¼"
-#~ msgid "ERROR: "
-#~ msgstr "¥¨¥é¡¼: "
+msgid "Path length too long!"
+msgstr "¥Ñ¥¹¤¬Ä¹²á¤®¤Þ¤¹!"
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[¥á¥â¥ê(¥Ð¥¤¥È)] Áí³äÅö-²òÊüÎÌ %<PRIu64>-%<PRIu64>, »ÈÍÑÎÌ %<PRIu64>, ¥Ô¡¼"
-#~ "¥¯»þ %<PRIu64>\n"
+msgid "--No lines in buffer--"
+msgstr "--¥Ð¥Ã¥Õ¥¡¤Ë¹Ô¤¬¤¢¤ê¤Þ¤»¤ó--"
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[¸Æ½Ð] Áí re/malloc() ²ó¿ô %<PRIu64>, Áí free() ²ó¿ô %<PRIu64>\n"
-#~ "\n"
+#.
+#. * 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 "E340: Line is becoming too long"
-#~ msgstr "E340: ¹Ô¤¬Ä¹¤¯¤Ê¤ê²á¤®¤Þ¤·¤¿"
+msgid "E471: Argument required"
+msgstr "E471: °ú¿ô¤¬É¬ÍפǤ¹"
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: ÆâÉô¥¨¥é¡¼: lalloc(%<PRId64>,)"
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ ¤Î¸å¤Ï / ¤« ? ¤« & ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: ÉÔÀµ¤Ê 'mouseshape' ¤Ç¤¹"
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: ¥³¥Þ¥ó¥É¥é¥¤¥ó¤Ç¤Ï̵¸ú¤Ç¤¹; <CR>¤Ç¼Â¹Ô, CTRL-C¤Ç¤ä¤á¤ë"
-#~ msgid "Enter encryption key: "
-#~ msgstr "°Å¹æ²½ÍѤΥ­¡¼¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤: "
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: ¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ä¥¿¥°¸¡º÷¤Ç¤Ïexrc/vimrc¤Î¥³¥Þ¥ó¥É¤Ïµö²Ä¤µ¤ì¤Þ¤»¤ó"
-#~ msgid "Enter same key again: "
-#~ msgstr "¤â¤¦°ìÅÙÆ±¤¸¥­¡¼¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤: "
+msgid "E171: Missing :endif"
+msgstr "E171: :endif ¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "Keys don't match!"
-#~ msgstr "¥­¡¼¤¬°ìÃפ·¤Þ¤»¤ó"
+msgid "E600: Missing :endtry"
+msgstr "E600: :endtry ¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Netbeans #2 ¤ËÀܳ¤Ç¤­¤Þ¤»¤ó"
+msgid "E170: Missing :endwhile"
+msgstr "E170: :endwhile ¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Netbeans ¤ËÀܳ¤Ç¤­¤Þ¤»¤ó"
+msgid "E170: Missing :endfor"
+msgstr "E170: :endfor ¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr ""
-#~ "E668: NetBeans¤ÎÀܳ¾ðÊó¥Õ¥¡¥¤¥ë¤Î¥¢¥¯¥»¥¹¥â¡¼¥É¤ËÌäÂ꤬¤¢¤ê¤Þ¤¹: \"%s\""
+msgid "E588: :endwhile without :while"
+msgstr "E588: :while ¤Î¤Ê¤¤ :endwhile ¤¬¤¢¤ê¤Þ¤¹"
-#~ msgid "read from Netbeans socket"
-#~ msgstr "Netbeans ¤Î¥½¥±¥Ã¥È¤òÆÉ¹þ¤ß"
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor ¤Î¤Ê¤¤ :for ¤¬¤¢¤ê¤Þ¤¹"
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: ¥Ð¥Ã¥Õ¥¡ %<PRId64> ¤Î NetBeans Àܳ¤¬¼º¤ï¤ì¤Þ¤·¤¿"
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: ¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤·¤Þ¤¹ (! ¤òÄɲäǾå½ñ)"
-#~ msgid "E838: netbeans is not supported with this GUI"
-#~ msgstr "E838: NetBeans¤Ï¤³¤ÎGUI¤Ë¤ÏÂбþ¤·¤Æ¤¤¤Þ¤»¤ó"
+msgid "E472: Command failed"
+msgstr "E472: ¥³¥Þ¥ó¥É¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "E511: netbeans already connected"
-#~ msgstr "E511: NetBeans¤Ï´û¤ËÀܳ¤·¤Æ¤¤¤Þ¤¹"
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: ̤ÃΤΥե©¥ó¥È¥»¥Ã¥È: %s"
-#~ msgid "E505: %s is read-only (add ! to override)"
-#~ msgstr "E505: %s ¤ÏÆÉ¹þÀìÍѤǤ¹ (¶¯À©½ñ¹þ¤Ë¤Ï ! ¤òÄɲÃ)"
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: ̤ÃΤΥե©¥ó¥È: %s"
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: ¼°É¾²Áµ¡Ç½¤¬Ìµ¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹"
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: ¥Õ¥©¥ó¥È \"%s\" ¤Ï¸ÇÄêÉý¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "%<PRId64> ¹Ô¤ò²òÊüÃæ"
+msgid "E473: Internal error"
+msgstr "E473: ÆâÉô¥¨¥é¡¼¤Ç¤¹"
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: GUI¤Ç¤Ï 'term' ¤òÊѹ¹¤Ç¤­¤Þ¤»¤ó"
+msgid "Interrupted"
+msgstr "³ä¹þ¤Þ¤ì¤Þ¤·¤¿"
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: GUI¤ò¥¹¥¿¡¼¥È¤¹¤ë¤Ë¤Ï \":gui\" ¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤"
+msgid "E14: Invalid address"
+msgstr "E14: ̵¸ú¤Ê¥¢¥É¥ì¥¹¤Ç¤¹"
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: GTK+2 GUI¤Ç¤ÏÊѹ¹¤Ç¤­¤Þ¤»¤ó"
+msgid "E474: Invalid argument"
+msgstr "E474: ̵¸ú¤Ê°ú¿ô¤Ç¤¹"
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: ̵¸ú¤Ê¥Õ¥©¥ó¥È¤Ç¤¹"
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: ̵¸ú¤Ê°ú¿ô¤Ç¤¹: %s"
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: ¥Õ¥©¥ó¥È¥»¥Ã¥È¤òÁªÂò¤Ç¤­¤Þ¤»¤ó"
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: ̵¸ú¤Ê¼°¤Ç¤¹: %s"
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: ̵¸ú¤Ê¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ç¤¹"
+msgid "E16: Invalid range"
+msgstr "E16: ̵¸ú¤ÊÈϰϤǤ¹"
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: ¥ï¥¤¥É¥Õ¥©¥ó¥È¤òÁªÂò¤Ç¤­¤Þ¤»¤ó"
+msgid "E476: Invalid command"
+msgstr "E476: ̵¸ú¤Ê¥³¥Þ¥ó¥É¤Ç¤¹"
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: ̵¸ú¤Ê¥ï¥¤¥É¥Õ¥©¥ó¥È¤Ç¤¹"
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" ¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹"
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: ¥Þ¥¦¥¹¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤»¤ó"
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: \"%s\"() ¤Î¥é¥¤¥Ö¥é¥ê¸Æ½Ð¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "cannot open "
-#~ msgstr "³«¤±¤Þ¤»¤ó "
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: ¥é¥¤¥Ö¥é¥ê¤Î´Ø¿ô %s ¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: ¥¦¥£¥ó¥É¥¦¤ò³«¤±¤Þ¤»¤ó!\n"
+msgid "E19: Mark has invalid line number"
+msgstr "E19: ¥Þ¡¼¥¯¤Ë̵¸ú¤Ê¹ÔÈֹ椬»ØÄꤵ¤ì¤Æ¤¤¤Þ¤·¤¿"
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Amigados¤Î¥Ð¡¼¥¸¥ç¥ó 2.04¤«¤½¤ì°Ê¹ß¤¬É¬ÍפǤ¹\n"
+msgid "E20: Mark not set"
+msgstr "E20: ¥Þ¡¼¥¯¤ÏÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "%s ¤Î¥Ð¡¼¥¸¥ç¥ó %<PRId64> ¤¬É¬ÍפǤ¹\n"
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: 'modifiable' ¤¬¥ª¥Õ¤Ê¤Î¤Ç, Êѹ¹¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "NIL¤ò³«¤±¤Þ¤»¤ó:\n"
+msgid "E22: Scripts nested too deep"
+msgstr "E22: ¥¹¥¯¥ê¥×¥È¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
-#~ msgid "Cannot create "
-#~ msgstr "ºîÀ®¤Ç¤­¤Þ¤»¤ó "
+msgid "E23: No alternate file"
+msgstr "E23: Éû¥Õ¥¡¥¤¥ë¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim¤Ï %d ¤Ç½ªÎ»¤·¤Þ¤¹\n"
+msgid "E24: No such abbreviation"
+msgstr "E24: ¤½¤Î¤è¤¦¤Êû½ÌÆþÎϤϤ¢¤ê¤Þ¤»¤ó"
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "¥³¥ó¥½¡¼¥ë¥â¡¼¥É¤òÊѹ¹¤Ç¤­¤Þ¤»¤ó?!\n"
+msgid "E477: No ! allowed"
+msgstr "E477: ! ¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: ¥³¥ó¥½¡¼¥ë¤Ç¤Ï¤Ê¤¤??\n"
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: GUI¤Ï»ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹"
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: -f ¥ª¥×¥·¥ç¥ó¤Ç¥·¥§¥ë¤ò¼Â¹Ô¤Ç¤­¤Þ¤»¤ó"
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: ¥Ø¥Ö¥é¥¤¸ì¤Ï»ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹\n"
-#~ msgid "Cannot execute "
-#~ msgstr "¼Â¹Ô¤Ç¤­¤Þ¤»¤ó "
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: ¥Ú¥ë¥·¥¢¸ì¤Ï»ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹\n"
-#~ msgid "shell "
-#~ msgstr "¥·¥§¥ë "
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: ¥¢¥é¥Ó¥¢¸ì¤Ï»ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹\n"
-#~ msgid " returned\n"
-#~ msgstr " Ìá¤ê¤Þ¤·¤¿\n"
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: ¤½¤Î¤è¤¦¤Ê̾¤Î¥Ï¥¤¥é¥¤¥È¥°¥ë¡¼¥×¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE ¤¬¾®¤µ²á¤®¤Þ¤¹."
+msgid "E29: No inserted text yet"
+msgstr "E29: ¤Þ¤À¥Æ¥­¥¹¥È¤¬ÁÞÆþ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "I/O ERROR"
-#~ msgstr "Æþ½ÐÎÏ¥¨¥é¡¼"
+msgid "E30: No previous command line"
+msgstr "E30: °ÊÁ°¤Ë¥³¥Þ¥ó¥É¹Ô¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "Message"
-#~ msgstr "¥á¥Ã¥»¡¼¥¸"
+msgid "E31: No such mapping"
+msgstr "E31: ¤½¤Î¤è¤¦¤Ê¥Þ¥Ã¥Ô¥ó¥°¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "'columns' ¤¬80¤Ç¤Ï¤Ê¤¤¤¿¤á, ³°Éô¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤Ç¤­¤Þ¤»¤ó"
+msgid "E479: No match"
+msgstr "E479: ³ºÅö¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: ¥×¥ê¥ó¥¿¤ÎÁªÂò¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: ³ºÅö¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
-#~ msgid "to %s on %s"
-#~ msgstr "%s ¤Ø (%s ¾å¤Î)"
+msgid "E32: No file name"
+msgstr "E32: ¥Õ¥¡¥¤¥ë̾¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: ̤ÃΤΥץê¥ó¥¿¥ª¥×¥·¥ç¥ó¤Ç¤¹: %s"
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Àµµ¬É½¸½ÃÖ´¹¤¬¤Þ¤À¼Â¹Ô¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: °õºþ¥¨¥é¡¼: %s"
+msgid "E34: No previous command"
+msgstr "E34: ¥³¥Þ¥ó¥É¤¬¤Þ¤À¼Â¹Ô¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "Printing '%s'"
-#~ msgstr "°õºþ¤·¤Æ¤¤¤Þ¤¹: '%s'"
+msgid "E35: No previous regular expression"
+msgstr "E35: Àµµ¬É½¸½¤¬¤Þ¤À¼Â¹Ô¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
-#~ msgstr "E244: ʸ»ú¥»¥Ã¥È̾ \"%s\" ¤ÏÉÔÀµ¤Ç¤¹ (¥Õ¥©¥ó¥È̾ \"%s\")"
+msgid "E481: No range allowed"
+msgstr "E481: ÈϰϻØÄê¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: '%c' ¤ÏÉÔÀµ¤Êʸ»ú¤Ç¤¹ (¥Õ¥©¥ó¥È̾ \"%s\")"
+msgid "E36: Not enough room"
+msgstr "E36: ¥¦¥£¥ó¥É¥¦¤Ë½½Ê¬¤Ê¹â¤µ¤â¤·¤¯¤ÏÉý¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "Vim: Double signal, exiting\n"
-#~ msgstr "Vim: 2½Å¤Î¥·¥°¥Ê¥ë¤Î¤¿¤á, ½ªÎ»¤·¤Þ¤¹\n"
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: %s ¤È¤¤¤¦Ì¾Á°¤ÎÅÐÏ¿¤µ¤ì¤¿¥µ¡¼¥Ð¡¼¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "Vim: Ã×̿Ū¥·¥°¥Ê¥ë %s ¤ò¸¡ÃΤ·¤Þ¤·¤¿\n"
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "Vim: Ã×̿Ū¥·¥°¥Ê¥ë¤ò¸¡ÃΤ·¤Þ¤·¤¿\n"
+msgid "E483: Can't get temp file name"
+msgstr "E483: °ì»þ¥Õ¥¡¥¤¥ë¤Î̾Á°¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "X¥µ¡¼¥Ð¤Ø¤ÎÀܳ¤Ë %<PRId64> ¥ß¥êÉ䫤«¤ê¤Þ¤·¤¿"
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: ¥Õ¥¡¥¤¥ë \"%s\" ¤ò³«¤±¤Þ¤»¤ó"
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim: X ¤Î¥¨¥é¡¼¤ò¸¡½Ð¤·¤Þ¤·¤¿r\n"
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: ¥Õ¥¡¥¤¥ë %s ¤òÆÉ¹þ¤á¤Þ¤»¤ó"
-#~ msgid "Testing the X display failed"
-#~ msgstr "X display ¤Î¥Á¥§¥Ã¥¯¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: ºÇ¸å¤ÎÊѹ¹¤¬Êݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó (! ¤òÄɲäÇÊѹ¹¤òÇË´þ)"
-#~ msgid "Opening the X display timed out"
-#~ msgstr "X display ¤Î open ¤¬¥¿¥¤¥à¥¢¥¦¥È¤·¤Þ¤·¤¿"
+msgid "E37: No write since last change"
+msgstr "E37: ºÇ¸å¤ÎÊѹ¹¤¬Êݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "sh ¥·¥§¥ë¤ò¼Â¹Ô¤Ç¤­¤Þ¤»¤ó\n"
+msgid "E38: Null argument"
+msgstr "E38: °ú¿ô¤¬¶õ¤Ç¤¹"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "¥Ñ¥¤¥×¤òºîÀ®¤Ç¤­¤Þ¤»¤ó\n"
+msgid "E39: Number expected"
+msgstr "E39: ¿ôÃͤ¬Í׵ᤵ¤ì¤Æ¤¤¤Þ¤¹"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "fork ¤Ç¤­¤Þ¤»¤ó\n"
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: ¥¨¥é¡¼¥Õ¥¡¥¤¥ë %s ¤ò³«¤±¤Þ¤»¤ó"
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "¥³¥Þ¥ó¥É¤òÃæÃǤ·¤Þ¤·¤¿\n"
+msgid "E233: cannot open display"
+msgstr "E233: ¥Ç¥£¥¹¥×¥ì¥¤¤ò³«¤±¤Þ¤»¤ó"
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP ¤¬ICEÀܳ¤ò¼º¤¤¤Þ¤·¤¿"
+msgid "E41: Out of memory!"
+msgstr "E41: ¥á¥â¥ê¤¬¿Ô¤­²Ì¤Æ¤Þ¤·¤¿!"
-#~ msgid "Opening the X display failed"
-#~ msgstr "X display ¤Î open ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "Pattern not found"
+msgstr "¥Ñ¥¿¡¼¥ó¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP ¤¬save-yourselfÍ×µá¤ò½èÍý¤·¤Æ¤¤¤Þ¤¹"
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: ¥Ñ¥¿¡¼¥ó¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿: %s"
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP ¤¬Àܳ¤ò³«»Ï¤·¤Æ¤¤¤Þ¤¹"
+msgid "E487: Argument must be positive"
+msgstr "E487: °ú¿ô¤ÏÀµ¤ÎÃͤǤʤ±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP ICEÀܳ¤¬¼ºÇÔ¤·¤¿¤è¤¦¤Ç¤¹"
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Á°¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ËÌá¤ì¤Þ¤»¤ó"
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP SmcOpenConnection¤¬¼ºÇÔ¤·¤Þ¤·¤¿: %s"
+msgid "E42: No Errors"
+msgstr "E42: ¥¨¥é¡¼¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "At line"
-#~ msgstr "¹Ô"
+msgid "E776: No location list"
+msgstr "E776: ¥í¥±¡¼¥·¥ç¥ó¥ê¥¹¥È¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "vim32.dll ¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
+msgid "E43: Damaged match string"
+msgstr "E43: ³ºÅöʸ»úÎó¤¬ÇË»¤·¤Æ¤¤¤Þ¤¹"
-#~ msgid "VIM Error"
-#~ msgstr "VIM¥¨¥é¡¼"
+msgid "E44: Corrupted regexp program"
+msgstr "E44: ÉÔÀµ¤ÊÀµµ¬É½¸½¥×¥í¥°¥é¥à¤Ç¤¹"
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "DLL¤«¤é´Ø¿ô¥Ý¥¤¥ó¥¿¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: 'readonly' ¥ª¥×¥·¥ç¥ó¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹ (! ¤òÄɲäǾå½ñ¤­)"
-#~ msgid "shell returned %d"
-#~ msgstr "¥·¥§¥ë¤¬¥³¡¼¥É %d ¤Ç½ªÎ»¤·¤Þ¤·¤¿"
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: ÆÉ¼èÀìÍÑÊÑ¿ô \"%s\" ¤Ë¤ÏÃͤòÀßÄê¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: ¥¤¥Ù¥ó¥È %s ¤ò¸¡ÃÎ\n"
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: ¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤ÏÊÑ¿ô \"%s\" ¤ËÃͤòÀßÄê¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "close"
-#~ msgstr "ÊĤ¸¤ë"
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: ¼­½ñ·¿¤Ë¶õ¤Î¥­¡¼¤ò»È¤¦¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "logoff"
-#~ msgstr "¥í¥°¥ª¥Õ"
+msgid "E715: Dictionary required"
+msgstr "E715: ¼­½ñ·¿¤¬É¬ÍפǤ¹"
-#~ msgid "shutdown"
-#~ msgstr "¥·¥ã¥Ã¥È¥À¥¦¥ó"
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: ¥ê¥¹¥È¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤¬Èϰϳ°¤Ç¤¹: %ld"
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: ¥³¥Þ¥ó¥É¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#~ msgid ""
-#~ "VIMRUN.EXE not found in your $PATH.\n"
-#~ "External commands will not pause after completion.\n"
-#~ "See :help win32-vimrun for more information."
-#~ msgstr ""
-#~ "VIMRUN.EXE¤¬ $PATH ¤ÎÃæ¤Ë¸«¤Ä¤«¤ê¤Þ¤»¤ó.\n"
-#~ "³°Éô¥³¥Þ¥ó¥É¤Î½ªÎ»¸å¤Ë°ì»þÄä»ß¤ò¤·¤Þ¤»¤ó.\n"
-#~ "¾ÜºÙ¤Ï :help win32-vimrun ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤."
-
-#~ msgid "Vim Warning"
-#~ msgstr "Vim¤Î·Ù¹ð"
-
-#~ msgid "Error file"
-#~ msgstr "¥¨¥é¡¼¥Õ¥¡¥¤¥ë"
-
-#~ msgid "E868: Error building NFA with equivalence class!"
-#~ msgstr "E868: Åù²Á¥¯¥é¥¹¤ò´Þ¤àNFA¹½Ãۤ˼ºÇÔ¤·¤Þ¤·¤¿!"
-
-#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!"
-#~ msgstr "E878: (NFA) ¸½ºß²£ÃÇÃæ¤Î¥Ö¥é¥ó¥Á¤Ë½½Ê¬¤Ê¥á¥â¥ê¤ò³ä¤êÅö¤Æ¤é¤ì¤Þ¤»¤ó!"
-
-#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
-#~ msgstr ""
-#~ "·Ù¹ð: ñ¸ì¥ê¥¹¥È \"%s_%s.spl\" ¤ª¤è¤Ó \"%s_ascii.spl\" ¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "%s Æâ¤ÎÊÑ´¹¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-
-#~ msgid "E845: Insufficient memory, word list will be incomplete"
-#~ msgstr "E845: ¥á¥â¥ê¤¬Â­¤ê¤Ê¤¤¤Î¤Ç¡¢Ã±¸ì¥ê¥¹¥È¤ÏÉÔ´°Á´¤Ç¤¹"
-
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: ¥¿¥°¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤¬ %s ¤ËÀÚ¤ê¼Î¤Æ¤é¤ì¤Þ¤·¤¿\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "¿·¤·¤¤¥·¥§¥ë¤òµ¯Æ°¤·¤Þ¤¹\n"
-
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "¶õ¤ÎÁªÂòÎΰè¤Î¤«¤ï¤ê¤ËCUT_BUFFER0¤¬»ÈÍѤµ¤ì¤Þ¤·¤¿"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "²Äǽ¤Ê¥¢¥ó¥É¥¥¤Ï¤¢¤ê¤Þ¤»¤ó: ¤È¤ê¤¢¤¨¤ºÂ³¤±¤Þ¤¹"
-
-#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
-#~ msgstr ""
-#~ "E832: Èó°Å¹æ²½¥Õ¥¡¥¤¥ë¤¬°Å¹æ²½¤µ¤ì¤¿¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤ò»È¤Ã¤Æ¤Þ¤¹: %s"
-
-#~ msgid "E826: Undo file decryption failed: %s"
-#~ msgstr "E826: °Å¹æ²½¤µ¤ì¤¿¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤Î²òÆÉ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿: %s"
-
-#~ msgid "E827: Undo file is encrypted: %s"
-#~ msgstr "E827: ¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤¬°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹: %s"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16/32 ¥Ó¥Ã¥È GUI ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 64 ¥Ó¥Ã¥È GUI ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32 ¥Ó¥Ã¥È GUI ÈÇ"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " in Win32s ¥â¡¼¥É"
-
-#~ msgid " with OLE support"
-#~ msgstr " with OLE ¥µ¥Ý¡¼¥È"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 64 ¥Ó¥Ã¥È ¥³¥ó¥½¡¼¥ë ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32 ¥Ó¥Ã¥È ¥³¥ó¥½¡¼¥ë ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16 ¥Ó¥Ã¥È ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "32 ¥Ó¥Ã¥È MS-DOS ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "16 ¥Ó¥Ã¥È MS-DOS ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X (unix) ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "OpenVMS ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Big ÈÇ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Ä̾ï ÈÇ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Small ÈÇ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Tiny ÈÇ "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "with GTK2-GNOME GUI."
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: ´Ø¿ô¤Î°ú¿ô¤¬Â¿²á¤®¤Þ¤¹: %s"
-#~ msgid "with GTK2 GUI."
-#~ msgstr "with GTK2 GUI."
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: ¼­½ñ·¿¤Ë¥­¡¼¤¬Â¸ºß¤·¤Þ¤»¤ó: %s"
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "with X11-Motif GUI."
+msgid "E714: List required"
+msgstr "E714: ¥ê¥¹¥È·¿¤¬É¬ÍפǤ¹"
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "with X11-neXtaw GUI."
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: %s ¤Î°ú¿ô¤Ï¥ê¥¹¥È·¿¤Þ¤¿¤Ï¼­½ñ·¿¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "with X11-Athena GUI."
+msgid "E47: Error while reading errorfile"
+msgstr "E47: ¥¨¥é¡¼¥Õ¥¡¥¤¥ë¤ÎÆÉ¹þÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿"
-#~ msgid "with Photon GUI."
-#~ msgstr "with Photon GUI."
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: ¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤Ïµö¤µ¤ì¤Þ¤»¤ó"
-#~ msgid "with GUI."
-#~ msgstr "with GUI."
+msgid "E523: Not allowed here"
+msgstr "E523: ¤³¤³¤Ç¤Ïµö²Ä¤µ¤ì¤Þ¤»¤ó"
-#~ msgid "with Carbon GUI."
-#~ msgstr "with Carbon GUI."
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: ¥¹¥¯¥ê¡¼¥ó¥â¡¼¥É¤ÎÀßÄê¤Ë¤ÏÂбþ¤·¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "with Cocoa GUI."
-#~ msgstr "with Cocoa GUI."
+msgid "E49: Invalid scroll size"
+msgstr "E49: ̵¸ú¤Ê¥¹¥¯¥í¡¼¥ëÎ̤Ǥ¹"
-#~ msgid "with (classic) GUI."
-#~ msgstr "with (¥¯¥é¥·¥Ã¥¯) GUI."
+msgid "E91: 'shell' option is empty"
+msgstr "E91: 'shell' ¥ª¥×¥·¥ç¥ó¤¬¶õ¤Ç¤¹"
-#~ msgid " system gvimrc file: \""
-#~ msgstr " ¥·¥¹¥Æ¥à gvimrc: \""
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: sign ¤Î¥Ç¡¼¥¿¤òÆÉ¹þ¤á¤Þ¤»¤ó¤Ç¤·¤¿"
-#~ msgid " user gvimrc file: \""
-#~ msgstr " ¥æ¡¼¥¶ gvimrc: \""
+msgid "E72: Close error on swap file"
+msgstr "E72: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î¥¯¥í¡¼¥º»þ¥¨¥é¡¼¤Ç¤¹"
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr " Âè2¥æ¡¼¥¶ gvimrc: \""
+msgid "E73: tag stack empty"
+msgstr "E73: ¥¿¥°¥¹¥¿¥Ã¥¯¤¬¶õ¤Ç¤¹"
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr " Âè3¥æ¡¼¥¶ gvimrc: \""
+msgid "E74: Command too complex"
+msgstr "E74: ¥³¥Þ¥ó¥É¤¬Ê£»¨²á¤®¤Þ¤¹"
-#~ msgid " system menu file: \""
-#~ msgstr " ¥·¥¹¥Æ¥à¥á¥Ë¥å¡¼: \""
+msgid "E75: Name too long"
+msgstr "E75: ̾Á°¤¬Ä¹²á¤®¤Þ¤¹"
-#~ msgid "Compiler: "
-#~ msgstr "¥³¥ó¥Ñ¥¤¥é: "
+msgid "E76: Too many ["
+msgstr "E76: [ ¤¬Â¿²á¤®¤Þ¤¹"
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "¾ÜºÙ¤Ï¥á¥Ë¥å¡¼¤Î ¥Ø¥ë¥×¢ª¸É»ù ¤ò»²¾È¤·¤Æ²¼¤µ¤¤ "
+msgid "E77: Too many file names"
+msgstr "E77: ¥Õ¥¡¥¤¥ë̾¤¬Â¿²á¤®¤Þ¤¹"
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "¥â¡¼¥É̵¤Ç¼Â¹ÔÃæ, ¥¿¥¤¥×¤·¤¿Ê¸»ú¤¬ÁÞÆþ¤µ¤ì¤Þ¤¹"
+msgid "E488: Trailing characters"
+msgstr "E488: ;ʬ¤Êʸ»ú¤¬¸å¤í¤Ë¤¢¤ê¤Þ¤¹"
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "¥á¥Ë¥å¡¼¤Î ÊÔ½¸¢ªÁ´ÂÎÀßÄꢪÁÞÆþ(½é¿´¼Ô)¥â¡¼¥ÉÀÚÂØ "
+msgid "E78: Unknown mark"
+msgstr "E78: ̤ÃΤΥޡ¼¥¯"
-#~ msgid " for two modes "
-#~ msgstr " ¤Ç¥â¡¼¥ÉÍ­¤Ë "
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: ¥ï¥¤¥ë¥É¥«¡¼¥É¤òŸ³«¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "¥á¥Ë¥å¡¼¤Î ÊÔ½¸¢ªÁ´ÂÎÀßÄꢪVi¸ß´¹¥â¡¼¥ÉÀÚÂØ "
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' ¤Ï 'winminheight' ¤è¤ê¾®¤µ¤¯¤Ç¤­¤Þ¤»¤ó"
-#~ msgid " for Vim defaults "
-#~ msgstr " ¤ÇVim¤È¤·¤ÆÆ°ºî "
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' ¤Ï 'winminwidth' ¤è¤ê¾®¤µ¤¯¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr " ·Ù¹ð: Windows 95/98/Me ¤ò¸¡½Ð "
+msgid "E80: Error while writing"
+msgstr "E80: ½ñ¹þ¤ßÃæ¤Î¥¨¥é¡¼"
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr " ¾ÜºÙ¤Ê¾ðÊó¤Ï :help windows95<Enter> "
+msgid "Zero count"
+msgstr "¥¼¥í¥«¥¦¥ó¥È"
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "Ê£¿ô¤ÎVim¤ÇÊÔ½¸¤¹¤ë (&M)"
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: ¥¹¥¯¥ê¥×¥È°Ê³°¤Ç<SID>¤¬»È¤ï¤ì¤Þ¤·¤¿"
-#~ msgid "Edit with single &Vim"
-#~ msgstr "1¤Ä¤ÎVim¤ÇÊÔ½¸¤¹¤ë (&V)"
+msgid "E449: Invalid expression received"
+msgstr "E449: ̵¸ú¤Ê¼°¤ò¼õ¤±¼è¤ê¤Þ¤·¤¿"
-#~ msgid "Diff with Vim"
-#~ msgstr "Vim¤Çº¹Ê¬¤òɽ¼¨¤¹¤ë"
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Îΰ褬Êݸ¤ì¤Æ¤¤¤ë¤Î¤Ç, Êѹ¹¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "Edit with &Vim"
-#~ msgstr "Vim¤ÇÊÔ½¸¤¹¤ë (&V)"
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans ¤ÏÆÉ¹þÀìÍÑ¥Õ¥¡¥¤¥ë¤òÊѹ¹¤¹¤ë¤³¤È¤òµö¤·¤Þ¤»¤ó"
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "µ¯Æ°ºÑ¤ÎVim¤ÇÊÔ½¸¤¹¤ë - "
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: ÆâÉô¥¨¥é¡¼¤Ç¤¹: %s"
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "ÁªÂò¤·¤¿¥Õ¥¡¥¤¥ë¤òVim¤ÇÊÔ½¸¤¹¤ë"
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: ¥Ñ¥¿¡¼¥ó¤¬ 'maxmempattern' °Ê¾å¤Î¥á¥â¥ê¤ò»ÈÍѤ·¤Þ¤¹"
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "¥×¥í¥»¥¹¤ÎºîÀ®¤Ë¼ºÇÔ: gvim¤¬´Ä¶­ÊÑ¿ôPATH¾å¤Ë¤¢¤ë¤«³Îǧ¤·¤Æ¤¯¤À¤µ¤¤!"
+msgid "E749: empty buffer"
+msgstr "E749: ¥Ð¥Ã¥Õ¥¡¤¬¶õ¤Ç¤¹"
-#~ msgid "gvimext.dll error"
-#~ msgstr "gvimext.dll ¥¨¥é¡¼"
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: ¥Ð¥Ã¥Õ¥¡ %ld ¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "Path length too long!"
-#~ msgstr "¥Ñ¥¹¤¬Ä¹¤¹¤®¤Þ¤¹!"
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: ¸¡º÷¥Ñ¥¿¡¼¥ó¤«¶èÀڤ국¹æ¤¬ÉÔÀµ¤Ç¤¹"
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: ̤ÃΤΥե©¥ó¥È¥»¥Ã¥È: %s"
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Ʊ¤¸Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¾¤Î¥Ð¥Ã¥Õ¥¡¤ÇÆÉ¹þ¤Þ¤ì¤Æ¤¤¤Þ¤¹"
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: ̤ÃΤΥե©¥ó¥È: %s"
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: ¥ª¥×¥·¥ç¥ó '%s' ¤ÏÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: ¥Õ¥©¥ó¥È \"%s\" ¤Ï¸ÇÄêÉý¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "E850: Invalid register name"
+msgstr "E850: ̵¸ú¤Ê¥ì¥¸¥¹¥¿Ì¾¤Ç¤¹"
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: ¥é¥¤¥Ö¥é¥ê¤Î´Ø¿ô %s ¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
+#, c-format
+msgid "E919: Directory not found in '%s': \"%s\""
+msgstr "E919: ¥Ç¥£¥ì¥¯¥È¥ê¤¬ '%s' ¤ÎÃæ¤Ë¤¢¤ê¤Þ¤»¤ó: \"%s\""
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr "E26: ¥Ø¥Ö¥é¥¤¸ì¤Ï»ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹\n"
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "¾å¤Þ¤Ç¸¡º÷¤·¤¿¤Î¤Ç²¼¤ËÌá¤ê¤Þ¤¹"
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: ¥Ú¥ë¥·¥¢¸ì¤Ï»ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹\n"
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "²¼¤Þ¤Ç¸¡º÷¤·¤¿¤Î¤Ç¾å¤ËÌá¤ê¤Þ¤¹"
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E800: ¥¢¥é¥Ó¥¢¸ì¤Ï»ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹\n"
+#, c-format
+msgid "Need encryption key for \"%s\""
+msgstr "°Å¹æ¥­¡¼¤¬É¬ÍפǤ¹: \"%s\""
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: %s ¤È¤¤¤¦Ì¾Á°¤ÎÅÐÏ¿¤µ¤ì¤¿¥µ¡¼¥Ð¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "empty keys are not allowed"
+msgstr "¶õ¤Î¥­¡¼¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: ¥Ç¥£¥¹¥×¥ì¥¤¤ò³«¤±¤Þ¤»¤ó"
+msgid "dictionary is locked"
+msgstr "¼­½ñ¤Ï¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤Þ¤¹"
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: ̵¸ú¤Ê¼°¤ò¼õ¤±¼è¤ê¤Þ¤·¤¿"
+msgid "list is locked"
+msgstr "¥ê¥¹¥È¤Ï¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤Þ¤¹"
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: Îΰ褬Êݸ¤ì¤Æ¤¤¤ë¤Î¤Ç, Êѹ¹¤Ç¤­¤Þ¤»¤ó"
+#, c-format
+msgid "failed to add key '%s' to dictionary"
+msgstr "¼­½ñ¤Ë¥­¡¼ '%s' ¤òÄɲ乤ë¤Î¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans ¤ÏÆÉ¹þÀìÍÑ¥Õ¥¡¥¤¥ë¤òÊѹ¹¤¹¤ë¤³¤È¤òµö¤·¤Þ¤»¤ó"
+#, c-format
+msgid "index must be int or slice, not %s"
+msgstr "¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ï %s ¤Ç¤Ï¤Ê¤¯À°¿ô¤«¥¹¥é¥¤¥¹¤Ë¤·¤Æ¤¯¤À¤µ¤¤"
-#~ msgid "Need encryption key for \"%s\""
-#~ msgstr "°Å¹æ¥­¡¼¤¬É¬ÍפǤ¹: \"%s\""
+#, c-format
+msgid "expected str() or unicode() instance, but got %s"
+msgstr "str() ¤â¤·¤¯¤Ï unicode() ¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
-#~ msgid "empty keys are not allowed"
-#~ msgstr "¶õ¤Î¥­¡¼¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+#, c-format
+msgid "expected bytes() or str() instance, but got %s"
+msgstr "bytes() ¤â¤·¤¯¤Ï str() ¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
-#~ msgid "dictionary is locked"
-#~ msgstr "¼­½ñ¤Ï¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤Þ¤¹"
+#, c-format
+msgid ""
+"expected int(), long() or something supporting coercing to long(), but got %s"
+msgstr "long() ¤«¤½¤ì¤ØÊÑ´¹²Äǽ¤Ê¤â¤Î¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
-#~ msgid "list is locked"
-#~ msgstr "¥ê¥¹¥È¤Ï¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤Þ¤¹"
+#, c-format
+msgid "expected int() or something supporting coercing to int(), but got %s"
+msgstr "int() ¤«¤½¤ì¤ØÊÑ´¹²Äǽ¤Ê¤â¤Î¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
-#~ msgid "failed to add key '%s' to dictionary"
-#~ msgstr "¼­½ñ¤Ë¥­¡¼ '%s' ¤òÄɲ乤ë¤Î¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "value is too large to fit into C int type"
+msgstr "C¸À¸ì¤Î int ·¿¤È¤·¤Æ¤ÏÃͤ¬Â礭²á¤®¤Þ¤¹"
-#~ msgid "index must be int or slice, not %s"
-#~ msgstr "¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ï %s ¤Ç¤Ï¤Ê¤¯À°¿ô¤«¥¹¥é¥¤¥¹¤Ë¤·¤Æ¤¯¤À¤µ¤¤"
+msgid "value is too small to fit into C int type"
+msgstr "C¸À¸ì¤Î int ·¿¤È¤·¤Æ¤ÏÃͤ¬¾®¤µ²á¤®¤Þ¤¹"
-#~ msgid "expected str() or unicode() instance, but got %s"
-#~ msgstr ""
-#~ "str() ¤â¤·¤¯¤Ï unicode() ¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
+msgid "number must be greater than zero"
+msgstr "¿ôÃÍ¤Ï 0 ¤è¤êÂ礭¤¯¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#~ msgid "expected bytes() or str() instance, but got %s"
-#~ msgstr "bytes() ¤â¤·¤¯¤Ï str() ¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
+msgid "number must be greater or equal to zero"
+msgstr "¿ôÃÍ¤Ï 0 ¤«¤½¤ì°Ê¾å¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#~ msgid ""
-#~ "expected int(), long() or something supporting coercing to long(), but "
-#~ "got %s"
-#~ msgstr "long() ¤«¤½¤ì¤ØÊÑ´¹²Äǽ¤Ê¤â¤Î¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
+msgid "can't delete OutputObject attributes"
+msgstr "OutputObject°À­¤ò¾Ã¤»¤Þ¤»¤ó"
-#~ msgid "expected int() or something supporting coercing to int(), but got %s"
-#~ msgstr "int() ¤«¤½¤ì¤ØÊÑ´¹²Äǽ¤Ê¤â¤Î¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
+#, c-format
+msgid "invalid attribute: %s"
+msgstr "̵¸ú¤Ê°À­¤Ç¤¹: %s"
-#~ msgid "value is too large to fit into C int type"
-#~ msgstr "C¸À¸ì¤Î int ·¿¤È¤·¤Æ¤ÏÃͤ¬Â礭²á¤®¤Þ¤¹"
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: I/O¥ª¥Ö¥¸¥§¥¯¥È¤Î½é´ü²½¥¨¥é¡¼"
-#~ msgid "value is too small to fit into C int type"
-#~ msgstr "C¸À¸ì¤Î int ·¿¤È¤·¤Æ¤ÏÃͤ¬¾®¤µ²á¤®¤Þ¤¹"
+msgid "failed to change directory"
+msgstr "¼­½ñ¤ÎÊѹ¹¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "number must be greater then zero"
-#~ msgstr "¿ôÃÍ¤Ï 0 ¤è¤êÂ礭¤¯¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got %s"
+msgstr "imp.find_module() ¤¬ %s ¤òÊÖ¤·¤Þ¤·¤¿ (´üÂÔÃÍ: 3 Í×ÁǤΥ¿¥×¥ë)"
-#~ msgid "number must be greater or equal to zero"
-#~ msgstr "¿ôÃÍ¤Ï 0 ¤«¤½¤ì°Ê¾å¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
+msgstr "imp.find_module() ¤¬ %d Í×ÁǤΥ¿¥×¥ë¤òÊÖ¤·¤Þ¤·¤¿ (´üÂÔÃÍ: 3)"
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "OutputObject°À­¤ò¾Ã¤»¤Þ¤»¤ó"
+msgid "internal error: imp.find_module returned tuple with NULL"
+msgstr "ÆâÉô¥¨¥é¡¼: imp.find_module ¤¬ NULL ¤ò´Þ¤à¥¿¥×¥ë¤òÊÖ¤·¤Þ¤·¤¿"
-#~ msgid "invalid attribute: %s"
-#~ msgstr "̵¸ú¤Ê°À­¤Ç¤¹: %s"
+msgid "cannot delete vim.Dictionary attributes"
+msgstr "vim.Dictionary°À­¤Ï¾Ã¤»¤Þ¤»¤ó"
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: I/O¥ª¥Ö¥¸¥§¥¯¥È¤Î½é´ü²½¥¨¥é¡¼"
+msgid "cannot modify fixed dictionary"
+msgstr "¸ÇÄꤵ¤ì¤¿¼­½ñ¤ÏÊѹ¹¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "failed to change directory"
-#~ msgstr "¼­½ñ¤ÎÊѹ¹¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "°À­ %s ¤ÏÀßÄê¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "expected 3-tuple as imp.find_module() result, but got %s"
-#~ msgstr "imp.find_module() ¤¬ %s ¤òÊÖ¤·¤Þ¤·¤¿ (´üÂÔÃÍ: 2 Í×ÁǤΥ¿¥×¥ë)"
+msgid "hashtab changed during iteration"
+msgstr "¥¤¥Æ¥ì¡¼¥·¥ç¥óÃæ¤Ë hashtab ¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿"
-#~ msgid ""
-#~ "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
-#~ msgstr "impl.find_module() ¤¬ %d Í×ÁǤΥ¿¥×¥ë¤òÊÖ¤·¤Þ¤·¤¿ (´üÂÔÃÍ: 2)"
+#, c-format
+msgid "expected sequence element of size 2, but got sequence of size %d"
+msgstr "¥·¡¼¥±¥ó¥¹¤ÎÍ×ÁÇ¿ô¤Ë¤Ï 2 ¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤Þ¤·¤¿¤¬ %d ¤Ç¤·¤¿"
-#~ msgid "internal error: imp.find_module returned tuple with NULL"
-#~ msgstr "ÆâÉô¥¨¥é¡¼: imp.find_module ¤¬ NULL ¤ò´Þ¤à¥¿¥×¥ë¤òÊÖ¤·¤Þ¤·¤¿"
+msgid "list constructor does not accept keyword arguments"
+msgstr "¥ê¥¹¥È¤Î¥³¥ó¥¹¥È¥é¥¯¥¿¤Ï¥­¡¼¥ï¡¼¥É°ú¿ô¤ò¼õ¤±ÉÕ¤±¤Þ¤»¤ó"
-#~ msgid "cannot delete vim.Dictionary attributes"
-#~ msgstr "vim.Dictionary°À­¤Ï¾Ã¤»¤Þ¤»¤ó"
+msgid "list index out of range"
+msgstr "¥ê¥¹¥ÈÈϰϳ°¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç¤¹"
-#~ msgid "cannot modify fixed dictionary"
-#~ 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 "cannot set attribute %s"
-#~ msgstr "°À­ %s ¤ÏÀßÄê¤Ç¤­¤Þ¤»¤ó"
+msgid "slice step cannot be zero"
+msgstr "¥¹¥é¥¤¥¹¤Î¥¹¥Æ¥Ã¥×¤Ë 0 ¤Ï»ØÄê¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "hashtab changed during iteration"
-#~ msgstr "¥¤¥Æ¥ì¡¼¥·¥ç¥óÃæ¤Ë hashtab ¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿"
+#, c-format
+msgid "attempt to assign sequence of size greater than %d to extended slice"
+msgstr "Ťµ %d ¤Î³ÈÄ¥¥¹¥é¥¤¥¹¤Ë¡¢¤è¤êŤ¤¥¹¥é¥¤¥¹¤ò³ä¤êÅö¤Æ¤è¤¦¤È¤·¤Þ¤·¤¿"
-#~ msgid "expected sequence element of size 2, but got sequence of size %d"
-#~ msgstr "¥·¡¼¥±¥ó¥¹¤ÎÍ×ÁÇ¿ô¤Ë¤Ï 2 ¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤Þ¤·¤¿¤¬ %d ¤Ç¤·¤¿"
+#, c-format
+msgid "internal error: no vim list item %d"
+msgstr "ÆâÉô¥¨¥é¡¼: vim¤Î¥ê¥¹¥ÈÍ×ÁÇ %d ¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "list constructor does not accept keyword arguments"
-#~ msgstr "¥ê¥¹¥È¤Î¥³¥ó¥¹¥È¥é¥¯¥¿¤Ï¥­¡¼¥ï¡¼¥É°ú¿ô¤ò¼õ¤±ÉÕ¤±¤Þ¤»¤ó"
+msgid "internal error: not enough list items"
+msgstr "ÆâÉô¥¨¥é¡¼: ¥ê¥¹¥È¤Ë½½Ê¬¤ÊÍ×ÁǤ¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "list index out of range"
-#~ msgstr "¥ê¥¹¥ÈÈϰϳ°¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç¤¹"
+msgid "internal error: failed to add item to list"
+msgstr "ÆâÉô¥¨¥é¡¼: ¥ê¥¹¥È¤Ø¤ÎÍ×ÁÇÄɲä˼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "internal error: failed to get vim list item %d"
-#~ msgstr "ÆâÉô¥¨¥é¡¼: vim¤Î¥ê¥¹¥ÈÍ×ÁÇ %d ¤Î¼èÆÀ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+#, c-format
+msgid "attempt to assign sequence of size %d to extended slice of size %d"
+msgstr "Ťµ %d ¤Î¥¹¥é¥¤¥¹¤ò %d ¤Î³ÈÄ¥¥¹¥é¥¤¥¹¤Ë³ä¤êÅö¤Æ¤è¤¦¤È¤·¤Þ¤·¤¿"
-#~ msgid "failed to add item to list"
-#~ msgstr "¥ê¥¹¥È¤Ø¤ÎÍ×ÁÇÄɲä˼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "failed to add item to list"
+msgstr "¥ê¥¹¥È¤Ø¤ÎÍ×ÁÇÄɲä˼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "internal error: no vim list item %d"
-#~ msgstr "ÆâÉô¥¨¥é¡¼: vim¤Î¥ê¥¹¥ÈÍ×ÁÇ %d ¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "cannot delete vim.List attributes"
+msgstr "vim.List °À­¤Ï¾Ã¤»¤Þ¤»¤ó"
-#~ msgid "internal error: failed to add item to list"
-#~ msgstr "ÆâÉô¥¨¥é¡¼: ¥ê¥¹¥È¤Ø¤ÎÍ×ÁÇÄɲä˼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "cannot modify fixed list"
+msgstr "¸ÇÄꤵ¤ì¤¿¥ê¥¹¥È¤ÏÊѹ¹¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "cannot delete vim.List attributes"
-#~ msgstr "vim.List °À­¤Ï¾Ã¤»¤Þ¤»¤ó"
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "̵̾´Ø¿ô %s ¤Ï¸ºß¤·¤Þ¤»¤ó"
-#~ msgid "cannot modify fixed list"
-#~ msgstr "¸ÇÄꤵ¤ì¤¿¥ê¥¹¥È¤ÏÊѹ¹¤Ç¤­¤Þ¤»¤ó"
+#, c-format
+msgid "function %s does not exist"
+msgstr "´Ø¿ô %s ¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "unnamed function %s does not exist"
-#~ msgstr "̵̾´Ø¿ô %s ¤Ï¸ºß¤·¤Þ¤»¤ó"
+#, c-format
+msgid "failed to run function %s"
+msgstr "´Ø¿ô %s ¤Î¼Â¹Ô¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "function %s does not exist"
-#~ msgstr "´Ø¿ô %s ¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "unable to get option value"
+msgstr "¥ª¥×¥·¥ç¥ó¤ÎÃͤϼèÆÀ¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "function constructor does not accept keyword arguments"
-#~ msgstr "´Ø¿ô¤Î¥³¥ó¥¹¥È¥é¥¯¥¿¤Ï¥­¡¼¥ï¡¼¥É°ú¿ô¤ò¼õ¤±ÉÕ¤±¤Þ¤»¤ó"
+msgid "internal error: unknown option type"
+msgstr "ÆâÉô¥¨¥é¡¼: ̤ÃΤΥª¥×¥·¥ç¥ó·¿¤Ç¤¹"
-#~ msgid "failed to run function %s"
-#~ msgstr "´Ø¿ô %s ¤Î¼Â¹Ô¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "problem while switching windows"
+msgstr "¥¦¥£¥ó¥É¥¦¤òÀÚ´¹Ãæ¤ËÌäÂ꤬ȯÀ¸¤·¤Þ¤·¤¿"
-#~ msgid "problem while switching windows"
-#~ msgstr "¥¦¥£¥ó¥É¥¦¤òÀÚ´¹Ãæ¤ËÌäÂ꤬ȯÀ¸¤·¤Þ¤·¤¿"
+#, c-format
+msgid "unable to unset global option %s"
+msgstr "¥°¥í¡¼¥Ð¥ë¥ª¥×¥·¥ç¥ó %s ¤ÎÀßÄê²ò½ü¤Ï¤Ç¤­¤Þ¤»¤ó"
-#~ 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 "unable to unset option %s which does not have global value"
-#~ msgstr "¥°¥í¡¼¥Ð¥ë¤ÊÃͤÎ̵¤¤¥ª¥×¥·¥ç¥ó %s ¤ÎÀßÄê²ò½ü¤Ï¤Ç¤­¤Þ¤»¤ó"
+msgid "attempt to refer to deleted tab page"
+msgstr "ºï½ü¤µ¤ì¤¿¥¿¥Ö¤ò»²¾È¤·¤è¤¦¤È¤·¤Þ¤·¤¿"
-#~ msgid "attempt to refer to deleted tab page"
-#~ msgstr "ºï½ü¤µ¤ì¤¿¥¿¥Ö¤ò»²¾È¤·¤è¤¦¤È¤·¤Þ¤·¤¿"
+msgid "no such tab page"
+msgstr "¤½¤Î¤è¤¦¤Ê¥¿¥Ö¥Ú¡¼¥¸¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "no such tab page"
-#~ msgstr "¤½¤Î¤è¤¦¤Ê¥¿¥Ö¥Ú¡¼¥¸¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "attempt to refer to deleted window"
+msgstr "ºï½ü¤µ¤ì¤¿¥¦¥£¥ó¥É¥¦¤ò»²¾È¤·¤è¤¦¤È¤·¤Þ¤·¤¿"
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "ºï½ü¤µ¤ì¤¿¥¦¥£¥ó¥É¥¦¤ò»²¾È¤·¤è¤¦¤È¤·¤Þ¤·¤¿"
+msgid "readonly attribute: buffer"
+msgstr "ÆÉ¹þÀìÍѰÀ­: ¥Ð¥Ã¥Õ¥¡¡¼"
-#~ msgid "readonly attribute: buffer"
-#~ msgstr "ÆÉ¹þÀìÍѰÀ­: ¥Ð¥Ã¥Õ¥¡¡¼"
+msgid "cursor position outside buffer"
+msgstr "¥«¡¼¥½¥ë°ÌÃÖ¤¬¥Ð¥Ã¥Õ¥¡¤Î³°Â¦¤Ç¤¹"
-#~ msgid "cursor position outside buffer"
-#~ msgstr "¥«¡¼¥½¥ë°ÌÃÖ¤¬¥Ð¥Ã¥Õ¥¡¤Î³°Â¦¤Ç¤¹"
+msgid "no such window"
+msgstr "¤½¤Î¤è¤¦¤Ê¥¦¥£¥ó¥É¥¦¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "no such window"
-#~ msgstr "¤½¤Î¤è¤¦¤Ê¥¦¥£¥ó¥É¥¦¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "attempt to refer to deleted buffer"
+msgstr "ºï½ü¤µ¤ì¤¿¥Ð¥Ã¥Õ¥¡¤ò»²¾È¤·¤è¤¦¤È¤·¤Þ¤·¤¿"
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "ºï½ü¤µ¤ì¤¿¥Ð¥Ã¥Õ¥¡¤ò»²¾È¤·¤è¤¦¤È¤·¤Þ¤·¤¿"
+msgid "failed to rename buffer"
+msgstr "¥Ð¥Ã¥Õ¥¡Ì¾¤ÎÊѹ¹¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "failed to rename buffer"
-#~ msgstr "¥Ð¥Ã¥Õ¥¡Ì¾¤ÎÊѹ¹¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "mark name must be a single character"
+msgstr "¥Þ¡¼¥¯Ì¾¤Ï1ʸ»ú¤Î¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#~ msgid "mark name must be a single character"
-#~ msgstr "¥Þ¡¼¥¯Ì¾¤Ï1ʸ»ú¤Î¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+#, c-format
+msgid "expected vim.Buffer object, but got %s"
+msgstr "vim.Buffer¥ª¥Ö¥¸¥§¥¯¥È¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
-#~ msgid "expected vim.Buffer object, but got %s"
-#~ msgstr "vim.Buffer¥ª¥Ö¥¸¥§¥¯¥È¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
+#, c-format
+msgid "failed to switch to buffer %d"
+msgstr "»ØÄꤵ¤ì¤¿¥Ð¥Ã¥Õ¥¡ %d ¤Ø¤ÎÀÚ¤êÂØ¤¨¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "failed to switch to buffer %d"
-#~ msgstr "»ØÄꤵ¤ì¤¿¥Ð¥Ã¥Õ¥¡ %d ¤Ø¤ÎÀÚ¤êÂØ¤¨¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+#, c-format
+msgid "expected vim.Window object, but got %s"
+msgstr "vim.Window¥ª¥Ö¥¸¥§¥¯¥È¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
-#~ msgid "expected vim.Window object, but got %s"
-#~ msgstr "vim.Window¥ª¥Ö¥¸¥§¥¯¥È¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
+msgid "failed to find window in the current tab page"
+msgstr "¸½ºß¤Î¥¿¥Ö¤Ë¤Ï»ØÄꤵ¤ì¤¿¥¦¥£¥ó¥É¥¦¤¬¤¢¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
-#~ msgid "failed to find window in the current tab page"
-#~ msgstr "¸½ºß¤Î¥¿¥Ö¤Ë¤Ï»ØÄꤵ¤ì¤¿¥¦¥£¥ó¥É¥¦¤¬¤¢¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
+msgid "did not switch to the specified window"
+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 "expected vim.TabPage object, but got %s"
-#~ msgstr "vim.TabPage¥ª¥Ö¥¸¥§¥¯¥È¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
+msgid "did not switch to the specified tab page"
+msgstr "»ØÄꤵ¤ì¤¿¥¿¥Ö¥Ú¡¼¥¸¤ËÀÚ¤êÂØ¤¨¤Þ¤»¤ó¤Ç¤·¤¿"
-#~ msgid "did not switch to the specified tab page"
-#~ msgstr "»ØÄꤵ¤ì¤¿¥¿¥Ö¥Ú¡¼¥¸¤ËÀÚ¤êÂØ¤¨¤Þ¤»¤ó¤Ç¤·¤¿"
+msgid "failed to run the code"
+msgstr "¥³¡¼¥É¤Î¼Â¹Ô¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "failed to run the code"
-#~ msgstr "¥³¡¼¥É¤Î¼Â¹Ô¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "E858: Eval did not return a valid python object"
+msgstr "E858: ¼°É¾²Á¤ÏÍ­¸ú¤Êpython¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤·¤Þ¤»¤ó¤Ç¤·¤¿"
-#~ 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¤ÎÃͤËÊÑ´¹¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
-#~ 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¤Î¼­½ñ·¿¤ËÊÑ´¹¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "unable to convert %s to vim dictionary"
-#~ msgstr "%s vim¤Î¼­½ñ·¿¤ËÊÑ´¹¤Ç¤­¤Þ¤»¤ó"
+#, c-format
+msgid "unable to convert %s to vim list"
+msgstr "%s ¤òvim¤Î¥ê¥¹¥È¤ËÊÑ´¹¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "unable to convert %s to vim structure"
-#~ 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: NULL reference passed"
+msgstr "ÆâÉô¥¨¥é¡¼: NULL»²¾È¤¬ÅϤµ¤ì¤Þ¤·¤¿"
-#~ msgid "internal error: invalid value type"
-#~ msgstr "ÆâÉô¥¨¥é¡¼: ̵¸ú¤ÊÃÍ·¿¤Ç¤¹"
+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 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 ¤ËÄɲ䷤Ƥ¯¤À¤µ¤¤"
+msgid ""
+"Failed to set path: sys.path is not a list\n"
+"You should now append vim.VIM_SPECIAL_PATH to sys.path"
+msgstr ""
+"¥Ñ¥¹¤ÎÀßÄê¤Ë¼ºÇÔ¤·¤Þ¤·¤¿: sys.path ¤¬¥ê¥¹¥È¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó\n"
+"¤¹¤°¤Ë vim.VIM_SPECIAL_PATH ¤ò sys.path ¤ËÄɲ䷤Ƥ¯¤À¤µ¤¤"
diff --git a/src/nvim/po/ja.po b/src/nvim/po/ja.po
index e12cfb7e70..5cb789c93e 100644
--- a/src/nvim/po/ja.po
+++ b/src/nvim/po/ja.po
@@ -1,3 +1,4 @@
+
# Japanese translation for Vim
#
# Do ":help uganda" in Vim to read copying and usage conditions.
@@ -14,213 +15,176 @@ msgid ""
msgstr ""
"Project-Id-Version: Vim 7.4\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-02-01 09:02+0900\n"
-"PO-Revision-Date: 2013-06-02-01 09:08+09n"
+"POT-Creation-Date: 2016-09-10 21:10+0900\n"
+"PO-Revision-Date: 2016-09-10 21:20+0900\n"
"Last-Translator: MURAOKA Taro <koron.kaoriya@gmail.com>\n"
"Language-Team: vim-jp (https://github.com/vim-jp/lang-ja)\n"
"Language: Japanese\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8-bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "オプションã®å€¤ã¯å–å¾—ã§ãã¾ã›ã‚“"
+msgid "E831: bf_key_init() called with empty password"
+msgstr "E831: bf_key_init() ãŒç©ºãƒ‘スワードã§å‘¼ã³å‡ºã•れã¾ã—ãŸ"
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr "内部エラー: 未知ã®ã‚ªãƒ—ション型ã§ã™"
+msgid "E820: sizeof(uint32_t) != 4"
+msgstr "E820: sizeof(uint32_t) != 4"
+
+msgid "E817: Blowfish big/little endian use wrong"
+msgstr "E817: Blowfishæš—å·ã®ãƒ“ッグ/リトルエンディアンãŒé–“é•ã£ã¦ã„ã¾ã™"
+
+msgid "E818: sha256 test failed"
+msgstr "E818: sha256ã®ãƒ†ã‚¹ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "E819: Blowfish test failed"
+msgstr "E819: Blowfishæš—å·ã®ãƒ†ã‚¹ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../buffer.c:92
msgid "[Location List]"
msgstr "[ロケーションリスト]"
-#: ../buffer.c:93
msgid "[Quickfix List]"
msgstr "[Quickfixリスト]"
-#: ../buffer.c:94
msgid "E855: Autocommands caused command to abort"
msgstr "E855: autocommandãŒã‚³ãƒžãƒ³ãƒ‰ã®åœæ­¢ã‚’引ãèµ·ã“ã—ã¾ã—ãŸ"
-#: ../buffer.c:135
msgid "E82: Cannot allocate any buffer, exiting..."
msgstr "E82: ãƒãƒƒãƒ•ã‚¡ã‚’1ã¤ã‚‚作æˆã§ããªã„ã®ã§, 終了ã—ã¾ã™..."
-#: ../buffer.c:138
msgid "E83: Cannot allocate buffer, using other one..."
msgstr "E83: ãƒãƒƒãƒ•ァを作æˆã§ããªã„ã®ã§, ä»–ã®ã‚’使用ã—ã¾ã™..."
-#: ../buffer.c:763
+msgid "E931: Buffer cannot be registered"
+msgstr "E931: ãƒãƒƒãƒ•ァを登録ã§ãã¾ã›ã‚“"
+
+msgid "E937: Attempt to delete a buffer that is in use"
+msgstr "E937: 使用中ã®ãƒãƒƒãƒ•ァを削除ã—よã†ã¨è©¦ã¿ã¾ã—ãŸ"
+
msgid "E515: No buffers were unloaded"
msgstr "E515: 解放ã•れãŸãƒãƒƒãƒ•ã‚¡ã¯ã‚りã¾ã›ã‚“"
-#: ../buffer.c:765
msgid "E516: No buffers were deleted"
msgstr "E516: 削除ã•れãŸãƒãƒƒãƒ•ã‚¡ã¯ã‚りã¾ã›ã‚“"
-#: ../buffer.c:767
msgid "E517: No buffers were wiped out"
msgstr "E517: 破棄ã•れãŸãƒãƒƒãƒ•ã‚¡ã¯ã‚りã¾ã›ã‚“"
-#: ../buffer.c:772
msgid "1 buffer unloaded"
msgstr "1 個ã®ãƒãƒƒãƒ•ã‚¡ãŒè§£æ”¾ã•れã¾ã—ãŸ"
-#: ../buffer.c:774
#, c-format
msgid "%d buffers unloaded"
msgstr "%d 個ã®ãƒãƒƒãƒ•ã‚¡ãŒè§£æ”¾ã•れã¾ã—ãŸ"
-#: ../buffer.c:777
msgid "1 buffer deleted"
msgstr "1 個ã®ãƒãƒƒãƒ•ã‚¡ãŒå‰Šé™¤ã•れã¾ã—ãŸ"
-#: ../buffer.c:779
#, c-format
msgid "%d buffers deleted"
msgstr "%d 個ã®ãƒãƒƒãƒ•ã‚¡ãŒå‰Šé™¤ã•れã¾ã—ãŸ"
-#: ../buffer.c:782
msgid "1 buffer wiped out"
msgstr "1 個ã®ãƒãƒƒãƒ•ã‚¡ãŒç ´æ£„ã•れã¾ã—ãŸ"
-#: ../buffer.c:784
#, c-format
msgid "%d buffers wiped out"
msgstr "%d 個ã®ãƒãƒƒãƒ•ã‚¡ãŒç ´æ£„ã•れã¾ã—ãŸ"
-#: ../buffer.c:806
msgid "E90: Cannot unload last buffer"
msgstr "E90: 最後ã®ãƒãƒƒãƒ•ã‚¡ã¯è§£æ”¾ã§ãã¾ã›ã‚“"
-#: ../buffer.c:874
msgid "E84: No modified buffer found"
msgstr "E84: 変更ã•れãŸãƒãƒƒãƒ•ã‚¡ã¯ã‚りã¾ã›ã‚“"
#. back where we started, didn't find anything.
-#: ../buffer.c:903
msgid "E85: There is no listed buffer"
msgstr "E85: リスト表示ã•れるãƒãƒƒãƒ•ã‚¡ã¯ã‚りã¾ã›ã‚“"
-#: ../buffer.c:913
-#, c-format
-msgid "E86: Buffer %<PRId64> does not exist"
-msgstr "E86: ãƒãƒƒãƒ•ã‚¡ %<PRId64> ã¯ã‚りã¾ã›ã‚“"
-
-#: ../buffer.c:915
msgid "E87: Cannot go beyond last buffer"
msgstr "E87: 最後ã®ãƒãƒƒãƒ•ã‚¡ã‚’è¶Šãˆã¦ç§»å‹•ã¯ã§ãã¾ã›ã‚“"
-#: ../buffer.c:917
msgid "E88: Cannot go before first buffer"
msgstr "E88: 最åˆã®ãƒãƒƒãƒ•ァよりå‰ã¸ã¯ç§»å‹•ã§ãã¾ã›ã‚“"
-#: ../buffer.c:945
#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
-msgstr "E89: ãƒãƒƒãƒ•ã‚¡ %<PRId64> ã®å¤‰æ›´ã¯ä¿å­˜ã•れã¦ã„ã¾ã›ã‚“ (! ã§å¤‰æ›´ã‚’破棄)"
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr "E89: ãƒãƒƒãƒ•ã‚¡ %ld ã®å¤‰æ›´ã¯ä¿å­˜ã•れã¦ã„ã¾ã›ã‚“ (! ã§å¤‰æ›´ã‚’破棄)"
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
msgid "W14: Warning: List of file names overflow"
msgstr "W14: 警告: ファイルåã®ãƒªã‚¹ãƒˆãŒé•·éŽãŽã¾ã™"
-#: ../buffer.c:1555 ../quickfix.c:3361
#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: ãƒãƒƒãƒ•ã‚¡ %<PRId64> ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+msgid "E92: Buffer %ld not found"
+msgstr "E92: ãƒãƒƒãƒ•ã‚¡ %ld ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../buffer.c:1798
#, c-format
msgid "E93: More than one match for %s"
msgstr "E93: %s ã«è¤‡æ•°ã®è©²å½“ãŒã‚りã¾ã—ãŸ"
-#: ../buffer.c:1800
#, c-format
msgid "E94: No matching buffer for %s"
msgstr "E94: %s ã«è©²å½“ã™ã‚‹ãƒãƒƒãƒ•ã‚¡ã¯ã‚りã¾ã›ã‚“ã§ã—ãŸ"
-#: ../buffer.c:2161
#, c-format
-msgid "line %<PRId64>"
-msgstr "行 %<PRId64>"
+msgid "line %ld"
+msgstr "行 %ld"
-#: ../buffer.c:2233
msgid "E95: Buffer with this name already exists"
msgstr "E95: ã“ã®åå‰ã®ãƒãƒƒãƒ•ã‚¡ã¯æ—¢ã«ã‚りã¾ã™"
-#: ../buffer.c:2498
msgid " [Modified]"
msgstr " [変更ã‚り]"
-#: ../buffer.c:2501
msgid "[Not edited]"
msgstr "[未編集]"
-#: ../buffer.c:2504
msgid "[New file]"
msgstr "[新ファイル]"
-#: ../buffer.c:2505
msgid "[Read errors]"
msgstr "[読込エラー]"
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
msgid "[RO]"
msgstr "[読専]"
-#: ../buffer.c:2507 ../fileio.c:1807
msgid "[readonly]"
msgstr "[読込専用]"
-#: ../buffer.c:2524
#, c-format
msgid "1 line --%d%%--"
msgstr "1 行 --%d%%--"
-#: ../buffer.c:2526
#, c-format
-msgid "%<PRId64> lines --%d%%--"
-msgstr "%<PRId64> 行 --%d%%--"
+msgid "%ld lines --%d%%--"
+msgstr "%ld 行 --%d%%--"
-#: ../buffer.c:2530
#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "行 %<PRId64> (全体 %<PRId64>) --%d%%-- col "
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "行 %ld (全体 %ld) --%d%%-- col "
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
msgid "[No Name]"
msgstr "[ç„¡å]"
#. must be a help buffer
-#: ../buffer.c:2667
msgid "help"
msgstr "ヘルプ"
-#: ../buffer.c:3225 ../screen.c:4883
msgid "[Help]"
msgstr "[ヘルプ]"
-#: ../buffer.c:3254 ../screen.c:4887
msgid "[Preview]"
msgstr "[プレビュー]"
-#: ../buffer.c:3528
msgid "All"
msgstr "å…¨ã¦"
-#: ../buffer.c:3528
msgid "Bot"
msgstr "末尾"
-#: ../buffer.c:3531
msgid "Top"
msgstr "先頭"
-#: ../buffer.c:4244
msgid ""
"\n"
"# Buffer list:\n"
@@ -228,11 +192,9 @@ msgstr ""
"\n"
"# ãƒãƒƒãƒ•ァリスト:\n"
-#: ../buffer.c:4289
msgid "[Scratch]"
msgstr "[下書ã]"
-#: ../buffer.c:4529
msgid ""
"\n"
"--- Signs ---"
@@ -240,200 +202,235 @@ msgstr ""
"\n"
"--- サイン ---"
-#: ../buffer.c:4538
#, c-format
msgid "Signs for %s:"
msgstr "%s ã®ã‚µã‚¤ãƒ³:"
-#: ../buffer.c:4543
#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " 行=%<PRId64> 識別å­=%d åå‰=%s"
+msgid " line=%ld id=%d name=%s"
+msgstr " 行=%ld 識別å­=%d åå‰=%s"
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: コロンãŒã‚りã¾ã›ã‚“"
+msgid "E902: Cannot connect to port"
+msgstr "E902: ãƒãƒ¼ãƒˆã«æŽ¥ç¶šã§ãã¾ã›ã‚“"
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: 䏿­£ãªãƒ¢ãƒ¼ãƒ‰ã§ã™"
+msgid "E901: gethostbyname() in channel_open()"
+msgstr "E901: channel_open() 内㮠gethostbyname() ãŒå¤±æ•—ã—ã¾ã—ãŸ"
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: 数値ãŒå¿…è¦ã§ã™"
+msgid "E898: socket() in channel_open()"
+msgstr "E898: channel_open() 内㮠socket() ãŒå¤±æ•—ã—ã¾ã—ãŸ"
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: 䏿­£ãªãƒ‘ーセンテージã§ã™"
+msgid "E903: received command with non-string argument"
+msgstr "E903: éžæ–‡å­—列ã®å¼•æ•°ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’å—ä¿¡ã—ã¾ã—ãŸ"
+
+msgid "E904: last argument for expr/call must be a number"
+msgstr "E904: expr/call ã®æœ€å¾Œã®å¼•æ•°ã¯æ•°å­—ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+
+msgid "E904: third argument for call must be a list"
+msgstr "E904: call ã®3番目ã®å¼•æ•°ã¯ãƒªã‚¹ãƒˆåž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+
+#, c-format
+msgid "E905: received unknown command: %s"
+msgstr "E905: 未知ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’å—ä¿¡ã—ã¾ã—ãŸ: %s"
+
+#, c-format
+msgid "E630: %s(): write while not connected"
+msgstr "E630: %s(): éžæŽ¥ç¶šçŠ¶æ…‹ã§æ›¸ãè¾¼ã¿ã¾ã—ãŸ"
+
+#, c-format
+msgid "E631: %s(): write failed"
+msgstr "E631: %s(): 書ãè¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+#, c-format
+msgid "E917: Cannot use a callback with %s()"
+msgstr "E917: %s() ã«ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã¯ä½¿ãˆã¾ã›ã‚“"
+
+msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel"
+msgstr "E912: 生や nl ãƒãƒ£ãƒ³ãƒãƒ«ã« ch_evalexpr()/ch_sendexpr ã¯ä½¿ãˆã¾ã›ã‚“"
+
+msgid "E906: not an open channel"
+msgstr "E906: é–‹ã„ã¦ã„ãªã„ãƒãƒ£ãƒ³ãƒãƒ«ã§ã™"
+
+msgid "E920: _io file requires _name to be set"
+msgstr "E920: _io ファイル㯠_name ã®è¨­å®šãŒå¿…è¦ã§ã™"
+
+msgid "E915: in_io buffer requires in_buf or in_name to be set"
+msgstr "E915: in_io ãƒãƒƒãƒ•ァ㯠in_buf ã‹ in_name ã®è¨­å®šãŒå¿…è¦ã§ã™"
+
+#, c-format
+msgid "E918: buffer must be loaded: %s"
+msgstr "E918: ãƒãƒƒãƒ•ã‚¡ãŒãƒ­ãƒ¼ãƒ‰ã•れã¦ãªã‘れã°ãªã‚Šã¾ã›ã‚“: %s"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: ãƒ•ã‚¡ã‚¤ãƒ«ãŒæœªçŸ¥ã®æ–¹æ³•ã§æš—å·åŒ–ã•れã¦ã„ã¾ã™"
+
+msgid "Warning: Using a weak encryption method; see :help 'cm'"
+msgstr "警告: å¼±ã„æš—å·æ–¹æ³•を使ã£ã¦ã„ã¾ã™; :help 'cm' ã‚’å‚ç…§ã—ã¦ãã ã•ã„"
+
+msgid "Enter encryption key: "
+msgstr "æš—å·åŒ–用ã®ã‚­ãƒ¼ã‚’入力ã—ã¦ãã ã•ã„: "
+
+msgid "Enter same key again: "
+msgstr "ã‚‚ã†ä¸€åº¦åŒã˜ã‚­ãƒ¼ã‚’入力ã—ã¦ãã ã•ã„: "
+
+msgid "Keys don't match!"
+msgstr "キーãŒä¸€è‡´ã—ã¾ã›ã‚“"
+
+msgid "[crypted]"
+msgstr "[æš—å·åŒ–]"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: 辞書型ã«ã‚³ãƒ­ãƒ³ãŒã‚りã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: 辞書型ã«é‡è¤‡ã‚­ãƒ¼ãŒã‚りã¾ã™: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: 辞書型ã«ã‚«ãƒ³ãƒžãŒã‚りã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: è¾žæ›¸åž‹ã®æœ€å¾Œã« '}' ãŒã‚りã¾ã›ã‚“: %s"
+
+msgid "extend() argument"
+msgstr "extend() ã®å¼•æ•°"
-#: ../diff.c:146
#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: %<PRId64> 以上ã®ãƒãƒƒãƒ•ã‚¡ã¯diffã§ãã¾ã›ã‚“"
+msgid "E737: Key already exists: %s"
+msgstr "E737: ã‚­ãƒ¼ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™: %s"
+
+#, c-format
+msgid "E96: Cannot diff more than %ld buffers"
+msgstr "E96: %ld 以上ã®ãƒãƒƒãƒ•ã‚¡ã¯diffã§ãã¾ã›ã‚“"
-#: ../diff.c:753
msgid "E810: Cannot read or write temp files"
msgstr "E810: 一時ファイルã®èª­è¾¼ã‚‚ã—ãã¯æ›¸è¾¼ãŒã§ãã¾ã›ã‚“"
-#: ../diff.c:755
msgid "E97: Cannot create diffs"
msgstr "E97: 差分を作æˆã§ãã¾ã›ã‚“"
-#: ../diff.c:966
+msgid "Patch file"
+msgstr "パッãƒãƒ•ァイル"
+
msgid "E816: Cannot read patch output"
msgstr "E816: patchã®å‡ºåŠ›ã‚’èª­è¾¼ã‚ã¾ã›ã‚“"
-#: ../diff.c:1220
msgid "E98: Cannot read diff output"
msgstr "E98: diffã®å‡ºåŠ›ã‚’èª­è¾¼ã‚ã¾ã›ã‚“"
-#: ../diff.c:2081
msgid "E99: Current buffer is not in diff mode"
msgstr "E99: ç¾åœ¨ã®ãƒãƒƒãƒ•ã‚¡ã¯å·®åˆ†ãƒ¢ãƒ¼ãƒ‰ã§ã¯ã‚りã¾ã›ã‚“"
-#: ../diff.c:2100
msgid "E793: No other buffer in diff mode is modifiable"
msgstr "E793: 差分モードã§ã‚ã‚‹ä»–ã®ãƒãƒƒãƒ•ã‚¡ã¯å¤‰æ›´ã§ãã¾ã›ã‚“"
-#: ../diff.c:2102
msgid "E100: No other buffer in diff mode"
msgstr "E100: 差分モードã§ã‚ã‚‹ä»–ã®ãƒãƒƒãƒ•ã‚¡ã¯ã‚りã¾ã›ã‚“"
-#: ../diff.c:2112
msgid "E101: More than two buffers in diff mode, don't know which one to use"
msgstr ""
"E101: 差分モードã®ãƒãƒƒãƒ•ã‚¡ãŒ2個以上ã‚ã‚‹ã®ã§ã€ã©ã‚Œã‚’使ã†ã‹ç‰¹å®šã§ãã¾ã›ã‚“"
-#: ../diff.c:2141
#, c-format
msgid "E102: Can't find buffer \"%s\""
msgstr "E102: ãƒãƒƒãƒ•ã‚¡ \"%s\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../diff.c:2152
#, c-format
msgid "E103: Buffer \"%s\" is not in diff mode"
msgstr "E103: ãƒãƒƒãƒ•ã‚¡ \"%s\" ã¯å·®åˆ†ãƒ¢ãƒ¼ãƒ‰ã§ã¯ã‚りã¾ã›ã‚“"
-#: ../diff.c:2193
msgid "E787: Buffer changed unexpectedly"
msgstr "E787: 予期ã›ãšãƒãƒƒãƒ•ã‚¡ãŒå¤‰æ›´å¤‰æ›´ã•れã¾ã—ãŸ"
-#: ../digraph.c:1598
msgid "E104: Escape not allowed in digraph"
msgstr "E104: åˆå­—ã«Escapeã¯ä½¿ç”¨ã§ãã¾ã›ã‚“"
-#: ../digraph.c:1760
msgid "E544: Keymap file not found"
msgstr "E544: キーマップファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../digraph.c:1785
msgid "E105: Using :loadkeymap not in a sourced file"
msgstr "E105: :source ã§å–込むファイル以外ã§ã¯ :loadkeymap を使ãˆã¾ã›ã‚“"
-#: ../digraph.c:1821
msgid "E791: Empty keymap entry"
msgstr "E791: 空ã®ã‚­ãƒ¼ãƒžãƒƒãƒ—エントリ"
-#: ../edit.c:82
msgid " Keyword completion (^N^P)"
msgstr " キーワード補完 (^N^P)"
#. ctrl_x_mode == 0, ^P/^N compl.
-#: ../edit.c:83
msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
msgstr " ^X モード (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
-#: ../edit.c:85
msgid " Whole line completion (^L^N^P)"
msgstr " 行(全体)補完 (^L^N^P)"
-#: ../edit.c:86
msgid " File name completion (^F^N^P)"
msgstr " ファイルå補完 (^F^N^P)"
-#: ../edit.c:87
msgid " Tag completion (^]^N^P)"
msgstr " タグ補完 (^]^N^P)"
-#: ../edit.c:88
msgid " Path pattern completion (^N^P)"
msgstr " パスパターン補完 (^N^P)"
-#: ../edit.c:89
msgid " Definition completion (^D^N^P)"
msgstr " 定義補完 (^D^N^P)"
-#: ../edit.c:91
msgid " Dictionary completion (^K^N^P)"
msgstr " 辞書補完 (^K^N^P)"
-#: ../edit.c:92
msgid " Thesaurus completion (^T^N^P)"
msgstr " シソーラス補完 (^T^N^P)"
-#: ../edit.c:93
msgid " Command-line completion (^V^N^P)"
msgstr " コマンドライン補完 (^V^N^P)"
-#: ../edit.c:94
msgid " User defined completion (^U^N^P)"
msgstr " ユーザー定義補完 (^U^N^P)"
-#: ../edit.c:95
msgid " Omni completion (^O^N^P)"
msgstr " オムニ補完 (^O^N^P)"
-#: ../edit.c:96
msgid " Spelling suggestion (s^N^P)"
msgstr " 綴り修正候補 (s^N^P)"
-#: ../edit.c:97
msgid " Keyword Local completion (^N^P)"
msgstr " 局所キーワード補完 (^N^P)"
-#: ../edit.c:100
msgid "Hit end of paragraph"
msgstr "段è½ã®æœ€å¾Œã«ãƒ’ット"
-#: ../edit.c:101
msgid "E839: Completion function changed window"
msgstr "E839: 補間関数ãŒã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’変更ã—ã¾ã—ãŸ"
-#: ../edit.c:102
msgid "E840: Completion function deleted text"
msgstr "E840: 補完関数ãŒãƒ†ã‚­ã‚¹ãƒˆã‚’削除ã—ã¾ã—ãŸ"
-#: ../edit.c:1847
msgid "'dictionary' option is empty"
msgstr "'dictionary' オプションãŒç©ºã§ã™"
-#: ../edit.c:1848
msgid "'thesaurus' option is empty"
msgstr "'thesaurus' オプションãŒç©ºã§ã™"
-#: ../edit.c:2655
#, c-format
msgid "Scanning dictionary: %s"
msgstr "辞書をスキャン中: %s"
-#: ../edit.c:3079
msgid " (insert) Scroll (^E/^Y)"
msgstr " (挿入) スクロール(^E/^Y)"
-#: ../edit.c:3081
msgid " (replace) Scroll (^E/^Y)"
msgstr " (ç½®æ›) スクロール (^E/^Y)"
-#: ../edit.c:3587
#, c-format
msgid "Scanning: %s"
msgstr "スキャン中: %s"
-#: ../edit.c:3614
msgid "Scanning tags."
msgstr "タグをスキャン中."
-#: ../edit.c:4519
msgid " Adding"
msgstr " 追加中"
@@ -441,430 +438,161 @@ msgstr " 追加中"
#. * be called before line = ml_get(), or when this address is no
#. * longer needed. -- Acevedo.
#.
-#: ../edit.c:4562
msgid "-- Searching..."
msgstr "-- 検索中..."
-#: ../edit.c:4618
msgid "Back at original"
msgstr "å§‹ã‚ã«æˆ»ã‚‹"
-#: ../edit.c:4621
msgid "Word from other line"
msgstr "ä»–ã®è¡Œã®å˜èªž"
-#: ../edit.c:4624
msgid "The only match"
msgstr "唯一ã®è©²å½“"
-#: ../edit.c:4680
#, c-format
msgid "match %d of %d"
msgstr "%d 番目ã®è©²å½“ (全該当 %d 個中)"
-#: ../edit.c:4684
#, c-format
msgid "match %d"
msgstr "%d 番目ã®è©²å½“"
-#: ../eval.c:137
+#. maximum nesting of lists and dicts
msgid "E18: Unexpected characters in :let"
msgstr "E18: 予期ã›ã¬æ–‡å­—㌠:let ã«ã‚りã¾ã—ãŸ"
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: リストã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãŒç¯„囲外ã§ã™: %<PRId64>"
-
-#: ../eval.c:139
#, c-format
msgid "E121: Undefined variable: %s"
msgstr "E121: 未定義ã®å¤‰æ•°ã§ã™: %s"
-#: ../eval.c:140
msgid "E111: Missing ']'"
msgstr "E111: ']' ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: %s ã®å¼•æ•°ã¯ãƒªã‚¹ãƒˆåž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: %s ã®å¼•æ•°ã¯ãƒªã‚¹ãƒˆåž‹ã¾ãŸã¯è¾žæ›¸åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: 辞書型ã«ç©ºã®ã‚­ãƒ¼ã‚’使ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: リスト型ãŒå¿…è¦ã§ã™"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: 辞書型ãŒå¿…è¦ã§ã™"
-
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: 関数ã®å¼•æ•°ãŒå¤šéŽãŽã¾ã™: %s"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: 辞書型ã«ã‚­ãƒ¼ãŒå­˜åœ¨ã—ã¾ã›ã‚“: %s"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: 関数 %s ã¯å®šç¾©æ¸ˆã§ã™, å†å®šç¾©ã™ã‚‹ã«ã¯ ! を追加ã—ã¦ãã ã•ã„"
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: 辞書型内ã«ã‚¨ãƒ³ãƒˆãƒªãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: 関数å‚ç…§åž‹ãŒè¦æ±‚ã•れã¾ã™"
-
-#: ../eval.c:153
msgid "E719: Cannot use [:] with a Dictionary"
msgstr "E719: [:] を辞書型ã¨çµ„ã¿åˆã‚ã›ã¦ã¯ä½¿ãˆã¾ã›ã‚“"
-#: ../eval.c:154
#, c-format
msgid "E734: Wrong variable type for %s="
msgstr "E734: ç•°ãªã£ãŸåž‹ã®å¤‰æ•°ã§ã™ %s="
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: 未知ã®é–¢æ•°ã§ã™: %s"
-
-#: ../eval.c:156
#, c-format
msgid "E461: Illegal variable name: %s"
msgstr "E461: 䏿­£ãªå¤‰æ•°åã§ã™: %s"
-#: ../eval.c:157
msgid "E806: using Float as a String"
msgstr "E806: æµ®å‹•å°æ•°ç‚¹æ•°ã‚’文字列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-#: ../eval.c:1830
msgid "E687: Less targets than List items"
msgstr "E687: ターゲットãŒãƒªã‚¹ãƒˆåž‹å†…ã®è¦ç´ ã‚ˆã‚Šã‚‚å°‘ãªã„ã§ã™"
-#: ../eval.c:1834
msgid "E688: More targets than List items"
msgstr "E688: ターゲットãŒãƒªã‚¹ãƒˆåž‹å†…ã®è¦ç´ ã‚ˆã‚Šã‚‚多ã„ã§ã™"
-#: ../eval.c:1906
msgid "Double ; in list of variables"
msgstr "リスト型ã®å€¤ã«2ã¤ä»¥ä¸Šã® ; ãŒæ¤œå‡ºã•れã¾ã—ãŸ"
-#: ../eval.c:2078
#, c-format
msgid "E738: Can't list variables for %s"
msgstr "E738: %s ã®å€¤ã‚’一覧表示ã§ãã¾ã›ã‚“"
-#: ../eval.c:2391
msgid "E689: Can only index a List or Dictionary"
msgstr "E689: リスト型ã¨è¾žæ›¸åž‹ä»¥å¤–ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹æŒ‡å®šã§ãã¾ã›ã‚“"
-#: ../eval.c:2396
msgid "E708: [:] must come last"
msgstr "E708: [:] ã¯æœ€å¾Œã§ãªã‘れã°ã„ã‘ã¾ã›ã‚“"
-#: ../eval.c:2439
msgid "E709: [:] requires a List value"
msgstr "E709: [:] ã«ã¯ãƒªã‚¹ãƒˆåž‹ã®å€¤ãŒå¿…è¦ã§ã™"
-#: ../eval.c:2674
msgid "E710: List value has more items than target"
msgstr "E710: リスト型変数ã«ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã‚ˆã‚Šã‚‚多ã„è¦ç´ ãŒã‚りã¾ã™"
-#: ../eval.c:2678
msgid "E711: List value has not enough items"
msgstr "E711: リスト型変数ã«ååˆ†ãªæ•°ã®è¦ç´ ãŒã‚りã¾ã›ã‚“"
#
-#: ../eval.c:2867
msgid "E690: Missing \"in\" after :for"
msgstr "E690: :for ã®å¾Œã« \"in\" ãŒã‚りã¾ã›ã‚“"
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: カッコ '(' ãŒã‚りã¾ã›ã‚“: %s"
-
-#: ../eval.c:3263
#, c-format
msgid "E108: No such variable: \"%s\""
msgstr "E108: ãã®å¤‰æ•°ã¯ã‚りã¾ã›ã‚“: \"%s\""
-#: ../eval.c:3333
msgid "E743: variable nested too deep for (un)lock"
msgstr "E743: (アン)ロックã™ã‚‹ã«ã¯å¤‰æ•°ã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
-#: ../eval.c:3630
msgid "E109: Missing ':' after '?'"
msgstr "E109: '?' ã®å¾Œã« ':' ãŒã‚りã¾ã›ã‚“"
-#: ../eval.c:3893
msgid "E691: Can only compare List with List"
msgstr "E691: リスト型ã¯ãƒªã‚¹ãƒˆåž‹ã¨ã—ã‹æ¯”較ã§ãã¾ã›ã‚“"
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
+msgid "E692: Invalid operation for List"
msgstr "E692: リスト型ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™"
-#: ../eval.c:3915
msgid "E735: Can only compare Dictionary with Dictionary"
msgstr "E735: 辞書型ã¯è¾žæ›¸åž‹ã¨ã—ã‹æ¯”較ã§ãã¾ã›ã‚“"
-#: ../eval.c:3917
msgid "E736: Invalid operation for Dictionary"
msgstr "E736: 辞書型ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™"
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: 関数å‚ç…§åž‹ã¯é–¢æ•°å‚ç…§åž‹ã¨ã—ã‹æ¯”較ã§ãã¾ã›ã‚“"
-
-#: ../eval.c:3934
msgid "E694: Invalid operation for Funcrefs"
msgstr "E694: 関数å‚ç…§åž‹ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™"
-#: ../eval.c:4277
msgid "E804: Cannot use '%' with Float"
msgstr "E804: '%' ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨çµ„ã¿åˆã‚ã›ã¦ã¯ä½¿ãˆã¾ã›ã‚“"
-#: ../eval.c:4478
msgid "E110: Missing ')'"
msgstr "E110: ')' ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../eval.c:4609
msgid "E695: Cannot index a Funcref"
msgstr "E695: 関数å‚ç…§åž‹ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ãã¾ã›ã‚“"
-#: ../eval.c:4839
+msgid "E909: Cannot index a special variable"
+msgstr "E909: 特殊変数ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ãã¾ã›ã‚“"
+
#, c-format
msgid "E112: Option name missing: %s"
msgstr "E112: オプションåãŒã‚りã¾ã›ã‚“: %s"
-#: ../eval.c:4855
#, c-format
msgid "E113: Unknown option: %s"
msgstr "E113: 未知ã®ã‚ªãƒ—ションã§ã™: %s"
-#: ../eval.c:4904
#, c-format
msgid "E114: Missing quote: %s"
msgstr "E114: 引用符 (\") ãŒã‚りã¾ã›ã‚“: %s"
-#: ../eval.c:5020
#, c-format
msgid "E115: Missing quote: %s"
msgstr "E115: 引用符 (') ãŒã‚りã¾ã›ã‚“: %s"
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: リスト型ã«ã‚«ãƒ³ãƒžãŒã‚りã¾ã›ã‚“: %s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: ãƒªã‚¹ãƒˆåž‹ã®æœ€å¾Œã« ']' ãŒã‚りã¾ã›ã‚“: %s"
-
msgid "Not enough memory to set references, garbage collection aborted!"
msgstr ""
"ガーベッジコレクションを中止ã—ã¾ã—ãŸ! å‚照を作æˆã™ã‚‹ã®ã«ãƒ¡ãƒ¢ãƒªãŒä¸è¶³ã—ã¾ã—ãŸ"
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: 辞書型ã«ã‚³ãƒ­ãƒ³ãŒã‚りã¾ã›ã‚“: %s"
-
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: 辞書型ã«é‡è¤‡ã‚­ãƒ¼ãŒã‚りã¾ã™: \"%s\""
-
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: 辞書型ã«ã‚«ãƒ³ãƒžãŒã‚りã¾ã›ã‚“: %s"
-
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: è¾žæ›¸åž‹ã®æœ€å¾Œã« '}' ãŒã‚りã¾ã›ã‚“: %s"
-
-#: ../eval.c:6555
msgid "E724: variable nested too deep for displaying"
msgstr "E724: 表示ã™ã‚‹ã«ã¯å¤‰æ•°ã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
-#: ../eval.c:7188
-#, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E740: 関数ã®å¼•æ•°ãŒå¤šéŽãŽã¾ã™: %s"
-
-#: ../eval.c:7190
-#, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E116: 関数ã®ç„¡åйãªå¼•æ•°ã§ã™: %s"
-
-#: ../eval.c:7377
-#, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E117: 未知ã®é–¢æ•°ã§ã™: %s"
-
-#: ../eval.c:7383
-#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: 関数ã®å¼•æ•°ãŒè¶³ã‚Šã¾ã›ã‚“: %s"
-
-#: ../eval.c:7387
-#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: スクリプト以外ã§<SID>ãŒä½¿ã‚れã¾ã—ãŸ: %s"
-
-#: ../eval.c:7391
-#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E725: 辞書用関数ãŒå‘¼ã°ã‚Œã¾ã—ãŸãŒè¾žæ›¸ãŒã‚りã¾ã›ã‚“: %s"
-
-#: ../eval.c:7453
-msgid "E808: Number or Float required"
-msgstr "E808: æ•°å€¤ã‹æµ®å‹•å°æ•°ç‚¹æ•°ãŒå¿…è¦ã§ã™"
-
-#: ../eval.c:7503
-msgid "add() argument"
-msgstr "add() ã®å¼•æ•°"
-
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: 引数ãŒå¤šéŽãŽã¾ã™"
-
-#: ../eval.c:8073
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete() ã¯æŒ¿å…¥ãƒ¢ãƒ¼ãƒ‰ã§ã—ã‹åˆ©ç”¨ã§ãã¾ã›ã‚“"
-
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "&Ok"
-
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: ã‚­ãƒ¼ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™: %s"
-
-#: ../eval.c:8692
-msgid "extend() argument"
-msgstr "extend() ã®å¼•æ•°"
-
-#: ../eval.c:8915
-msgid "map() argument"
-msgstr "map() ã®å¼•æ•°"
-
-#: ../eval.c:8916
-msgid "filter() argument"
-msgstr "filter() ã®å¼•æ•°"
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld 行: "
-
-#: ../eval.c:9291
-#, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E700: 未知ã®é–¢æ•°ã§ã™: %s"
-
-#: ../eval.c:10729
-msgid "called inputrestore() more often than inputsave()"
-msgstr "inputrestore() ㌠inputsave() よりも多ã呼ã°ã‚Œã¾ã—ãŸ"
-
-#: ../eval.c:10771
-msgid "insert() argument"
-msgstr "insert() ã®å¼•æ•°"
-
-#: ../eval.c:10841
-msgid "E786: Range not allowed"
-msgstr "E786: 範囲指定ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
-
-#: ../eval.c:11140
-msgid "E701: Invalid type for len()"
-msgstr "E701: len() ã«ã¯ç„¡åйãªåž‹ã§ã™"
-
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr "E726: ストライド(å‰é€²é‡)㌠0 ã§ã™"
-
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr "E727: é–‹å§‹ä½ç½®ãŒçµ‚了ä½ç½®ã‚’è¶Šãˆã¾ã—ãŸ"
-
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr "<空>"
-
-#: ../eval.c:12282
-msgid "remove() argument"
-msgstr "remove() ã®å¼•æ•°"
-
-# Added at 10-Mar-2004.
-#: ../eval.c:12466
-msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: シンボリックリンクãŒå¤šéŽãŽã¾ã™ (循環ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™)"
-
-#: ../eval.c:12593
-msgid "reverse() argument"
-msgstr "reverse() ã®å¼•æ•°"
-
-#: ../eval.c:13721
-msgid "sort() argument"
-msgstr "sort() ã®å¼•æ•°"
-
-#: ../eval.c:13721
-msgid "uniq() argument"
-msgstr "uniq() ã®å¼•æ•°"
-
-#: ../eval.c:13776
-msgid "E702: Sort compare function failed"
-msgstr "E702: ã‚½ãƒ¼ãƒˆã®æ¯”較関数ãŒå¤±æ•—ã—ã¾ã—ãŸ"
-
-#: ../eval.c:13806
-msgid "E882: Uniq compare function failed"
-msgstr "E882: Uniq ã®æ¯”較関数ãŒå¤±æ•—ã—ã¾ã—ãŸ"
-
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(無効)"
-
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: 一時ファイル書込中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
-
-#: ../eval.c:16159
msgid "E805: Using a Float as a Number"
msgstr "E805: æµ®å‹•å°æ•°ç‚¹æ•°ã‚’数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-#: ../eval.c:16162
msgid "E703: Using a Funcref as a Number"
msgstr "E703: 関数å‚照型を数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™ã€‚"
-#: ../eval.c:16170
msgid "E745: Using a List as a Number"
msgstr "E745: リスト型を数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-#: ../eval.c:16173
msgid "E728: Using a Dictionary as a Number"
msgstr "E728: 辞書型を数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
+msgid "E910: Using a Job as a Number"
+msgstr "E910: ジョブを数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
+
+msgid "E913: Using a Channel as a Number"
+msgstr "E913: ãƒãƒ£ãƒ³ãƒãƒ«ã‚’数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™ã€‚"
+
msgid "E891: Using a Funcref as a Float"
msgstr "E891: 関数å‚ç…§åž‹ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™ã€‚"
@@ -877,265 +605,280 @@ msgstr "E893: ãƒªã‚¹ãƒˆåž‹ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
msgid "E894: Using a Dictionary as a Float"
msgstr "E894: è¾žæ›¸åž‹ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-#: ../eval.c:16259
+msgid "E907: Using a special value as a Float"
+msgstr "E907: ç‰¹æ®Šå€¤ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
+
+msgid "E911: Using a Job as a Float"
+msgstr "E911: ã‚¸ãƒ§ãƒ–ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
+
+msgid "E914: Using a Channel as a Float"
+msgstr "E914: ãƒãƒ£ãƒ³ãƒãƒ«ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™ã€‚"
+
msgid "E729: using Funcref as a String"
msgstr "E729: 関数å‚照型を文字列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-#: ../eval.c:16262
msgid "E730: using List as a String"
msgstr "E730: リスト型を文字列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-#: ../eval.c:16265
msgid "E731: using Dictionary as a String"
msgstr "E731: 辞書型を文字列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: 変数ã®åž‹ãŒä¸€è‡´ã—ã¾ã›ã‚“: %s"
+msgid "E908: using an invalid value as a String"
+msgstr "E908: 無効ãªå€¤ã‚’文字列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-#: ../eval.c:16705
#, c-format
msgid "E795: Cannot delete variable %s"
msgstr "E795: 変数 %s を削除ã§ãã¾ã›ã‚“"
-#: ../eval.c:16724
#, c-format
msgid "E704: Funcref variable name must start with a capital: %s"
msgstr "E704: 関数å‚照型変数åã¯å¤§æ–‡å­—ã§å§‹ã¾ã‚‰ãªã‘れã°ãªã‚Šã¾ã›ã‚“: %s"
-#: ../eval.c:16732
#, c-format
msgid "E705: Variable name conflicts with existing function: %s"
msgstr "E705: 変数åãŒæ—¢å­˜ã®é–¢æ•°åã¨è¡çªã—ã¾ã™: %s"
-#: ../eval.c:16763
#, c-format
msgid "E741: Value is locked: %s"
msgstr "E741: 値ãŒãƒ­ãƒƒã‚¯ã•れã¦ã„ã¾ã™: %s"
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
msgid "Unknown"
msgstr "䏿˜Ž"
-#: ../eval.c:16768
#, c-format
msgid "E742: Cannot change value of %s"
msgstr "E742: %s ã®å€¤ã‚’変更ã§ãã¾ã›ã‚“"
-#: ../eval.c:16838
msgid "E698: variable nested too deep for making a copy"
msgstr "E698: コピーをå–ã‚‹ã«ã¯å¤‰æ•°ã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: 未定義ã®é–¢æ•°ã§ã™: %s"
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# グローãƒãƒ«å¤‰æ•°:\n"
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: '(' ãŒã‚りã¾ã›ã‚“: %s"
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\t最後ã«ã‚»ãƒƒãƒˆã—ãŸã‚¹ã‚¯ãƒªãƒ—ト: "
-#: ../eval.c:17293
-msgid "E862: Cannot use g: here"
-msgstr "E862: ã“ã“ã§ã¯ g: ã¯ä½¿ãˆã¾ã›ã‚“"
+msgid "map() argument"
+msgstr "map() ã®å¼•æ•°"
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: 䏿­£ãªå¼•æ•°ã§ã™: %s"
+msgid "filter() argument"
+msgstr "filter() ã®å¼•æ•°"
-#: ../eval.c:17323
#, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E853: 引数åãŒé‡è¤‡ã—ã¦ã„ã¾ã™: %s"
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: %s ã®å¼•æ•°ã¯ãƒªã‚¹ãƒˆåž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: :endfunction ãŒã‚りã¾ã›ã‚“"
+msgid "E928: String required"
+msgstr "E928: 文字列ãŒå¿…è¦ã§ã™"
-#: ../eval.c:17537
-#, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E707: 関数åãŒå¤‰æ•°åã¨è¡çªã—ã¾ã™: %s"
+msgid "E808: Number or Float required"
+msgstr "E808: æ•°å€¤ã‹æµ®å‹•å°æ•°ç‚¹æ•°ãŒå¿…è¦ã§ã™"
-#: ../eval.c:17549
-#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: 関数 %s ã‚’å†å®šç¾©ã§ãã¾ã›ã‚“: 使用中ã§ã™"
+msgid "add() argument"
+msgstr "add() ã®å¼•æ•°"
-#: ../eval.c:17604
-#, c-format
-msgid "E746: Function name does not match script file name: %s"
-msgstr "E746: 関数åãŒã‚¹ã‚¯ãƒªãƒ—トã®ãƒ•ァイルåã¨ä¸€è‡´ã—ã¾ã›ã‚“: %s"
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() ã¯æŒ¿å…¥ãƒ¢ãƒ¼ãƒ‰ã§ã—ã‹åˆ©ç”¨ã§ãã¾ã›ã‚“"
-#: ../eval.c:17716
-msgid "E129: Function name required"
-msgstr "E129: 関数åãŒè¦æ±‚ã•れã¾ã™"
+#.
+#. * Yes this is ugly, I don't particularly like it either. But doing it
+#. * this way has the compelling advantage that translations need not to
+#. * be touched at all. See below what 'ok' and 'ync' are used for.
+#.
+msgid "&Ok"
+msgstr "&Ok"
-#: ../eval.c:17824
#, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr "E128: 関数åã¯å¤§æ–‡å­—ã‹ \"s:\" ã§å§‹ã¾ã‚‰ãªã‘れã°ãªã‚Šã¾ã›ã‚“: %s"
+msgid "+-%s%3ld line: "
+msgid_plural "+-%s%3ld lines: "
+msgstr[0] "+-%s%3ld 行: "
-#: ../eval.c:17833
#, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr "E884: 関数åã«ã¯ã‚³ãƒ­ãƒ³ã¯å«ã‚られã¾ã›ã‚“: %s"
+msgid "E700: Unknown function: %s"
+msgstr "E700: 未知ã®é–¢æ•°ã§ã™: %s"
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: 関数 %s を削除ã§ãã¾ã›ã‚“: 使用中ã§ã™"
+msgid "E922: expected a dict"
+msgstr "E922: è¾žæ›¸ãŒæœŸå¾…ã•れã¦ã„ã¾ã™"
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: 関数呼出ã®å…¥ã‚Œå­æ•°ãŒ 'maxfuncdepth' ã‚’è¶…ãˆã¾ã—ãŸ"
+msgid "E923: Second argument of function() must be a list or a dict"
+msgstr "E923: function() ã®ç¬¬ 2 引数ã¯ãƒªã‚¹ãƒˆåž‹ã¾ãŸã¯è¾žæ›¸åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#: ../eval.c:18568
-#, c-format
-msgid "calling %s"
-msgstr "%s を実行中ã§ã™"
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"決定(&O)\n"
+"キャンセル(&C)"
-#: ../eval.c:18651
-#, c-format
-msgid "%s aborted"
-msgstr "%s ãŒä¸­æ–­ã•れã¾ã—ãŸ"
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore() ㌠inputsave() よりも多ã呼ã°ã‚Œã¾ã—ãŸ"
+
+msgid "insert() argument"
+msgstr "insert() ã®å¼•æ•°"
+
+msgid "E786: Range not allowed"
+msgstr "E786: 範囲指定ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
+
+msgid "E916: not a valid job"
+msgstr "E916: 有効ãªã‚¸ãƒ§ãƒ–ã§ã¯ã‚りã¾ã›ã‚“"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: len() ã«ã¯ç„¡åйãªåž‹ã§ã™"
-#: ../eval.c:18653
#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s ㌠#%<PRId64> ã‚’è¿”ã—ã¾ã—ãŸ"
+msgid "E798: ID is reserved for \":match\": %ld"
+msgstr "E798: ID 㯠\":match\" ã®ãŸã‚ã«äºˆç´„ã•れã¦ã„ã¾ã™: %ld"
+
+msgid "E726: Stride is zero"
+msgstr "E726: ストライド(å‰é€²é‡)㌠0 ã§ã™"
+
+msgid "E727: Start past end"
+msgstr "E727: é–‹å§‹ä½ç½®ãŒçµ‚了ä½ç½®ã‚’è¶Šãˆã¾ã—ãŸ"
+
+msgid "<empty>"
+msgstr "<空>"
+
+msgid "E240: No connection to Vim server"
+msgstr "E240: Vim サーãƒãƒ¼ã¸ã®æŽ¥ç¶šãŒã‚りã¾ã›ã‚“"
-#: ../eval.c:18670
#, c-format
-msgid "%s returning %s"
-msgstr "%s ㌠%s ã‚’è¿”ã—ã¾ã—ãŸ"
+msgid "E241: Unable to send to %s"
+msgstr "E241: %s ã¸é€ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: サーãƒãƒ¼ã®å¿œç­”ãŒã‚りã¾ã›ã‚“"
+
+msgid "remove() argument"
+msgstr "remove() ã®å¼•æ•°"
+
+# Added at 10-Mar-2004.
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: シンボリックリンクãŒå¤šéŽãŽã¾ã™ (循環ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™)"
+
+msgid "reverse() argument"
+msgstr "reverse() ã®å¼•æ•°"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: クライアントã¸é€ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
-#: ../eval.c:18691 ../ex_cmds2.c:2695
#, c-format
-msgid "continuing in %s"
-msgstr "%s ã®å®Ÿè¡Œã‚’継続中ã§ã™"
+msgid "E927: Invalid action: '%s'"
+msgstr "E927: ç„¡åŠ¹ãªæ“作ã§ã™: %s"
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: 関数外㫠:return ãŒã‚りã¾ã—ãŸ"
+msgid "sort() argument"
+msgstr "sort() ã®å¼•æ•°"
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# グローãƒãƒ«å¤‰æ•°:\n"
+msgid "uniq() argument"
+msgstr "uniq() ã®å¼•æ•°"
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\tLast set from "
+msgid "E702: Sort compare function failed"
+msgstr "E702: ã‚½ãƒ¼ãƒˆã®æ¯”較関数ãŒå¤±æ•—ã—ã¾ã—ãŸ"
-#: ../eval.c:19272
-msgid "No old files"
-msgstr "å¤ã„ファイルã¯ã‚りã¾ã›ã‚“"
+msgid "E882: Uniq compare function failed"
+msgstr "E882: Uniq ã®æ¯”較関数ãŒå¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "(Invalid)"
+msgstr "(無効)"
+
+#, c-format
+msgid "E935: invalid submatch number: %d"
+msgstr "E935: 無効ãªã‚µãƒ–マッãƒç•ªå·: %d"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: 一時ファイル書込中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+
+msgid "E921: Invalid callback argument"
+msgstr "E921: 無効ãªã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯å¼•æ•°ã§ã™"
-#: ../ex_cmds.c:122
#, c-format
msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
msgstr "<%s>%s%s %d, 16進数 %02x, 8進数 %03o"
-#: ../ex_cmds.c:145
#, c-format
msgid "> %d, Hex %04x, Octal %o"
msgstr "> %d, 16進数 %04x, 8進数 %o"
-#: ../ex_cmds.c:146
#, c-format
msgid "> %d, Hex %08x, Octal %o"
msgstr "> %d, 16進数 %08x, 8進数 %o"
-#: ../ex_cmds.c:684
msgid "E134: Move lines into themselves"
msgstr "E134: 行をãれ自身ã«ã¯ç§»å‹•ã§ãã¾ã›ã‚“"
-#: ../ex_cmds.c:747
msgid "1 line moved"
msgstr "1 行ãŒç§»å‹•ã•れã¾ã—ãŸ"
-#: ../ex_cmds.c:749
#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "%<PRId64> 行ãŒç§»å‹•ã•れã¾ã—ãŸ"
+msgid "%ld lines moved"
+msgstr "%ld 行ãŒç§»å‹•ã•れã¾ã—ãŸ"
-#: ../ex_cmds.c:1175
#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "%<PRId64> 行ãŒãƒ•ィルタ処ç†ã•れã¾ã—ãŸ"
+msgid "%ld lines filtered"
+msgstr "%ld 行ãŒãƒ•ィルタ処ç†ã•れã¾ã—ãŸ"
-#: ../ex_cmds.c:1194
msgid "E135: *Filter* Autocommands must not change current buffer"
msgstr "E135: *フィルタ* autocommandã¯ç¾åœ¨ã®ãƒãƒƒãƒ•ァを変更ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“"
-#: ../ex_cmds.c:1244
msgid "[No write since last change]\n"
msgstr "[最後ã®å¤‰æ›´ãŒä¿å­˜ã•れã¦ã„ã¾ã›ã‚“]\n"
-#: ../ex_cmds.c:1424
#, c-format
msgid "%sviminfo: %s in line: "
msgstr "%sviminfo: %s 行目: "
-#: ../ex_cmds.c:1431
msgid "E136: viminfo: Too many errors, skipping rest of file"
msgstr "E136: viminfo: エラーãŒå¤šéŽãŽã‚‹ã®ã§, 以é™ã¯ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™"
-#: ../ex_cmds.c:1458
#, c-format
msgid "Reading viminfo file \"%s\"%s%s%s"
msgstr "viminfoファイル \"%s\"%s%s%s を読込ã¿ä¸­"
-#: ../ex_cmds.c:1460
msgid " info"
msgstr " 情報"
-#: ../ex_cmds.c:1461
msgid " marks"
msgstr " マーク"
-#: ../ex_cmds.c:1462
msgid " oldfiles"
msgstr " 旧ファイル群"
-#: ../ex_cmds.c:1463
msgid " FAILED"
msgstr " 失敗"
#. avoid a wait_return for this message, it's annoying
-#: ../ex_cmds.c:1541
#, c-format
msgid "E137: Viminfo file is not writable: %s"
msgstr "E137: viminfoãƒ•ã‚¡ã‚¤ãƒ«ãŒæ›¸è¾¼ã¿ã§ãã¾ã›ã‚“: %s"
-#: ../ex_cmds.c:1626
+#, c-format
+msgid "E929: Too many viminfo temp files, like %s!"
+msgstr "E929: 一時viminfoファイルãŒå¤šéŽãŽã¾ã™! 例: %s"
+
#, c-format
msgid "E138: Can't write viminfo file %s!"
msgstr "E138: viminfoファイル %s ã‚’ä¿å­˜ã§ãã¾ã›ã‚“!"
-#: ../ex_cmds.c:1635
#, c-format
msgid "Writing viminfo file \"%s\""
msgstr "viminfoファイル \"%s\" を書込ã¿ä¸­"
+#, c-format
+msgid "E886: Can't rename viminfo file to %s!"
+msgstr "E886: viminfoファイルを %s ã¸åå‰å¤‰æ›´ã§ãã¾ã›ã‚“!"
+
#. Write the info:
-#: ../ex_cmds.c:1720
#, c-format
msgid "# This viminfo file was generated by Vim %s.\n"
msgstr "# ã“ã® viminfo ファイル㯠Vim %s ã«ã‚ˆã£ã¦ç”Ÿæˆã•れã¾ã—ãŸ.\n"
-#: ../ex_cmds.c:1722
msgid ""
"# You may edit it if you're careful!\n"
"\n"
@@ -1143,47 +886,47 @@ msgstr ""
"# 変更ã™ã‚‹éš›ã«ã¯å分注æ„ã—ã¦ãã ã•ã„!\n"
"\n"
-#: ../ex_cmds.c:1723
msgid "# Value of 'encoding' when this file was written\n"
msgstr "# ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ›¸ã‹ã‚ŒãŸæ™‚ã® 'encoding' ã®å€¤\n"
-#: ../ex_cmds.c:1800
msgid "Illegal starting char"
msgstr "䏿­£ãªå…ˆé ­æ–‡å­—ã§ã™"
-#: ../ex_cmds.c:2162
+msgid ""
+"\n"
+"# Bar lines, copied verbatim:\n"
+msgstr ""
+"\n"
+"# '|' ã§å§‹ã¾ã‚‹è¡Œã®ã€æ–‡å­—通りã®ã‚³ãƒ”ー:\n"
+
+msgid "Save As"
+msgstr "別åã§ä¿å­˜"
+
msgid "Write partial file?"
msgstr "ファイルを部分的ã«ä¿å­˜ã—ã¾ã™ã‹?"
-#: ../ex_cmds.c:2166
msgid "E140: Use ! to write partial buffer"
msgstr "E140: ãƒãƒƒãƒ•ァを部分的ã«ä¿å­˜ã™ã‚‹ã«ã¯ ! を使ã£ã¦ãã ã•ã„"
-#: ../ex_cmds.c:2281
#, c-format
msgid "Overwrite existing file \"%s\"?"
msgstr "既存ã®ãƒ•ァイル \"%s\" を上書ãã—ã¾ã™ã‹?"
-#: ../ex_cmds.c:2317
#, c-format
msgid "Swap file \"%s\" exists, overwrite anyway?"
msgstr "スワップファイル \"%s\" ãŒå­˜åœ¨ã—ã¾ã™. 上書ãを強制ã—ã¾ã™ã‹?"
-#: ../ex_cmds.c:2326
#, c-format
msgid "E768: Swap file exists: %s (:silent! overrides)"
msgstr "E768: スワップファイルãŒå­˜åœ¨ã—ã¾ã™: %s (:silent! を追加ã§ä¸Šæ›¸)"
-#: ../ex_cmds.c:2381
#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: ãƒãƒƒãƒ•ã‚¡ %<PRId64> ã«ã¯åå‰ãŒã‚りã¾ã›ã‚“"
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: ãƒãƒƒãƒ•ã‚¡ %ld ã«ã¯åå‰ãŒã‚りã¾ã›ã‚“"
-#: ../ex_cmds.c:2412
msgid "E142: File not written: Writing is disabled by 'write' option"
msgstr "E142: ファイルã¯ä¿å­˜ã•れã¾ã›ã‚“ã§ã—ãŸ: 'write' オプションã«ã‚ˆã‚Šç„¡åйã§ã™"
-#: ../ex_cmds.c:2434
#, c-format
msgid ""
"'readonly' option is set for \"%s\".\n"
@@ -1192,7 +935,6 @@ msgstr ""
"\"%s\" ã«ã¯ 'readonly' オプションãŒè¨­å®šã•れã¦ã„ã¾ã™.\n"
"上書ã強制をã—ã¾ã™ã‹?"
-#: ../ex_cmds.c:2439
#, c-format
msgid ""
"File permissions of \"%s\" are read-only.\n"
@@ -1203,83 +945,68 @@ msgstr ""
"ãれã§ã‚‚æã‚‰ã書ã込むã“ã¨ã¯å¯èƒ½ã§ã™.\n"
"継続ã—ã¾ã™ã‹?"
-#: ../ex_cmds.c:2451
#, c-format
msgid "E505: \"%s\" is read-only (add ! to override)"
msgstr "E505: \"%s\" ã¯èª­è¾¼å°‚用ã§ã™ (強制書込ã«ã¯ ! を追加)"
-#: ../ex_cmds.c:3120
+msgid "Edit File"
+msgstr "ファイルを編集"
+
#, c-format
msgid "E143: Autocommands unexpectedly deleted new buffer %s"
msgstr "E143: autocommandãŒäºˆæœŸã›ãšæ–°ã—ã„ãƒãƒƒãƒ•ã‚¡ %s を削除ã—ã¾ã—ãŸ"
-#: ../ex_cmds.c:3313
msgid "E144: non-numeric argument to :z"
msgstr "E144: æ•°ã§ã¯ãªã„引数㌠:z ã«æ¸¡ã•れã¾ã—ãŸ"
-#: ../ex_cmds.c:3404
msgid "E145: Shell commands not allowed in rvim"
msgstr "E145: rvimã§ã¯ã‚·ã‚§ãƒ«ã‚³ãƒžãƒ³ãƒ‰ã‚’使ãˆã¾ã›ã‚“"
-#: ../ex_cmds.c:3498
msgid "E146: Regular expressions can't be delimited by letters"
msgstr "E146: æ­£è¦è¡¨ç¾ã¯æ–‡å­—ã§åŒºåˆ‡ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
-#: ../ex_cmds.c:3964
#, c-format
msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
msgstr "%s ã«ç½®æ›ã—ã¾ã™ã‹? (y/n/a/q/l/^E/^Y)"
-#: ../ex_cmds.c:4379
msgid "(Interrupted) "
msgstr "(割込ã¾ã‚Œã¾ã—ãŸ) "
-#: ../ex_cmds.c:4384
msgid "1 match"
msgstr "1 箇所該当ã—ã¾ã—ãŸ"
-#: ../ex_cmds.c:4384
msgid "1 substitution"
msgstr "1 箇所置æ›ã—ã¾ã—ãŸ"
-#: ../ex_cmds.c:4387
#, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> 箇所該当ã—ã¾ã—ãŸ"
+msgid "%ld matches"
+msgstr "%ld 箇所該当ã—ã¾ã—ãŸ"
-#: ../ex_cmds.c:4388
#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> 箇所置æ›ã—ã¾ã—ãŸ"
+msgid "%ld substitutions"
+msgstr "%ld 箇所置æ›ã—ã¾ã—ãŸ"
-#: ../ex_cmds.c:4392
msgid " on 1 line"
msgstr " (計 1 行内)"
-#: ../ex_cmds.c:4395
#, c-format
-msgid " on %<PRId64> lines"
-msgstr " (計 %<PRId64> 行内)"
+msgid " on %ld lines"
+msgstr " (計 %ld 行内)"
-#: ../ex_cmds.c:4438
msgid "E147: Cannot do :global recursive"
msgstr "E147: :global ã‚’å†å¸°çš„ã«ã¯ä½¿ãˆã¾ã›ã‚“"
-#: ../ex_cmds.c:4467
msgid "E148: Regular expression missing from global"
msgstr "E148: globalã‚³ãƒžãƒ³ãƒ‰ã«æ­£è¦è¡¨ç¾ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“"
-#: ../ex_cmds.c:4508
#, c-format
msgid "Pattern found in every line: %s"
msgstr "パターンãŒå…¨ã¦ã®è¡Œã§è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ: %s"
-#: ../ex_cmds.c:4510
#, c-format
msgid "Pattern not found: %s"
msgstr "パターンã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ: %s"
-#: ../ex_cmds.c:4587
msgid ""
"\n"
"# Last Substitute String:\n"
@@ -1289,110 +1016,102 @@ msgstr ""
"# 最後ã«ç½®æ›ã•ã‚ŒãŸæ–‡å­—列:\n"
"$"
-#: ../ex_cmds.c:4679
msgid "E478: Don't panic!"
msgstr "E478: æ…Œã¦ãªã„ã§ãã ã•ã„"
-#: ../ex_cmds.c:4717
#, c-format
msgid "E661: Sorry, no '%s' help for %s"
msgstr "E661: 残念ã§ã™ãŒ '%s' ã®ãƒ˜ãƒ«ãƒ—㌠%s ã«ã¯ã‚りã¾ã›ã‚“"
-#: ../ex_cmds.c:4719
#, c-format
msgid "E149: Sorry, no help for %s"
msgstr "E149: 残念ã§ã™ãŒ %s ã«ã¯ãƒ˜ãƒ«ãƒ—ãŒã‚りã¾ã›ã‚“"
-#: ../ex_cmds.c:4751
#, c-format
msgid "Sorry, help file \"%s\" not found"
msgstr "残念ã§ã™ãŒãƒ˜ãƒ«ãƒ—ファイル \"%s\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../ex_cmds.c:5323
#, c-format
-msgid "E150: Not a directory: %s"
-msgstr "E150: ディレクトリã§ã¯ã‚りã¾ã›ã‚“: %s"
+msgid "E151: No match: %s"
+msgstr "E151: マッãƒã¯ã‚りã¾ã›ã‚“: %s"
-#: ../ex_cmds.c:5446
#, c-format
msgid "E152: Cannot open %s for writing"
msgstr "E152: 書込ã¿ç”¨ã« %s ã‚’é–‹ã‘ã¾ã›ã‚“"
-#: ../ex_cmds.c:5471
#, c-format
msgid "E153: Unable to open %s for reading"
msgstr "E153: 読込用㫠%s ã‚’é–‹ã‘ã¾ã›ã‚“"
# Added at 29-Apr-2004.
-#: ../ex_cmds.c:5500
#, c-format
msgid "E670: Mix of help file encodings within a language: %s"
msgstr "E670: 1ã¤ã®è¨€èªžã®ãƒ˜ãƒ«ãƒ—ファイルã«è¤‡æ•°ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ãŒæ··åœ¨ã—ã¦ã„ã¾ã™: %s"
-#: ../ex_cmds.c:5565
#, c-format
msgid "E154: Duplicate tag \"%s\" in file %s/%s"
msgstr "E154: ã‚¿ã‚° \"%s\" ãŒãƒ•ァイル %s/%s ã«é‡è¤‡ã—ã¦ã„ã¾ã™"
-#: ../ex_cmds.c:5687
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: ディレクトリã§ã¯ã‚りã¾ã›ã‚“: %s"
+
#, c-format
msgid "E160: Unknown sign command: %s"
msgstr "E160: 未知ã®signコマンドã§ã™: %s"
-#: ../ex_cmds.c:5704
msgid "E156: Missing sign name"
msgstr "E156: signåãŒã‚りã¾ã›ã‚“"
-#: ../ex_cmds.c:5746
msgid "E612: Too many signs defined"
msgstr "E612: signã®å®šç¾©ãŒå¤šæ•°è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ"
-#: ../ex_cmds.c:5813
#, c-format
msgid "E239: Invalid sign text: %s"
msgstr "E239: 無効ãªsignã®ãƒ†ã‚­ã‚¹ãƒˆã§ã™: %s"
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
#, c-format
msgid "E155: Unknown sign: %s"
msgstr "E155: 未知ã®signã§ã™: %s"
-#: ../ex_cmds.c:5877
msgid "E159: Missing sign number"
msgstr "E159: signã®ç•ªå·ãŒã‚りã¾ã›ã‚“"
-#: ../ex_cmds.c:5971
#, c-format
msgid "E158: Invalid buffer name: %s"
msgstr "E158: 無効ãªãƒãƒƒãƒ•ã‚¡åã§ã™: %s"
-#: ../ex_cmds.c:6008
+msgid "E934: Cannot jump to a buffer that does not have a name"
+msgstr "E934: åå‰ã®ç„¡ã„ãƒãƒƒãƒ•ã‚¡ã¸ã¯ã‚¸ãƒ£ãƒ³ãƒ—ã§ãã¾ã›ã‚“"
+
#, c-format
-msgid "E157: Invalid sign ID: %<PRId64>"
-msgstr "E157: 無効ãªsign識別å­ã§ã™: %<PRId64>"
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: 無効ãªsign識別å­ã§ã™: %ld"
#, c-format
msgid "E885: Not possible to change sign %s"
msgstr "E885: 変更ã§ããªã„ sign ã§ã™: %s"
-#: ../ex_cmds.c:6066
+# Added at 27-Jan-2004.
+msgid " (NOT FOUND)"
+msgstr " (見ã¤ã‹ã‚Šã¾ã›ã‚“)"
+
msgid " (not supported)"
msgstr " (éžã‚µãƒãƒ¼ãƒˆ)"
-#: ../ex_cmds.c:6169
msgid "[Deleted]"
msgstr "[削除済]"
-#: ../ex_cmds2.c:139
+msgid "No old files"
+msgstr "å¤ã„ファイルã¯ã‚りã¾ã›ã‚“"
+
msgid "Entering Debug mode. Type \"cont\" to continue."
msgstr "デãƒãƒƒã‚°ãƒ¢ãƒ¼ãƒ‰ã«å…¥ã‚Šã¾ã™. ç¶šã‘ã‚‹ã«ã¯ \"cont\" ã¨å…¥åŠ›ã—ã¦ãã ã•ã„."
-#: ../ex_cmds2.c:143 ../ex_docmd.c:759
#, c-format
-msgid "line %<PRId64>: %s"
-msgstr "行 %<PRId64>: %s"
+msgid "line %ld: %s"
+msgstr "行 %ld: %s"
-#: ../ex_cmds2.c:145
#, c-format
msgid "cmd: %s"
msgstr "コマンド: %s"
@@ -1404,232 +1123,184 @@ msgstr "フレーム㌠0 ã§ã™"
msgid "frame at highest level: %d"
msgstr "最高レベルã®ãƒ•レーム: %d"
-#: ../ex_cmds2.c:322
#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "ブレークãƒã‚¤ãƒ³ãƒˆ \"%s%s\" 行 %<PRId64>"
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "ブレークãƒã‚¤ãƒ³ãƒˆ \"%s%s\" 行 %ld"
-#: ../ex_cmds2.c:581
#, c-format
msgid "E161: Breakpoint not found: %s"
msgstr "E161: ブレークãƒã‚¤ãƒ³ãƒˆãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %s"
-#: ../ex_cmds2.c:611
msgid "No breakpoints defined"
msgstr "ブレークãƒã‚¤ãƒ³ãƒˆãŒå®šç¾©ã•れã¦ã„ã¾ã›ã‚“"
-#: ../ex_cmds2.c:617
#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s 行 %<PRId64>"
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s 行 %ld"
-#: ../ex_cmds2.c:942
msgid "E750: First use \":profile start {fname}\""
msgstr "E750: åˆã‚ã« \":profile start {fname}\" を実行ã—ã¦ãã ã•ã„"
-#: ../ex_cmds2.c:1269
#, c-format
msgid "Save changes to \"%s\"?"
msgstr "変更を \"%s\" ã«ä¿å­˜ã—ã¾ã™ã‹?"
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
msgid "Untitled"
msgstr "無題"
-#: ../ex_cmds2.c:1421
#, c-format
msgid "E162: No write since last change for buffer \"%s\""
msgstr "E162: ãƒãƒƒãƒ•ã‚¡ \"%s\" ã®å¤‰æ›´ã¯ä¿å­˜ã•れã¦ã„ã¾ã›ã‚“"
-#: ../ex_cmds2.c:1480
msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
msgstr "警告: 予期ã›ãšä»–ãƒãƒƒãƒ•ã‚¡ã¸ç§»å‹•ã—ã¾ã—㟠(autocommands を調ã¹ã¦ãã ã•ã„)"
-#: ../ex_cmds2.c:1826
msgid "E163: There is only one file to edit"
msgstr "E163: 編集ã™ã‚‹ãƒ•ァイルã¯1ã¤ã—ã‹ã‚りã¾ã›ã‚“"
-#: ../ex_cmds2.c:1828
msgid "E164: Cannot go before first file"
msgstr "E164: 最åˆã®ãƒ•ァイルよりå‰ã«ã¯è¡Œã‘ã¾ã›ã‚“"
-#: ../ex_cmds2.c:1830
msgid "E165: Cannot go beyond last file"
msgstr "E165: 最後ã®ãƒ•ァイルを越ãˆã¦å¾Œã«ã¯è¡Œã‘ã¾ã›ã‚“"
-#: ../ex_cmds2.c:2175
#, c-format
msgid "E666: compiler not supported: %s"
msgstr "E666: ãã®ã‚³ãƒ³ãƒ‘イラã«ã¯å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“: %s"
-#: ../ex_cmds2.c:2257
#, c-format
msgid "Searching for \"%s\" in \"%s\""
msgstr "\"%s\" ã‚’ \"%s\" ã‹ã‚‰æ¤œç´¢ä¸­"
-#: ../ex_cmds2.c:2284
#, c-format
msgid "Searching for \"%s\""
msgstr "\"%s\" を検索中"
-#: ../ex_cmds2.c:2307
#, c-format
-msgid "not found in 'runtimepath': \"%s\""
-msgstr "'runtimepath' ã®ä¸­ã«ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: \"%s\""
+msgid "not found in '%s': \"%s\""
+msgstr "'%s' ã®ä¸­ã«ã¯ã‚りã¾ã›ã‚“: \"%s\""
+
+msgid "Source Vim script"
+msgstr "Vimスクリプトã®å–è¾¼ã¿"
-#: ../ex_cmds2.c:2472
#, c-format
msgid "Cannot source a directory: \"%s\""
msgstr "ディレクトリã¯å–è¾¼ã‚ã¾ã›ã‚“: \"%s\""
-#: ../ex_cmds2.c:2518
#, c-format
msgid "could not source \"%s\""
msgstr "\"%s\" ã‚’å–è¾¼ã‚ã¾ã›ã‚“"
-#: ../ex_cmds2.c:2520
#, c-format
-msgid "line %<PRId64>: could not source \"%s\""
-msgstr "行 %<PRId64>: \"%s\" ã‚’å–è¾¼ã‚ã¾ã›ã‚“"
+msgid "line %ld: could not source \"%s\""
+msgstr "行 %ld: \"%s\" ã‚’å–è¾¼ã‚ã¾ã›ã‚“"
-#: ../ex_cmds2.c:2535
#, c-format
msgid "sourcing \"%s\""
msgstr "\"%s\" ã‚’å–込中"
-#: ../ex_cmds2.c:2537
#, c-format
-msgid "line %<PRId64>: sourcing \"%s\""
-msgstr "行 %<PRId64>: %s ã‚’å–込中"
+msgid "line %ld: sourcing \"%s\""
+msgstr "行 %ld: %s ã‚’å–込中"
-#: ../ex_cmds2.c:2693
#, c-format
msgid "finished sourcing %s"
msgstr "%s ã®å–込を完了"
-#: ../ex_cmds2.c:2765
+#, c-format
+msgid "continuing in %s"
+msgstr "%s ã®å®Ÿè¡Œã‚’継続中ã§ã™"
+
msgid "modeline"
msgstr "モード行"
-#: ../ex_cmds2.c:2767
msgid "--cmd argument"
msgstr "--cmd 引数"
-#: ../ex_cmds2.c:2769
msgid "-c argument"
msgstr "-c 引数"
-#: ../ex_cmds2.c:2771
msgid "environment variable"
msgstr "環境変数"
-#: ../ex_cmds2.c:2773
msgid "error handler"
msgstr "エラーãƒãƒ³ãƒ‰ãƒ©"
-#: ../ex_cmds2.c:3020
msgid "W15: Warning: Wrong line separator, ^M may be missing"
msgstr "W15: 警告: 行区切ãŒä¸æ­£ã§ã™. ^M ãŒãªã„ã®ã§ã—ょã†"
-#: ../ex_cmds2.c:3139
msgid "E167: :scriptencoding used outside of a sourced file"
msgstr "E167: :scriptencoding ãŒå–込スクリプト以外ã§ä½¿ç”¨ã•れã¾ã—ãŸ"
-#: ../ex_cmds2.c:3166
msgid "E168: :finish used outside of a sourced file"
msgstr "E168: :finish ãŒå–込スクリプト以外ã§ä½¿ç”¨ã•れã¾ã—ãŸ"
-#: ../ex_cmds2.c:3389
#, c-format
msgid "Current %slanguage: \"%s\""
msgstr "ç¾åœ¨ã® %s言語: \"%s\""
-#: ../ex_cmds2.c:3404
#, c-format
msgid "E197: Cannot set language to \"%s\""
msgstr "E197: 言語を \"%s\" ã«è¨­å®šã§ãã¾ã›ã‚“"
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
msgstr ""
"Exモードã«å…¥ã‚Šã¾ã™. ãƒŽãƒ¼ãƒžãƒ«ãƒ¢ãƒ¼ãƒ‰ã«æˆ»ã‚‹ã«ã¯\"visual\"ã¨å…¥åŠ›ã—ã¦ãã ã•ã„."
-#: ../ex_docmd.c:428
msgid "E501: At end-of-file"
msgstr "E501: ファイルã®çµ‚了ä½ç½®"
-#: ../ex_docmd.c:513
msgid "E169: Command too recursive"
msgstr "E169: コマンドãŒå†å¸°çš„éŽãŽã¾ã™"
-#: ../ex_docmd.c:1006
#, c-format
msgid "E605: Exception not caught: %s"
msgstr "E605: ä¾‹å¤–ãŒæ•æ‰ã•れã¾ã›ã‚“ã§ã—ãŸ: %s"
-#: ../ex_docmd.c:1085
msgid "End of sourced file"
msgstr "å–è¾¼ãƒ•ã‚¡ã‚¤ãƒ«ã®æœ€å¾Œã§ã™"
-#: ../ex_docmd.c:1086
msgid "End of function"
msgstr "é–¢æ•°ã®æœ€å¾Œã§ã™"
-#: ../ex_docmd.c:1628
msgid "E464: Ambiguous use of user-defined command"
msgstr "E464: ユーザー定義コマンドã®ã‚ã„ã¾ã„ãªä½¿ç”¨ã§ã™"
-#: ../ex_docmd.c:1638
msgid "E492: Not an editor command"
msgstr "E492: エディタã®ã‚³ãƒžãƒ³ãƒ‰ã§ã¯ã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:1729
msgid "E493: Backwards range given"
msgstr "E493: 逆ã•ã¾ã®ç¯„å›²ãŒæŒ‡å®šã•れã¾ã—ãŸ"
-#: ../ex_docmd.c:1733
msgid "Backwards range given, OK to swap"
msgstr "逆ã•ã¾ã®ç¯„å›²ãŒæŒ‡å®šã•れã¾ã—ãŸ, 入替ãˆã¾ã™ã‹?"
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
msgid "E494: Use w or w>>"
msgstr "E494: w ã‚‚ã—ã㯠w>> を使用ã—ã¦ãã ã•ã„"
-#: ../ex_docmd.c:3454
-msgid "E319: The command is not available in this version"
+msgid "E319: Sorry, the command is not available in this version"
msgstr "E319: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“, ã”ã‚ã‚“ãªã•ã„"
-#: ../ex_docmd.c:3752
msgid "E172: Only one file name allowed"
msgstr "E172: ファイルå㯠1 ã¤ã«ã—ã¦ãã ã•ã„"
-#: ../ex_docmd.c:4238
msgid "1 more file to edit. Quit anyway?"
msgstr "編集ã™ã¹ãファイル㌠1 個ã‚りã¾ã™ãŒ, 終了ã—ã¾ã™ã‹?"
-#: ../ex_docmd.c:4242
#, c-format
msgid "%d more files to edit. Quit anyway?"
msgstr "編集ã™ã¹ãファイルãŒã‚㨠%d 個ã‚りã¾ã™ãŒ, 終了ã—ã¾ã™ã‹?"
-#: ../ex_docmd.c:4248
msgid "E173: 1 more file to edit"
msgstr "E173: 編集ã™ã¹ãファイル㌠1 個ã‚りã¾ã™"
-#: ../ex_docmd.c:4250
#, c-format
-msgid "E173: %<PRId64> more files to edit"
-msgstr "E173: 編集ã™ã¹ãファイルãŒã‚㨠%<PRId64> 個ã‚りã¾ã™"
+msgid "E173: %ld more files to edit"
+msgstr "E173: 編集ã™ã¹ãファイルãŒã‚㨠%ld 個ã‚りã¾ã™"
-#: ../ex_docmd.c:4320
msgid "E174: Command already exists: add ! to replace it"
msgstr "E174: ã‚³ãƒžãƒ³ãƒ‰ãŒæ—¢ã«ã‚りã¾ã™: å†å®šç¾©ã™ã‚‹ã«ã¯ ! を追加ã—ã¦ãã ã•ã„"
-#: ../ex_docmd.c:4432
msgid ""
"\n"
" Name Args Address Complete Definition"
@@ -1637,51 +1308,40 @@ msgstr ""
"\n"
" åå‰ å¼•æ•° アドレス 補完 定義"
-#: ../ex_docmd.c:4516
msgid "No user-defined commands found"
msgstr "ユーザー定義コマンドãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
-#: ../ex_docmd.c:4538
msgid "E175: No attribute specified"
msgstr "E175: 属性ã¯å®šç¾©ã•れã¦ã„ã¾ã›ã‚“"
-#: ../ex_docmd.c:4583
msgid "E176: Invalid number of arguments"
msgstr "E176: å¼•æ•°ã®æ•°ãŒç„¡åйã§ã™"
-#: ../ex_docmd.c:4594
msgid "E177: Count cannot be specified twice"
msgstr "E177: カウントを2釿Œ‡å®šã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-#: ../ex_docmd.c:4603
msgid "E178: Invalid default value for count"
msgstr "E178: カウントã®çœç•¥å€¤ãŒç„¡åйã§ã™"
-#: ../ex_docmd.c:4625
msgid "E179: argument required for -complete"
msgstr "E179: -complete ã«ã¯å¼•æ•°ãŒå¿…è¦ã§ã™"
msgid "E179: argument required for -addr"
msgstr "E179: -addr ã«ã¯å¼•æ•°ãŒå¿…è¦ã§ã™"
-#: ../ex_docmd.c:4635
#, c-format
msgid "E181: Invalid attribute: %s"
msgstr "E181: 無効ãªå±žæ€§ã§ã™: %s"
-#: ../ex_docmd.c:4678
msgid "E182: Invalid command name"
msgstr "E182: 無効ãªã‚³ãƒžãƒ³ãƒ‰åã§ã™"
-#: ../ex_docmd.c:4691
msgid "E183: User defined commands must start with an uppercase letter"
msgstr "E183: ユーザー定義コマンドã¯è‹±å¤§æ–‡å­—ã§å§‹ã¾ã‚‰ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#: ../ex_docmd.c:4696
msgid "E841: Reserved name, cannot be used for user defined command"
msgstr "E841: 予約åãªã®ã§, ユーザー定義コマンドã«åˆ©ç”¨ã§ãã¾ã›ã‚“"
-#: ../ex_docmd.c:4751
#, c-format
msgid "E184: No such user-defined command: %s"
msgstr "E184: ãã®ãƒ¦ãƒ¼ã‚¶ãƒ¼å®šç¾©ã‚³ãƒžãƒ³ãƒ‰ã¯ã‚りã¾ã›ã‚“: %s"
@@ -1690,293 +1350,261 @@ msgstr "E184: ãã®ãƒ¦ãƒ¼ã‚¶ãƒ¼å®šç¾©ã‚³ãƒžãƒ³ãƒ‰ã¯ã‚りã¾ã›ã‚“: %s"
msgid "E180: Invalid address type value: %s"
msgstr "E180: 無効ãªã‚¢ãƒ‰ãƒ¬ã‚¹ã‚¿ã‚¤ãƒ—値ã§ã™: %s"
-#: ../ex_docmd.c:5219
#, c-format
msgid "E180: Invalid complete value: %s"
msgstr "E180: 無効ãªè£œå®ŒæŒ‡å®šã§ã™: %s"
-#: ../ex_docmd.c:5225
msgid "E468: Completion argument only allowed for custom completion"
msgstr "E468: 補完引数ã¯ã‚«ã‚¹ã‚¿ãƒ è£œå®Œã§ã—ã‹ä½¿ç”¨ã§ãã¾ã›ã‚“"
-#: ../ex_docmd.c:5231
msgid "E467: Custom completion requires a function argument"
msgstr "E467: カスタム補完ã«ã¯å¼•æ•°ã¨ã—ã¦é–¢æ•°ãŒå¿…è¦ã§ã™"
-#: ../ex_docmd.c:5257
+msgid "unknown"
+msgstr "䏿˜Ž"
+
#, c-format
msgid "E185: Cannot find color scheme '%s'"
msgstr "E185: カラースキーム '%s' ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../ex_docmd.c:5263
msgid "Greetings, Vim user!"
msgstr "Vim 使ã„ã•ã‚“ã€ã‚„ã‚!"
-#: ../ex_docmd.c:5431
msgid "E784: Cannot close last tab page"
msgstr "E784: 最後ã®ã‚¿ãƒ–ページを閉ã˜ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-#: ../ex_docmd.c:5462
msgid "Already only one tab page"
msgstr "æ—¢ã«ã‚¿ãƒ–ページã¯1ã¤ã—ã‹ã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:6004
+msgid "Edit File in new window"
+msgstr "æ–°ã—ã„ウィンドウã§ãƒ•ァイルを編集ã—ã¾ã™"
+
#, c-format
msgid "Tab page %d"
msgstr "タブページ %d"
-#: ../ex_docmd.c:6295
msgid "No swap file"
msgstr "スワップファイルãŒã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:6478
+msgid "Append File"
+msgstr "追加ファイル"
+
msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
msgstr ""
"E747: ãƒãƒƒãƒ•ã‚¡ãŒä¿®æ­£ã•れã¦ã„ã‚‹ã®ã§, ディレクトリを変更ã§ãã¾ã›ã‚“ (! を追加ã§"
"上書)"
-#: ../ex_docmd.c:6485
msgid "E186: No previous directory"
msgstr "E186: å‰ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¯ã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:6530
msgid "E187: Unknown"
msgstr "E187: 未知"
-#: ../ex_docmd.c:6610
msgid "E465: :winsize requires two number arguments"
msgstr "E465: :winsize ã«ã¯2ã¤ã®æ•°å€¤ã®å¼•æ•°ãŒå¿…è¦ã§ã™"
-#: ../ex_docmd.c:6655
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "ウィンドウä½ç½®: X %d, Y %d"
+
msgid "E188: Obtaining window position not implemented for this platform"
msgstr ""
"E188: ã“ã®ãƒ—ラットホームã«ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ä½ç½®ã®å–得機能ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“"
-#: ../ex_docmd.c:6662
msgid "E466: :winpos requires two number arguments"
msgstr "E466: :winpos ã«ã¯2ã¤ã®æ•°å€¤ã®å¼•æ•°ãŒå¿…è¦ã§ã™"
-#: ../ex_docmd.c:7241
+msgid "E930: Cannot use :redir inside execute()"
+msgstr "E930: execute() ã®ä¸­ã§ã¯ :redir ã¯ä½¿ãˆã¾ã›ã‚“"
+
+msgid "Save Redirection"
+msgstr "リダイレクトをä¿å­˜ã—ã¾ã™"
+
+msgid "Save View"
+msgstr "ビューをä¿å­˜ã—ã¾ã™"
+
+msgid "Save Session"
+msgstr "セッション情報をä¿å­˜ã—ã¾ã™"
+
+msgid "Save Setup"
+msgstr "設定をä¿å­˜ã—ã¾ã™"
+
#, c-format
msgid "E739: Cannot create directory: %s"
msgstr "E739: ディレクトリを作æˆã§ãã¾ã›ã‚“: %s"
-#: ../ex_docmd.c:7268
#, c-format
msgid "E189: \"%s\" exists (add ! to override)"
msgstr "E189: \"%s\" ãŒå­˜åœ¨ã—ã¾ã™ (上書ã™ã‚‹ã«ã¯ ! を追加ã—ã¦ãã ã•ã„)"
-#: ../ex_docmd.c:7273
#, c-format
msgid "E190: Cannot open \"%s\" for writing"
msgstr "E190: \"%s\" を書込ã¿ç”¨ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“"
#. set mark
-#: ../ex_docmd.c:7294
msgid "E191: Argument must be a letter or forward/backward quote"
msgstr "E191: 引数ã¯1文字ã®è‹±å­—ã‹å¼•用符 (' ã‹ `) ã§ãªã‘れã°ã„ã‘ã¾ã›ã‚“"
-#: ../ex_docmd.c:7333
msgid "E192: Recursive use of :normal too deep"
msgstr "E192: :normal ã®å†å¸°åˆ©ç”¨ãŒæ·±ããªã‚ŠéŽãŽã¾ã—ãŸ"
-#: ../ex_docmd.c:7807
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< 㯠+eval 機能ãŒç„¡ã„ã¨åˆ©ç”¨ã§ãã¾ã›ã‚“"
+
msgid "E194: No alternate file name to substitute for '#'"
msgstr "E194: '#'ã‚’ç½®ãæ›ãˆã‚‹å‰¯ãƒ•ァイルã®åå‰ãŒã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:7841
msgid "E495: no autocommand file name to substitute for \"<afile>\""
msgstr "E495: \"<afile>\"ã‚’ç½®ãæ›ãˆã‚‹autocommandã®ãƒ•ァイルåãŒã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:7850
msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
msgstr "E496: \"<abuf>\"ã‚’ç½®ãæ›ãˆã‚‹autocommandãƒãƒƒãƒ•ァ番å·ãŒã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:7861
msgid "E497: no autocommand match name to substitute for \"<amatch>\""
msgstr "E497: \"<amatch>\"ã‚’ç½®ãæ›ãˆã‚‹autocommandã®è©²å½“åãŒã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:7870
msgid "E498: no :source file name to substitute for \"<sfile>\""
msgstr "E498: \"<sfile>\"ã‚’ç½®ãæ›ãˆã‚‹ :source 対象ファイルåãŒã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:7876
msgid "E842: no line number to use for \"<slnum>\""
msgstr "E842: \"<slnum>\"ã‚’ç½®ãæ›ãˆã‚‹è¡Œç•ªå·ãŒã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
+#, no-c-format
msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
msgstr ""
"E499: '%' ã‚„ '#' ãŒç„¡åファイルãªã®ã§ \":p:h\" ã‚’ä¼´ã‚ãªã„ä½¿ã„æ–¹ã¯ã§ãã¾ã›ã‚“"
-#: ../ex_docmd.c:7905
msgid "E500: Evaluates to an empty string"
msgstr "E500: 空文字列ã¨ã—ã¦è©•価ã•れã¾ã—ãŸ"
-#: ../ex_docmd.c:8838
msgid "E195: Cannot open viminfo file for reading"
msgstr "E195: viminfoファイルを読込用ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“"
-#: ../ex_eval.c:464
+msgid "E196: No digraphs in this version"
+msgstr "E196: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«åˆå­—ã¯ã‚りã¾ã›ã‚“"
+
msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
msgstr "E608: 'Vim' ã§å§‹ã¾ã‚‹ä¾‹å¤–㯠:throw ã§ãã¾ã›ã‚“"
#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
#, c-format
msgid "Exception thrown: %s"
msgstr "例外ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s"
-#: ../ex_eval.c:545
#, c-format
msgid "Exception finished: %s"
msgstr "例外ãŒåŽæŸã—ã¾ã—ãŸ: %s"
-#: ../ex_eval.c:546
#, c-format
msgid "Exception discarded: %s"
msgstr "例外ãŒç ´æ£„ã•れã¾ã—ãŸ: %s"
-#: ../ex_eval.c:588 ../ex_eval.c:634
#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, 行 %<PRId64>"
+msgid "%s, line %ld"
+msgstr "%s, 行 %ld"
#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
#, c-format
msgid "Exception caught: %s"
msgstr "ä¾‹å¤–ãŒæ•æ‰ã•れã¾ã—ãŸ: %s"
-#: ../ex_eval.c:676
#, c-format
msgid "%s made pending"
msgstr "%s ã«ã‚ˆã‚Šæœªæ±ºå®šçŠ¶æ…‹ãŒç”Ÿã˜ã¾ã—ãŸ"
-#: ../ex_eval.c:679
#, c-format
msgid "%s resumed"
msgstr "%s ãŒå†é–‹ã—ã¾ã—ãŸ"
-#: ../ex_eval.c:683
#, c-format
msgid "%s discarded"
msgstr "%s ãŒç ´æ£„ã•れã¾ã—ãŸ"
-#: ../ex_eval.c:708
msgid "Exception"
msgstr "例外"
-#: ../ex_eval.c:713
msgid "Error and interrupt"
msgstr "エラーã¨å‰²è¾¼ã¿"
-#: ../ex_eval.c:715
msgid "Error"
msgstr "エラー"
#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
msgid "Interrupt"
msgstr "割込ã¿"
-#: ../ex_eval.c:795
msgid "E579: :if nesting too deep"
msgstr "E579: :if ã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
-#: ../ex_eval.c:830
msgid "E580: :endif without :if"
msgstr "E580: :if ã®ãªã„ :endif ãŒã‚りã¾ã™"
-#: ../ex_eval.c:873
msgid "E581: :else without :if"
msgstr "E581: :if ã®ãªã„ :else ãŒã‚りã¾ã™"
-#: ../ex_eval.c:876
msgid "E582: :elseif without :if"
msgstr "E582: :if ã®ãªã„ :elseif ãŒã‚りã¾ã™"
-#: ../ex_eval.c:880
msgid "E583: multiple :else"
msgstr "E583: 複数㮠:else ãŒã‚りã¾ã™"
-#: ../ex_eval.c:883
msgid "E584: :elseif after :else"
msgstr "E584: :else ã®å¾Œã« :elseif ãŒã‚りã¾ã™"
-#: ../ex_eval.c:941
msgid "E585: :while/:for nesting too deep"
msgstr "E585: :while ã‚„ :for ã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
-#: ../ex_eval.c:1028
msgid "E586: :continue without :while or :for"
msgstr "E586: :while ã‚„ :for ã®ãªã„ :continue ãŒã‚りã¾ã™"
-#: ../ex_eval.c:1061
msgid "E587: :break without :while or :for"
msgstr "E587: :while ã‚„ :for ã®ãªã„ :break ãŒã‚りã¾ã™"
-#: ../ex_eval.c:1102
msgid "E732: Using :endfor with :while"
msgstr "E732: :endfor ã‚’ :while ã¨çµ„ã¿åˆã‚ã›ã¦ã„ã¾ã™"
-#: ../ex_eval.c:1104
msgid "E733: Using :endwhile with :for"
msgstr "E733: :endwhile ã‚’ :for ã¨çµ„ã¿åˆã‚ã›ã¦ã„ã¾ã™"
-#: ../ex_eval.c:1247
msgid "E601: :try nesting too deep"
msgstr "E601: :try ã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
-#: ../ex_eval.c:1317
msgid "E603: :catch without :try"
msgstr "E603: :try ã®ãªã„ :catch ãŒã‚りã¾ã™"
#. Give up for a ":catch" after ":finally" and ignore it.
#. * Just parse.
-#: ../ex_eval.c:1332
msgid "E604: :catch after :finally"
msgstr "E604: :finally ã®å¾Œã« :catch ãŒã‚りã¾ã™"
-#: ../ex_eval.c:1451
msgid "E606: :finally without :try"
msgstr "E606: :try ã®ãªã„ :finally ãŒã‚りã¾ã™"
#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
msgid "E607: multiple :finally"
msgstr "E607: 複数㮠:finally ãŒã‚りã¾ã™"
-#: ../ex_eval.c:1571
msgid "E602: :endtry without :try"
msgstr "E602: :try ã®ãªã„ :endtry ã§ã™"
-#: ../ex_eval.c:2026
msgid "E193: :endfunction not inside a function"
msgstr "E193: 関数ã®å¤–ã« :endfunction ãŒã‚りã¾ã—ãŸ"
-#: ../ex_getln.c:1643
msgid "E788: Not allowed to edit another buffer now"
msgstr "E788: ç¾åœ¨ã¯ä»–ã®ãƒãƒƒãƒ•ァを編集ã™ã‚‹ã“ã¨ã¯è¨±ã•れã¾ã›ã‚“"
-#: ../ex_getln.c:1656
msgid "E811: Not allowed to change buffer information now"
msgstr "E811: ç¾åœ¨ã¯ãƒãƒƒãƒ•ァ情報を変更ã™ã‚‹ã“ã¨ã¯è¨±ã•れã¾ã›ã‚“"
-#: ../ex_getln.c:3178
msgid "tagname"
msgstr "ã‚¿ã‚°å"
-#: ../ex_getln.c:3181
msgid " kind file\n"
msgstr " ファイル種類\n"
-#: ../ex_getln.c:4799
msgid "'history' option is zero"
msgstr "オプション 'history' ãŒã‚¼ãƒ­ã§ã™"
-#: ../ex_getln.c:5046
#, c-format
msgid ""
"\n"
@@ -1985,303 +1613,224 @@ msgstr ""
"\n"
"# %s é …ç›®ã®å±¥æ­´ (æ–°ã—ã„ã‚‚ã®ã‹ã‚‰å¤ã„ã‚‚ã®ã¸):\n"
-#: ../ex_getln.c:5047
msgid "Command Line"
msgstr "コマンドライン"
-#: ../ex_getln.c:5048
msgid "Search String"
msgstr "検索文字列"
-#: ../ex_getln.c:5049
msgid "Expression"
msgstr "å¼"
-#: ../ex_getln.c:5050
msgid "Input Line"
msgstr "入力行"
-#: ../ex_getln.c:5117
+msgid "Debug Line"
+msgstr "デãƒãƒƒã‚°è¡Œ"
+
msgid "E198: cmd_pchar beyond the command length"
msgstr "E198: cmd_pchar ãŒã‚³ãƒžãƒ³ãƒ‰é•·ã‚’è¶…ãˆã¾ã—ãŸ"
-#: ../ex_getln.c:5279
msgid "E199: Active window or buffer deleted"
msgstr "E199: アクティブãªã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‹ãƒãƒƒãƒ•ã‚¡ãŒå‰Šé™¤ã•れã¾ã—ãŸ"
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr "E854: パスãŒé•·éŽãŽã¦è£œå®Œã§ãã¾ã›ã‚“"
-
-#: ../file_search.c:446
-#, c-format
-msgid ""
-"E343: Invalid path: '**[number]' must be at the end of the path or be "
-"followed by '%s'."
-msgstr ""
-"E343: 無効ãªãƒ‘スã§ã™: '**[数値]' ã¯pathã®æœ€å¾Œã‹ '%s' ãŒç¶šã„ã¦ãªã„ã¨ã„ã‘ã¾ã›"
-"ã‚“."
-
-#: ../file_search.c:1505
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: cdpathã«ã¯ \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: pathã«ã¯ \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: cdpathã«ã¯ã“れ以上 \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: パスã«ã¯ã“れ以上 \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
-
-#: ../fileio.c:137
msgid "E812: Autocommands changed buffer or buffer name"
msgstr "E812: autocommandãŒãƒãƒƒãƒ•ã‚¡ã‹ãƒãƒƒãƒ•ã‚¡åを変更ã—ã¾ã—ãŸ"
-#: ../fileio.c:368
msgid "Illegal file name"
msgstr "䏿­£ãªãƒ•ァイルå"
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
msgid "is a directory"
msgstr "ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã™"
-#: ../fileio.c:397
msgid "is not a file"
msgstr "ã¯ãƒ•ァイルã§ã¯ã‚りã¾ã›ã‚“"
-#: ../fileio.c:508 ../fileio.c:3522
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "ã¯ãƒ‡ãƒã‚¤ã‚¹ã§ã™ ('opendevice' オプションã§å›žé¿ã§ãã¾ã™)"
+
msgid "[New File]"
msgstr "[新ファイル]"
-#: ../fileio.c:511
msgid "[New DIRECTORY]"
msgstr "[æ–°è¦ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª]"
-#: ../fileio.c:529 ../fileio.c:532
msgid "[File too big]"
msgstr "[ファイルéŽå¤§]"
-#: ../fileio.c:534
msgid "[Permission Denied]"
msgstr "[権é™ãŒã‚りã¾ã›ã‚“]"
-#: ../fileio.c:653
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr "E200: *ReadPre autocommand ãŒãƒ•ァイルを読込ä¸å¯ã«ã—ã¾ã—ãŸ"
-#: ../fileio.c:655
msgid "E201: *ReadPre autocommands must not change current buffer"
msgstr "E201: *ReadPre autocommand ã¯ç¾åœ¨ã®ãƒãƒƒãƒ•ァを変ãˆã‚‰ã‚Œã¾ã›ã‚“"
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
+msgid "Vim: Reading from stdin...\n"
msgstr "Vim: 標準入力ã‹ã‚‰èª­è¾¼ä¸­...\n"
+msgid "Reading from stdin..."
+msgstr "標準入力ã‹ã‚‰èª­è¾¼ã¿ä¸­..."
+
#. Re-opening the original file failed!
-#: ../fileio.c:909
msgid "E202: Conversion made file unreadable!"
msgstr "E202: 変æ›ãŒãƒ•ァイルを読込ä¸å¯ã«ã—ã¾ã—ãŸ"
-#. fifo or socket
-#: ../fileio.c:1782
msgid "[fifo/socket]"
msgstr "[FIFO/ソケット]"
-#. fifo
-#: ../fileio.c:1788
msgid "[fifo]"
msgstr "[FIFO]"
-#. or socket
-#: ../fileio.c:1794
msgid "[socket]"
msgstr "[ソケット]"
-#. or character special
-#: ../fileio.c:1801
msgid "[character special]"
msgstr "[キャラクタ・デãƒã‚¤ã‚¹]"
-#: ../fileio.c:1815
msgid "[CR missing]"
msgstr "[CRç„¡]"
-#: ../fileio.c:1819
msgid "[long lines split]"
msgstr "[長行分割]"
-#: ../fileio.c:1823 ../fileio.c:3512
msgid "[NOT converted]"
msgstr "[未変æ›]"
-#: ../fileio.c:1826 ../fileio.c:3515
msgid "[converted]"
msgstr "[å¤‰æ›æ¸ˆ]"
-#: ../fileio.c:1831
#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[%<PRId64> 行目ã§å¤‰æ›ã‚¨ãƒ©ãƒ¼]"
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[%ld 行目ã§å¤‰æ›ã‚¨ãƒ©ãƒ¼]"
-#: ../fileio.c:1835
#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[%<PRId64> 行目ã®ä¸æ­£ãªãƒã‚¤ãƒˆ]"
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[%ld 行目ã®ä¸æ­£ãªãƒã‚¤ãƒˆ]"
-#: ../fileio.c:1838
msgid "[READ ERRORS]"
msgstr "[読込エラー]"
-#: ../fileio.c:2104
msgid "Can't find temp file for conversion"
msgstr "変æ›ã«å¿…è¦ãªä¸€æ™‚ファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../fileio.c:2110
msgid "Conversion with 'charconvert' failed"
msgstr "'charconvert' ã«ã‚ˆã‚‹å¤‰æ›ãŒå¤±æ•—ã—ã¾ã—ãŸ"
-#: ../fileio.c:2113
msgid "can't read output of 'charconvert'"
msgstr "'charconvert' ã®å‡ºåŠ›ã‚’èª­è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ"
-#: ../fileio.c:2437
msgid "E676: No matching autocommands for acwrite buffer"
msgstr "E676: acwriteãƒãƒƒãƒ•ã‚¡ã®è©²å½“ã™ã‚‹autocommandã¯å­˜åœ¨ã—ã¾ã›ã‚“"
-#: ../fileio.c:2466
msgid "E203: Autocommands deleted or unloaded buffer to be written"
msgstr "E203: ä¿å­˜ã™ã‚‹ãƒãƒƒãƒ•ã‚¡ã‚’autocommandãŒå‰Šé™¤ã‹è§£æ”¾ã—ã¾ã—ãŸ"
-#: ../fileio.c:2486
msgid "E204: Autocommand changed number of lines in unexpected way"
msgstr "E204: autocommandãŒäºˆæœŸã›ã¬æ–¹æ³•ã§è¡Œæ•°ã‚’変更ã—ã¾ã—ãŸ"
-#: ../fileio.c:2548 ../fileio.c:2565
+# Added at 19-Jan-2004.
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeansã¯æœªå¤‰æ›´ã®ãƒãƒƒãƒ•ァを上書ã™ã‚‹ã“ã¨ã¯è¨±å¯ã—ã¦ã„ã¾ã›ã‚“"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "NetBeansãƒãƒƒãƒ•ã‚¡ã®ä¸€éƒ¨ã‚’書ã出ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
msgid "is not a file or writable device"
msgstr "ã¯ãƒ•ァイルã§ã‚‚書込ã¿å¯èƒ½ãƒ‡ãƒã‚¤ã‚¹ã§ã‚‚ã‚りã¾ã›ã‚“"
-#: ../fileio.c:2601
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "'opendevice' オプションã«ã‚ˆã‚Šãƒ‡ãƒã‚¤ã‚¹ã¸ã®æ›¸ãè¾¼ã¿ã¯ã§ãã¾ã›ã‚“"
+
msgid "is read-only (add ! to override)"
msgstr "ã¯èª­è¾¼å°‚用ã§ã™ (強制書込ã«ã¯ ! を追加)"
-#: ../fileio.c:2886
msgid "E506: Can't write to backup file (add ! to override)"
msgstr "E506: ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ファイルをä¿å­˜ã§ãã¾ã›ã‚“ (! を追加ã§å¼·åˆ¶ä¿å­˜)"
-#: ../fileio.c:2898
msgid "E507: Close error for backup file (add ! to override)"
msgstr ""
"E507: ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ファイルを閉ã˜ã‚‹éš›ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—㟠(! を追加ã§å¼·åˆ¶)"
-#: ../fileio.c:2901
msgid "E508: Can't read file for backup (add ! to override)"
msgstr "E508: ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—用ファイルを読込ã‚ã¾ã›ã‚“ (! を追加ã§å¼·åˆ¶èª­è¾¼)"
-#: ../fileio.c:2923
msgid "E509: Cannot create backup file (add ! to override)"
msgstr "E509: ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ファイルを作れã¾ã›ã‚“ (! を追加ã§å¼·åˆ¶ä½œæˆ)"
-#: ../fileio.c:3008
msgid "E510: Can't make backup file (add ! to override)"
msgstr "E510: ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ファイルを作れã¾ã›ã‚“ (! を追加ã§å¼·åˆ¶ä½œæˆ)"
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: リソースフォークãŒå¤±ã‚れるã‹ã‚‚ã—れã¾ã›ã‚“ (! を追加ã§å¼·åˆ¶)"
+
msgid "E214: Can't find temp file for writing"
msgstr "E214: ä¿å­˜ç”¨ä¸€æ™‚ファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../fileio.c:3134
msgid "E213: Cannot convert (add ! to write without conversion)"
msgstr "E213: 変æ›ã§ãã¾ã›ã‚“ (! を追加ã§å¤‰æ›ã›ãšã«ä¿å­˜)"
-#: ../fileio.c:3169
msgid "E166: Can't open linked file for writing"
msgstr "E166: リンクã•れãŸãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸è¾¼ã‚ã¾ã›ã‚“"
-#: ../fileio.c:3173
msgid "E212: Can't open file for writing"
msgstr "E212: 書込ã¿ç”¨ã«ãƒ•ァイルを開ã‘ã¾ã›ã‚“"
-#: ../fileio.c:3363
msgid "E667: Fsync failed"
msgstr "E667: fsync ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../fileio.c:3398
msgid "E512: Close failed"
msgstr "E512: é–‰ã˜ã‚‹ã“ã¨ã«å¤±æ•—"
-#: ../fileio.c:3436
msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
msgstr "E513: 書込ã¿ã‚¨ãƒ©ãƒ¼, 変æ›å¤±æ•— (上書ã™ã‚‹ã«ã¯ 'fenc' を空ã«ã—ã¦ãã ã•ã„)"
-#: ../fileio.c:3441
#, c-format
msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
"override)"
msgstr ""
-"E513: 書込ã¿ã‚¨ãƒ©ãƒ¼, 変æ›å¤±æ•—, 行数 %<PRId64> (上書ã™ã‚‹ã«ã¯ 'fenc' を空ã«ã—ã¦"
-"ãã ã•ã„)"
+"E513: 書込ã¿ã‚¨ãƒ©ãƒ¼, 変æ›å¤±æ•—, 行数 %ld (上書ã™ã‚‹ã«ã¯ 'fenc' を空ã«ã—ã¦ãã ã•"
+"ã„)"
-#: ../fileio.c:3448
msgid "E514: write error (file system full?)"
msgstr "E514: 書込ã¿ã‚¨ãƒ©ãƒ¼, (ãƒ•ã‚¡ã‚¤ãƒ«ã‚·ã‚¹ãƒ†ãƒ ãŒæº€æ¯?)"
-#: ../fileio.c:3506
msgid " CONVERSION ERROR"
msgstr " 変æ›ã‚¨ãƒ©ãƒ¼"
-#: ../fileio.c:3509
#, c-format
-msgid " in line %<PRId64>;"
-msgstr " 行 %<PRId64>;"
+msgid " in line %ld;"
+msgstr " 行 %ld;"
-#: ../fileio.c:3519
msgid "[Device]"
msgstr "[デãƒã‚¤ã‚¹]"
-#: ../fileio.c:3522
msgid "[New]"
msgstr "[æ–°]"
-#: ../fileio.c:3535
msgid " [a]"
msgstr " [a]"
-#: ../fileio.c:3535
msgid " appended"
msgstr " 追加"
-#: ../fileio.c:3537
msgid " [w]"
msgstr " [w]"
-#: ../fileio.c:3537
msgid " written"
msgstr " 書込ã¿"
-#: ../fileio.c:3579
msgid "E205: Patchmode: can't save original file"
msgstr "E205: patchmode: 原本ファイルをä¿å­˜ã§ãã¾ã›ã‚“"
-#: ../fileio.c:3602
msgid "E206: patchmode: can't touch empty original file"
msgstr "E206: patchmode: 空ã®åŽŸæœ¬ãƒ•ã‚¡ã‚¤ãƒ«ã‚’touchã§ãã¾ã›ã‚“"
-#: ../fileio.c:3616
msgid "E207: Can't delete backup file"
msgstr "E207: ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ファイルを消ã›ã¾ã›ã‚“"
-#: ../fileio.c:3672
msgid ""
"\n"
"WARNING: Original file may be lost or damaged\n"
@@ -2289,134 +1838,105 @@ msgstr ""
"\n"
"警告: 原本ファイルãŒå¤±ã‚れãŸã‹å¤‰æ›´ã•れã¾ã—ãŸ\n"
-#: ../fileio.c:3675
msgid "don't quit the editor until the file is successfully written!"
msgstr "ファイルã®ä¿å­˜ã«æˆåŠŸã™ã‚‹ã¾ã§ã‚¨ãƒ‡ã‚£ã‚¿ã‚’終了ã—ãªã„ã§ãã ã•ã„!"
-#: ../fileio.c:3795
msgid "[dos]"
msgstr "[dos]"
-#: ../fileio.c:3795
msgid "[dos format]"
msgstr "[dosフォーマット]"
-#: ../fileio.c:3801
msgid "[mac]"
msgstr "[mac]"
-#: ../fileio.c:3801
msgid "[mac format]"
msgstr "[macフォーマット]"
-#: ../fileio.c:3807
msgid "[unix]"
msgstr "[unix]"
-#: ../fileio.c:3807
msgid "[unix format]"
msgstr "[unixフォーマット]"
-#: ../fileio.c:3831
msgid "1 line, "
msgstr "1 行, "
-#: ../fileio.c:3833
#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> 行, "
+msgid "%ld lines, "
+msgstr "%ld 行, "
-#: ../fileio.c:3836
msgid "1 character"
msgstr "1 文字"
-#: ../fileio.c:3838
#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> 文字"
+msgid "%lld characters"
+msgstr "%lld 文字"
-#: ../fileio.c:3849
msgid "[noeol]"
msgstr "[noeol]"
-#: ../fileio.c:3849
msgid "[Incomplete last line]"
msgstr "[最終行ãŒä¸å®Œå…¨]"
#. don't overwrite messages here
#. must give this prompt
#. don't use emsg() here, don't want to flush the buffers
-#: ../fileio.c:3865
msgid "WARNING: The file has been changed since reading it!!!"
msgstr "警告: 読込んã å¾Œã«ãƒ•ァイルã«å¤‰æ›´ãŒã‚りã¾ã—ãŸ!!!"
-#: ../fileio.c:3867
msgid "Do you really want to write to it"
msgstr "本当ã«ä¸Šæ›¸ãã—ã¾ã™ã‹"
-#: ../fileio.c:4648
#, c-format
msgid "E208: Error writing to \"%s\""
msgstr "E208: \"%s\" を書込ã¿ä¸­ã®ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../fileio.c:4655
#, c-format
msgid "E209: Error closing \"%s\""
msgstr "E209: \"%s\" ã‚’é–‰ã˜ã‚‹æ™‚ã«ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../fileio.c:4657
#, c-format
msgid "E210: Error reading \"%s\""
msgstr "E210: \"%s\" を読込中ã®ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../fileio.c:4883
msgid "E246: FileChangedShell autocommand deleted buffer"
msgstr "E246: autocommand ã® FileChangedShell ãŒãƒãƒƒãƒ•ァを削除ã—ã¾ã—ãŸ"
-#: ../fileio.c:4894
#, c-format
msgid "E211: File \"%s\" no longer available"
msgstr "E211: ファイル \"%s\" ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã›ã‚“"
-#: ../fileio.c:4906
#, c-format
msgid ""
"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
"well"
msgstr "W12: 警告: ファイル \"%s\" ãŒå¤‰æ›´ã•れVimã®ãƒãƒƒãƒ•ァも変更ã•れã¾ã—ãŸ"
-#: ../fileio.c:4907
msgid "See \":help W12\" for more info."
msgstr "詳細㯠\":help W12\" ã‚’å‚ç…§ã—ã¦ãã ã•ã„"
-#: ../fileio.c:4910
#, c-format
msgid "W11: Warning: File \"%s\" has changed since editing started"
msgstr "W11: 警告: ファイル \"%s\" ã¯ç·¨é›†é–‹å§‹å¾Œã«å¤‰æ›´ã•れã¾ã—ãŸ"
-#: ../fileio.c:4911
msgid "See \":help W11\" for more info."
msgstr "詳細㯠\":help W11\" ã‚’å‚ç…§ã—ã¦ãã ã•ã„"
-#: ../fileio.c:4914
#, c-format
msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
msgstr "W16: 警告: ファイル \"%s\" ã®ãƒ¢ãƒ¼ãƒ‰ãŒç·¨é›†é–‹å§‹å¾Œã«å¤‰æ›´ã•れã¾ã—ãŸ"
-#: ../fileio.c:4915
msgid "See \":help W16\" for more info."
msgstr "詳細㯠\":help W16\" ã‚’å‚ç…§ã—ã¦ãã ã•ã„"
-#: ../fileio.c:4927
#, c-format
msgid "W13: Warning: File \"%s\" has been created after editing started"
msgstr "W13: 警告: ファイル \"%s\" ã¯ç·¨é›†é–‹å§‹å¾Œã«ä½œæˆã•れã¾ã—ãŸ"
-#: ../fileio.c:4947
msgid "Warning"
msgstr "警告"
-#: ../fileio.c:4948
msgid ""
"&OK\n"
"&Load File"
@@ -2424,48 +1944,45 @@ msgstr ""
"&OK\n"
"ファイル読込(&L)"
-#: ../fileio.c:5065
#, c-format
msgid "E462: Could not prepare for reloading \"%s\""
msgstr "E462: \"%s\" をリロードã™ã‚‹æº–å‚™ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ"
-#: ../fileio.c:5078
#, c-format
msgid "E321: Could not reload \"%s\""
msgstr "E321: \"%s\" ã¯ãƒªãƒ­ãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸ"
-#: ../fileio.c:5601
msgid "--Deleted--"
msgstr "--削除済--"
-#: ../fileio.c:5732
#, c-format
msgid "auto-removing autocommand: %s <buffer=%d>"
msgstr "autocommand: %s <ãƒãƒƒãƒ•ã‚¡=%d> ãŒè‡ªå‹•çš„ã«å‰Šé™¤ã•れã¾ã™"
#. the group doesn't exist
-#: ../fileio.c:5772
#, c-format
msgid "E367: No such group: \"%s\""
msgstr "E367: ãã®ã‚°ãƒ«ãƒ¼ãƒ—ã¯ã‚りã¾ã›ã‚“: \"%s\""
-#: ../fileio.c:5897
+msgid "E936: Cannot delete the current group"
+msgstr "E936: ç¾åœ¨ã®ã‚°ãƒ«ãƒ¼ãƒ—ã¯å‰Šé™¤ã§ãã¾ã›ã‚“"
+
+msgid "W19: Deleting augroup that is still in use"
+msgstr "W19: 使用中㮠augroup を消ãã†ã¨ã—ã¦ã„ã¾ã™"
+
#, c-format
msgid "E215: Illegal character after *: %s"
msgstr "E215: * ã®å¾Œã«ä¸æ­£ãªæ–‡å­—ãŒã‚りã¾ã—ãŸ: %s"
-#: ../fileio.c:5905
#, c-format
msgid "E216: No such event: %s"
msgstr "E216: ãã®ã‚ˆã†ãªã‚¤ãƒ™ãƒ³ãƒˆã¯ã‚りã¾ã›ã‚“: %s"
-#: ../fileio.c:5907
#, c-format
msgid "E216: No such group or event: %s"
msgstr "E216: ãã®ã‚ˆã†ãªã‚°ãƒ«ãƒ¼ãƒ—ã‚‚ã—ãã¯ã‚¤ãƒ™ãƒ³ãƒˆã¯ã‚りã¾ã›ã‚“: %s"
#. Highlight title
-#: ../fileio.c:6090
msgid ""
"\n"
"--- Auto-Commands ---"
@@ -2473,756 +1990,555 @@ msgstr ""
"\n"
"--- Auto-Commands ---"
-#: ../fileio.c:6293
#, c-format
msgid "E680: <buffer=%d>: invalid buffer number "
msgstr "E680: <ãƒãƒƒãƒ•ã‚¡=%d>: 無効ãªãƒãƒƒãƒ•ァ番å·ã§ã™ "
-#: ../fileio.c:6370
msgid "E217: Can't execute autocommands for ALL events"
msgstr "E217: å…¨ã¦ã®ã‚¤ãƒ™ãƒ³ãƒˆã«å¯¾ã—ã¦ã®autocommandã¯å®Ÿè¡Œã§ãã¾ã›ã‚“"
-#: ../fileio.c:6393
msgid "No matching autocommands"
msgstr "該当ã™ã‚‹autocommandã¯å­˜åœ¨ã—ã¾ã›ã‚“"
-#: ../fileio.c:6831
msgid "E218: autocommand nesting too deep"
msgstr "E218: autocommandã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
-#: ../fileio.c:7143
#, c-format
msgid "%s Auto commands for \"%s\""
msgstr "%s Auto commands for \"%s\""
-#: ../fileio.c:7149
#, c-format
msgid "Executing %s"
msgstr "%s を実行ã—ã¦ã„ã¾ã™"
-#: ../fileio.c:7211
#, c-format
msgid "autocommand %s"
msgstr "autocommand %s"
-#: ../fileio.c:7795
msgid "E219: Missing {."
msgstr "E219: { ãŒã‚りã¾ã›ã‚“."
-#: ../fileio.c:7797
msgid "E220: Missing }."
msgstr "E220: } ãŒã‚りã¾ã›ã‚“."
-#: ../fold.c:93
msgid "E490: No fold found"
msgstr "E490: 折畳ã¿ãŒã‚りã¾ã›ã‚“"
-#: ../fold.c:544
msgid "E350: Cannot create fold with current 'foldmethod'"
msgstr "E350: ç¾åœ¨ã® 'foldmethod' ã§ã¯æŠ˜ç•³ã¿ã‚’作æˆã§ãã¾ã›ã‚“"
-#: ../fold.c:546
msgid "E351: Cannot delete fold with current 'foldmethod'"
msgstr "E351: ç¾åœ¨ã® 'foldmethod' ã§ã¯æŠ˜ç•³ã¿ã‚’削除ã§ãã¾ã›ã‚“"
-#: ../fold.c:1784
#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld è¡ŒãŒæŠ˜ç•³ã¾ã‚Œã¾ã—㟠"
+msgid "+--%3ld line folded "
+msgid_plural "+--%3ld lines folded "
+msgstr[0] "+--%3ld è¡ŒãŒæŠ˜ç•³ã¾ã‚Œã¾ã—㟠"
-#. buffer has already been read
-#: ../getchar.c:273
msgid "E222: Add to read buffer"
msgstr "E222: 読込ãƒãƒƒãƒ•ã‚¡ã¸è¿½åŠ "
-#: ../getchar.c:2040
msgid "E223: recursive mapping"
msgstr "E223: å†å¸°çš„マッピング"
-#: ../getchar.c:2849
#, c-format
msgid "E224: global abbreviation already exists for %s"
msgstr "E224: %s ã¨ã„ã†ã‚°ãƒ­ãƒ¼ãƒãƒ«çŸ­ç¸®å…¥åŠ›ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™"
-#: ../getchar.c:2852
#, c-format
msgid "E225: global mapping already exists for %s"
msgstr "E225: %s ã¨ã„ã†ã‚°ãƒ­ãƒ¼ãƒãƒ«ãƒžãƒƒãƒ”ãƒ³ã‚°ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™"
-#: ../getchar.c:2952
#, c-format
msgid "E226: abbreviation already exists for %s"
msgstr "E226: %s ã¨ã„ã†çŸ­ç¸®å…¥åŠ›ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™"
-#: ../getchar.c:2955
#, c-format
msgid "E227: mapping already exists for %s"
msgstr "E227: %s ã¨ã„ã†ãƒžãƒƒãƒ”ãƒ³ã‚°ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™"
-#: ../getchar.c:3008
msgid "No abbreviation found"
msgstr "短縮入力ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
-#: ../getchar.c:3010
msgid "No mapping found"
msgstr "マッピングã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
-#: ../getchar.c:3974
msgid "E228: makemap: Illegal mode"
msgstr "E228: makemap: 䏿­£ãªãƒ¢ãƒ¼ãƒ‰"
-#. key value of 'cedit' option
-#. type of cmdline window or 0
-#. result of cmdline window or 0
-#: ../globals.h:924
-msgid "--No lines in buffer--"
-msgstr "--ãƒãƒƒãƒ•ã‚¡ã«è¡ŒãŒã‚りã¾ã›ã‚“--"
+msgid "E851: Failed to create a new process for the GUI"
+msgstr "E851: GUI用ã®ãƒ—ロセスã®èµ·å‹•ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#.
-#. * The error messages that can be shared are included here.
-#. * Excluded are errors that are only used once and debugging messages.
-#.
-#: ../globals.h:996
-msgid "E470: Command aborted"
-msgstr "E470: コマンドãŒä¸­æ–­ã•れã¾ã—ãŸ"
+msgid "E852: The child process failed to start the GUI"
+msgstr "E852: å­ãƒ—ロセスãŒGUIã®èµ·å‹•ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: 引数ãŒå¿…è¦ã§ã™"
+msgid "E229: Cannot start the GUI"
+msgstr "E229: GUIã‚’é–‹å§‹ã§ãã¾ã›ã‚“"
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: \\ ã®å¾Œã¯ / ã‹ ? ã‹ & ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: \"%s\"ã‹ã‚‰èª­è¾¼ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“"
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr "E11: コマンドラインã§ã¯ç„¡åйã§ã™; <CR>ã§å®Ÿè¡Œ, CTRL-Cã§ã‚„ã‚ã‚‹"
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr "E665: 有効ãªãƒ•ォントãŒè¦‹ã¤ã‹ã‚‰ãªã„ã®ã§, GUIã‚’é–‹å§‹ã§ãã¾ã›ã‚“"
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
-msgstr ""
-"E12: ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚„タグ検索ã§ã¯exrc/vimrcã®ã‚³ãƒžãƒ³ãƒ‰ã¯è¨±å¯ã•れã¾ã›ã‚“"
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' ãŒç„¡åйã§ã™"
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: :endif ãŒã‚りã¾ã›ã‚“"
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: 'imactivatekey' ã«è¨­å®šã•れãŸå€¤ãŒç„¡åйã§ã™"
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: :endtry ãŒã‚りã¾ã›ã‚“"
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: %s ã®è‰²ã‚’割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“"
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: :endwhile ãŒã‚りã¾ã›ã‚“"
+msgid "No match at cursor, finding next"
+msgstr "カーソルã®ä½ç½®ã«ãƒžãƒƒãƒã¯ã‚りã¾ã›ã‚“, 次を検索ã—ã¦ã„ã¾ã™"
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: :endfor ãŒã‚りã¾ã›ã‚“"
-
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: :while ã®ãªã„ :endwhile ãŒã‚りã¾ã™"
+msgid "<cannot open> "
+msgstr "<é–‹ã‘ã¾ã›ã‚“> "
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: :endfor ã®ãªã„ :for ãŒã‚りã¾ã™"
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: フォント %s ã‚’å–å¾—ã§ãã¾ã›ã‚“"
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: ファイルãŒå­˜åœ¨ã—ã¾ã™ (! を追加ã§ä¸Šæ›¸)"
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æˆ»ã‚Œã¾ã›ã‚“"
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: コマンドãŒå¤±æ•—ã—ã¾ã—ãŸ"
+msgid "Pathname:"
+msgstr "パスå:"
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: 内部エラーã§ã™"
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’å–å¾—ã§ãã¾ã›ã‚“"
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "割込ã¾ã‚Œã¾ã—ãŸ"
+msgid "OK"
+msgstr "OK"
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: 無効ãªã‚¢ãƒ‰ãƒ¬ã‚¹ã§ã™"
+msgid "Cancel"
+msgstr "キャンセル"
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: 無効ãªå¼•æ•°ã§ã™"
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "スクロールãƒãƒ¼: ç”»åƒã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ."
-#: ../globals.h:1015
-#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: 無効ãªå¼•æ•°ã§ã™: %s"
+msgid "Vim dialog"
+msgstr "Vim ダイアログ"
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: 無効ãªå¼ã§ã™: %s"
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: メッセージã¨ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã®ã‚ã‚‹ BalloonEval を作æˆã§ãã¾ã›ã‚“"
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: 無効ãªç¯„囲ã§ã™"
+msgid "_Cancel"
+msgstr "キャンセル(_C)"
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: 無効ãªã‚³ãƒžãƒ³ãƒ‰ã§ã™"
+msgid "_Save"
+msgstr "ä¿å­˜(_S)"
-#: ../globals.h:1019
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: \"%s\" ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã™"
+msgid "_Open"
+msgstr "é–‹ã(_O)"
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: 無効ãªã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«é‡ã§ã™"
+msgid "_OK"
+msgstr "_OK"
-#: ../globals.h:1021
-msgid "E901: Job table is full"
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
msgstr ""
+"ã¯ã„(&Y)\n"
+"ã„ã„ãˆ(&N)\n"
+"キャンセル(&C)"
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: \"%s\"() ã®ãƒ©ã‚¤ãƒ–ラリ呼出ã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "Yes"
+msgstr "ã¯ã„"
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: マークã«ç„¡åйãªè¡Œç•ªå·ãŒæŒ‡å®šã•れã¦ã„ã¾ã—ãŸ"
+msgid "No"
+msgstr "ã„ã„ãˆ"
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: マークã¯è¨­å®šã•れã¦ã„ã¾ã›ã‚“"
+msgid "Input _Methods"
+msgstr "インプットメソッド"
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: 'modifiable' ãŒã‚ªãƒ•ãªã®ã§, 変更ã§ãã¾ã›ã‚“"
+msgid "VIM - Search and Replace..."
+msgstr "VIM - 検索ã¨ç½®æ›..."
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: スクリプトã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
+msgid "VIM - Search..."
+msgstr "VIM - 検索..."
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: 副ファイルã¯ã‚りã¾ã›ã‚“"
+msgid "Find what:"
+msgstr "検索文字列:"
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: ãã®ã‚ˆã†ãªçŸ­ç¸®å…¥åŠ›ã¯ã‚りã¾ã›ã‚“"
+msgid "Replace with:"
+msgstr "ç½®æ›æ–‡å­—列:"
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: ! ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
+#. whole word only button
+msgid "Match whole word only"
+msgstr "正確ã«è©²å½“ã™ã‚‹ã‚‚ã®ã ã‘"
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: GUIã¯ä½¿ç”¨ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™"
+#. match case button
+msgid "Match case"
+msgstr "大文字/å°æ–‡å­—を区別ã™ã‚‹"
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: ãã®ã‚ˆã†ãªåã®ãƒã‚¤ãƒ©ã‚¤ãƒˆã‚°ãƒ«ãƒ¼ãƒ—ã¯ã‚りã¾ã›ã‚“: %s"
+msgid "Direction"
+msgstr "æ–¹å‘"
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: ã¾ã ãƒ†ã‚­ã‚¹ãƒˆãŒæŒ¿å…¥ã•れã¦ã„ã¾ã›ã‚“"
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "上"
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: 以å‰ã«ã‚³ãƒžãƒ³ãƒ‰è¡ŒãŒã‚りã¾ã›ã‚“"
+msgid "Down"
+msgstr "下"
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: ãã®ã‚ˆã†ãªãƒžãƒƒãƒ”ングã¯ã‚りã¾ã›ã‚“"
+msgid "Find Next"
+msgstr "次を検索"
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: 該当ã¯ã‚りã¾ã›ã‚“"
+msgid "Replace"
+msgstr "ç½®æ›"
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: 該当ã¯ã‚りã¾ã›ã‚“: %s"
+msgid "Replace All"
+msgstr "å…¨ã¦ç½®æ›"
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: ファイルåãŒã‚りã¾ã›ã‚“"
+msgid "_Close"
+msgstr "é–‰ã˜ã‚‹(_C)"
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: æ­£è¦è¡¨ç¾ç½®æ›ãŒã¾ã å®Ÿè¡Œã•れã¦ã„ã¾ã›ã‚“"
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: セッションマãƒãƒ¼ã‚¸ãƒ£ã‹ã‚‰ \"die\" è¦æ±‚ã‚’å—ã‘å–りã¾ã—ãŸ\n"
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: コマンドãŒã¾ã å®Ÿè¡Œã•れã¦ã„ã¾ã›ã‚“"
+msgid "Close tab"
+msgstr "タブページを閉ã˜ã‚‹"
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: æ­£è¦è¡¨ç¾ãŒã¾ã å®Ÿè¡Œã•れã¦ã„ã¾ã›ã‚“"
+msgid "New tab"
+msgstr "æ–°è¦ã‚¿ãƒ–ページ"
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: 範囲指定ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
+msgid "Open Tab..."
+msgstr "タブページを開ã..."
-#: ../globals.h:1048
-msgid "E36: Not enough room"
-msgstr "E36: ウィンドウã«å分ãªé«˜ã•ã‚‚ã—ãã¯å¹…ãŒã‚りã¾ã›ã‚“"
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: メインウィンドウãŒä¸æ„ã«ç ´å£Šã•れã¾ã—ãŸ\n"
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: ファイル %s を作æˆã§ãã¾ã›ã‚“"
+msgid "&Filter"
+msgstr "フィルタ(&F)"
-#: ../globals.h:1050
-msgid "E483: Can't get temp file name"
-msgstr "E483: 一時ファイルã®åå‰ã‚’å–å¾—ã§ãã¾ã›ã‚“"
+msgid "&Cancel"
+msgstr "キャンセル(&C)"
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: ファイル \"%s\" ã‚’é–‹ã‘ã¾ã›ã‚“"
+msgid "Directories"
+msgstr "ディレクトリ"
-#: ../globals.h:1052
-#, c-format
-msgid "E485: Can't read file %s"
-msgstr "E485: ファイル %s を読込ã‚ã¾ã›ã‚“"
+msgid "Filter"
+msgstr "フィルタ"
-#: ../globals.h:1054
-msgid "E37: No write since last change (add ! to override)"
-msgstr "E37: 最後ã®å¤‰æ›´ãŒä¿å­˜ã•れã¦ã„ã¾ã›ã‚“ (! を追加ã§å¤‰æ›´ã‚’破棄)"
+msgid "&Help"
+msgstr "ヘルプ(&H)"
-#: ../globals.h:1055
-msgid "E37: No write since last change"
-msgstr "E37: 最後ã®å¤‰æ›´ãŒä¿å­˜ã•れã¦ã„ã¾ã›ã‚“"
+msgid "Files"
+msgstr "ファイル"
-#: ../globals.h:1056
-msgid "E38: Null argument"
-msgstr "E38: 引数ãŒç©ºã§ã™"
+msgid "&OK"
+msgstr "&OK"
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: 数値ãŒè¦æ±‚ã•れã¦ã„ã¾ã™"
+msgid "Selection"
+msgstr "é¸æŠž"
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: エラーファイル %s ã‚’é–‹ã‘ã¾ã›ã‚“"
+msgid "Find &Next"
+msgstr "次を検索(&N)"
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: メモリãŒå°½ãæžœã¦ã¾ã—ãŸ!"
+msgid "&Replace"
+msgstr "ç½®æ›(&R)"
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "パターンã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
+msgid "Replace &All"
+msgstr "å…¨ã¦ç½®æ›(&A)"
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: パターンã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ: %s"
+msgid "&Undo"
+msgstr "アンドゥ(&U)"
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: å¼•æ•°ã¯æ­£ã®å€¤ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+msgid "Open tab..."
+msgstr "タブページを開ã"
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: å‰ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æˆ»ã‚Œã¾ã›ã‚“"
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "検索文字列 ('\\' を検索ã™ã‚‹ã«ã¯ '\\\\')"
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: エラーã¯ã‚りã¾ã›ã‚“"
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "æ¤œç´¢ãƒ»ç½®æ› ('\\' を検索ã™ã‚‹ã«ã¯ '\\\\')"
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: ロケーションリストã¯ã‚りã¾ã›ã‚“"
-
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: 該当文字列ãŒç ´æã—ã¦ã„ã¾ã™"
+#. 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 "使ã‚れã¾ã›ã‚“"
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: 䏿­£ãªæ­£è¦è¡¨ç¾ãƒ—ログラムã§ã™"
+msgid "Directory\t*.nothing\n"
+msgstr "ディレクトリ\t*.nothing\n"
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: 'readonly' オプションãŒè¨­å®šã•れã¦ã„ã¾ã™ (! を追加ã§ä¸Šæ›¸ã)"
-
-#: ../globals.h:1073
#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: 読å–専用変数 \"%s\" ã«ã¯å€¤ã‚’設定ã§ãã¾ã›ã‚“"
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: タイトル㌠\"%s\" ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../globals.h:1075
#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E794: サンドボックスã§ã¯å¤‰æ•° \"%s\" ã«å€¤ã‚’設定ã§ãã¾ã›ã‚“"
-
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: エラーファイルã®èª­è¾¼ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
-
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: サンドボックスã§ã¯è¨±ã•れã¾ã›ã‚“"
-
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: ã“ã“ã§ã¯è¨±å¯ã•れã¾ã›ã‚“"
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: 引数ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“: \"-%s\"; OLE版を使用ã—ã¦ãã ã•ã„."
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: スクリーンモードã®è¨­å®šã«ã¯å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“"
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: MDIアプリã®ä¸­ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’é–‹ã‘ã¾ã›ã‚“"
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: 無効ãªã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«é‡ã§ã™"
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr "Vim E458: è‰²æŒ‡å®šãŒæ­£ã—ããªã„ã®ã§ã‚¨ãƒ³ãƒˆãƒªã‚’割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“"
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: 'shell' オプションãŒç©ºã§ã™"
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: ä»¥ä¸‹ã®æ–‡å­—セットã®ãƒ•ォントãŒã‚りã¾ã›ã‚“ %s:"
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: sign ã®ãƒ‡ãƒ¼ã‚¿ã‚’読込ã‚ã¾ã›ã‚“ã§ã—ãŸ"
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: フォントセットå: %s"
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: スワップファイルã®ã‚¯ãƒ­ãƒ¼ã‚ºæ™‚エラーã§ã™"
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "フォント '%s' ã¯å›ºå®šå¹…ã§ã¯ã‚りã¾ã›ã‚“"
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: タグスタックãŒç©ºã§ã™"
+#, c-format
+msgid "E253: Fontset name: %s"
+msgstr "E253: フォントセットå: %s"
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: コマンドãŒè¤‡é›‘éŽãŽã¾ã™"
+#, c-format
+msgid "Font0: %s"
+msgstr "フォント0: %s"
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: åå‰ãŒé•·éŽãŽã¾ã™"
+#, c-format
+msgid "Font1: %s"
+msgstr "フォント1: %s"
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: [ ãŒå¤šéŽãŽã¾ã™"
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "フォント%ld ã®å¹…ãŒãƒ•ォント0ã®2å€ã§ã¯ã‚りã¾ã›ã‚“"
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: ファイルåãŒå¤šéŽãŽã¾ã™"
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "フォント0ã®å¹…: %ld"
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: ä½™åˆ†ãªæ–‡å­—ãŒå¾Œã‚ã«ã‚りã¾ã™"
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "フォント1ã®å¹…: %ld"
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: 未知ã®ãƒžãƒ¼ã‚¯"
+msgid "Invalid font specification"
+msgstr "無効ãªãƒ•ォント指定ã§ã™"
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: ワイルドカードを展開ã§ãã¾ã›ã‚“"
+msgid "&Dismiss"
+msgstr "å´ä¸‹ã™ã‚‹(&D)"
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: 'winheight' 㯠'winminheight' よりå°ã•ãã§ãã¾ã›ã‚“"
+msgid "no specific match"
+msgstr "マッãƒã™ã‚‹ã‚‚ã®ãŒã‚りã¾ã›ã‚“"
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: 'winwidth' 㯠'winminwidth' よりå°ã•ãã§ãã¾ã›ã‚“"
+msgid "Vim - Font Selector"
+msgstr "Vim - ãƒ•ã‚©ãƒ³ãƒˆé¸æŠž"
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: 書込ã¿ä¸­ã®ã‚¨ãƒ©ãƒ¼"
+msgid "Name:"
+msgstr "åå‰:"
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "ゼロカウント"
+#. create toggle button
+msgid "Show size in Points"
+msgstr "サイズをãƒã‚¤ãƒ³ãƒˆã§è¡¨ç¤ºã™ã‚‹"
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: スクリプト以外ã§<SID>ãŒä½¿ã‚れã¾ã—ãŸ"
+msgid "Encoding:"
+msgstr "エンコード:"
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: 内部エラーã§ã™: %s"
+msgid "Font:"
+msgstr "フォント:"
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: パターン㌠'maxmempattern' 以上ã®ãƒ¡ãƒ¢ãƒªã‚’使用ã—ã¾ã™"
+msgid "Style:"
+msgstr "スタイル:"
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: ãƒãƒƒãƒ•ã‚¡ãŒç©ºã§ã™"
+msgid "Size:"
+msgstr "サイズ:"
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: 検索パターンã‹åŒºåˆ‡ã‚Šè¨˜å·ãŒä¸æ­£ã§ã™"
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: ãƒãƒ³ã‚°ãƒ«ã‚ªãƒ¼ãƒˆãƒžãƒˆãƒ³ã‚¨ãƒ©ãƒ¼"
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: åŒã˜åå‰ã®ãƒ•ァイルãŒä»–ã®ãƒãƒƒãƒ•ã‚¡ã§èª­è¾¼ã¾ã‚Œã¦ã„ã¾ã™"
-
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: オプション '%s' ã¯è¨­å®šã•れã¦ã„ã¾ã›ã‚“"
-
-#: ../globals.h:1111
-msgid "E850: Invalid register name"
-msgstr "E850: 無効ãªãƒ¬ã‚¸ã‚¹ã‚¿åã§ã™"
-
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "上ã¾ã§æ¤œç´¢ã—ãŸã®ã§ä¸‹ã«æˆ»ã‚Šã¾ã™"
-
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "下ã¾ã§æ¤œç´¢ã—ãŸã®ã§ä¸Šã«æˆ»ã‚Šã¾ã™"
-
-#: ../hardcopy.c:240
msgid "E550: Missing colon"
msgstr "E550: コロンãŒã‚りã¾ã›ã‚“"
-#: ../hardcopy.c:252
msgid "E551: Illegal component"
msgstr "E551: 䏿­£ãªæ§‹æ–‡è¦ç´ ã§ã™"
-#: ../hardcopy.c:259
msgid "E552: digit expected"
msgstr "E552: 数値ãŒå¿…è¦ã§ã™"
-#: ../hardcopy.c:473
#, c-format
msgid "Page %d"
msgstr "%d ページ"
-#: ../hardcopy.c:597
msgid "No text to be printed"
msgstr "å°åˆ·ã™ã‚‹ãƒ†ã‚­ã‚¹ãƒˆãŒã‚りã¾ã›ã‚“"
-#: ../hardcopy.c:668
#, c-format
msgid "Printing page %d (%d%%)"
msgstr "å°åˆ·ä¸­: ページ %d (%d%%)"
-#: ../hardcopy.c:680
#, c-format
msgid " Copy %d of %d"
msgstr " コピー %d (全 %d 中)"
-#: ../hardcopy.c:733
#, c-format
msgid "Printed: %s"
msgstr "å°åˆ·ã—ã¾ã—ãŸ: %s"
-#: ../hardcopy.c:740
msgid "Printing aborted"
msgstr "å°åˆ·ãŒä¸­æ­¢ã•れã¾ã—ãŸ"
-#: ../hardcopy.c:1365
msgid "E455: Error writing to PostScript output file"
msgstr "E455: PostScriptå‡ºåŠ›ãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸è¾¼ã¿ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../hardcopy.c:1747
#, c-format
msgid "E624: Can't open file \"%s\""
msgstr "E624: ファイル \"%s\" ã‚’é–‹ã‘ã¾ã›ã‚“"
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
#, c-format
msgid "E457: Can't read PostScript resource file \"%s\""
msgstr "E457: PostScriptã®ãƒªã‚½ãƒ¼ã‚¹ãƒ•ァイル \"%s\" を読込ã‚ã¾ã›ã‚“"
-#: ../hardcopy.c:1772
#, c-format
msgid "E618: file \"%s\" is not a PostScript resource file"
msgstr "E618: ファイル \"%s\" 㯠PostScript リソースファイルã§ã¯ã‚りã¾ã›ã‚“"
-#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844
#, c-format
msgid "E619: file \"%s\" is not a supported PostScript resource file"
msgstr "E619: ファイル \"%s\" ã¯å¯¾å¿œã—ã¦ã„ãªã„ PostScript リソースファイルã§ã™"
-#: ../hardcopy.c:1856
#, c-format
msgid "E621: \"%s\" resource file has wrong version"
msgstr "E621: リソースファイル \"%s\" ã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒç•°ãªã‚Šã¾ã™"
-#: ../hardcopy.c:2225
msgid "E673: Incompatible multi-byte encoding and character set."
msgstr "E673: äº’æ›æ€§ã®ç„¡ã„マルãƒãƒã‚¤ãƒˆã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã¨æ–‡å­—セットã§ã™"
-#: ../hardcopy.c:2238
msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
msgstr "E674: マルãƒãƒã‚¤ãƒˆã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã§ã¯ printmbcharset を空ã«ã§ãã¾ã›ã‚“"
-#: ../hardcopy.c:2254
msgid "E675: No default font specified for multi-byte printing."
msgstr ""
"E675: マルãƒãƒã‚¤ãƒˆæ–‡å­—ã‚’å°åˆ·ã™ã‚‹ãŸã‚ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆãƒ•ã‚©ãƒ³ãƒˆãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“"
-#: ../hardcopy.c:2426
msgid "E324: Can't open PostScript output file"
msgstr "E324: PostScript出力用ã®ãƒ•ァイルを開ã‘ã¾ã›ã‚“"
-#: ../hardcopy.c:2458
#, c-format
msgid "E456: Can't open file \"%s\""
msgstr "E456: ファイル \"%s\" ã‚’é–‹ã‘ã¾ã›ã‚“"
-#: ../hardcopy.c:2583
msgid "E456: Can't find PostScript resource file \"prolog.ps\""
msgstr "E456: PostScriptã®ãƒªã‚½ãƒ¼ã‚¹ãƒ•ァイル \"prolog.ps\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../hardcopy.c:2593
msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
msgstr "E456: PostScriptã®ãƒªã‚½ãƒ¼ã‚¹ãƒ•ァイル \"cidfont.ps\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
#, c-format
msgid "E456: Can't find PostScript resource file \"%s.ps\""
msgstr "E456: PostScriptã®ãƒªã‚½ãƒ¼ã‚¹ãƒ•ァイル \"%s.ps\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../hardcopy.c:2654
#, c-format
msgid "E620: Unable to convert to print encoding \"%s\""
msgstr "E620: å°åˆ·ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ \"%s\" ã¸å¤‰æ›ã§ãã¾ã›ã‚“"
-#: ../hardcopy.c:2877
msgid "Sending to printer..."
msgstr "プリンタã«é€ä¿¡ä¸­..."
-#: ../hardcopy.c:2881
msgid "E365: Failed to print PostScript file"
msgstr "E365: PostScriptファイルã®å°åˆ·ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../hardcopy.c:2883
msgid "Print job sent."
msgstr "å°åˆ·ã‚¸ãƒ§ãƒ–ã‚’é€ä¿¡ã—ã¾ã—ãŸ."
-#: ../if_cscope.c:85
msgid "Add a new database"
msgstr "新データベースを追加"
-#: ../if_cscope.c:87
msgid "Query for a pattern"
msgstr "パターンã®ã‚¯ã‚¨ãƒªãƒ¼ã‚’追加"
-#: ../if_cscope.c:89
msgid "Show this message"
msgstr "ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’表示ã™ã‚‹"
-#: ../if_cscope.c:91
msgid "Kill a connection"
msgstr "接続を終了ã™ã‚‹"
-#: ../if_cscope.c:93
msgid "Reinit all connections"
msgstr "å…¨ã¦ã®æŽ¥ç¶šã‚’å†åˆæœŸåŒ–ã™ã‚‹"
-#: ../if_cscope.c:95
msgid "Show connections"
msgstr "接続を表示ã™ã‚‹"
-#: ../if_cscope.c:101
#, c-format
msgid "E560: Usage: cs[cope] %s"
msgstr "E560: 使用方法: cs[cope] %s"
-#: ../if_cscope.c:225
msgid "This cscope command does not support splitting the window.\n"
msgstr "ã“ã®cscopeコマンドã¯åˆ†å‰²ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“.\n"
-#: ../if_cscope.c:266
msgid "E562: Usage: cstag <ident>"
msgstr "E562: 使用法: cstag <ident>"
-#: ../if_cscope.c:313
msgid "E257: cstag: tag not found"
msgstr "E257: cstag: ã‚¿ã‚°ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../if_cscope.c:461
#, c-format
msgid "E563: stat(%s) error: %d"
msgstr "E563: stat(%s) エラー: %d"
-#: ../if_cscope.c:551
+msgid "E563: stat error"
+msgstr "E563: stat エラー"
+
#, c-format
msgid "E564: %s is not a directory or a valid cscope database"
msgstr "E564: %s ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªåŠã³æœ‰åйãªcscopeã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã§ã¯ã‚りã¾ã›ã‚“"
-#: ../if_cscope.c:566
#, c-format
msgid "Added cscope database %s"
msgstr "cscopeデータベース %s を追加"
-#: ../if_cscope.c:616
#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: cscopeã®æŽ¥ç¶š %<PRId64> を読込ã¿ä¸­ã®ã‚¨ãƒ©ãƒ¼ã§ã™"
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: cscopeã®æŽ¥ç¶š %ld を読込ã¿ä¸­ã®ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../if_cscope.c:711
msgid "E561: unknown cscope search type"
msgstr "E561: 未知ã®cscope検索型ã§ã™"
-#: ../if_cscope.c:752 ../if_cscope.c:789
msgid "E566: Could not create cscope pipes"
msgstr "E566: cscopeパイプを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ"
-#: ../if_cscope.c:767
msgid "E622: Could not fork for cscope"
msgstr "E622: cscopeã®èµ·å‹•準備(fork)ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../if_cscope.c:849
msgid "cs_create_connection setpgid failed"
msgstr "cs_create_connection ã¸ã® setpgid ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../if_cscope.c:853 ../if_cscope.c:889
msgid "cs_create_connection exec failed"
msgstr "cs_create_connection ã®å®Ÿè¡Œã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../if_cscope.c:863 ../if_cscope.c:902
msgid "cs_create_connection: fdopen for to_fp failed"
msgstr "cs_create_connection: to_fp ã® fdopen ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../if_cscope.c:865 ../if_cscope.c:906
msgid "cs_create_connection: fdopen for fr_fp failed"
msgstr "cs_create_connection: fr_fp ã® fdopen ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../if_cscope.c:890
msgid "E623: Could not spawn cscope process"
msgstr "E623: cscopeプロセスを起動ã§ãã¾ã›ã‚“ã§ã—ãŸ"
-#: ../if_cscope.c:932
msgid "E567: no cscope connections"
msgstr "E567: cscope接続ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../if_cscope.c:1009
#, c-format
msgid "E469: invalid cscopequickfix flag %c for %c"
msgstr "E469: 無効㪠cscopequickfix フラグ %c ã® %c ã§ã™"
-#: ../if_cscope.c:1058
#, c-format
msgid "E259: no matches found for cscope query %s of %s"
msgstr "E259: cscopeクエリー %s of %s ã«è©²å½“ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ"
-#: ../if_cscope.c:1142
msgid "cscope commands:\n"
msgstr "cscopeコマンド:\n"
-#: ../if_cscope.c:1150
#, c-format
msgid "%-5s: %s%*s (Usage: %s)"
msgstr "%-5s: %s%*s (使用法: %s)"
-#: ../if_cscope.c:1155
msgid ""
"\n"
+" a: Find assignments to this symbol\n"
" c: Find functions calling this function\n"
" d: Find functions called by this function\n"
" e: Find this egrep pattern\n"
@@ -3233,6 +2549,7 @@ msgid ""
" t: Find this text string\n"
msgstr ""
"\n"
+" a: ã“ã®ã‚·ãƒ³ãƒœãƒ«ã«å¯¾ã™ã‚‹ä»£å…¥ã‚’探ã™\n"
" c: ã“ã®é–¢æ•°ã‚’呼んã§ã„る関数を探ã™\n"
" d: ã“ã®é–¢æ•°ã‹ã‚‰å‘¼ã‚“ã§ã„る関数を探ã™\n"
" e: ã“ã®egrepパターンを探ã™\n"
@@ -3242,31 +2559,32 @@ msgstr ""
" s: ã“ã®Cシンボルを探ã™\n"
" t: ã“ã®ãƒ†ã‚­ã‚¹ãƒˆæ–‡å­—列を探ã™\n"
-#: ../if_cscope.c:1226
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: cscopeデータベース: %s ã‚’é–‹ãã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: cscopeãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æƒ…報をå–å¾—ã§ãã¾ã›ã‚“"
+
msgid "E568: duplicate cscope database not added"
msgstr "E568: é‡è¤‡ã™ã‚‹cscopeデータベースã¯è¿½åŠ ã•れã¾ã›ã‚“ã§ã—ãŸ"
-#: ../if_cscope.c:1335
#, c-format
msgid "E261: cscope connection %s not found"
msgstr "E261: cscope接続 %s ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
-#: ../if_cscope.c:1364
#, c-format
msgid "cscope connection %s closed"
msgstr "cscope接続 %s ãŒé–‰ã˜ã‚‰ã‚Œã¾ã—ãŸ"
#. should not reach here
-#: ../if_cscope.c:1486
msgid "E570: fatal error in cs_manage_matches"
msgstr "E570: cs_manage_matches ã§è‡´å‘½çš„ãªã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../if_cscope.c:1693
#, c-format
msgid "Cscope tag: %s"
msgstr "Cscope ã‚¿ã‚°: %s"
-#: ../if_cscope.c:1711
msgid ""
"\n"
" # line"
@@ -3274,87 +2592,300 @@ msgstr ""
"\n"
" # 行番å·"
-#: ../if_cscope.c:1713
msgid "filename / context / line\n"
msgstr "ファイルå / 文脈 / 行\n"
-#: ../if_cscope.c:1809
#, c-format
msgid "E609: Cscope error: %s"
msgstr "E609: cscopeエラー: %s"
-#: ../if_cscope.c:2053
msgid "All cscope databases reset"
msgstr "å…¨ã¦ã®cscopeデータベースをリセットã—ã¾ã™"
-#: ../if_cscope.c:2123
msgid "no cscope connections\n"
msgstr "cscope接続ãŒã‚りã¾ã›ã‚“\n"
-#: ../if_cscope.c:2126
msgid " # pid database name prepend path\n"
msgstr " # pid データベースå prepend パス\n"
-#: ../main.c:144
+msgid "Lua library cannot be loaded."
+msgstr "Luaライブラリをロードã§ãã¾ã›ã‚“."
+
+msgid "cannot save undo information"
+msgstr "アンドゥ情報ãŒä¿å­˜ã§ãã¾ã›ã‚“"
+
+msgid ""
+"E815: Sorry, this command is disabled, the MzScheme libraries could not be "
+"loaded."
+msgstr "E815: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™. MzScheme ライブラリをロードã§ãã¾ã›ã‚“."
+
+msgid ""
+"E895: Sorry, this command is disabled, the MzScheme's racket/base module "
+"could not be loaded."
+msgstr ""
+"E895: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™,ã”ã‚ã‚“ãªã•ã„. MzScheme ã® racket/base モジュール"
+"ãŒãƒ­ãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸ."
+
+msgid "invalid expression"
+msgstr "無効ãªå¼ã§ã™"
+
+msgid "expressions disabled at compile time"
+msgstr "å¼ã¯ã‚³ãƒ³ãƒ‘イル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™"
+
+msgid "hidden option"
+msgstr "éš ã—オプション"
+
+msgid "unknown option"
+msgstr "未知ã®ã‚ªãƒ—ションã§ã™"
+
+msgid "window index is out of range"
+msgstr "範囲外ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ç•ªå·ã§ã™"
+
+msgid "couldn't open buffer"
+msgstr "ãƒãƒƒãƒ•ã‚¡ã‚’é–‹ã‘ã¾ã›ã‚“"
+
+msgid "cannot delete line"
+msgstr "行を消ã›ã¾ã›ã‚“"
+
+msgid "cannot replace line"
+msgstr "行を置æ›ã§ãã¾ã›ã‚“"
+
+msgid "cannot insert line"
+msgstr "行を挿入ã§ãã¾ã›ã‚“"
+
+msgid "string cannot contain newlines"
+msgstr "文字列ã«ã¯æ”¹è¡Œæ–‡å­—ã‚’å«ã‚られã¾ã›ã‚“"
+
+msgid "error converting Scheme values to Vim"
+msgstr "Scheme値ã®Vimã¸ã®å¤‰æ›ã‚¨ãƒ©ãƒ¼"
+
+msgid "Vim error: ~a"
+msgstr "Vim エラー: ~a"
+
+msgid "Vim error"
+msgstr "Vim エラー"
+
+msgid "buffer is invalid"
+msgstr "ãƒãƒƒãƒ•ã‚¡ã¯ç„¡åйã§ã™"
+
+msgid "window is invalid"
+msgstr "ウィンドウã¯ç„¡åйã§ã™"
+
+msgid "linenr out of range"
+msgstr "範囲外ã®è¡Œç•ªå·ã§ã™"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "サンドボックスã§ã¯è¨±ã•れã¾ã›ã‚“"
+
+msgid "E836: This Vim cannot execute :python after using :py3"
+msgstr "E836: ã“ã®Vimã§ã¯ :py3 を使ã£ãŸå¾Œã« :python を使ãˆã¾ã›ã‚“"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™,ã”ã‚ã‚“ãªã•ã„: Pythonライブラリをロードã§ãã¾ã›ã‚“"
+"ã§ã—ãŸ."
+
+msgid ""
+"E887: Sorry, this command is disabled, the Python's site module could not be "
+"loaded."
+msgstr ""
+"E887: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™,ã”ã‚ã‚“ãªã•ã„. Python ã® site モジュールをロード"
+"ã§ãã¾ã›ã‚“ã§ã—ãŸ."
+
+# Added at 07-Feb-2004.
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Python ã‚’å†å¸°çš„ã«å®Ÿè¡Œã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+msgid "E837: This Vim cannot execute :py3 after using :python"
+msgstr "E837: ã“ã®Vimã§ã¯ :python を使ã£ãŸå¾Œã« :py3 を使ãˆã¾ã›ã‚“"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: $_ ã¯æ–‡å­—列ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™,ã”ã‚ã‚“ãªã•ã„: Rubyライブラリをロードã§ãã¾ã›ã‚“ã§"
+"ã—ãŸ."
+
+msgid "E267: unexpected return"
+msgstr "E267: 予期ã›ã¬ return ã§ã™"
+
+msgid "E268: unexpected next"
+msgstr "E268: 予期ã›ã¬ next ã§ã™"
+
+msgid "E269: unexpected break"
+msgstr "E269: 予期ã›ã¬ break ã§ã™"
+
+msgid "E270: unexpected redo"
+msgstr "E270: 予期ã›ã¬ redo ã§ã™"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: rescue ã®å¤–ã® retry ã§ã™"
+
+msgid "E272: unhandled exception"
+msgstr "E272: å–り扱ã‚れãªã‹ã£ãŸä¾‹å¤–ãŒã‚りã¾ã™"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: 未知ã®longjmp状態: %d"
+
+msgid "invalid buffer number"
+msgstr "無効ãªãƒãƒƒãƒ•ァ番å·ã§ã™"
+
+msgid "not implemented yet"
+msgstr "ã¾ã å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "行を設定ã§ãã¾ã›ã‚“"
+
+msgid "invalid mark name"
+msgstr "無効ãªãƒžãƒ¼ã‚¯åã§ã™"
+
+msgid "mark not set"
+msgstr "マークã¯è¨­å®šã•れã¦ã„ã¾ã›ã‚“"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "行 %d 列 %d"
+
+msgid "cannot insert/append line"
+msgstr "è¡Œã®æŒ¿å…¥/追加をã§ãã¾ã›ã‚“"
+
+msgid "line number out of range"
+msgstr "範囲外ã®è¡Œç•ªå·ã§ã™"
+
+msgid "unknown flag: "
+msgstr "未知ã®ãƒ•ラグ: "
+
+msgid "unknown vimOption"
+msgstr "未知㮠vimOption ã§ã™"
+
+msgid "keyboard interrupt"
+msgstr "キーボード割込ã¿"
+
+msgid "vim error"
+msgstr "vim エラー"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr ""
+"ãƒãƒƒãƒ•ã‚¡/ウィンドウ作æˆã‚³ãƒžãƒ³ãƒ‰ã‚’作æˆã§ãã¾ã›ã‚“: ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒæ¶ˆåŽ»ã•れã¦ã„ã¾"
+"ã—ãŸ"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"コールãƒãƒƒã‚¯ã‚³ãƒžãƒ³ãƒ‰ã‚’登録ã§ãã¾ã›ã‚“: ãƒãƒƒãƒ•ã‚¡/ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒæ—¢ã«æ¶ˆåŽ»ã•れã¾ã—ãŸ"
+
+#. 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 実体ã®ç™»éŒ²ãƒ—ロパティãŒä¸æ­£ã§ã™. 消去ã—ã¾ã—ãŸ!"
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: リスト型ã«ã‚«ãƒ³ãƒžãŒã‚りã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: ãƒªã‚¹ãƒˆåž‹ã®æœ€å¾Œã« ']' ãŒã‚りã¾ã›ã‚“: %s"
+
msgid "Unknown option argument"
msgstr "未知ã®ã‚ªãƒ—ション引数ã§ã™"
-#: ../main.c:146
msgid "Too many edit arguments"
msgstr "編集引数ãŒå¤šéŽãŽã¾ã™"
-#: ../main.c:148
msgid "Argument missing after"
msgstr "引数ãŒã‚りã¾ã›ã‚“"
-#: ../main.c:150
msgid "Garbage after option argument"
msgstr "オプション引数ã®å¾Œã«ã‚´ãƒŸãŒã‚りã¾ã™"
-#: ../main.c:152
msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
msgstr "\"+command\", \"-c command\", \"--cmd command\" ã®å¼•æ•°ãŒå¤šéŽãŽã¾ã™"
-#: ../main.c:154
msgid "Invalid argument for"
msgstr "無効ãªå¼•æ•°ã§ã™: "
-#: ../main.c:294
#, c-format
msgid "%d files to edit\n"
msgstr "%d 個ã®ãƒ•ァイルãŒç·¨é›†ã‚’控ãˆã¦ã„ã¾ã™\n"
-#: ../main.c:1342
+msgid "netbeans is not supported with this GUI\n"
+msgstr "netbeans ã¯ã“ã®GUIã§ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“\n"
+
+msgid "'-nb' cannot be used: not enabled at compile time\n"
+msgstr "'-nb' 使用ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "ã“ã®Vimã«ã¯diff機能ãŒã‚りã¾ã›ã‚“(コンパイル時設定)."
+
msgid "Attempt to open script file again: \""
msgstr "スクリプトファイルをå†ã³é–‹ã„ã¦ã¿ã¾ã™: \""
-#: ../main.c:1350
msgid "Cannot open for reading: \""
msgstr "読込用ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“"
-#: ../main.c:1393
msgid "Cannot open for script output: \""
msgstr "スクリプト出力用を開ã‘ã¾ã›ã‚“"
-#: ../main.c:1622
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: エラー: NetBeansã‹ã‚‰gvimをスタートã§ãã¾ã›ã‚“\n"
+
+msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n"
+msgstr "Vim: エラー: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®Vimã¯Cygwin端末ã§ã¯å‹•作ã—ã¾ã›ã‚“\n"
+
msgid "Vim: Warning: Output is not to a terminal\n"
msgstr "Vim: 警告: 端末ã¸ã®å‡ºåŠ›ã§ã¯ã‚りã¾ã›ã‚“\n"
-#: ../main.c:1624
msgid "Vim: Warning: Input is not from a terminal\n"
msgstr "Vim: 警告: 端末ã‹ã‚‰ã®å…¥åŠ›ã§ã¯ã‚りã¾ã›ã‚“\n"
#. just in case..
-#: ../main.c:1891
msgid "pre-vimrc command line"
msgstr "vimrcå‰ã®ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³"
-#: ../main.c:1964
#, c-format
msgid "E282: Cannot read from \"%s\""
msgstr "E282: \"%s\"ã‹ã‚‰èª­è¾¼ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“"
-#: ../main.c:2149
msgid ""
"\n"
"More info with: \"vim -h\"\n"
@@ -3362,23 +2893,18 @@ msgstr ""
"\n"
"ã‚ˆã‚Šè©³ç´°ãªæƒ…å ±ã¯: \"vim -h\"\n"
-#: ../main.c:2178
msgid "[file ..] edit specified file(s)"
msgstr "[ファイル..] ã‚るファイルを編集ã™ã‚‹"
-#: ../main.c:2179
msgid "- read text from stdin"
msgstr "- 標準入力ã‹ã‚‰ãƒ†ã‚­ã‚¹ãƒˆã‚’読込む"
-#: ../main.c:2180
msgid "-t tag edit file where tag is defined"
msgstr "-t ã‚¿ã‚° ã‚¿ã‚°ãŒå®šç¾©ã•れãŸã¨ã“ã‚ã‹ã‚‰ç·¨é›†ã™ã‚‹"
-#: ../main.c:2181
msgid "-q [errorfile] edit file with first error"
msgstr "-q [errorfile] 最åˆã®ã‚¨ãƒ©ãƒ¼ã§ç·¨é›†ã™ã‚‹"
-#: ../main.c:2187
msgid ""
"\n"
"\n"
@@ -3388,11 +2914,9 @@ msgstr ""
"\n"
"使用法:"
-#: ../main.c:2189
msgid " vim [arguments] "
msgstr " vim [引数] "
-#: ../main.c:2193
msgid ""
"\n"
" or:"
@@ -3400,7 +2924,13 @@ msgstr ""
"\n"
" ã‚‚ã—ãã¯:"
-#: ../main.c:2196
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"大尿–‡å­—ãŒç„¡è¦–ã•れる場åˆã¯å¤§æ–‡å­—ã«ã™ã‚‹ãŸã‚ã« / ã‚’å‰ç½®ã—ã¦ãã ã•ã„"
+
msgid ""
"\n"
"\n"
@@ -3410,189 +2940,319 @@ msgstr ""
"\n"
"引数:\n"
-#: ../main.c:2197
msgid "--\t\t\tOnly file names after this"
msgstr "--\t\t\tã“ã®ã‚ã¨ã«ã¯ãƒ•ァイルåã ã‘"
-#: ../main.c:2199
msgid "--literal\t\tDon't expand wildcards"
msgstr "--literal\t\tワイルドカードを展開ã—ãªã„"
-#: ../main.c:2201
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tã“ã®gvimã‚’OLEã¨ã—ã¦ç™»éŒ²ã™ã‚‹"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tgvimã®OLE登録を解除ã™ã‚‹"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tGUIã§èµ·å‹•ã™ã‚‹ (\"gvim\" ã¨åŒã˜)"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f or --nofork\tフォアグラウンド: GUIã‚’å§‹ã‚ã‚‹ã¨ãã«forkã—ãªã„"
+
msgid "-v\t\t\tVi mode (like \"vi\")"
msgstr "-v\t\t\tViモード (\"vi\" ã¨åŒã˜)"
-#: ../main.c:2202
msgid "-e\t\t\tEx mode (like \"ex\")"
msgstr "-e\t\t\tExモード (\"ex\" ã¨åŒã˜)"
-#: ../main.c:2203
msgid "-E\t\t\tImproved Ex mode"
msgstr "-E\t\t\t改良Exモード"
-#: ../main.c:2204
msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
msgstr "-s\t\t\tサイレント(ãƒãƒƒãƒ)モード (\"ex\" 専用)"
-#: ../main.c:2205
msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
msgstr "-d\t\t\t差分モード (\"vidiff\" ã¨åŒã˜)"
-#: ../main.c:2206
msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
msgstr "-y\t\t\tイージーモード (\"evim\" ã¨åŒã˜, モード無)"
-#: ../main.c:2207
msgid "-R\t\t\tReadonly mode (like \"view\")"
msgstr "-R\t\t\t読込専用モード (\"view\" ã¨åŒã˜)"
-#: ../main.c:2208
msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
msgstr "-Z\t\t\t制é™ãƒ¢ãƒ¼ãƒ‰ (\"rvim\" ã¨åŒã˜)"
-#: ../main.c:2209
msgid "-m\t\t\tModifications (writing files) not allowed"
msgstr "-m\t\t\t変更 (ファイルä¿å­˜æ™‚) ã‚’ã§ããªã„よã†ã«ã™ã‚‹"
-#: ../main.c:2210
msgid "-M\t\t\tModifications in text not allowed"
msgstr "-M\t\t\tテキストã®ç·¨é›†ã‚’行ãªãˆãªã„よã†ã«ã™ã‚‹"
-#: ../main.c:2211
msgid "-b\t\t\tBinary mode"
msgstr "-b\t\t\tãƒã‚¤ãƒŠãƒªãƒ¢ãƒ¼ãƒ‰"
-#: ../main.c:2212
msgid "-l\t\t\tLisp mode"
msgstr "-l\t\t\tLispモード"
-#: ../main.c:2213
msgid "-C\t\t\tCompatible with Vi: 'compatible'"
msgstr "-C\t\t\tVi互æ›ãƒ¢ãƒ¼ãƒ‰: 'compatible'"
-#: ../main.c:2214
msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
msgstr "-N\t\t\tViéžäº’æ›ãƒ¢ãƒ¼ãƒ‰: 'nocompatible"
-#: ../main.c:2215
msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
msgstr "-V[N][fname]\t\tログ出力設定 [レベル N] [ログファイルå fname]"
-#: ../main.c:2216
msgid "-D\t\t\tDebugging mode"
msgstr "-D\t\t\tデãƒãƒƒã‚°ãƒ¢ãƒ¼ãƒ‰"
-#: ../main.c:2217
msgid "-n\t\t\tNo swap file, use memory only"
msgstr "-n\t\t\tスワップファイルを使用ã›ãšãƒ¡ãƒ¢ãƒªã ã‘"
-#: ../main.c:2218
msgid "-r\t\t\tList swap files and exit"
msgstr "-r\t\t\tスワップファイルを列挙ã—終了"
-#: ../main.c:2219
msgid "-r (with file name)\tRecover crashed session"
msgstr "-r (ファイルå)\tクラッシュã—ãŸã‚»ãƒƒã‚·ãƒ§ãƒ³ã‚’復帰"
-#: ../main.c:2220
msgid "-L\t\t\tSame as -r"
msgstr "-L\t\t\t-rã¨åŒã˜"
-#: ../main.c:2221
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tウィンドウを開ãã®ã« newcli を使用ã—ãªã„"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <device>\t\tI/Oã« <device> を使用ã™ã‚‹"
+
msgid "-A\t\t\tstart in Arabic mode"
msgstr "-A\t\t\tアラビア語モードã§èµ·å‹•ã™ã‚‹"
-#: ../main.c:2222
msgid "-H\t\t\tStart in Hebrew mode"
msgstr "-H\t\t\tヘブライ語モードã§èµ·å‹•ã™ã‚‹"
-#: ../main.c:2223
msgid "-F\t\t\tStart in Farsi mode"
msgstr "-F\t\t\tペルシア語モードã§èµ·å‹•ã™ã‚‹"
-#: ../main.c:2224
msgid "-T <terminal>\tSet terminal type to <terminal>"
msgstr "-T <terminal>\t端末を <terminal> ã«è¨­å®šã™ã‚‹"
-#: ../main.c:2225
+msgid "--not-a-term\t\tSkip warning for input/output not being a terminal"
+msgstr "--not-a-term\t\t入出力ãŒç«¯æœ«ã§ãªã„ã¨ã®è­¦å‘Šã‚’スキップã™ã‚‹"
+
msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
msgstr "-u <vimrc>\t\t.vimrcã®ä»£ã‚り㫠<vimrc> を使ã†"
-#: ../main.c:2226
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\t.gvimrcã®ä»£ã‚り㫠<gvimrc> を使ã†"
+
msgid "--noplugin\t\tDon't load plugin scripts"
msgstr "--noplugin\t\tプラグインスクリプトをロードã—ãªã„"
-#: ../main.c:2227
msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
msgstr "-p[N]\t\tN 個タブページを開ã(çœç•¥å€¤: ファイルã«ã¤ã1個)"
-#: ../main.c:2228
msgid "-o[N]\t\tOpen N windows (default: one for each file)"
msgstr "-o[N]\t\tN 個ウィンドウを開ã(çœç•¥å€¤: ファイルã«ã¤ã1個)"
-#: ../main.c:2229
msgid "-O[N]\t\tLike -o but split vertically"
msgstr "-O[N]\t\t-oã¨åŒã˜ã ãŒåž‚直分割"
-#: ../main.c:2230
msgid "+\t\t\tStart at end of file"
msgstr "+\t\t\tãƒ•ã‚¡ã‚¤ãƒ«ã®æœ€å¾Œã‹ã‚‰ã¯ã˜ã‚ã‚‹"
-#: ../main.c:2231
msgid "+<lnum>\t\tStart at line <lnum>"
msgstr "+<lnum>\t\t<lnum> 行ã‹ã‚‰ã¯ã˜ã‚ã‚‹"
-#: ../main.c:2232
msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
msgstr "--cmd <command>\tvimrcをロードã™ã‚‹å‰ã« <command> を実行ã™ã‚‹"
-#: ../main.c:2233
msgid "-c <command>\t\tExecute <command> after loading the first file"
msgstr "-c <command>\t\t最åˆã®ãƒ•ァイルをロード後 <command> を実行ã™ã‚‹"
-#: ../main.c:2235
msgid "-S <session>\t\tSource file <session> after loading the first file"
msgstr "-S <session>\t\t最åˆã®ãƒ•ァイルをロード後ファイル <session> ã‚’å–込む"
-#: ../main.c:2236
msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
msgstr "-s <scriptin>\tファイル <scriptin> ã‹ã‚‰ãƒŽãƒ¼ãƒžãƒ«ã‚³ãƒžãƒ³ãƒ‰ã‚’読込む"
-#: ../main.c:2237
msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
msgstr "-w <scriptout>\t入力ã—ãŸå…¨ã‚³ãƒžãƒ³ãƒ‰ã‚’ファイル <scriptout> ã«è¿½åŠ ã™ã‚‹"
-#: ../main.c:2238
msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
msgstr "-W <scriptout>\t入力ã—ãŸå…¨ã‚³ãƒžãƒ³ãƒ‰ã‚’ファイル <scriptout> ã«ä¿å­˜ã™ã‚‹"
-#: ../main.c:2240
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tæš—å·åŒ–ã•れãŸãƒ•ァイルを編集ã™ã‚‹"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <display>\tvimを指定ã—㟠X サーãƒãƒ¼ã«æŽ¥ç¶šã™ã‚‹"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tXサーãƒãƒ¼ã«æŽ¥ç¶šã—ãªã„"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <files>\tå¯èƒ½ãªã‚‰ã°Vimサーãƒãƒ¼ã§ <files> を編集ã™ã‚‹"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-silent <files> åŒä¸Š, サーãƒãƒ¼ãŒç„¡ãã¦ã‚‚警告文を出力ã—ãªã„"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr "--remote-wait <files>\t--remote後 ファイルã®ç·¨é›†ãŒçµ‚ã‚ã‚‹ã®ã‚’å¾…ã¤"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-wait-silent <files> åŒä¸Š, サーãƒãƒ¼ãŒç„¡ãã¦ã‚‚警告文を出力ã—ãªã„"
+
+msgid ""
+"--remote-tab[-wait][-silent] <files> As --remote but use tab page per file"
+msgstr ""
+"--remote-tab[-wait][-silent] <files> --remoteã§ãƒ•ァイル1ã¤ã«ã¤ã1ã¤ã®ã‚¿ãƒ–"
+"ページを開ã"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <keys>\tVimサーãƒãƒ¼ã« <keys> ã‚’é€ä¿¡ã—ã¦çµ‚了ã™ã‚‹"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr "--remote-expr <expr>\tサーãƒãƒ¼ã§ <expr> を実行ã—ã¦çµæžœã‚’表示ã™ã‚‹"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tVimサーãƒãƒ¼åã®ä¸€è¦§ã‚’表示ã—ã¦çµ‚了ã™ã‚‹"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <name>\tVimサーãƒãƒ¼ <name> ã«é€ä¿¡/åå‰è¨­å®šã™ã‚‹"
+
msgid "--startuptime <file>\tWrite startup timing messages to <file>"
msgstr "--startuptime <file>\tèµ·å‹•ã«ã‹ã‹ã£ãŸæ™‚é–“ã®è©³ç´°ã‚’ <file> ã¸å‡ºåŠ›ã™ã‚‹"
-#: ../main.c:2242
msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
msgstr "-i <viminfo>\t\t.viminfoã®ä»£ã‚り㫠<viminfo> を使ã†"
-#: ../main.c:2243
msgid "-h or --help\tPrint Help (this message) and exit"
msgstr "-h or --help\tヘルプ(ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸)を表示ã—終了ã™ã‚‹"
-#: ../main.c:2244
msgid "--version\t\tPrint version information and exit"
msgstr "--version\t\tãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—終了ã™ã‚‹"
-#: ../mark.c:676
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"gvimã«ã‚ˆã£ã¦è§£é‡ˆã•れる引数(Motifãƒãƒ¼ã‚¸ãƒ§ãƒ³):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"gvimã«ã‚ˆã£ã¦è§£é‡ˆã•れる引数(neXtawãƒãƒ¼ã‚¸ãƒ§ãƒ³):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"gvimã«ã‚ˆã£ã¦è§£é‡ˆã•れる引数(Athenaãƒãƒ¼ã‚¸ãƒ§ãƒ³):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <display>\t<display> ã§vimを実行ã™ã‚‹"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\t最å°åŒ–ã—ãŸçŠ¶æ…‹ã§vimã‚’èµ·å‹•ã™ã‚‹"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <color>\t背景色㫠<color> を使ã†(åŒç¾©: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <color>\t剿™¯è‰²ã« <color> を使ã†(åŒç¾©: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <font>\t\tテキスト表示㫠<font> を使ã†(åŒç¾©: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <font>\t太字㫠<font> を使ã†"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <for>\t斜体字㫠<font> を使ã†"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <geom>\tåˆæœŸé…置㫠<geom> を使ã†(åŒç¾©: -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <width>\t境界ã®å¹…ã‚’ <width> ã«ã™ã‚‹(åŒç¾©: -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <width> スクロールãƒãƒ¼ã®å¹…ã‚’ <width> ã«ã™ã‚‹(åŒç¾©: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr "-menuheight <height>\tメニューãƒãƒ¼ã®é«˜ã•ã‚’ <height> ã«ã™ã‚‹(åŒç¾©: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tå転映åƒã‚’使用ã™ã‚‹(åŒç¾©: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tå転映åƒã‚’使用ã—ãªã„(åŒç¾©: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <resource>\t特定ã®ãƒªã‚½ãƒ¼ã‚¹ã‚’使用ã™ã‚‹"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"gvimã«ã‚ˆã£ã¦è§£é‡ˆã•れる引数(GTK+ãƒãƒ¼ã‚¸ãƒ§ãƒ³):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <display>\t<display> ã§vimを実行ã™ã‚‹(åŒç¾©: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "--role <role>\tメインウィンドウを識別ã™ã‚‹ä¸€æ„ãªå½¹å‰²(role)を設定ã™ã‚‹"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tç•°ãªã‚‹GTK widgetã§Vimã‚’é–‹ã"
+
+msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
+msgstr "--echo-wid\t\tウィンドウIDを標準出力ã«å‡ºåŠ›ã™ã‚‹"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <親ã®ã‚¿ã‚¤ãƒˆãƒ«>\tVimを親アプリケーションã®ä¸­ã§èµ·å‹•ã™ã‚‹"
+
+msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
+msgstr "--windowid <HWND>\tç•°ãªã‚‹Win32 widgetã®å†…部ã«Vimã‚’é–‹ã"
+
+msgid "No display"
+msgstr "ディスプレイãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#. 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 "マークãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“"
-#: ../mark.c:678
#, c-format
msgid "E283: No marks matching \"%s\""
msgstr "E283: \"%s\" ã«è©²å½“ã™ã‚‹ãƒžãƒ¼ã‚¯ãŒã‚りã¾ã›ã‚“"
#. Highlight title
-#: ../mark.c:687
msgid ""
"\n"
"mark line col file/text"
@@ -3601,7 +3261,6 @@ msgstr ""
"mark 行 列 ファイル/テキスト"
#. Highlight title
-#: ../mark.c:789
msgid ""
"\n"
" jump line col file/text"
@@ -3610,7 +3269,6 @@ msgstr ""
" jump 行 列 ファイル/テキスト"
#. Highlight title
-#: ../mark.c:831
msgid ""
"\n"
"change line col text"
@@ -3618,7 +3276,6 @@ msgstr ""
"\n"
"変更 行 列 テキスト"
-#: ../mark.c:1238
msgid ""
"\n"
"# File marks:\n"
@@ -3627,7 +3284,6 @@ msgstr ""
"# ファイルマーク:\n"
#. Write the jumplist with -'
-#: ../mark.c:1271
msgid ""
"\n"
"# Jumplist (newest first):\n"
@@ -3635,7 +3291,6 @@ msgstr ""
"\n"
"# ジャンプリスト (æ–°ã—ã„ã‚‚ã®ãŒå…ˆ):\n"
-#: ../mark.c:1352
msgid ""
"\n"
"# History of marks within files (newest to oldest):\n"
@@ -3643,84 +3298,88 @@ msgstr ""
"\n"
"# ファイル内マークã®å±¥æ­´ (æ–°ã—ã„ã‚‚ã®ã‹ã‚‰å¤ã„ã‚‚ã®):\n"
-#: ../mark.c:1431
msgid "Missing '>'"
msgstr "'>' ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../memfile.c:426
+msgid "E543: Not a valid codepage"
+msgstr "E543: 無効ãªã‚³ãƒ¼ãƒ‰ãƒšãƒ¼ã‚¸ã§ã™"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: ICã®å€¤ã‚’設定ã§ãã¾ã›ã‚“"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: インプットコンテキストã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: インプットメソッドã®ã‚ªãƒ¼ãƒ—ンã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: 警告: IMã®ç ´å£Šã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã‚’設定ã§ãã¾ã›ã‚“ã§ã—ãŸ"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: インプットメソッドã¯ã©ã‚“ãªã‚¹ã‚¿ã‚¤ãƒ«ã‚‚サãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: インプットメソッド㯠my preedit type をサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
+
msgid "E293: block was not locked"
msgstr "E293: ブロックãŒãƒ­ãƒƒã‚¯ã•れã¦ã„ã¾ã›ã‚“"
-#: ../memfile.c:799
msgid "E294: Seek error in swap file read"
msgstr "E294: スワップファイル読込時ã«ã‚·ãƒ¼ã‚¯ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../memfile.c:803
msgid "E295: Read error in swap file"
msgstr "E295: スワップファイルã®èª­è¾¼ã¿ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../memfile.c:849
msgid "E296: Seek error in swap file write"
msgstr "E296: ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«æ›¸è¾¼ã¿æ™‚ã«ã‚·ãƒ¼ã‚¯ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../memfile.c:865
msgid "E297: Write error in swap file"
msgstr "E297: ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸è¾¼ã¿ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../memfile.c:1036
msgid "E300: Swap file already exists (symlink attack?)"
msgstr "E300: ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™ (symlinkã«ã‚ˆã‚‹æ”»æ’ƒ?)"
-#: ../memline.c:318
msgid "E298: Didn't get block nr 0?"
msgstr "E298: ブロック 0 ã‚’å–å¾—ã§ãã¾ã›ã‚“?"
-#: ../memline.c:361
msgid "E298: Didn't get block nr 1?"
msgstr "E298: ブロック 1 ã‚’å–å¾—ã§ãã¾ã›ã‚“?"
-#: ../memline.c:377
msgid "E298: Didn't get block nr 2?"
msgstr "E298: ブロック 2 ã‚’å–å¾—ã§ãã¾ã›ã‚“?"
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ã®æš—å·ã‚’更新中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+
#. could not (re)open the swap file, what can we do????
-#: ../memline.c:465
msgid "E301: Oops, lost the swap file!!!"
msgstr "E301: ãŠã£ã¨, スワップファイルãŒå¤±ã‚れã¾ã—ãŸ!!!"
-#: ../memline.c:477
msgid "E302: Could not rename swap file"
msgstr "E302: スワップファイルã®åå‰ã‚’変ãˆã‚‰ã‚Œã¾ã›ã‚“"
-#: ../memline.c:554
#, c-format
msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
msgstr "E303: \"%s\" ã®ã‚¹ãƒ¯ãƒƒãƒ—ファイルを開ã‘ãªã„ã®ã§ãƒªã‚«ãƒãƒªã¯ä¸å¯èƒ½ã§ã™"
-#: ../memline.c:666
msgid "E304: ml_upd_block0(): Didn't get block 0??"
msgstr "E304: ml_upd_block0(): ブロック 0 ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ??"
-#. no swap files found
-#: ../memline.c:830
#, c-format
msgid "E305: No swap file found for %s"
msgstr "E305: %s ã«ã¯ã‚¹ãƒ¯ãƒƒãƒ—ファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../memline.c:839
msgid "Enter number of swap file to use (0 to quit): "
msgstr "使用ã™ã‚‹ã‚¹ãƒ¯ãƒƒãƒ—ファイルã®ç•ªå·ã‚’入力ã—ã¦ãã ã•ã„(0 ã§çµ‚了): "
-#: ../memline.c:879
#, c-format
msgid "E306: Cannot open %s"
msgstr "E306: %s ã‚’é–‹ã‘ã¾ã›ã‚“"
-#: ../memline.c:897
msgid "Unable to read block 0 from "
msgstr "ブロック 0 を読込ã‚ã¾ã›ã‚“ "
-#: ../memline.c:900
msgid ""
"\n"
"Maybe no changes were made or Vim did not update the swap file."
@@ -3728,28 +3387,22 @@ msgstr ""
"\n"
"æã‚‰ã変更ãŒã•れã¦ã„ãªã„ã‹VimãŒã‚¹ãƒ¯ãƒƒãƒ—ファイルを更新ã—ã¦ã„ã¾ã›ã‚“."
-#: ../memline.c:909
msgid " cannot be used with this version of Vim.\n"
msgstr " Vimã®ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“.\n"
-#: ../memline.c:911
msgid "Use Vim version 3.0.\n"
msgstr "Vimã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³3.0を使用ã—ã¦ãã ã•ã„.\n"
-#: ../memline.c:916
#, c-format
msgid "E307: %s does not look like a Vim swap file"
msgstr "E307: %s ã¯Vimã®ã‚¹ãƒ¯ãƒƒãƒ—ファイルã§ã¯ãªã„よã†ã§ã™"
-#: ../memline.c:922
msgid " cannot be used on this computer.\n"
msgstr " ã“ã®ã‚³ãƒ³ãƒ”ュータã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“.\n"
-#: ../memline.c:924
msgid "The file was created on "
msgstr "ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯æ¬¡ã®å ´æ‰€ã§ä½œã‚‰ã‚Œã¾ã—㟠"
-#: ../memline.c:928
msgid ""
",\n"
"or the file has been damaged."
@@ -3757,85 +3410,104 @@ msgstr ""
",\n"
"ã‚‚ã—ãã¯ãƒ•ã‚¡ã‚¤ãƒ«ãŒæå‚·ã—ã¦ã„ã¾ã™."
-#: ../memline.c:945
+#, c-format
+msgid ""
+"E833: %s is encrypted and this version of Vim does not support encryption"
+msgstr ""
+"E833: %s ã¯ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®Vimã§ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ãªã„å½¢å¼ã§æš—å·åŒ–ã•れã¦ã„ã¾ã™"
+
msgid " has been damaged (page size is smaller than minimum value).\n"
msgstr " ã¯æå‚·ã—ã¦ã„ã¾ã™ (ãƒšãƒ¼ã‚¸ã‚µã‚¤ã‚ºãŒæœ€å°å€¤ã‚’下回ã£ã¦ã„ã¾ã™).\n"
-#: ../memline.c:974
#, c-format
msgid "Using swap file \"%s\""
msgstr "スワップファイル \"%s\" を使用中"
-#: ../memline.c:980
#, c-format
msgid "Original file \"%s\""
msgstr "原本ファイル \"%s\""
-#: ../memline.c:995
msgid "E308: Warning: Original file may have been changed"
msgstr "E308: 警告: 原本ファイルãŒå¤‰æ›´ã•れã¦ã„ã¾ã™"
-#: ../memline.c:1061
+#, c-format
+msgid "Swap file is encrypted: \"%s\""
+msgstr "ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ã¯æš—å·åŒ–ã•れã¦ã„ã¾ã™: \"%s\""
+
+msgid ""
+"\n"
+"If you entered a new crypt key but did not write the text file,"
+msgstr ""
+"\n"
+"æ–°ã—ã„æš—å·ã‚­ãƒ¼ã‚’入力ã—ãŸã‚ã¨ã«ãƒ†ã‚­ã‚¹ãƒˆãƒ•ァイルをä¿å­˜ã—ã¦ã„ãªã„å ´åˆã¯,"
+
+msgid ""
+"\n"
+"enter the new crypt key."
+msgstr ""
+"\n"
+"æ–°ã—ã„æš—å·ã‚­ãƒ¼ã‚’入力ã—ã¦ãã ã•ã„."
+
+msgid ""
+"\n"
+"If you wrote the text file after changing the crypt key press enter"
+msgstr ""
+"\n"
+"æš—å·ã‚­ãƒ¼ã‚’変ãˆãŸã‚ã¨ã«ãƒ†ã‚­ã‚¹ãƒˆãƒ•ァイルをä¿å­˜ã—ãŸå ´åˆã¯, テキストファイルã¨"
+
+msgid ""
+"\n"
+"to use the same key for text file and swap file"
+msgstr ""
+"\n"
+"スワップファイルã«åŒã˜æš—å·ã‚­ãƒ¼ã‚’使ã†ãŸã‚ã«enterã ã‘を押ã—ã¦ãã ã•ã„."
+
#, c-format
msgid "E309: Unable to read block 1 from %s"
msgstr "E309: %s ã‹ã‚‰ãƒ–ロック 1 を読込ã‚ã¾ã›ã‚“"
-#: ../memline.c:1065
msgid "???MANY LINES MISSING"
msgstr "???多ãã®è¡ŒãŒå¤±ã‚れã¦ã„ã¾ã™"
-#: ../memline.c:1076
msgid "???LINE COUNT WRONG"
msgstr "???行数ãŒé–“é•ã£ã¦ã„ã¾ã™"
-#: ../memline.c:1082
msgid "???EMPTY BLOCK"
msgstr "???ブロックãŒç©ºã§ã™"
-#: ../memline.c:1103
msgid "???LINES MISSING"
msgstr "???行ãŒå¤±ã‚れã¦ã„ã¾ã™"
-#: ../memline.c:1128
#, c-format
msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
msgstr "E310: ブロック 1 ã®IDãŒé–“é•ã£ã¦ã„ã¾ã™(%s ãŒ.swpファイルã§ãªã„?)"
-#: ../memline.c:1133
msgid "???BLOCK MISSING"
msgstr "???ブロックãŒã‚りã¾ã›ã‚“"
-#: ../memline.c:1147
msgid "??? from here until ???END lines may be messed up"
msgstr "??? ã“ã“ã‹ã‚‰ ???END ã¾ã§ã®è¡ŒãŒç ´å£Šã•れã¦ã„るよã†ã§ã™"
-#: ../memline.c:1164
msgid "??? from here until ???END lines may have been inserted/deleted"
msgstr "??? ã“ã“ã‹ã‚‰ ???END ã¾ã§ã®è¡ŒãŒæŒ¿å…¥ã‹å‰Šé™¤ã•れãŸã‚ˆã†ã§ã™"
-#: ../memline.c:1181
msgid "???END"
msgstr "???END"
-#: ../memline.c:1238
msgid "E311: Recovery Interrupted"
msgstr "E311: リカãƒãƒªãŒå‰²è¾¼ã¾ã‚Œã¾ã—ãŸ"
-#: ../memline.c:1243
msgid ""
"E312: Errors detected while recovering; look for lines starting with ???"
msgstr ""
"E312: リカãƒãƒªã®æœ€ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒæ¤œå‡ºã•れã¾ã—ãŸ; ???ã§å§‹ã¾ã‚‹è¡Œã‚’å‚ç…§ã—ã¦ãã ã•ã„"
-#: ../memline.c:1245
msgid "See \":help E312\" for more information."
msgstr "詳細㯠\":help E312\" ã‚’å‚ç…§ã—ã¦ãã ã•ã„"
-#: ../memline.c:1249
msgid "Recovery completed. You should check if everything is OK."
msgstr "リカãƒãƒªãŒçµ‚了ã—ã¾ã—ãŸ. å…¨ã¦ãŒæ­£ã—ã„ã‹ãƒã‚§ãƒƒã‚¯ã—ã¦ãã ã•ã„."
-#: ../memline.c:1251
msgid ""
"\n"
"(You might want to write out this file under another name\n"
@@ -3843,15 +3515,12 @@ msgstr ""
"\n"
"(変更をãƒã‚§ãƒƒã‚¯ã™ã‚‹ãŸã‚ã«, ã“ã®ãƒ•ァイルを別ã®åå‰ã§ä¿å­˜ã—ãŸä¸Šã§\n"
-#: ../memline.c:1252
msgid "and run diff with the original file to check for changes)"
msgstr "原本ファイルã¨ã® diff を実行ã™ã‚‹ã¨è‰¯ã„ã§ã—ょã†)"
-#: ../memline.c:1254
msgid "Recovery completed. Buffer contents equals file contents."
msgstr "復元完了. ãƒãƒƒãƒ•ã‚¡ã®å†…容ã¯ãƒ•ァイルã¨åŒã˜ã«ãªã‚Šã¾ã—ãŸ."
-#: ../memline.c:1255
msgid ""
"\n"
"You may want to delete the .swp file now.\n"
@@ -3861,52 +3530,43 @@ msgstr ""
"å…ƒã®.swpファイルã¯å‰Šé™¤ã—ã¦ã‚‚æ§‹ã„ã¾ã›ã‚“\n"
"\n"
+msgid "Using crypt key from swap file for the text file.\n"
+msgstr "スワップファイルã‹ã‚‰å–å¾—ã—ãŸæš—å·ã‚­ãƒ¼ã‚’テキストファイルã«ä½¿ã„ã¾ã™.\n"
+
#. use msg() to start the scrolling properly
-#: ../memline.c:1327
msgid "Swap files found:"
msgstr "スワップファイルãŒè¤‡æ•°è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ:"
-#: ../memline.c:1446
msgid " In current directory:\n"
msgstr " ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª:\n"
-#: ../memline.c:1448
msgid " Using specified name:\n"
msgstr " 以下ã®åå‰ã‚’使用中:\n"
-#: ../memline.c:1450
msgid " In directory "
msgstr " ディレクトリ "
-#: ../memline.c:1465
msgid " -- none --\n"
msgstr " -- ãªã— --\n"
-#: ../memline.c:1527
msgid " owned by: "
msgstr " 所有者: "
-#: ../memline.c:1529
msgid " dated: "
msgstr " 日付: "
-#: ../memline.c:1532 ../memline.c:3231
msgid " dated: "
msgstr " 日付: "
-#: ../memline.c:1548
msgid " [from Vim version 3.0]"
msgstr " [from Vim version 3.0]"
-#: ../memline.c:1550
msgid " [does not look like a Vim swap file]"
msgstr " [Vimã®ã‚¹ãƒ¯ãƒƒãƒ—ファイルã§ã¯ãªã„よã†ã§ã™]"
-#: ../memline.c:1552
msgid " file name: "
msgstr " ファイルå: "
-#: ../memline.c:1558
msgid ""
"\n"
" modified: "
@@ -3914,15 +3574,12 @@ msgstr ""
"\n"
" 変更状態: "
-#: ../memline.c:1559
msgid "YES"
msgstr "ã‚り"
-#: ../memline.c:1559
msgid "no"
msgstr "ãªã—"
-#: ../memline.c:1562
msgid ""
"\n"
" user name: "
@@ -3930,11 +3587,9 @@ msgstr ""
"\n"
" ユーザーå: "
-#: ../memline.c:1568
msgid " host name: "
msgstr " ホストå: "
-#: ../memline.c:1570
msgid ""
"\n"
" host name: "
@@ -3942,7 +3597,6 @@ msgstr ""
"\n"
" ホストå: "
-#: ../memline.c:1575
msgid ""
"\n"
" process ID: "
@@ -3950,11 +3604,16 @@ msgstr ""
"\n"
" プロセスID: "
-#: ../memline.c:1579
msgid " (still running)"
msgstr " (ã¾ã å®Ÿè¡Œä¸­)"
-#: ../memline.c:1586
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [ã“ã®Vimãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“]"
+
msgid ""
"\n"
" [not usable on this computer]"
@@ -3962,97 +3621,75 @@ msgstr ""
"\n"
" [ã“ã®ã‚³ãƒ³ãƒ”ュータã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“]"
-#: ../memline.c:1590
msgid " [cannot be read]"
msgstr " [読込ã‚ã¾ã›ã‚“]"
-#: ../memline.c:1593
msgid " [cannot be opened]"
msgstr " [é–‹ã‘ã¾ã›ã‚“]"
-#: ../memline.c:1698
msgid "E313: Cannot preserve, there is no swap file"
msgstr "E313: スワップファイルãŒç„¡ã„ã®ã§ç¶­æŒã§ãã¾ã›ã‚“"
-#: ../memline.c:1747
msgid "File preserved"
msgstr "ファイルãŒç¶­æŒã•れã¾ã™"
-#: ../memline.c:1749
msgid "E314: Preserve failed"
msgstr "E314: ç¶­æŒã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../memline.c:1819
#, c-format
-msgid "E315: ml_get: invalid lnum: %<PRId64>"
-msgstr "E315: ml_get: 無効ãªlnumã§ã™: %<PRId64>"
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: 無効ãªlnumã§ã™: %ld"
-#: ../memline.c:1851
#, c-format
-msgid "E316: ml_get: cannot find line %<PRId64>"
-msgstr "E316: ml_get: 行 %<PRId64> を見ã¤ã‘られã¾ã›ã‚“"
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: 行 %ld を見ã¤ã‘られã¾ã›ã‚“"
-#: ../memline.c:2236
msgid "E317: pointer block id wrong 3"
msgstr "E317: ãƒã‚¤ãƒ³ã‚¿ãƒ–ロックã®IDãŒé–“é•ã£ã¦ã„ã¾ã™ 3"
-#: ../memline.c:2311
msgid "stack_idx should be 0"
msgstr "stack_idx 㯠0 ã§ã‚ã‚‹ã¹ãã§ã™"
-#: ../memline.c:2369
msgid "E318: Updated too many blocks?"
msgstr "E318: æ›´æ–°ã•れãŸãƒ–ロックãŒå¤šéŽãŽã‚‹ã‹ã‚‚?"
-#: ../memline.c:2511
msgid "E317: pointer block id wrong 4"
msgstr "E317: ãƒã‚¤ãƒ³ã‚¿ãƒ–ロックã®IDãŒé–“é•ã£ã¦ã„ã¾ã™ 4"
-#: ../memline.c:2536
msgid "deleted block 1?"
msgstr "ブロック 1 ã¯æ¶ˆã•れãŸ?"
-#: ../memline.c:2707
#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: 行 %<PRId64> ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+msgid "E320: Cannot find line %ld"
+msgstr "E320: 行 %ld ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../memline.c:2916
msgid "E317: pointer block id wrong"
msgstr "E317: ãƒã‚¤ãƒ³ã‚¿ãƒ–ロックã®IDãŒé–“é•ã£ã¦ã„ã¾ã™"
-#: ../memline.c:2930
msgid "pe_line_count is zero"
msgstr "pe_line_count ãŒã‚¼ãƒ­ã§ã™"
-#: ../memline.c:2955
#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: 行番å·ãŒç¯„囲外ã§ã™: %<PRId64> è¶…ãˆã¦ã„ã¾ã™"
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: 行番å·ãŒç¯„囲外ã§ã™: %ld è¶…ãˆã¦ã„ã¾ã™"
-#: ../memline.c:2959
#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: ブロック %<PRId64> ã®è¡Œã‚«ã‚¦ãƒ³ãƒˆãŒé–“é•ã£ã¦ã„ã¾ã™"
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: ブロック %ld ã®è¡Œã‚«ã‚¦ãƒ³ãƒˆãŒé–“é•ã£ã¦ã„ã¾ã™"
-#: ../memline.c:2999
msgid "Stack size increases"
msgstr "スタックサイズãŒå¢—ãˆã¾ã™"
-#: ../memline.c:3038
msgid "E317: pointer block id wrong 2"
msgstr "E317: ãƒã‚¤ãƒ³ã‚¿ãƒ–ロックã®IDãŒé–“é•ã£ã¦ã„ã¾ã™ 2"
-#: ../memline.c:3070
#, c-format
msgid "E773: Symlink loop for \"%s\""
msgstr "E773: \"%s\" ã®ã‚·ãƒ³ãƒœãƒªãƒƒã‚¯ãƒªãƒ³ã‚¯ãŒãƒ«ãƒ¼ãƒ—ã«ãªã£ã¦ã„ã¾ã™"
-#: ../memline.c:3221
msgid "E325: ATTENTION"
msgstr "E325: 注æ„"
-#: ../memline.c:3222
msgid ""
"\n"
"Found a swap file by the name \""
@@ -4060,39 +3697,32 @@ msgstr ""
"\n"
"次ã®åå‰ã§ã‚¹ãƒ¯ãƒƒãƒ—ファイルを見ã¤ã‘ã¾ã—㟠\""
-#: ../memline.c:3226
msgid "While opening file \""
msgstr "次ã®ãƒ•ァイルを開ã„ã¦ã„る最中 \""
-#: ../memline.c:3239
msgid " NEWER than swap file!\n"
msgstr " スワップファイルよりも新ã—ã„ã§ã™!\n"
-#: ../memline.c:3244
+#. Some of these messages are long to allow translation to
+#. * other languages.
msgid ""
"\n"
"(1) Another program may be editing the same file. If this is the case,\n"
" be careful not to end up with two different instances of the same\n"
-" file when making changes."
+" file when making changes. Quit, or continue with caution.\n"
msgstr ""
"\n"
"(1) 別ã®ãƒ—ログラムãŒåŒã˜ãƒ•ァイルを編集ã—ã¦ã„ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“.\n"
" ã“ã®å ´åˆã«ã¯, 変更をã—ã¦ã—ã¾ã†ã¨1ã¤ã®ãƒ•ァイルã«å¯¾ã—ã¦ç•°ãªã‚‹2ã¤ã®\n"
-" インスタンスãŒã§ãã¦ã—ã¾ã†ã®ã§, ãã†ã—ãªã„よã†ã«æ°—ã‚’ã¤ã‘ã¦ãã ã•ã„."
-
-#: ../memline.c:3245
-msgid " Quit, or continue with caution.\n"
-msgstr " 終了ã™ã‚‹ã‹, 注æ„ã—ãªãŒã‚‰ç¶šã‘ã¦ãã ã•ã„.\n"
+" インスタンスãŒã§ãã¦ã—ã¾ã†ã®ã§, ãã†ã—ãªã„よã†ã«æ°—ã‚’ã¤ã‘ã¦ãã ã•ã„.\n"
+" 終了ã™ã‚‹ã‹, 注æ„ã—ãªãŒã‚‰ç¶šã‘ã¦ãã ã•ã„.\n"
-#: ../memline.c:3246
msgid "(2) An edit session for this file crashed.\n"
msgstr "(2) ã“ã®ãƒ•ァイルã®ç·¨é›†ã‚»ãƒƒã‚·ãƒ§ãƒ³ãŒã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã—ãŸ.\n"
-#: ../memline.c:3247
msgid " If this is the case, use \":recover\" or \"vim -r "
msgstr " ã“ã®å ´åˆã«ã¯ \":recover\" ã‹ \"vim -r "
-#: ../memline.c:3249
msgid ""
"\"\n"
" to recover the changes (see \":help recovery\").\n"
@@ -4100,11 +3730,9 @@ msgstr ""
"\"\n"
" を使用ã—ã¦å¤‰æ›´ã‚’リカãƒãƒ¼ã—ã¾ã™(\":help recovery\" ã‚’å‚ç…§).\n"
-#: ../memline.c:3250
msgid " If you did this already, delete the swap file \""
msgstr " æ—¢ã«ã“れを行ãªã£ãŸã®ãªã‚‰ã°, スワップファイル \""
-#: ../memline.c:3252
msgid ""
"\"\n"
" to avoid this message.\n"
@@ -4112,23 +3740,18 @@ msgstr ""
"\"\n"
" を消ã›ã°ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’回é¿ã§ãã¾ã™.\n"
-#: ../memline.c:3450 ../memline.c:3452
msgid "Swap file \""
msgstr "スワップファイル \""
-#: ../memline.c:3451 ../memline.c:3455
msgid "\" already exists!"
msgstr "\" ãŒæ—¢ã«ã‚りã¾ã™!"
-#: ../memline.c:3457
msgid "VIM - ATTENTION"
msgstr "VIM - 注æ„"
-#: ../memline.c:3459
msgid "Swap file already exists!"
msgstr "ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™!"
-#: ../memline.c:3464
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4142,7 +3765,6 @@ msgstr ""
"終了ã™ã‚‹(&Q)\n"
"中止ã™ã‚‹(&A)"
-#: ../memline.c:3467
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4158,56 +3780,34 @@ msgstr ""
"終了ã™ã‚‹(&Q)\n"
"中止ã™ã‚‹(&A)"
-#.
-#. * Change the ".swp" extension to find another file that can be used.
-#. * First decrement the last char: ".swo", ".swn", etc.
-#. * If that still isn't enough decrement the last but one char: ".svz"
-#. * Can happen when editing many "No Name" buffers.
-#.
-#. ".s?a"
-#. ".saa": tried enough, give up
-#: ../memline.c:3528
msgid "E326: Too many swap files found"
msgstr "E326: スワップファイルãŒå¤šæ•°è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ"
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: メモリãŒè¶³ã‚Šã¾ã›ã‚“! (%<PRIu64> ãƒã‚¤ãƒˆã‚’å‰²å½“è¦æ±‚)"
-
-#: ../menu.c:62
msgid "E327: Part of menu-item path is not sub-menu"
msgstr "E327: メニューアイテムã®ãƒ‘スã®éƒ¨åˆ†ãŒã‚µãƒ–メニューã§ã¯ã‚りã¾ã›ã‚“"
-#: ../menu.c:63
msgid "E328: Menu only exists in another mode"
msgstr "E328: メニューã¯ä»–ã®ãƒ¢ãƒ¼ãƒ‰ã«ã ã‘ã‚りã¾ã™"
-#: ../menu.c:64
#, c-format
msgid "E329: No menu \"%s\""
msgstr "E329: \"%s\" ã¨ã„ã†ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã¯ã‚りã¾ã›ã‚“"
#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
msgid "E792: Empty menu name"
msgstr "E792: メニューåãŒç©ºã§ã™"
-#: ../menu.c:340
msgid "E330: Menu path must not lead to a sub-menu"
msgstr "E330: メニューパスã¯ã‚µãƒ–メニューを生ã˜ã‚‹ã¹ãã§ã¯ã‚りã¾ã›ã‚“"
-#: ../menu.c:365
msgid "E331: Must not add menu items directly to menu bar"
msgstr "E331: メニューãƒãƒ¼ã«ã¯ç›´æŽ¥ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚¢ã‚¤ãƒ†ãƒ ã‚’追加ã§ãã¾ã›ã‚“"
-#: ../menu.c:370
msgid "E332: Separator cannot be part of a menu path"
msgstr "E332: 区切りã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãƒ‘スã®ä¸€éƒ¨ã§ã¯ã‚りã¾ã›ã‚“"
#. Now we have found the matching menu, and we list the mappings
#. Highlight title
-#: ../menu.c:762
msgid ""
"\n"
"--- Menus ---"
@@ -4215,69 +3815,60 @@ msgstr ""
"\n"
"--- メニュー ---"
-#: ../menu.c:1313
+msgid "Tear off this menu"
+msgstr "ã“ã®ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚’切りå–ã‚‹"
+
msgid "E333: Menu path must lead to a menu item"
msgstr "E333: メニューパスã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚¢ã‚¤ãƒ†ãƒ ã‚’生ã˜ãªã‘れã°ã„ã‘ã¾ã›ã‚“"
-#: ../menu.c:1330
#, c-format
msgid "E334: Menu not found: %s"
msgstr "E334: メニューãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %s"
-#: ../menu.c:1396
#, c-format
msgid "E335: Menu not defined for %s mode"
msgstr "E335: %s ã«ã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãŒå®šç¾©ã•れã¦ã„ã¾ã›ã‚“"
-#: ../menu.c:1426
msgid "E336: Menu path must lead to a sub-menu"
msgstr "E336: メニューパスã¯ã‚µãƒ–メニューを生ã˜ãªã‘れã°ã„ã‘ã¾ã›ã‚“"
-#: ../menu.c:1447
msgid "E337: Menu not found - check menu names"
msgstr "E337: メニューãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ - メニューåを確èªã—ã¦ãã ã•ã„"
-#: ../message.c:423
#, c-format
msgid "Error detected while processing %s:"
msgstr "%s ã®å‡¦ç†ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒæ¤œå‡ºã•れã¾ã—ãŸ:"
-#: ../message.c:445
#, c-format
msgid "line %4ld:"
msgstr "行 %4ld:"
-#: ../message.c:617
#, c-format
msgid "E354: Invalid register name: '%s'"
msgstr "E354: 無効ãªãƒ¬ã‚¸ã‚¹ã‚¿å: '%s'"
-#: ../message.c:986
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "日本語メッセージ翻訳/監修: æ‘岡 太郎 <koron.kaoriya@gmail.com>"
+
msgid "Interrupt: "
msgstr "割込ã¿: "
-#: ../message.c:988
msgid "Press ENTER or type command to continue"
msgstr "ç¶šã‘ã‚‹ã«ã¯ENTERを押ã™ã‹ã‚³ãƒžãƒ³ãƒ‰ã‚’入力ã—ã¦ãã ã•ã„"
-#: ../message.c:1843
#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s 行 %<PRId64>"
+msgid "%s line %ld"
+msgstr "%s 行 %ld"
-#: ../message.c:2392
msgid "-- More --"
msgstr "-- 継続 --"
-#: ../message.c:2398
msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
msgstr " SPACE/d/j: ç”»é¢/ページ/行 下, b/u/k: 上, q: 終了 "
-#: ../message.c:3021 ../message.c:3031
msgid "Question"
msgstr "質å•"
-#: ../message.c:3023
msgid ""
"&Yes\n"
"&No"
@@ -4285,17 +3876,6 @@ msgstr ""
"ã¯ã„(&Y)\n"
"ã„ã„ãˆ(&N)"
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"ã¯ã„(&Y)\n"
-"ã„ã„ãˆ(&N)\n"
-"キャンセル(&C)"
-
-#: ../message.c:3045
msgid ""
"&Yes\n"
"&No\n"
@@ -4309,175 +3889,247 @@ msgstr ""
"å…¨ã¦æ”¾æ£„(&D)\n"
"キャンセル(&C)"
-#: ../message.c:3058
+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() ã®å¼•æ•°ãŒä¸å分ã§ã™"
-#: ../message.c:3119
msgid "E807: Expected Float argument for printf()"
msgstr "E807: printf() ã®å¼•æ•°ã«ã¯æµ®å‹•å°‘æ•°ç‚¹æ•°ãŒæœŸå¾…ã•れã¦ã„ã¾ã™"
-#: ../message.c:3873
msgid "E767: Too many arguments to printf()"
msgstr "E767: printf() ã®å¼•æ•°ãŒå¤šéŽãŽã¾ã™"
-#: ../misc1.c:2256
msgid "W10: Warning: Changing a readonly file"
msgstr "W10: 警告: 読込専用ファイルを変更ã—ã¾ã™"
-#: ../misc1.c:2537
msgid "Type number and <Enter> or click with mouse (empty cancels): "
msgstr ""
"番å·ã¨<Enter>を入力ã™ã‚‹ã‹ãƒžã‚¦ã‚¹ã§ã‚¯ãƒªãƒƒã‚¯ã—ã¦ãã ã•ã„ (空ã§ã‚­ãƒ£ãƒ³ã‚»ãƒ«): "
-#: ../misc1.c:2539
msgid "Type number and <Enter> (empty cancels): "
msgstr "番å·ã¨<Enter>を入力ã—ã¦ãã ã•ã„ (空ã§ã‚­ãƒ£ãƒ³ã‚»ãƒ«): "
-#: ../misc1.c:2585
msgid "1 more line"
msgstr "1 行 追加ã—ã¾ã—ãŸ"
-#: ../misc1.c:2588
msgid "1 line less"
msgstr "1 行 削除ã—ã¾ã—ãŸ"
-#: ../misc1.c:2593
#, c-format
-msgid "%<PRId64> more lines"
-msgstr "%<PRId64> 行 追加ã—ã¾ã—ãŸ"
+msgid "%ld more lines"
+msgstr "%ld 行 追加ã—ã¾ã—ãŸ"
-#: ../misc1.c:2596
#, c-format
-msgid "%<PRId64> fewer lines"
-msgstr "%<PRId64> 行 削除ã—ã¾ã—ãŸ"
+msgid "%ld fewer lines"
+msgstr "%ld 行 削除ã—ã¾ã—ãŸ"
-#: ../misc1.c:2599
msgid " (Interrupted)"
msgstr " (割込ã¾ã‚Œã¾ã—ãŸ)"
-#: ../misc1.c:2635
msgid "Beep!"
msgstr "ビーッ!"
-#: ../misc2.c:738
+msgid "ERROR: "
+msgstr "エラー: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[メモリ(ãƒã‚¤ãƒˆ)] ç·å‰²å½“-è§£æ”¾é‡ %lu-%lu, ä½¿ç”¨é‡ %lu, ピーク時 %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[呼出] ç· re/malloc() 回数 %lu, ç· free() 回数 %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: 行ãŒé•·ããªã‚ŠéŽãŽã¾ã—ãŸ"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: 内部エラー: lalloc(%ld,)"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: メモリãŒè¶³ã‚Šã¾ã›ã‚“! (%lu ãƒã‚¤ãƒˆã‚’å‰²å½“è¦æ±‚)"
+
#, c-format
msgid "Calling shell to execute: \"%s\""
msgstr "実行ã®ãŸã‚ã«ã‚·ã‚§ãƒ«ã‚’呼出ã—中: \"%s\""
-#: ../normal.c:183
+msgid "E545: Missing colon"
+msgstr "E545: コロンãŒã‚りã¾ã›ã‚“"
+
+msgid "E546: Illegal mode"
+msgstr "E546: 䏿­£ãªãƒ¢ãƒ¼ãƒ‰ã§ã™"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: 䏿­£ãª 'mouseshape' ã§ã™"
+
+msgid "E548: digit expected"
+msgstr "E548: 数値ãŒå¿…è¦ã§ã™"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: 䏿­£ãªãƒ‘ーセンテージã§ã™"
+
+msgid "E854: path too long for completion"
+msgstr "E854: パスãŒé•·éŽãŽã¦è£œå®Œã§ãã¾ã›ã‚“"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: 無効ãªãƒ‘スã§ã™: '**[数値]' ã¯pathã®æœ€å¾Œã‹ '%s' ãŒç¶šã„ã¦ãªã„ã¨ã„ã‘ã¾ã›"
+"ã‚“."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: cdpathã«ã¯ \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: pathã«ã¯ \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: cdpathã«ã¯ã“れ以上 \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: パスã«ã¯ã“れ以上 \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: NetBeansã®æŽ¥ç¶šæƒ…å ±ãƒ•ã‚¡ã‚¤ãƒ«ã®ã‚¢ã‚¯ã‚»ã‚¹ãƒ¢ãƒ¼ãƒ‰ã«å•題ãŒã‚りã¾ã™: \"%s\""
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: ãƒãƒƒãƒ•ã‚¡ %ld ã® NetBeans 接続ãŒå¤±ã‚れã¾ã—ãŸ"
+
+msgid "E838: netbeans is not supported with this GUI"
+msgstr "E838: NetBeansã¯ã“ã®GUIã«ã¯å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“"
+
+msgid "E511: netbeans already connected"
+msgstr "E511: NetBeansã¯æ—¢ã«æŽ¥ç¶šã—ã¦ã„ã¾ã™"
+
+#, c-format
+msgid "E505: %s is read-only (add ! to override)"
+msgstr "E505: %s ã¯èª­è¾¼å°‚用ã§ã™ (強制書込ã«ã¯ ! を追加)"
+
msgid "E349: No identifier under cursor"
msgstr "E349: カーソルã®ä½ç½®ã«ã¯è­˜åˆ¥å­ãŒã‚りã¾ã›ã‚“"
-#: ../normal.c:1866
msgid "E774: 'operatorfunc' is empty"
msgstr "E774: 'operatorfunc' オプションãŒç©ºã§ã™"
-#: ../normal.c:2637
+msgid "E775: Eval feature not available"
+msgstr "E775: å¼è©•価機能ãŒç„¡åйã«ãªã£ã¦ã„ã¾ã™"
+
msgid "Warning: terminal cannot highlight"
msgstr "警告: 使用ã—ã¦ã„る端末ã¯ãƒã‚¤ãƒ©ã‚¤ãƒˆã§ãã¾ã›ã‚“"
-#: ../normal.c:2807
msgid "E348: No string under cursor"
msgstr "E348: カーソルã®ä½ç½®ã«ã¯æ–‡å­—列ãŒã‚りã¾ã›ã‚“"
-#: ../normal.c:3937
msgid "E352: Cannot erase folds with current 'foldmethod'"
msgstr "E352: ç¾åœ¨ã® 'foldmethod' ã§ã¯æŠ˜ç•³ã¿ã‚’消去ã§ãã¾ã›ã‚“"
-#: ../normal.c:5897
msgid "E664: changelist is empty"
msgstr "E664: 変更リストãŒç©ºã§ã™"
-#: ../normal.c:5899
msgid "E662: At start of changelist"
msgstr "E662: 変更リストã®å…ˆé ­"
-#: ../normal.c:5901
msgid "E663: At end of changelist"
msgstr "E663: å¤‰æ›´ãƒªã‚¹ãƒˆã®æœ«å°¾"
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
+msgid "Type :quit<Enter> to exit Vim"
msgstr "Vimを終了ã™ã‚‹ã«ã¯ :quit<Enter> ã¨å…¥åŠ›ã—ã¦ãã ã•ã„"
-#: ../ops.c:248
#, c-format
msgid "1 line %sed 1 time"
msgstr "1 行㌠%s ã§ 1 回処ç†ã•れã¾ã—ãŸ"
-#: ../ops.c:250
#, c-format
msgid "1 line %sed %d times"
msgstr "1 行㌠%s ã§ %d 回処ç†ã•れã¾ã—ãŸ"
-#: ../ops.c:253
#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> 行㌠%s ã§ 1 回処ç†ã•れã¾ã—ãŸ"
+msgid "%ld lines %sed 1 time"
+msgstr "%ld 行㌠%s ã§ 1 回処ç†ã•れã¾ã—ãŸ"
-#: ../ops.c:256
#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> 行㌠%s ã§ %d 回処ç†ã•れã¾ã—ãŸ"
+msgid "%ld lines %sed %d times"
+msgstr "%ld 行㌠%s ã§ %d 回処ç†ã•れã¾ã—ãŸ"
-#: ../ops.c:592
#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "%<PRId64> 行ãŒã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã•れã¾ã™... "
+msgid "%ld lines to indent... "
+msgstr "%ld 行ãŒã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã•れã¾ã™... "
-#: ../ops.c:634
msgid "1 line indented "
msgstr "1 行をインデントã—ã¾ã—㟠"
-#: ../ops.c:636
#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "%<PRId64> 行をインデントã—ã¾ã—㟠"
+msgid "%ld lines indented "
+msgstr "%ld 行をインデントã—ã¾ã—㟠"
-#: ../ops.c:938
msgid "E748: No previously used register"
msgstr "E748: ã¾ã ãƒ¬ã‚¸ã‚¹ã‚¿ã‚’使用ã—ã¦ã„ã¾ã›ã‚“"
#. must display the prompt
-#: ../ops.c:1433
msgid "cannot yank; delete anyway"
msgstr "ヤンクã§ãã¾ã›ã‚“; ã¨ã«ã‹ã消去"
-#: ../ops.c:1929
msgid "1 line changed"
msgstr "1 行ãŒå¤‰æ›´ã•れã¾ã—ãŸ"
-#: ../ops.c:1931
#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "%<PRId64> 行ãŒå¤‰æ›´ã•れã¾ã—ãŸ"
+msgid "%ld lines changed"
+msgstr "%ld 行ãŒå¤‰æ›´ã•れã¾ã—ãŸ"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "%ld 行を解放中"
-#: ../ops.c:2521
msgid "block of 1 line yanked"
msgstr "1 行ã®ãƒ–ロックãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ"
-#: ../ops.c:2523
msgid "1 line yanked"
msgstr "1 行ãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ"
-#: ../ops.c:2525
#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "%<PRId64> 行ã®ãƒ–ロックãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ"
+msgid "block of %ld lines yanked"
+msgstr "%ld 行ã®ãƒ–ロックãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ"
-#: ../ops.c:2528
#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "%<PRId64> 行ãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ"
+msgid "%ld lines yanked"
+msgstr "%ld 行ãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ"
-#: ../ops.c:2710
#, c-format
msgid "E353: Nothing in register %s"
msgstr "E353: レジスタ %s ã«ã¯ä½•ã‚‚ã‚りã¾ã›ã‚“"
#. Highlight title
-#: ../ops.c:3185
msgid ""
"\n"
"--- Registers ---"
@@ -4485,11 +4137,9 @@ msgstr ""
"\n"
"--- レジスタ ---"
-#: ../ops.c:4455
msgid "Illegal register name"
msgstr "䏿­£ãªãƒ¬ã‚¸ã‚¹ã‚¿å"
-#: ../ops.c:4533
msgid ""
"\n"
"# Registers:\n"
@@ -4497,7 +4147,6 @@ msgstr ""
"\n"
"# レジスタ:\n"
-#: ../ops.c:4575
#, c-format
msgid "E574: Unknown register type %d"
msgstr "E574: 未知ã®ãƒ¬ã‚¸ã‚¹ã‚¿åž‹ %d ã§ã™"
@@ -4507,86 +4156,61 @@ msgid ""
"lines"
msgstr "E883: 検索パターンã¨å¼ãƒ¬ã‚¸ã‚¹ã‚¿ã«ã¯2行以上をå«ã‚られã¾ã›ã‚“"
-#: ../ops.c:5089
#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> 列; "
+msgid "%ld Cols; "
+msgstr "%ld 列; "
-#: ../ops.c:5097
#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"é¸æŠž %s%<PRId64> / %<PRId64> 行; %<PRId64> / %<PRId64> å˜èªž; %<PRId64> / "
-"%<PRId64> ãƒã‚¤ãƒˆ"
+msgid "Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes"
+msgstr "é¸æŠž %s%ld / %ld 行; %lld / %lld å˜èªž; %lld / %lld ãƒã‚¤ãƒˆ"
-#: ../ops.c:5105
#, c-format
msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
+"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of "
+"%lld Bytes"
msgstr ""
-"é¸æŠž %s%<PRId64> / %<PRId64> 行; %<PRId64> / %<PRId64> å˜èªž; %<PRId64> / "
-"%<PRId64> 文字; %<PRId64> / %<PRId64> ãƒã‚¤ãƒˆ"
+"é¸æŠž %s%ld / %ld 行; %lld / %lld å˜èªž; %lld / %lld 文字; %lld / %lld ãƒã‚¤ãƒˆ"
-#: ../ops.c:5123
#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
-msgstr ""
-"列 %s / %s; 行 %<PRId64> of %<PRId64>; å˜èªž %<PRId64> / %<PRId64>; ãƒã‚¤ãƒˆ "
-"%<PRId64> / %<PRId64>"
+msgid "Col %s of %s; Line %ld of %ld; Word %lld of %lld; Byte %lld of %lld"
+msgstr "列 %s / %s; 行 %ld of %ld; å˜èªž %lld / %lld; ãƒã‚¤ãƒˆ %lld / %lld"
-#: ../ops.c:5133
#, c-format
msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
+"Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte "
+"%lld of %lld"
msgstr ""
-"列 %s / %s; 行 %<PRId64> / %<PRId64>; å˜èªž %<PRId64> / %<PRId64>; 文字 "
-"%<PRId64> / %<PRId64>; ãƒã‚¤ãƒˆ %<PRId64> of %<PRId64>"
+"列 %s / %s; 行 %ld / %ld; å˜èªž %lld / %lld; 文字 %lld / %lld; ãƒã‚¤ãƒˆ %lld of "
+"%lld"
-#: ../ops.c:5146
#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> for BOM)"
+msgid "(+%ld for BOM)"
+msgstr "(+%ld for BOM)"
-#: ../option.c:1238
msgid "%<%f%h%m%=Page %N"
msgstr "%<%f%h%m%=%N ページ"
-#: ../option.c:1574
msgid "Thanks for flying Vim"
msgstr "Vim を使ã£ã¦ãれã¦ã‚りãŒã¨ã†"
-#. found a mismatch: skip
-#: ../option.c:2698
msgid "E518: Unknown option"
msgstr "E518: 未知ã®ã‚ªãƒ—ションã§ã™"
-#: ../option.c:2709
msgid "E519: Option not supported"
msgstr "E519: オプションã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
-#: ../option.c:2740
msgid "E520: Not allowed in a modeline"
msgstr "E520: modeline ã§ã¯è¨±å¯ã•れã¾ã›ã‚“"
-#: ../option.c:2815
msgid "E846: Key code not set"
msgstr "E846: キーコードãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“"
-#: ../option.c:2924
msgid "E521: Number required after ="
msgstr "E521: = ã®å¾Œã«ã¯æ•°å­—ãŒå¿…è¦ã§ã™"
-#: ../option.c:3226 ../option.c:3864
msgid "E522: Not found in termcap"
msgstr "E522: termcap 内ã«è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../option.c:3335
#, c-format
msgid "E539: Illegal character <%s>"
msgstr "E539: 䏿­£ãªæ–‡å­—ã§ã™ <%s>"
@@ -4595,93 +4219,99 @@ msgstr "E539: 䏿­£ãªæ–‡å­—ã§ã™ <%s>"
msgid "For option %s"
msgstr "オプション: %s"
-#: ../option.c:3862
msgid "E529: Cannot set 'term' to empty string"
msgstr "E529: 'term' ã«ã¯ç©ºæ–‡å­—列を設定ã§ãã¾ã›ã‚“"
-#: ../option.c:3885
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: GUIã§ã¯ 'term' を変更ã§ãã¾ã›ã‚“"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: GUIをスタートã™ã‚‹ã«ã¯ \":gui\" を使用ã—ã¦ãã ã•ã„"
+
msgid "E589: 'backupext' and 'patchmode' are equal"
msgstr "E589: 'backupext' 㨠'patchmode' ãŒåŒã˜ã§ã™"
-#: ../option.c:3964
msgid "E834: Conflicts with value of 'listchars'"
msgstr "E834: 'listchars'ã®å€¤ã«çŸ›ç›¾ãŒã‚りã¾ã™"
-#: ../option.c:3966
msgid "E835: Conflicts with value of 'fillchars'"
msgstr "E835: 'fillchars'ã®å€¤ã«çŸ›ç›¾ãŒã‚りã¾ã™"
-#: ../option.c:4163
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: GTK+2 GUIã§ã¯å¤‰æ›´ã§ãã¾ã›ã‚“"
+
msgid "E524: Missing colon"
msgstr "E524: コロンãŒã‚りã¾ã›ã‚“"
-#: ../option.c:4165
msgid "E525: Zero length string"
msgstr "E525: 文字列ã®é•·ã•ãŒã‚¼ãƒ­ã§ã™"
-#: ../option.c:4220
#, c-format
msgid "E526: Missing number after <%s>"
msgstr "E526: <%s> ã®å¾Œã«æ•°å­—ãŒã‚りã¾ã›ã‚“"
-#: ../option.c:4232
msgid "E527: Missing comma"
msgstr "E527: カンマãŒã‚りã¾ã›ã‚“"
-#: ../option.c:4239
msgid "E528: Must specify a ' value"
msgstr "E528: ' ã®å€¤ã‚’指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#: ../option.c:4271
msgid "E595: contains unprintable or wide character"
msgstr "E595: 表示ã§ããªã„文字ã‹ãƒ¯ã‚¤ãƒ‰æ–‡å­—ã‚’å«ã‚“ã§ã„ã¾ã™"
-#: ../option.c:4469
+msgid "E596: Invalid font(s)"
+msgstr "E596: 無効ãªãƒ•ォントã§ã™"
+
+msgid "E597: can't select fontset"
+msgstr "E597: ãƒ•ã‚©ãƒ³ãƒˆã‚»ãƒƒãƒˆã‚’é¸æŠžã§ãã¾ã›ã‚“"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: 無効ãªãƒ•ォントセットã§ã™"
+
+msgid "E533: can't select wide font"
+msgstr "E533: ãƒ¯ã‚¤ãƒ‰ãƒ•ã‚©ãƒ³ãƒˆã‚’é¸æŠžã§ãã¾ã›ã‚“"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: 無効ãªãƒ¯ã‚¤ãƒ‰ãƒ•ォントã§ã™"
+
#, c-format
msgid "E535: Illegal character after <%c>"
msgstr "E535: <%c> ã®å¾Œã«ä¸æ­£ãªæ–‡å­—ãŒã‚りã¾ã™"
-#: ../option.c:4534
msgid "E536: comma required"
msgstr "E536: カンマãŒå¿…è¦ã§ã™"
-#: ../option.c:4543
#, c-format
msgid "E537: 'commentstring' must be empty or contain %s"
msgstr "E537: 'commentstring' ã¯ç©ºã§ã‚ã‚‹ã‹ %s ã‚’å«ã‚€å¿…è¦ãŒã‚りã¾ã™"
-#: ../option.c:4928
+msgid "E538: No mouse support"
+msgstr "E538: マウスã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“"
+
msgid "E540: Unclosed expression sequence"
msgstr "E540: å¼ãŒçµ‚了ã—ã¦ã„ã¾ã›ã‚“"
-#: ../option.c:4932
msgid "E541: too many items"
msgstr "E541: è¦ç´ ãŒå¤šéŽãŽã¾ã™"
-#: ../option.c:4934
msgid "E542: unbalanced groups"
msgstr "E542: グループãŒé‡£åˆã„ã¾ã›ã‚“"
-#: ../option.c:5148
msgid "E590: A preview window already exists"
msgstr "E590: ãƒ—ãƒ¬ãƒ“ãƒ¥ãƒ¼ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™"
-#: ../option.c:5311
msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
msgstr ""
"W17: アラビア文字ã«ã¯UTF-8ãŒå¿…è¦ãªã®ã§, ':set encoding=utf-8' ã—ã¦ãã ã•ã„"
-#: ../option.c:5623
#, c-format
msgid "E593: Need at least %d lines"
msgstr "E593: 最低 %d ã®è¡Œæ•°ãŒå¿…è¦ã§ã™"
-#: ../option.c:5631
#, c-format
msgid "E594: Need at least %d columns"
msgstr "E594: 最低 %d ã®ã‚«ãƒ©ãƒ å¹…ãŒå¿…è¦ã§ã™"
-#: ../option.c:6011
#, c-format
msgid "E355: Unknown option: %s"
msgstr "E355: 未知ã®ã‚ªãƒ—ションã§ã™: %s"
@@ -4689,12 +4319,10 @@ msgstr "E355: 未知ã®ã‚ªãƒ—ションã§ã™: %s"
#. There's another character after zeros or the string
#. * is empty. In both cases, we are trying to set a
#. * num option using a string.
-#: ../option.c:6037
#, c-format
msgid "E521: Number required: &%s = '%s'"
msgstr "E521: æ•°å­—ãŒå¿…è¦ã§ã™: &%s = '%s'"
-#: ../option.c:6149
msgid ""
"\n"
"--- Terminal codes ---"
@@ -4702,7 +4330,6 @@ msgstr ""
"\n"
"--- 端末コード ---"
-#: ../option.c:6151
msgid ""
"\n"
"--- Global option values ---"
@@ -4710,7 +4337,6 @@ msgstr ""
"\n"
"--- グローãƒãƒ«ã‚ªãƒ—ション値 ---"
-#: ../option.c:6153
msgid ""
"\n"
"--- Local option values ---"
@@ -4718,7 +4344,6 @@ msgstr ""
"\n"
"--- ローカルオプション値 ---"
-#: ../option.c:6155
msgid ""
"\n"
"--- Options ---"
@@ -4726,37 +4351,119 @@ msgstr ""
"\n"
"--- オプション ---"
-#: ../option.c:6816
msgid "E356: get_varp ERROR"
msgstr "E356: get_varp エラー"
-#: ../option.c:7696
#, c-format
msgid "E357: 'langmap': Matching character missing for %s"
msgstr "E357: 'langmap': %s ã«å¯¾å¿œã™ã‚‹æ–‡å­—ãŒã‚りã¾ã›ã‚“"
-#: ../option.c:7715
#, c-format
msgid "E358: 'langmap': Extra characters after semicolon: %s"
msgstr "E358: 'langmap': セミコロンã®å¾Œã«ä½™åˆ†ãªæ–‡å­—ãŒã‚りã¾ã™: %s"
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"シェルを実行ã§ãã¾ã›ã‚“ "
+msgid "cannot open "
+msgstr "é–‹ã‘ã¾ã›ã‚“ "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: ウィンドウを開ã‘ã¾ã›ã‚“!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Amigadosã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 2.04ã‹ãれ以é™ãŒå¿…è¦ã§ã™\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "%s ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %ld ãŒå¿…è¦ã§ã™\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "NILã‚’é–‹ã‘ã¾ã›ã‚“:\n"
+
+msgid "Cannot create "
+msgstr "作æˆã§ãã¾ã›ã‚“ "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim㯠%d ã§çµ‚了ã—ã¾ã™\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "コンソールモードを変更ã§ãã¾ã›ã‚“?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: コンソールã§ã¯ãªã„??\n"
+
+#. 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 "E244: Illegal quality name \"%s\" in font name \"%s\""
+msgstr "E244: å“質å \"%s\" ã¯ä¸æ­£ã§ã™ (フォントå \"%s\")"
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: '%c' ã¯ä¸æ­£ãªæ–‡å­—ã§ã™ (フォントå \"%s\")"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Xサーãƒãƒ¼ã¸ã®æŽ¥ç¶šã« %ld ミリ秒ã‹ã‹ã‚Šã¾ã—ãŸ"
-#: ../os/shell.c:439
msgid ""
"\n"
-"shell returned "
+"Vim: Got X error\n"
msgstr ""
"\n"
-"シェルãŒå€¤ã‚’è¿”ã—ã¾ã—㟠"
+"Vim: X ã®ã‚¨ãƒ©ãƒ¼ã‚’検出ã—ã¾ã—ãŸr\n"
+
+msgid "Testing the X display failed"
+msgstr "X display ã®ãƒã‚§ãƒƒã‚¯ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "Opening the X display timed out"
+msgstr "X display ã® open ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸ"
-#: ../os_unix.c:465 ../os_unix.c:471
msgid ""
"\n"
"Could not get security context for "
@@ -4764,7 +4471,6 @@ msgstr ""
"\n"
"セキュリティコンテキストをå–å¾—ã§ãã¾ã›ã‚“ "
-#: ../os_unix.c:479
msgid ""
"\n"
"Could not set security context for "
@@ -4780,223 +4486,293 @@ msgstr "セキュリティコンテキスト %s ã‚’ %s ã«è¨­å®šã§ãã¾ã›ã‚“"
msgid "Could not get security context %s for %s. Removing it!"
msgstr "セキュリティコンテキスト %s ã‚’ %s ã‹ã‚‰å–å¾—ã§ãã¾ã›ã‚“. 削除ã—ã¾ã™!"
-#: ../os_unix.c:1558 ../os_unix.c:1647
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"sh シェルを実行ã§ãã¾ã›ã‚“\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"シェルãŒå€¤ã‚’è¿”ã—ã¾ã—㟠"
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"パイプを作æˆã§ãã¾ã›ã‚“\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"fork ã§ãã¾ã›ã‚“\n"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"シェルを実行ã§ãã¾ã›ã‚“ "
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"コマンドを中断ã—ã¾ã—ãŸ\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP ãŒICE接続を失ã„ã¾ã—ãŸ"
+
#, c-format
msgid "dlerror = \"%s\""
msgstr "dlerror = \"%s\""
-#: ../path.c:1449
+msgid "Opening the X display failed"
+msgstr "X display ã® open ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP ãŒsave-yourselfè¦æ±‚を処ç†ã—ã¦ã„ã¾ã™"
+
+msgid "XSMP opening connection"
+msgstr "XSMP ãŒæŽ¥ç¶šã‚’é–‹å§‹ã—ã¦ã„ã¾ã™"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP ICE接続ãŒå¤±æ•—ã—ãŸã‚ˆã†ã§ã™"
+
#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: pathã«ã¯ \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP SmcOpenConnectionãŒå¤±æ•—ã—ã¾ã—ãŸ: %s"
+
+msgid "At line"
+msgstr "行"
+
+msgid "Could not load vim32.dll!"
+msgstr "vim32.dll をロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
+
+msgid "VIM Error"
+msgstr "VIMエラー"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "DLLã‹ã‚‰é–¢æ•°ãƒã‚¤ãƒ³ã‚¿ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: イベント %s を検知\n"
+
+msgid "close"
+msgstr "é–‰ã˜ã‚‹"
+
+msgid "logoff"
+msgstr "ログオフ"
+
+msgid "shutdown"
+msgstr "シャットダウン"
+
+msgid "E371: Command not found"
+msgstr "E371: コマンドãŒã‚りã¾ã›ã‚“"
+
+msgid ""
+"VIMRUN.EXE not found in your $PATH.\n"
+"External commands will not pause after completion.\n"
+"See :help win32-vimrun for more information."
+msgstr ""
+"VIMRUN.EXE㌠$PATH ã®ä¸­ã«è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“.\n"
+"外部コマンドã®çµ‚了後ã«ä¸€æ™‚åœæ­¢ã‚’ã—ã¾ã›ã‚“.\n"
+"詳細㯠:help win32-vimrun ã‚’å‚ç…§ã—ã¦ãã ã•ã„."
+
+msgid "Vim Warning"
+msgstr "Vimã®è­¦å‘Š"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "シェルãŒã‚³ãƒ¼ãƒ‰ %d ã§çµ‚了ã—ã¾ã—ãŸ"
-#: ../quickfix.c:359
#, c-format
msgid "E372: Too many %%%c in format string"
msgstr "E372: フォーマット文字列㫠%%%c ãŒå¤šéŽãŽã¾ã™"
-#: ../quickfix.c:371
#, c-format
msgid "E373: Unexpected %%%c in format string"
msgstr "E373: フォーマット文字列ã«äºˆæœŸã›ã¬ %%%c ãŒã‚りã¾ã—ãŸ"
-#: ../quickfix.c:420
msgid "E374: Missing ] in format string"
msgstr "E374: フォーマット文字列㫠] ãŒã‚りã¾ã›ã‚“"
-#: ../quickfix.c:431
#, c-format
msgid "E375: Unsupported %%%c in format string"
msgstr "E375: フォーマット文字列ã§ã¯ %%%c ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“"
-#: ../quickfix.c:448
#, c-format
msgid "E376: Invalid %%%c in format string prefix"
msgstr "E376: フォーマット文字列ã®å‰ç½®ã«ç„¡åŠ¹ãª %%%c ãŒã‚りã¾ã™"
-#: ../quickfix.c:454
#, c-format
msgid "E377: Invalid %%%c in format string"
msgstr "E377: フォーマット文字列ã«ç„¡åŠ¹ãª %%%c ãŒã‚りã¾ã™"
#. nothing found
-#: ../quickfix.c:477
msgid "E378: 'errorformat' contains no pattern"
msgstr "E378: 'errorformat' ã«ãƒ‘ã‚¿ãƒ¼ãƒ³ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“"
-#: ../quickfix.c:695
msgid "E379: Missing or empty directory name"
msgstr "E379: ディレクトリåãŒç„¡ã„ã‹ç©ºã§ã™"
-#: ../quickfix.c:1305
msgid "E553: No more items"
msgstr "E553: è¦ç´ ãŒã‚‚ã†ã‚りã¾ã›ã‚“"
-#: ../quickfix.c:1674
+msgid "E924: Current window was closed"
+msgstr "E924: ç¾åœ¨ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒé–‰ã˜ã‚‰ã‚Œã¾ã—ãŸ"
+
+msgid "E925: Current quickfix was changed"
+msgstr "E925: ç¾åœ¨ã® quickfix ãŒå¤‰æ›´ã•れã¾ã—ãŸ"
+
+msgid "E926: Current location list was changed"
+msgstr "E926: ç¾åœ¨ã®ãƒ­ã‚±ãƒ¼ã‚·ãƒ§ãƒ³ãƒªã‚¹ãƒˆãŒå¤‰æ›´ã•れã¾ã—ãŸ"
+
#, c-format
msgid "(%d of %d)%s%s: "
msgstr "(%d of %d)%s%s: "
-#: ../quickfix.c:1676
msgid " (line deleted)"
msgstr " (行ãŒå‰Šé™¤ã•れã¾ã—ãŸ)"
-#: ../quickfix.c:1863
+#, c-format
+msgid "%serror list %d of %d; %d errors "
+msgstr "%s エラー一覧 %d of %d; %d 個エラー"
+
msgid "E380: At bottom of quickfix stack"
msgstr "E380: quickfix ã‚¹ã‚¿ãƒƒã‚¯ã®æœ«å°¾ã§ã™"
-#: ../quickfix.c:1869
msgid "E381: At top of quickfix stack"
msgstr "E381: quickfix スタックã®å…ˆé ­ã§ã™"
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "エラー一覧 %d of %d; %d 個エラー"
+msgid "No entries"
+msgstr "エントリãŒã‚りã¾ã›ã‚“"
-#: ../quickfix.c:2427
msgid "E382: Cannot write, 'buftype' option is set"
msgstr "E382: 'buftype' オプションãŒè¨­å®šã•れã¦ã„ã‚‹ã®ã§æ›¸è¾¼ã¿ã¾ã›ã‚“"
-#: ../quickfix.c:2812
+msgid "Error file"
+msgstr "エラーファイル"
+
msgid "E683: File name missing or invalid pattern"
msgstr "E683: ファイルåãŒç„¡ã„ã‹ç„¡åйãªãƒ‘ターンã§ã™"
-#: ../quickfix.c:2911
#, c-format
msgid "Cannot open file \"%s\""
msgstr "ファイル \"%s\" ã‚’é–‹ã‘ã¾ã›ã‚“"
-#: ../quickfix.c:3429
msgid "E681: Buffer is not loaded"
msgstr "E681: ãƒãƒƒãƒ•ã‚¡ã¯èª­ã¿è¾¼ã¾ã‚Œã¾ã›ã‚“ã§ã—ãŸ"
-#: ../quickfix.c:3487
msgid "E777: String or List expected"
msgstr "E777: 文字列ã‹ãƒªã‚¹ãƒˆãŒå¿…è¦ã§ã™"
-#: ../regexp.c:359
#, c-format
msgid "E369: invalid item in %s%%[]"
msgstr "E369: 無効ãªé …ç›®ã§ã™: %s%%[]"
#
-#: ../regexp.c:374
#, c-format
msgid "E769: Missing ] after %s["
msgstr "E769: %s[ ã®å¾Œã« ] ãŒã‚りã¾ã›ã‚“"
-#: ../regexp.c:375
#, c-format
msgid "E53: Unmatched %s%%("
msgstr "E53: %s%%( ãŒé‡£ã‚Šåˆã£ã¦ã„ã¾ã›ã‚“"
-#: ../regexp.c:376
#, c-format
msgid "E54: Unmatched %s("
msgstr "E54: %s( ãŒé‡£ã‚Šåˆã£ã¦ã„ã¾ã›ã‚“"
-#: ../regexp.c:377
#, c-format
msgid "E55: Unmatched %s)"
msgstr "E55: %s) ãŒé‡£ã‚Šåˆã£ã¦ã„ã¾ã›ã‚“"
#
-#: ../regexp.c:378
msgid "E66: \\z( not allowed here"
msgstr "E66: \\z( ã¯ã‚³ã‚³ã§ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
#
-#: ../regexp.c:379
msgid "E67: \\z1 et al. not allowed here"
msgstr "E67: \\z1 ãã®ä»–ã¯ã‚³ã‚³ã§ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
#
-#: ../regexp.c:380
#, c-format
msgid "E69: Missing ] after %s%%["
msgstr "E69: %s%%[ ã®å¾Œã« ] ãŒã‚りã¾ã›ã‚“"
-#: ../regexp.c:381
#, c-format
msgid "E70: Empty %s%%[]"
msgstr "E70: %s%%[] ãŒç©ºã§ã™"
-#: ../regexp.c:1209 ../regexp.c:1224
msgid "E339: Pattern too long"
msgstr "E339: パターンãŒé•·éŽãŽã¾ã™"
-#: ../regexp.c:1371
msgid "E50: Too many \\z("
msgstr "E50: \\z( ãŒå¤šéŽãŽã¾ã™"
-#: ../regexp.c:1378
#, c-format
msgid "E51: Too many %s("
msgstr "E51: %s( ãŒå¤šéŽãŽã¾ã™"
-#: ../regexp.c:1427
msgid "E52: Unmatched \\z("
msgstr "E52: \\z( ãŒé‡£ã‚Šåˆã£ã¦ã„ã¾ã›ã‚“"
-#: ../regexp.c:1637
#, c-format
msgid "E59: invalid character after %s@"
msgstr "E59: %s@ ã®å¾Œã«ä¸æ­£ãªæ–‡å­—ãŒã‚りã¾ã—ãŸ"
-#: ../regexp.c:1672
#, c-format
msgid "E60: Too many complex %s{...}s"
msgstr "E60: 複雑㪠%s{...} ãŒå¤šéŽãŽã¾ã™"
-#: ../regexp.c:1687
#, c-format
msgid "E61: Nested %s*"
msgstr "E61:%s* ãŒå…¥ã‚Œå­ã«ãªã£ã¦ã„ã¾ã™"
-#: ../regexp.c:1690
#, c-format
msgid "E62: Nested %s%c"
msgstr "E62:%s%c ãŒå…¥ã‚Œå­ã«ãªã£ã¦ã„ã¾ã™"
#
-#: ../regexp.c:1800
msgid "E63: invalid use of \\_"
msgstr "E63: \\_ ã®ç„¡åйãªä½¿ç”¨æ–¹æ³•ã§ã™"
-#: ../regexp.c:1850
#, c-format
msgid "E64: %s%c follows nothing"
msgstr "E64:%s%c ã®å¾Œã«ãªã«ã‚‚ã‚りã¾ã›ã‚“"
#
-#: ../regexp.c:1902
msgid "E65: Illegal back reference"
msgstr "E65: 䏿­£ãªå¾Œæ–¹å‚ç…§ã§ã™"
#
-#: ../regexp.c:1943
msgid "E68: Invalid character after \\z"
msgstr "E68: \\z ã®å¾Œã«ä¸æ­£ãªæ–‡å­—ãŒã‚りã¾ã—ãŸ"
#
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
#, c-format
msgid "E678: Invalid character after %s%%[dxouU]"
msgstr "E678: %s%%[dxouU] ã®å¾Œã«ä¸æ­£ãªæ–‡å­—ãŒã‚りã¾ã—ãŸ"
#
-#: ../regexp.c:2107
#, c-format
msgid "E71: Invalid character after %s%%"
msgstr "E71: %s%% ã®å¾Œã«ä¸æ­£ãªæ–‡å­—ãŒã‚りã¾ã—ãŸ"
-#: ../regexp.c:3017
#, c-format
msgid "E554: Syntax error in %s{...}"
msgstr "E554: %s{...} å†…ã«æ–‡æ³•エラーãŒã‚りã¾ã™"
-#: ../regexp.c:3805
msgid "External submatches:\n"
msgstr "外部ã®éƒ¨åˆ†è©²å½“:\n"
@@ -5004,7 +4780,6 @@ msgstr "外部ã®éƒ¨åˆ†è©²å½“:\n"
msgid "E888: (NFA regexp) cannot repeat %s"
msgstr "E888: (NFA æ­£è¦è¡¨ç¾) 繰り返ã›ã¾ã›ã‚“ %s"
-#: ../regexp.c:7022
msgid ""
"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
"used "
@@ -5015,62 +4790,54 @@ msgstr ""
msgid "Switching to backtracking RE engine for pattern: "
msgstr "次ã®ãƒ‘ターンã«ãƒãƒƒã‚¯ãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚° RE エンジンをé©ç”¨ã—ã¾ã™: "
-#: ../regexp_nfa.c:239
msgid "E865: (NFA) Regexp end encountered prematurely"
msgstr "E865: (NFA) æœŸå¾…ã‚ˆã‚Šæ—©ãæ­£è¦è¡¨ç¾ã®çµ‚端ã«åˆ°é”ã—ã¾ã—ãŸ"
-#: ../regexp_nfa.c:240
#, c-format
msgid "E866: (NFA regexp) Misplaced %c"
msgstr "E866: (NFA æ­£è¦è¡¨ç¾) ä½ç½®ãŒèª¤ã£ã¦ã„ã¾ã™: %c"
-#: ../regexp_nfa.c:242
+#
#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr "E877: (NFA æ­£è¦è¡¨ç¾) ç„¡åŠ¹ãªæ–‡å­—クラス: %<PRId64>"
+msgid "E877: (NFA regexp) Invalid character class: %ld"
+msgstr "E877: (NFA æ­£è¦è¡¨ç¾) ç„¡åŠ¹ãªæ–‡å­—クラス: %ld"
-#: ../regexp_nfa.c:1261
#, c-format
msgid "E867: (NFA) Unknown operator '\\z%c'"
msgstr "E867: (NFA) 未知ã®ã‚ªãƒšãƒ¬ãƒ¼ã‚¿ã§ã™: '\\z%c'"
-#: ../regexp_nfa.c:1387
#, c-format
msgid "E867: (NFA) Unknown operator '\\%%%c'"
msgstr "E867: (NFA) 未知ã®ã‚ªãƒšãƒ¬ãƒ¼ã‚¿ã§ã™: '\\%%%c'"
-#: ../regexp_nfa.c:1802
+#. 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'"
-#: ../regexp_nfa.c:1831
msgid "E870: (NFA regexp) Error reading repetition limits"
msgstr "E870: (NFA æ­£è¦è¡¨ç¾) 繰り返ã—ã®åˆ¶é™å›žæ•°ã‚’読込中ã«ã‚¨ãƒ©ãƒ¼"
#. Can't have a multi follow a multi.
-#: ../regexp_nfa.c:1895
msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
msgstr "E871: (NFA æ­£è¦è¡¨ç¾) 繰り返㗠ã®å¾Œã« 繰り返㗠ã¯ã§ãã¾ã›ã‚“!"
#. Too many `('
-#: ../regexp_nfa.c:2037
msgid "E872: (NFA regexp) Too many '('"
msgstr "E872: (NFA æ­£è¦è¡¨ç¾) '(' ãŒå¤šéŽãŽã¾ã™"
-#: ../regexp_nfa.c:2042
msgid "E879: (NFA regexp) Too many \\z("
msgstr "E879: (NFA æ­£è¦è¡¨ç¾) \\z( ãŒå¤šéŽãŽã¾ã™"
-#: ../regexp_nfa.c:2066
msgid "E873: (NFA regexp) proper termination error"
msgstr "E873: (NFA æ­£è¦è¡¨ç¾) 終端記å·ãŒã‚りã¾ã›ã‚“"
-#: ../regexp_nfa.c:2599
msgid "E874: (NFA) Could not pop the stack !"
msgstr "E874: (NFA) スタックをãƒãƒƒãƒ—ã§ãã¾ã›ã‚“!"
-#: ../regexp_nfa.c:3298
msgid ""
"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
"left on stack"
@@ -5078,177 +4845,136 @@ msgstr ""
"E875: (NFA æ­£è¦è¡¨ç¾) (後置文字列をNFAã«å¤‰æ›ä¸­ã«) ã‚¹ã‚¿ãƒƒã‚¯ã«æ®‹ã•れãŸã‚¹ãƒ†ãƒ¼ãƒˆãŒ"
"多éŽãŽã¾ã™"
-#: ../regexp_nfa.c:3302
msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
msgstr "E876: (NFA æ­£è¦è¡¨ç¾) NFA全体をä¿å­˜ã™ã‚‹ã«ã¯ç©ºãスペースãŒè¶³ã‚Šã¾ã›ã‚“"
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
+msgid "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æ­£è¦è¡¨ç¾ã‚¨ãƒ³ã‚¸ãƒ³ç”¨ã®ãƒ­ã‚°ãƒ•ァイルを書込用ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“ã€‚ãƒ­ã‚°ã¯æ¨™æº–出力ã«"
"出力ã—ã¾ã™ã€‚"
-#: ../regexp_nfa.c:4840
#, c-format
msgid "(NFA) COULD NOT OPEN %s !"
msgstr "(NFA) ログファイル %s ã‚’é–‹ã‘ã¾ã›ã‚“!"
-#: ../regexp_nfa.c:6049
msgid "Could not open temporary log file for writing "
msgstr "NFAæ­£è¦è¡¨ç¾ã‚¨ãƒ³ã‚¸ãƒ³ç”¨ã®ãƒ­ã‚°ãƒ•ァイルを書込用ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“。"
-#: ../screen.c:7435
msgid " VREPLACE"
msgstr " 仮想置æ›"
-#: ../screen.c:7437
msgid " REPLACE"
msgstr " ç½®æ›"
-#: ../screen.c:7440
msgid " REVERSE"
msgstr " å転"
-#: ../screen.c:7441
msgid " INSERT"
msgstr " 挿入"
-#: ../screen.c:7443
msgid " (insert)"
msgstr " (挿入)"
-#: ../screen.c:7445
msgid " (replace)"
msgstr " (ç½®æ›)"
-#: ../screen.c:7447
msgid " (vreplace)"
msgstr " (仮想置æ›)"
-#: ../screen.c:7449
msgid " Hebrew"
msgstr " ヘブライ"
-#: ../screen.c:7454
msgid " Arabic"
msgstr " アラビア"
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (言語)"
-
-#: ../screen.c:7459
msgid " (paste)"
msgstr " (貼り付ã‘)"
-#: ../screen.c:7469
msgid " VISUAL"
msgstr " ビジュアル"
-#: ../screen.c:7470
msgid " VISUAL LINE"
msgstr " ビジュアル 行"
-#: ../screen.c:7471
msgid " VISUAL BLOCK"
msgstr " ビジュアル 矩形"
-#: ../screen.c:7472
msgid " SELECT"
msgstr " セレクト"
-#: ../screen.c:7473
msgid " SELECT LINE"
msgstr " 行指å‘é¸æŠž"
-#: ../screen.c:7474
msgid " SELECT BLOCK"
msgstr " çŸ©å½¢é¸æŠž"
-#: ../screen.c:7486 ../screen.c:7541
msgid "recording"
msgstr "記録中"
-#: ../search.c:487
#, c-format
msgid "E383: Invalid search string: %s"
msgstr "E383: ç„¡åŠ¹ãªæ¤œç´¢æ–‡å­—列ã§ã™: %s"
-#: ../search.c:832
#, c-format
msgid "E384: search hit TOP without match for: %s"
msgstr "E384: 上ã¾ã§æ¤œç´¢ã—ã¾ã—ãŸãŒè©²å½“箇所ã¯ã‚りã¾ã›ã‚“: %s"
-#: ../search.c:835
#, c-format
msgid "E385: search hit BOTTOM without match for: %s"
msgstr "E385: 下ã¾ã§æ¤œç´¢ã—ã¾ã—ãŸãŒè©²å½“箇所ã¯ã‚りã¾ã›ã‚“: %s"
-#: ../search.c:1200
msgid "E386: Expected '?' or '/' after ';'"
msgstr "E386: ';' ã®ã‚ã¨ã«ã¯ '?' ã‹ '/' ãŒæœŸå¾…ã•れã¦ã„ã‚‹"
-#: ../search.c:4085
msgid " (includes previously listed match)"
msgstr " (å‰ã«åˆ—挙ã—ãŸè©²å½“箇所をå«ã‚€)"
#. cursor at status line
-#: ../search.c:4104
msgid "--- Included files "
msgstr "--- インクルードã•れãŸãƒ•ァイル "
-#: ../search.c:4106
msgid "not found "
msgstr "見ã¤ã‹ã‚Šã¾ã›ã‚“ "
-#: ../search.c:4107
msgid "in path ---\n"
msgstr "パス㫠----\n"
-#: ../search.c:4168
msgid " (Already listed)"
msgstr " (æ—¢ã«åˆ—挙)"
-#: ../search.c:4170
msgid " NOT FOUND"
msgstr " 見ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../search.c:4211
#, c-format
msgid "Scanning included file: %s"
msgstr "インクルードã•れãŸãƒ•ァイルをスキャン中: %s"
-#: ../search.c:4216
#, c-format
msgid "Searching included file %s"
msgstr "インクルードã•れãŸãƒ•ァイルをスキャン中 %s"
-#: ../search.c:4405
msgid "E387: Match is on current line"
msgstr "E387: ç¾åœ¨è¡Œã«è©²å½“ãŒã‚りã¾ã™"
-#: ../search.c:4517
msgid "All included files were found"
msgstr "å…¨ã¦ã®ã‚¤ãƒ³ã‚¯ãƒ«ãƒ¼ãƒ‰ã•れãŸãƒ•ァイルãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ"
-#: ../search.c:4519
msgid "No included files"
msgstr "インクルードファイルã¯ã‚りã¾ã›ã‚“"
-#: ../search.c:4527
msgid "E388: Couldn't find definition"
msgstr "E388: 定義を見ã¤ã‘られã¾ã›ã‚“"
-#: ../search.c:4529
msgid "E389: Couldn't find pattern"
msgstr "E389: パターンを見ã¤ã‘られã¾ã›ã‚“"
-#: ../search.c:4668
msgid "Substitute "
msgstr "Substitute "
-#: ../search.c:4681
#, c-format
msgid ""
"\n"
@@ -5259,99 +4985,131 @@ msgstr ""
"# 最後㮠%s検索パターン:\n"
"~"
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: ã‚¹ãƒšãƒ«ãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸å¼ã‚¨ãƒ©ãƒ¼ã§ã™"
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: スペルãƒã‚§ãƒƒã‚¯ã¯ç„¡åŠ¹åŒ–ã•れã¦ã„ã¾ã™"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
+msgstr ""
+"警告: å˜èªžãƒªã‚¹ãƒˆ \"%s_%s.spl\" ãŠã‚ˆã³ \"%s_ascii.spl\" ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr ""
+"警告: å˜èªžãƒªã‚¹ãƒˆ \"%s.%s.spl\" ãŠã‚ˆã³ \"%s.ascii.spl\" ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+msgid "E797: SpellFileMissing autocommand deleted buffer"
+msgstr "E797: autocommand ã® SpellFileMissing ãŒãƒãƒƒãƒ•ァを削除ã—ã¾ã—ãŸ"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "警告9: %s ã¨ã„ã†ç¯„囲ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
+
+msgid "Sorry, no suggestions"
+msgstr "残念ã§ã™ãŒ, 修正候補ã¯ã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "残念ã§ã™ãŒ, 修正候補㯠%ld 個ã—ã‹ã‚りã¾ã›ã‚“"
+
+#. 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"
-#: ../spell.c:952
msgid "E758: Truncated spell file"
msgstr "E758: スペルファイルãŒåˆ‡å–られã¦ã„るよã†ã§ã™"
-#: ../spell.c:953
#, c-format
msgid "Trailing text in %s line %d: %s"
msgstr "%s (%d 行目) ã«ç¶šãテキスト: %s"
-#: ../spell.c:954
#, c-format
msgid "Affix name too long in %s line %d: %s"
msgstr "%s (%d 行目) ã® affix åãŒé•·éŽãŽã¾ã™: %s"
-#: ../spell.c:955
msgid "E761: Format error in affix file FOL, LOW or UPP"
msgstr ""
"E761: affixファイル㮠FOL, LOW ã‚‚ã—ã㯠UPP ã®ãƒ•ォーマットã«ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã™"
-#: ../spell.c:957
msgid "E762: Character in FOL, LOW or UPP is out of range"
msgstr "E762: FOL, LOW ã‚‚ã—ã㯠UPP ã®æ–‡å­—ãŒç¯„囲外ã§ã™"
-#: ../spell.c:958
msgid "Compressing word tree..."
msgstr "å˜èªžãƒ„リーを圧縮ã—ã¦ã„ã¾ã™..."
-#: ../spell.c:1951
-msgid "E756: Spell checking is not enabled"
-msgstr "E756: スペルãƒã‚§ãƒƒã‚¯ã¯ç„¡åŠ¹åŒ–ã•れã¦ã„ã¾ã™"
-
-#: ../spell.c:2249
-#, c-format
-msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
-msgstr ""
-"警告: å˜èªžãƒªã‚¹ãƒˆ \"%s.%s.spl\" ãŠã‚ˆã³ \"%s.ascii.spl\" ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-
-#: ../spell.c:2473
#, c-format
msgid "Reading spell file \"%s\""
msgstr "スペルファイル \"%s\" を読込中"
-#: ../spell.c:2496
msgid "E757: This does not look like a spell file"
msgstr "E757: スペルファイルã§ã¯ãªã„よã†ã§ã™"
-#: ../spell.c:2501
msgid "E771: Old spell file, needs to be updated"
msgstr "E771: å¤ã„スペルファイルãªã®ã§, アップデートã—ã¦ãã ã•ã„"
-#: ../spell.c:2504
msgid "E772: Spell file is for newer version of Vim"
msgstr "E772: より新ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® Vim 用ã®ã‚¹ãƒšãƒ«ãƒ•ァイルã§ã™"
-#: ../spell.c:2602
msgid "E770: Unsupported section in spell file"
msgstr "E770: スペルファイルã«ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ãªã„セクションãŒã‚りã¾ã™"
-#: ../spell.c:3762
#, c-format
-msgid "Warning: region %s not supported"
-msgstr "警告9: %s ã¨ã„ã†ç¯„囲ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: .sug ファイルã§ã¯ãªã„よã†ã§ã™: %s"
+
+#, 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"
-#: ../spell.c:4550
#, c-format
msgid "Reading affix file %s ..."
msgstr "affix ファイル %s を読込中..."
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
msgid "Conversion failure for word in %s line %d: %s"
msgstr "%s (%d 行目) ã®å˜èªžã‚’変æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s"
-#: ../spell.c:4630 ../spell.c:6170
#, c-format
msgid "Conversion in %s not supported: from %s to %s"
msgstr "%s å†…ã®æ¬¡ã®å¤‰æ›ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“: %s ã‹ã‚‰ %s ã¸"
-#: ../spell.c:4642
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "%s 内ã®å¤‰æ›ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
+
#, c-format
msgid "Invalid value for FLAG in %s line %d: %s"
msgstr "%s 内㮠%d 行目㮠FLAG ã«ç„¡åйãªå€¤ãŒã‚りã¾ã™: %s"
-#: ../spell.c:4655
#, c-format
msgid "FLAG after using flags in %s line %d: %s"
msgstr "%s 内㮠%d 行目ã«ãƒ•ラグã®äºŒé‡ä½¿ç”¨ãŒã‚りã¾ã™: %s"
-#: ../spell.c:4723
#, c-format
msgid ""
"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
@@ -5360,7 +5118,6 @@ msgstr ""
"%s ã® %d 行目㮠PFX é …ç›®ã®å¾Œã® COMPOUNDFORBIDFLAG ã®å®šç¾©ã¯èª¤ã£ãŸçµæžœã‚’生ã˜ã‚‹"
"ã“ã¨ãŒã‚りã¾ã™"
-#: ../spell.c:4731
#, c-format
msgid ""
"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
@@ -5369,43 +5126,35 @@ msgstr ""
"%s ã® %d 行目㮠PFX é …ç›®ã®å¾Œã® COMPOUNDPERMITFLAG ã®å®šç¾©ã¯èª¤ã£ãŸçµæžœã‚’生ã˜ã‚‹"
"ã“ã¨ãŒã‚りã¾ã™"
-#: ../spell.c:4747
#, c-format
msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
msgstr "COMPOUNDRULES ã®å€¤ã«èª¤ã‚ŠãŒã‚りã¾ã™. ファイル %s ã® %d 行目: %s"
-#: ../spell.c:4771
#, c-format
msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
msgstr "%s ã® %d 行目㮠COMPOUNDWORDMAX ã®å€¤ã«èª¤ã‚ŠãŒã‚りã¾ã™: %s"
-#: ../spell.c:4777
#, c-format
msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
msgstr "%s ã® %d 行目㮠COMPOUNDMIN ã®å€¤ã«èª¤ã‚ŠãŒã‚りã¾ã™: %s"
-#: ../spell.c:4783
#, c-format
msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
msgstr "%s ã® %d 行目㮠COMPOUNDSYLMAX ã®å€¤ã«èª¤ã‚ŠãŒã‚りã¾ã™: %s"
-#: ../spell.c:4795
#, c-format
msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
msgstr "%s ã® %d 行目㮠CHECKCOMPOUNDPATTERN ã®å€¤ã«èª¤ã‚ŠãŒã‚りã¾ã™: %s"
-#: ../spell.c:4847
#, c-format
msgid "Different combining flag in continued affix block in %s line %d: %s"
msgstr ""
"%s ã® %d 行目㮠連続 affix ブロックã®ãƒ•ラグã®çµ„åˆã›ã«é•ã„ãŒã‚りã¾ã™: %s"
-#: ../spell.c:4850
#, c-format
msgid "Duplicate affix in %s line %d: %s"
msgstr "%s ã® %d 行目㫠é‡è¤‡ã—㟠affix を検出ã—ã¾ã—ãŸ: %s"
-#: ../spell.c:4871
#, c-format
msgid ""
"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
@@ -5414,308 +5163,206 @@ msgstr ""
"%s 㮠%d 行目㮠affix 㯠BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST "
"ã«ä½¿ç”¨ã—ã¦ãã ã•ã„: %s"
-#: ../spell.c:4893
#, c-format
msgid "Expected Y or N in %s line %d: %s"
msgstr "%s ã® %d 行目ã§ã¯ Y ã‹ N ãŒå¿…è¦ã§ã™: %s"
-#: ../spell.c:4968
#, c-format
msgid "Broken condition in %s line %d: %s"
msgstr "%s ã® %d 行目㮠æ¡ä»¶ã¯å£Šã‚Œã¦ã„ã¾ã™: %s"
-#: ../spell.c:5091
#, c-format
msgid "Expected REP(SAL) count in %s line %d"
msgstr "%s ã® %d 行目ã«ã¯ REP(SAL) ã®å›žæ•°ãŒå¿…è¦ã§ã™"
-#: ../spell.c:5120
#, c-format
msgid "Expected MAP count in %s line %d"
msgstr "%s ã® %d 行目ã«ã¯ MAP ã®å›žæ•°ãŒå¿…è¦ã§ã™"
-#: ../spell.c:5132
#, c-format
msgid "Duplicate character in MAP in %s line %d"
msgstr "%s ã® %d 行目㮠MAP ã«é‡è¤‡ã—ãŸæ–‡å­—ãŒã‚りã¾ã™"
-#: ../spell.c:5176
#, c-format
msgid "Unrecognized or duplicate item in %s line %d: %s"
msgstr "%s ã® %d 行目㫠èªè­˜ã§ããªã„ã‹é‡è¤‡ã—ãŸé …ç›®ãŒã‚りã¾ã™: %s"
-#: ../spell.c:5197
#, c-format
msgid "Missing FOL/LOW/UPP line in %s"
msgstr "%s 行目㫠FOL/LOW/UPP ãŒã‚りã¾ã›ã‚“"
-#: ../spell.c:5220
msgid "COMPOUNDSYLMAX used without SYLLABLE"
msgstr "SYLLABLE ãŒæŒ‡å®šã•れãªã„ COMPOUNDSYLMAX"
-#: ../spell.c:5236
msgid "Too many postponed prefixes"
msgstr "é…延後置å­ãŒå¤šéŽãŽã¾ã™"
-#: ../spell.c:5238
msgid "Too many compound flags"
msgstr "複åˆãƒ•ラグãŒå¤šéŽãŽã¾ã™"
-#: ../spell.c:5240
msgid "Too many postponed prefixes and/or compound flags"
msgstr "é…å»¶å¾Œç½®å­ ã¨/ã‚‚ã—ã㯠複åˆãƒ•ラグãŒå¤šéŽãŽã¾ã™"
-#: ../spell.c:5250
#, c-format
msgid "Missing SOFO%s line in %s"
msgstr "SOFO%s 行㌠%s ã«ã‚りã¾ã›ã‚“"
-#: ../spell.c:5253
#, c-format
msgid "Both SAL and SOFO lines in %s"
msgstr "SAL行 㨠SOFO行 ㌠%s ã§ä¸¡æ–¹æŒ‡å®šã•れã¦ã„ã¾ã™"
-#: ../spell.c:5331
#, c-format
msgid "Flag is not a number in %s line %d: %s"
msgstr "%s ã® %d è¡Œã® ãƒ•ãƒ©ã‚°ãŒæ•°å€¤ã§ã¯ã‚りã¾ã›ã‚“: %s"
-#: ../spell.c:5334
#, c-format
msgid "Illegal flag in %s line %d: %s"
msgstr "%s ã® %d 行目㮠フラグãŒä¸æ­£ã§ã™: %s"
-#: ../spell.c:5493 ../spell.c:5501
#, c-format
msgid "%s value differs from what is used in another .aff file"
msgstr "値 %s ã¯ä»–ã® .aff ファイルã§ä½¿ç”¨ã•れãŸã®ã¨ç•°ãªã‚Šã¾ã™"
-#: ../spell.c:5602
#, c-format
msgid "Reading dictionary file %s ..."
msgstr "辞書ファイル %s をスキャン中..."
-#: ../spell.c:5611
#, c-format
msgid "E760: No word count in %s"
msgstr "E760: %s ã«ã¯å˜èªžæ•°ãŒã‚りã¾ã›ã‚“"
-#: ../spell.c:5669
#, c-format
msgid "line %6d, word %6d - %s"
msgstr "行 %6d, å˜èªž %6d - %s"
-#: ../spell.c:5691
#, c-format
msgid "Duplicate word in %s line %d: %s"
msgstr "%s ã® %d 行目㧠é‡è¤‡å˜èªžãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ: %s"
-#: ../spell.c:5694
#, c-format
msgid "First duplicate word in %s line %d: %s"
msgstr "é‡è¤‡ã®ã†ã¡æœ€åˆã®å˜èªžã¯ %s ã® %d 行目ã§ã™: %s"
-#: ../spell.c:5746
#, c-format
msgid "%d duplicate word(s) in %s"
msgstr "%d 個ã®å˜èªžãŒè¦‹ã¤ã‹ã‚Šã¾ã—㟠(%s 内)"
-#: ../spell.c:5748
#, c-format
msgid "Ignored %d word(s) with non-ASCII characters in %s"
msgstr "éžASCII文字をå«ã‚€ %d 個ã®å˜èªžã‚’無視ã—ã¾ã—㟠(%s 内)"
-#: ../spell.c:6115
#, c-format
msgid "Reading word file %s ..."
msgstr "標準入力ã‹ã‚‰èª­è¾¼ã¿ä¸­ %s ..."
-#: ../spell.c:6155
#, c-format
msgid "Duplicate /encoding= line ignored in %s line %d: %s"
msgstr "%s ã® %d 行目㮠é‡è¤‡ã—㟠/encoding= 行を無視ã—ã¾ã—ãŸ: %s"
-#: ../spell.c:6159
#, c-format
msgid "/encoding= line after word ignored in %s line %d: %s"
msgstr "%s ã® %d 行目㮠å˜èªžã®å¾Œã® /encoding= 行を無視ã—ã¾ã—ãŸ: %s"
-#: ../spell.c:6180
#, c-format
msgid "Duplicate /regions= line ignored in %s line %d: %s"
msgstr "%s ã® %d 行目㮠é‡è¤‡ã—㟠/regions= 行を無視ã—ã¾ã—ãŸ: %s"
-#: ../spell.c:6185
#, c-format
msgid "Too many regions in %s line %d: %s"
msgstr "%s ã® %d 行目, 範囲指定ãŒå¤šéŽãŽã¾ã™: %s"
-#: ../spell.c:6198
#, c-format
msgid "/ line ignored in %s line %d: %s"
msgstr "%s ã® %d 行目㮠é‡è¤‡ã—㟠/ 行を無視ã—ã¾ã—ãŸ: %s"
-#: ../spell.c:6224
#, c-format
msgid "Invalid region nr in %s line %d: %s"
msgstr "%s ã® %d 行目 無効㪠nr 領域ã§ã™: %s"
-#: ../spell.c:6230
#, c-format
msgid "Unrecognized flags in %s line %d: %s"
msgstr "%s ã® %d 行目 èªè­˜ä¸èƒ½ãªãƒ•ラグã§ã™: %s"
-#: ../spell.c:6257
#, c-format
msgid "Ignored %d words with non-ASCII characters"
msgstr "éžASCII文字をå«ã‚€ %d 個ã®å˜èªžã‚’無視ã—ã¾ã—ãŸ"
-#: ../spell.c:6656
+msgid "E845: Insufficient memory, word list will be incomplete"
+msgstr "E845: メモリãŒè¶³ã‚Šãªã„ã®ã§ã€å˜èªžãƒªã‚¹ãƒˆã¯ä¸å®Œå…¨ã§ã™"
+
#, c-format
msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
msgstr "ノード %d 個(å…¨ %d 個中) を圧縮ã—ã¾ã—ãŸ; 残り %d (%d%%)"
-#: ../spell.c:7340
msgid "Reading back spell file..."
msgstr "スペルファイルを逆読込中"
-#. Go through the trie of good words, soundfold each word and add it to
-#. the soundfold trie.
-#: ../spell.c:7357
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
msgid "Performing soundfolding..."
msgstr "音声畳込ã¿ã‚’実行中..."
-#: ../spell.c:7368
#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "音声畳込ã¿å¾Œã®ç·å˜èªžæ•°: %<PRId64>"
+msgid "Number of words after soundfolding: %ld"
+msgstr "音声畳込ã¿å¾Œã®ç·å˜èªžæ•°: %ld"
-#: ../spell.c:7476
#, c-format
msgid "Total number of words: %d"
msgstr "ç·å˜èªžæ•°: %d"
-#: ../spell.c:7655
#, c-format
msgid "Writing suggestion file %s ..."
msgstr "修正候補ファイル \"%s\" を書込ã¿ä¸­..."
-#: ../spell.c:7707 ../spell.c:7927
#, c-format
msgid "Estimated runtime memory use: %d bytes"
msgstr "推定メモリ使用é‡: %d ãƒã‚¤ãƒˆ"
-#: ../spell.c:7820
msgid "E751: Output file name must not have region name"
msgstr "E751: 出力ファイルåã«ã¯ç¯„囲åã‚’å«ã‚られã¾ã›ã‚“"
-#: ../spell.c:7822
msgid "E754: Only up to 8 regions supported"
msgstr "E754: 範囲㯠8 個ã¾ã§ã—ã‹ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
-#: ../spell.c:7846
#, c-format
msgid "E755: Invalid region in %s"
msgstr "E755: 無効ãªç¯„囲ã§ã™: %s"
-#: ../spell.c:7907
msgid "Warning: both compounding and NOBREAK specified"
msgstr "警告: 複åˆãƒ•ラグ㨠NOBREAK ãŒä¸¡æ–¹ã¨ã‚‚指定ã•れã¾ã—ãŸ"
-#: ../spell.c:7920
#, c-format
msgid "Writing spell file %s ..."
msgstr "スペルファイル %s を書込ã¿ä¸­..."
-#: ../spell.c:7925
msgid "Done!"
msgstr "実行ã—ã¾ã—ãŸ!"
-#: ../spell.c:8034
#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: 'spellfile' ã«ã¯ %<PRId64> 個ã®ã‚¨ãƒ³ãƒˆãƒªã¯ã‚りã¾ã›ã‚“"
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' ã«ã¯ %ld 個ã®ã‚¨ãƒ³ãƒˆãƒªã¯ã‚りã¾ã›ã‚“"
-#: ../spell.c:8074
#, c-format
msgid "Word '%.*s' removed from %s"
msgstr "å˜èªž '%.*s' ㌠%s ã‹ã‚‰å‰Šé™¤ã•れã¾ã—ãŸ"
-#: ../spell.c:8117
#, c-format
msgid "Word '%.*s' added to %s"
msgstr "å˜èªž '%.*s' ㌠%s ã¸è¿½åŠ ã•れã¾ã—ãŸ"
-#: ../spell.c:8381
msgid "E763: Word characters differ between spell files"
msgstr "E763: å˜èªžã®æ–‡å­—ãŒã‚¹ãƒšãƒ«ãƒ•ァイルã¨ç•°ãªã‚Šã¾ã™"
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "残念ã§ã™ãŒ, 修正候補ã¯ã‚りã¾ã›ã‚“"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "残念ã§ã™ãŒ, 修正候補㯠%<PRId64> 個ã—ã‹ã‚りã¾ã›ã‚“"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "\"%.*s\" を次ã¸å¤‰æ›:"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < \"%.*s\""
-
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: スペル置æ›ãŒã¾ã å®Ÿè¡Œã•れã¦ã„ã¾ã›ã‚“"
-
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: 見ã¤ã‹ã‚Šã¾ã›ã‚“: %s"
-
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: .sug ファイルã§ã¯ãªã„よã†ã§ã™: %s"
-
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: å¤ã„ .sug ファイルãªã®ã§, アップデートã—ã¦ãã ã•ã„: %s"
-
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: より新ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® Vim 用㮠.sug ファイルã§ã™: %s"
-
-#: ../spell.c:9295
-#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr "E781: .sug ファイル㌠.spl ファイルã¨ä¸€è‡´ã—ã¾ã›ã‚“: %s"
-
-#: ../spell.c:9305
-#, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E782: .sug ファイルã®èª­è¾¼ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s"
-
#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
+#. * file.
msgid "E783: duplicate char in MAP entry"
msgstr "E783: MAP エントリã«é‡è¤‡æ–‡å­—ãŒå­˜åœ¨ã—ã¾ã™"
-#: ../syntax.c:266
msgid "No Syntax items defined for this buffer"
msgstr "ã“ã®ãƒãƒƒãƒ•ã‚¡ã«å®šç¾©ã•ã‚ŒãŸæ§‹æ–‡è¦ç´ ã¯ã‚りã¾ã›ã‚“"
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
#, c-format
msgid "E390: Illegal argument: %s"
msgstr "E390: 䏿­£ãªå¼•æ•°ã§ã™: %s"
@@ -5723,28 +5370,22 @@ msgstr "E390: 䏿­£ãªå¼•æ•°ã§ã™: %s"
msgid "syntax iskeyword "
msgstr "シンタックス用 iskeyword "
-#: ../syntax.c:3299
#, c-format
msgid "E391: No such syntax cluster: %s"
msgstr "E391: ãã®ã‚ˆã†ãªæ§‹æ–‡ã‚¯ãƒ©ã‚¹ã‚¿ã¯ã‚りã¾ã›ã‚“: %s"
-#: ../syntax.c:3433
msgid "syncing on C-style comments"
msgstr "C言語風コメントã‹ã‚‰åŒæœŸä¸­"
-#: ../syntax.c:3439
msgid "no syncing"
msgstr "éžåŒæœŸ"
-#: ../syntax.c:3441
msgid "syncing starts "
msgstr "åŒæœŸé–‹å§‹ "
-#: ../syntax.c:3443 ../syntax.c:3506
msgid " lines before top line"
msgstr " 行å‰(トップ行よりも)"
-#: ../syntax.c:3448
msgid ""
"\n"
"--- Syntax sync items ---"
@@ -5752,7 +5393,6 @@ msgstr ""
"\n"
"--- æ§‹æ–‡åŒæœŸè¦ç´  ---"
-#: ../syntax.c:3452
msgid ""
"\n"
"syncing on items"
@@ -5760,7 +5400,6 @@ msgstr ""
"\n"
"è¦ç´ ä¸Šã§åŒæœŸä¸­"
-#: ../syntax.c:3457
msgid ""
"\n"
"--- Syntax items ---"
@@ -5768,53 +5407,41 @@ msgstr ""
"\n"
"--- æ§‹æ–‡è¦ç´  ---"
-#: ../syntax.c:3475
#, c-format
msgid "E392: No such syntax cluster: %s"
msgstr "E392: ãã®ã‚ˆã†ãªæ§‹æ–‡ã‚¯ãƒ©ã‚¹ã‚¿ã¯ã‚りã¾ã›ã‚“: %s"
-#: ../syntax.c:3497
msgid "minimal "
msgstr "minimal "
-#: ../syntax.c:3503
msgid "maximal "
msgstr "maximal "
-#: ../syntax.c:3513
msgid "; match "
msgstr "; 該当 "
-#: ../syntax.c:3515
msgid " line breaks"
msgstr " å€‹ã®æ”¹è¡Œ"
-#: ../syntax.c:4076
msgid "E395: contains argument not accepted here"
msgstr "E395: ã“ã®å ´æ‰€ã§ã¯å¼•æ•°containsã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
-#: ../syntax.c:4096
msgid "E844: invalid cchar value"
msgstr "E844: 無効ãªccharã®å€¤ã§ã™"
-#: ../syntax.c:4107
msgid "E393: group[t]here not accepted here"
msgstr "E393: ã“ã“ã§ã¯ã‚°ãƒ«ãƒ¼ãƒ—ã¯è¨±å¯ã•れã¾ã›ã‚“"
-#: ../syntax.c:4126
#, c-format
msgid "E394: Didn't find region item for %s"
msgstr "E394: %s ã®ç¯„囲è¦ç´ ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../syntax.c:4188
msgid "E397: Filename required"
msgstr "E397: ファイルåãŒå¿…è¦ã§ã™"
-#: ../syntax.c:4221
msgid "E847: Too many syntax includes"
msgstr "E847: æ§‹æ–‡ã®å–り込ã¿(include)ãŒå¤šéŽãŽã¾ã™"
-#: ../syntax.c:4303
#, c-format
msgid "E789: Missing ']': %s"
msgstr "E789: ']' ãŒã‚りã¾ã›ã‚“: %s"
@@ -5823,221 +5450,173 @@ msgstr "E789: ']' ãŒã‚りã¾ã›ã‚“: %s"
msgid "E890: trailing char after ']': %s]%s"
msgstr "E890: ']' ã®å¾Œã‚ã«ä½™åˆ†ãªæ–‡å­—ãŒã‚りã¾ã™: %s]%s"
-#: ../syntax.c:4531
#, c-format
msgid "E398: Missing '=': %s"
msgstr "E398: '=' ãŒã‚りã¾ã›ã‚“: %s"
-#: ../syntax.c:4666
#, c-format
msgid "E399: Not enough arguments: syntax region %s"
msgstr "E399: 引数ãŒè¶³ã‚Šã¾ã›ã‚“: 構文範囲 %s"
-#: ../syntax.c:4870
msgid "E848: Too many syntax clusters"
msgstr "E848: 構文クラスタãŒå¤šéŽãŽã¾ã™"
-#: ../syntax.c:4954
msgid "E400: No cluster specified"
msgstr "E400: ã‚¯ãƒ©ã‚¹ã‚¿ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“"
-#. end delimiter not found
-#: ../syntax.c:4986
#, c-format
msgid "E401: Pattern delimiter not found: %s"
msgstr "E401: パターン区切りãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %s"
-#: ../syntax.c:5049
#, c-format
msgid "E402: Garbage after pattern: %s"
msgstr "E402: パターンã®ã‚ã¨ã«ã‚´ãƒŸãŒã‚りã¾ã™: %s"
-#: ../syntax.c:5120
msgid "E403: syntax sync: line continuations pattern specified twice"
msgstr "E403: æ§‹æ–‡åŒæœŸ: 連続行パターンãŒ2度指定ã•れã¾ã—ãŸ"
-#: ../syntax.c:5169
#, c-format
msgid "E404: Illegal arguments: %s"
msgstr "E404: 䏿­£ãªå¼•æ•°ã§ã™: %s"
-#: ../syntax.c:5217
#, c-format
msgid "E405: Missing equal sign: %s"
msgstr "E405: ç­‰å·ãŒã‚りã¾ã›ã‚“: %s"
-#: ../syntax.c:5222
#, c-format
msgid "E406: Empty argument: %s"
msgstr "E406: 空ã®å¼•æ•°: %s"
-#: ../syntax.c:5240
#, c-format
msgid "E407: %s not allowed here"
msgstr "E407: %s ã¯ã‚³ã‚³ã§ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
-#: ../syntax.c:5246
#, c-format
msgid "E408: %s must be first in contains list"
msgstr "E408: %s ã¯å†…容リストã®å…ˆé ­ã§ãªã‘れã°ãªã‚‰ãªã„"
-#: ../syntax.c:5304
#, c-format
msgid "E409: Unknown group name: %s"
msgstr "E409: 未知ã®ã‚°ãƒ«ãƒ¼ãƒ—å: %s"
-#: ../syntax.c:5512
#, c-format
msgid "E410: Invalid :syntax subcommand: %s"
msgstr "E410: 無効㪠:syntax ã®ã‚µãƒ–コマンド: %s"
-#: ../syntax.c:5854
msgid ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
msgstr ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
-#: ../syntax.c:6146
msgid "E679: recursive loop loading syncolor.vim"
msgstr "E679: syncolor.vim ã®å†å¸°å‘¼ã³å‡ºã—を検出ã—ã¾ã—ãŸ"
-#: ../syntax.c:6256
#, c-format
msgid "E411: highlight group not found: %s"
msgstr "E411: ãƒã‚¤ãƒ©ã‚¤ãƒˆã‚°ãƒ«ãƒ¼ãƒ—ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %s"
-#: ../syntax.c:6278
#, c-format
msgid "E412: Not enough arguments: \":highlight link %s\""
msgstr "E412: 引数ãŒå……分ã§ã¯ãªã„: \":highlight link %s\""
-#: ../syntax.c:6284
#, c-format
msgid "E413: Too many arguments: \":highlight link %s\""
msgstr "E413: 引数ãŒå¤šéŽãŽã¾ã™: \":highlight link %s\""
-#: ../syntax.c:6302
msgid "E414: group has settings, highlight link ignored"
msgstr "E414: グループãŒè¨­å®šã•れã¦ã„ã‚‹ã®ã§ãƒã‚¤ãƒ©ã‚¤ãƒˆãƒªãƒ³ã‚¯ã¯ç„¡è¦–ã•れã¾ã™"
-#: ../syntax.c:6367
#, c-format
msgid "E415: unexpected equal sign: %s"
msgstr "E415: 予期ã›ã¬ç­‰å·ã§ã™: %s"
-#: ../syntax.c:6395
#, c-format
msgid "E416: missing equal sign: %s"
msgstr "E416: ç­‰å·ãŒã‚りã¾ã›ã‚“: %s"
-#: ../syntax.c:6418
#, c-format
msgid "E417: missing argument: %s"
msgstr "E417: 引数ãŒã‚りã¾ã›ã‚“: %s"
-#: ../syntax.c:6446
#, c-format
msgid "E418: Illegal value: %s"
msgstr "E418: 䏿­£ãªå€¤ã§ã™: %s"
-#: ../syntax.c:6496
msgid "E419: FG color unknown"
msgstr "E419: 未知ã®å‰æ™¯è‰²ã§ã™"
-#: ../syntax.c:6504
msgid "E420: BG color unknown"
msgstr "E420: 未知ã®èƒŒæ™¯è‰²ã§ã™"
-#: ../syntax.c:6564
#, c-format
msgid "E421: Color name or number not recognized: %s"
msgstr "E421: カラーåや番å·ã‚’èªè­˜ã§ãã¾ã›ã‚“: %s"
-#: ../syntax.c:6714
#, c-format
msgid "E422: terminal code too long: %s"
msgstr "E422: 終端コードãŒé•·éŽãŽã¾ã™: %s"
-#: ../syntax.c:6753
#, c-format
msgid "E423: Illegal argument: %s"
msgstr "E423: 䏿­£ãªå¼•æ•°ã§ã™: %s"
-#: ../syntax.c:6925
msgid "E424: Too many different highlighting attributes in use"
msgstr "E424: 多ãã®ç•°ãªã‚‹ãƒã‚¤ãƒ©ã‚¤ãƒˆå±žæ€§ãŒä½¿ã‚れéŽãŽã¦ã„ã¾ã™"
-#: ../syntax.c:7427
msgid "E669: Unprintable character in group name"
msgstr "E669: グループåã«å°åˆ·ä¸å¯èƒ½ãªæ–‡å­—ãŒã‚りã¾ã™"
-#: ../syntax.c:7434
msgid "W18: Invalid character in group name"
msgstr "W18: グループåã«ä¸æ­£ãªæ–‡å­—ãŒã‚りã¾ã™"
-#: ../syntax.c:7448
msgid "E849: Too many highlight and syntax groups"
msgstr "E849: ãƒã‚¤ãƒ©ã‚¤ãƒˆã¨æ§‹æ–‡ã‚°ãƒ«ãƒ¼ãƒ—ãŒå¤šéŽãŽã¾ã™"
-#: ../tag.c:104
msgid "E555: at bottom of tag stack"
msgstr "E555: ã‚¿ã‚°ã‚¹ã‚¿ãƒƒã‚¯ã®æœ«å°¾ã§ã™"
-#: ../tag.c:105
msgid "E556: at top of tag stack"
msgstr "E556: タグスタックã®å…ˆé ­ã§ã™"
-#: ../tag.c:380
msgid "E425: Cannot go before first matching tag"
msgstr "E425: 最åˆã®è©²å½“ã‚¿ã‚°ã‚’è¶…ãˆã¦æˆ»ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-#: ../tag.c:504
#, c-format
msgid "E426: tag not found: %s"
msgstr "E426: ã‚¿ã‚°ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %s"
-#: ../tag.c:528
msgid " # pri kind tag"
msgstr " # pri kind tag"
-#: ../tag.c:531
msgid "file\n"
msgstr "ファイル\n"
-#: ../tag.c:829
msgid "E427: There is only one matching tag"
msgstr "E427: 該当タグãŒ1ã¤ã ã‘ã—ã‹ã‚りã¾ã›ã‚“"
-#: ../tag.c:831
msgid "E428: Cannot go beyond last matching tag"
msgstr "E428: 最後ã«è©²å½“ã™ã‚‹ã‚¿ã‚°ã‚’è¶…ãˆã¦é€²ã‚€ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-#: ../tag.c:850
#, c-format
msgid "File \"%s\" does not exist"
msgstr "ファイル \"%s\" ãŒã‚りã¾ã›ã‚“"
#. Give an indication of the number of matching tags
-#: ../tag.c:859
#, c-format
msgid "tag %d of %d%s"
msgstr "ã‚¿ã‚° %d (å…¨%d%s)"
-#: ../tag.c:862
msgid " or more"
msgstr " ã‹ãれ以上"
-#: ../tag.c:864
msgid " Using tag with different case!"
msgstr " ã‚¿ã‚°ã‚’ç•°ãªã‚‹caseã§ä½¿ç”¨ã—ã¾ã™!"
-#: ../tag.c:909
#, c-format
msgid "E429: File \"%s\" does not exist"
msgstr "E429: ファイル \"%s\" ãŒã‚りã¾ã›ã‚“"
#. Highlight title
-#: ../tag.c:960
msgid ""
"\n"
" # TO tag FROM line in file/text"
@@ -6045,79 +5624,66 @@ msgstr ""
"\n"
" # TO タグ FROM 行 in file/text"
-#: ../tag.c:1303
#, c-format
msgid "Searching tags file %s"
msgstr "タグファイル %s を検索中"
-#: ../tag.c:1545
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: タグファイルã®ãƒ‘ス㌠%s ã«åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã—ãŸ\n"
+
msgid "Ignoring long line in tags file"
msgstr "タグファイル内ã®é•·ã„行を無視ã—ã¾ã™"
-#: ../tag.c:1915
#, c-format
msgid "E431: Format error in tags file \"%s\""
msgstr "E431: タグファイル \"%s\" ã®ãƒ•ォーマットã«ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã™"
-#: ../tag.c:1917
#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "ç›´å‰ã® %<PRId64> ãƒã‚¤ãƒˆ"
+msgid "Before byte %ld"
+msgstr "ç›´å‰ã® %ld ãƒã‚¤ãƒˆ"
-#: ../tag.c:1929
#, c-format
msgid "E432: Tags file not sorted: %s"
msgstr "E432: タグファイルãŒã‚½ãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“: %s"
#. never opened any tags file
-#: ../tag.c:1960
msgid "E433: No tags file"
msgstr "E433: タグファイルãŒã‚りã¾ã›ã‚“"
-#: ../tag.c:2536
msgid "E434: Can't find tag pattern"
msgstr "E434: タグパターンを見ã¤ã‘られã¾ã›ã‚“"
-#: ../tag.c:2544
msgid "E435: Couldn't find tag, just guessing!"
msgstr "E435: タグを見ã¤ã‘られãªã„ã®ã§å˜ã«æŽ¨æ¸¬ã—ã¾ã™!"
-#: ../tag.c:2797
#, c-format
msgid "Duplicate field name: %s"
msgstr "é‡è¤‡ã—ãŸãƒ•ィールドå: %s"
-#: ../term.c:1442
msgid "' not known. Available builtin terminals are:"
msgstr "' ã¯æœªçŸ¥ã§ã™. ç¾è¡Œã®çµ„ã¿è¾¼ã¿ç«¯æœ«ã¯æ¬¡ã®ã¨ãŠã‚Šã§ã™:"
-#: ../term.c:1463
msgid "defaulting to '"
msgstr "çœç•¥å€¤ã‚’次ã®ã‚ˆã†ã«è¨­å®šã—ã¾ã™ '"
-#: ../term.c:1731
msgid "E557: Cannot open termcap file"
msgstr "E557: termcapファイルを開ã‘ã¾ã›ã‚“"
-#: ../term.c:1735
msgid "E558: Terminal entry not found in terminfo"
msgstr "E558: terminfoã«ç«¯æœ«ã‚¨ãƒ³ãƒˆãƒªã‚’見ã¤ã‘られã¾ã›ã‚“"
-#: ../term.c:1737
msgid "E559: Terminal entry not found in termcap"
msgstr "E559: termcapã«ç«¯æœ«ã‚¨ãƒ³ãƒˆãƒªã‚’見ã¤ã‘られã¾ã›ã‚“"
-#: ../term.c:1878
#, c-format
msgid "E436: No \"%s\" entry in termcap"
msgstr "E436: termcapã« \"%s\" ã®ã‚¨ãƒ³ãƒˆãƒªãŒã‚りã¾ã›ã‚“"
-#: ../term.c:2249
msgid "E437: terminal capability \"cm\" required"
msgstr "E437: 端末㫠\"cm\" 機能ãŒå¿…è¦ã§ã™"
#. Highlight title
-#: ../term.c:4376
msgid ""
"\n"
"--- Terminal keys ---"
@@ -6125,168 +5691,347 @@ msgstr ""
"\n"
"--- 端末キー ---"
-#: ../ui.c:481
+msgid "Cannot open $VIMRUNTIME/rgb.txt"
+msgstr "$VIMRUNTIME/rgb.txtã‚’é–‹ã‘ã¾ã›ã‚“"
+
+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.
-#: ../undo.c:379
msgid "E881: Line count changed unexpectedly"
msgstr "E881: 予期ã›ãšè¡Œã‚«ã‚¦ãƒ³ãƒˆãŒå¤‰ã‚りã¾ã—ãŸ"
-#: ../undo.c:627
+#. 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"
-#: ../undo.c:717
#, c-format
msgid "E825: Corrupted undo file (%s): %s"
msgstr "E825: アンドゥファイルãŒå£Šã‚Œã¦ã„ã¾ã™ (%s): %s"
-#: ../undo.c:1039
msgid "Cannot write undo file in any directory in 'undodir'"
msgstr "'undodir'ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«ã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ァイルを書ãè¾¼ã‚ã¾ã›ã‚“"
-#: ../undo.c:1074
#, c-format
msgid "Will not overwrite with undo file, cannot read: %s"
msgstr "アンドゥファイルã¨ã—ã¦èª­ã¿è¾¼ã‚ãªã„ã®ã§ä¸Šæ›¸ãã—ã¾ã›ã‚“: %s"
-#: ../undo.c:1092
#, c-format
msgid "Will not overwrite, this is not an undo file: %s"
msgstr "アンドゥファイルã§ã¯ãªã„ã®ã§ä¸Šæ›¸ãã—ã¾ã›ã‚“: %s"
-#: ../undo.c:1108
msgid "Skipping undo file write, nothing to undo"
msgstr "対象ãŒãªã„ã®ã§ã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸ãè¾¼ã¿ã‚’スキップã—ã¾ã™"
-#: ../undo.c:1121
#, c-format
msgid "Writing undo file: %s"
msgstr "アンドゥファイル書ãè¾¼ã¿ä¸­: %s"
-#: ../undo.c:1213
#, c-format
msgid "E829: write error in undo file: %s"
msgstr "E829: ã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸ãè¾¼ã¿ã‚¨ãƒ©ãƒ¼ã§ã™: %s"
-#: ../undo.c:1280
#, c-format
msgid "Not reading undo file, owner differs: %s"
msgstr "オーナーãŒç•°ãªã‚‹ã®ã§ã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ァイルを読ã¿è¾¼ã¿ã¾ã›ã‚“: %s"
-#: ../undo.c:1292
#, c-format
msgid "Reading undo file: %s"
msgstr "アンドゥファイル読込中: %s"
-#: ../undo.c:1299
#, c-format
msgid "E822: Cannot open undo file for reading: %s"
msgstr "E822: アンドゥファイルを読込用ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“: %s"
-#: ../undo.c:1308
#, c-format
msgid "E823: Not an undo file: %s"
msgstr "E823: アンドゥファイルã§ã¯ã‚りã¾ã›ã‚“: %s"
-#: ../undo.c:1313
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: éžæš—å·åŒ–ãƒ•ã‚¡ã‚¤ãƒ«ãŒæš—å·åŒ–ã•れãŸã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ァイルを使ã£ã¦ã¾ã™: %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: æš—å·åŒ–ã•れãŸã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ァイルã®è§£èª­ã«å¤±æ•—ã—ã¾ã—ãŸ: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: ã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ã‚¡ã‚¤ãƒ«ãŒæš—å·åŒ–ã•れã¦ã„ã¾ã™: %s"
+
#, c-format
msgid "E824: Incompatible undo file: %s"
msgstr "E824: äº’æ›æ€§ã®ç„¡ã„アンドゥファイルã§ã™: %s"
-#: ../undo.c:1328
msgid "File contents changed, cannot use undo info"
msgstr "ファイルã®å†…容ãŒå¤‰ã‚ã£ã¦ã„ã‚‹ãŸã‚ã€ã‚¢ãƒ³ãƒ‰ã‚¥æƒ…報を利用ã§ãã¾ã›ã‚“"
-#: ../undo.c:1497
#, c-format
msgid "Finished reading undo file %s"
msgstr "アンドゥファイル %s ã®å–込を完了"
-#: ../undo.c:1586 ../undo.c:1812
msgid "Already at oldest change"
msgstr "æ—¢ã«ä¸€ç•ªå¤ã„変更ã§ã™"
-#: ../undo.c:1597 ../undo.c:1814
msgid "Already at newest change"
msgstr "æ—¢ã«ä¸€ç•ªæ–°ã—ã„変更ã§ã™"
-#: ../undo.c:1806
#, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E830: ã‚¢ãƒ³ãƒ‰ã‚¥ç•ªå· %<PRId64> ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+msgid "E830: Undo number %ld not found"
+msgstr "E830: ã‚¢ãƒ³ãƒ‰ã‚¥ç•ªå· %ld ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../undo.c:1979
msgid "E438: u_undo: line numbers wrong"
msgstr "E438: u_undo: 行番å·ãŒé–“é•ã£ã¦ã„ã¾ã™"
-#: ../undo.c:2183
msgid "more line"
msgstr "行 追加ã—ã¾ã—ãŸ"
-#: ../undo.c:2185
msgid "more lines"
msgstr "行 追加ã—ã¾ã—ãŸ"
-#: ../undo.c:2187
msgid "line less"
msgstr "行 削除ã—ã¾ã—ãŸ"
-#: ../undo.c:2189
msgid "fewer lines"
msgstr "行 削除ã—ã¾ã—ãŸ"
-#: ../undo.c:2193
msgid "change"
msgstr "箇所変更ã—ã¾ã—ãŸ"
-#: ../undo.c:2195
msgid "changes"
msgstr "箇所変更ã—ã¾ã—ãŸ"
-#: ../undo.c:2225
#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s; %s #%<PRId64> %s"
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
-#: ../undo.c:2228
msgid "before"
msgstr "剿–¹"
-#: ../undo.c:2228
msgid "after"
msgstr "後方"
-#: ../undo.c:2325
msgid "Nothing to undo"
msgstr "アンドゥ対象ãŒã‚りã¾ã›ã‚“"
-#: ../undo.c:2330
msgid "number changes when saved"
msgstr "通番 変更数 変更時期 ä¿å­˜æ¸ˆ"
-#: ../undo.c:2360
#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> 秒経éŽã—ã¦ã„ã¾ã™"
+msgid "%ld seconds ago"
+msgstr "%ld 秒経éŽã—ã¦ã„ã¾ã™"
-#: ../undo.c:2372
msgid "E790: undojoin is not allowed after undo"
msgstr "E790: undo ã®ç›´å¾Œã« undojoin ã¯ã§ãã¾ã›ã‚“"
-#: ../undo.c:2466
msgid "E439: undo list corrupt"
msgstr "E439: アンドゥリストãŒå£Šã‚Œã¦ã„ã¾ã™"
-#: ../undo.c:2495
msgid "E440: undo line missing"
msgstr "E440: アンドゥ行ãŒã‚りã¾ã›ã‚“"
-#: ../version.c:600
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: 関数 %s ã¯å®šç¾©æ¸ˆã§ã™, å†å®šç¾©ã™ã‚‹ã«ã¯ ! を追加ã—ã¦ãã ã•ã„"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: 辞書型内ã«ã‚¨ãƒ³ãƒˆãƒªãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™"
+
+msgid "E718: Funcref required"
+msgstr "E718: 関数å‚ç…§åž‹ãŒè¦æ±‚ã•れã¾ã™"
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: 未知ã®é–¢æ•°ã§ã™: %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: 䏿­£ãªå¼•æ•°ã§ã™: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: 引数åãŒé‡è¤‡ã—ã¦ã„ã¾ã™: %s"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: 関数ã®å¼•æ•°ãŒå¤šéŽãŽã¾ã™: %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: 関数ã®ç„¡åйãªå¼•æ•°ã§ã™: %s"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: 関数呼出ã®å…¥ã‚Œå­æ•°ãŒ 'maxfuncdepth' ã‚’è¶…ãˆã¾ã—ãŸ"
+
+#, c-format
+msgid "calling %s"
+msgstr "%s を実行中ã§ã™"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s ãŒä¸­æ–­ã•れã¾ã—ãŸ"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s ㌠#%ld ã‚’è¿”ã—ã¾ã—ãŸ"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s ㌠%s ã‚’è¿”ã—ã¾ã—ãŸ"
+
+msgid "E699: Too many arguments"
+msgstr "E699: 引数ãŒå¤šéŽãŽã¾ã™"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: 未知ã®é–¢æ•°ã§ã™: %s"
+
+#, c-format
+msgid "E933: Function was deleted: %s"
+msgstr "E933: 関数ã¯å‰Šé™¤ã•れã¾ã—ãŸ: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: 関数ã®å¼•æ•°ãŒè¶³ã‚Šã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: スクリプト以外ã§<SID>ãŒä½¿ã‚れã¾ã—ãŸ: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: 辞書用関数ãŒå‘¼ã°ã‚Œã¾ã—ãŸãŒè¾žæ›¸ãŒã‚りã¾ã›ã‚“: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: 関数åãŒè¦æ±‚ã•れã¾ã™"
+
+#, c-format
+msgid "E128: Function name must start with a capital or \"s:\": %s"
+msgstr "E128: 関数åã¯å¤§æ–‡å­—ã‹ \"s:\" ã§å§‹ã¾ã‚‰ãªã‘れã°ãªã‚Šã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E884: Function name cannot contain a colon: %s"
+msgstr "E884: 関数åã«ã¯ã‚³ãƒ­ãƒ³ã¯å«ã‚られã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: 未定義ã®é–¢æ•°ã§ã™: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: '(' ãŒã‚りã¾ã›ã‚“: %s"
+
+msgid "E862: Cannot use g: here"
+msgstr "E862: ã“ã“ã§ã¯ g: ã¯ä½¿ãˆã¾ã›ã‚“"
+
+#, c-format
+msgid "E932: Closure function should not be at top level: %s"
+msgstr "E932: クロージャー関数ã¯ãƒˆãƒƒãƒ—レベルã«è¨˜è¿°ã§ãã¾ã›ã‚“: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: :endfunction ãŒã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: 関数åãŒå¤‰æ•°åã¨è¡çªã—ã¾ã™: %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: 関数 %s ã‚’å†å®šç¾©ã§ãã¾ã›ã‚“: 使用中ã§ã™"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: 関数åãŒã‚¹ã‚¯ãƒªãƒ—トã®ãƒ•ァイルåã¨ä¸€è‡´ã—ã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: 関数 %s を削除ã§ãã¾ã›ã‚“: 使用中ã§ã™"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: 関数外㫠:return ãŒã‚りã¾ã—ãŸ"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: カッコ '(' ãŒã‚りã¾ã›ã‚“: %s"
+
+#. 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 " with OLE support"
+msgstr " with OLE サãƒãƒ¼ãƒˆ"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 64 ビット コンソール 版"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 32 ビット コンソール 版"
+
+msgid ""
+"\n"
+"MacOS 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: "
@@ -6294,7 +6039,6 @@ msgstr ""
"\n"
"é©ç”¨æ¸ˆãƒ‘ッãƒ: "
-#: ../version.c:627
msgid ""
"\n"
"Extra patches: "
@@ -6302,11 +6046,9 @@ msgstr ""
"\n"
"追加拡張パッãƒ: "
-#: ../version.c:639 ../version.c:864
msgid "Modified by "
msgstr "Modified by "
-#: ../version.c:646
msgid ""
"\n"
"Compiled "
@@ -6314,11 +6056,9 @@ msgstr ""
"\n"
"Compiled "
-#: ../version.c:649
msgid "by "
msgstr "by "
-#: ../version.c:660
msgid ""
"\n"
"Huge version "
@@ -6326,1886 +6066,926 @@ msgstr ""
"\n"
"Huge 版 "
-#: ../version.c:661
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Big 版 "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"通常 版 "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Small 版 "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Tiny 版 "
+
msgid "without GUI."
msgstr "without GUI."
-#: ../version.c:662
+msgid "with GTK3 GUI."
+msgstr "with GTK3 GUI."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "with GTK2-GNOME GUI."
+
+msgid "with GTK2 GUI."
+msgstr "with GTK2 GUI."
+
+msgid "with X11-Motif GUI."
+msgstr "with X11-Motif GUI."
+
+msgid "with X11-neXtaw GUI."
+msgstr "with X11-neXtaw GUI."
+
+msgid "with X11-Athena GUI."
+msgstr "with X11-Athena GUI."
+
+msgid "with Photon GUI."
+msgstr "with Photon GUI."
+
+msgid "with GUI."
+msgstr "with GUI."
+
+msgid "with Carbon GUI."
+msgstr "with Carbon GUI."
+
+msgid "with Cocoa GUI."
+msgstr "with Cocoa GUI."
+
+msgid "with (classic) GUI."
+msgstr "with (クラシック) GUI."
+
msgid " Features included (+) or not (-):\n"
msgstr " 機能ã®ä¸€è¦§ 有効(+)/無効(-)\n"
-#: ../version.c:667
msgid " system vimrc file: \""
msgstr " システム vimrc: \""
-#: ../version.c:672
msgid " user vimrc file: \""
msgstr " ユーザー vimrc: \""
-#: ../version.c:677
msgid " 2nd user vimrc file: \""
msgstr " 第2ユーザー vimrc: \""
-#: ../version.c:682
msgid " 3rd user vimrc file: \""
msgstr " 第3ユーザー vimrc: \""
-#: ../version.c:687
msgid " user exrc file: \""
msgstr " ユーザー exrc: \""
-#: ../version.c:692
msgid " 2nd user exrc file: \""
msgstr " 第2ユーザー exrc: \""
-#: ../version.c:699
+msgid " system gvimrc file: \""
+msgstr " システム gvimrc: \""
+
+msgid " user gvimrc file: \""
+msgstr " ユーザー gvimrc: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr " 第2ユーザー gvimrc: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr " 第3ユーザー gvimrc: \""
+
+msgid " defaults file: \""
+msgstr " デフォルトファイル: \""
+
+msgid " system menu file: \""
+msgstr " システムメニュー: \""
+
msgid " fall-back for $VIM: \""
msgstr " çœç•¥æ™‚ã® $VIM: \""
-#: ../version.c:705
msgid " f-b for $VIMRUNTIME: \""
msgstr "çœç•¥æ™‚ã® $VIMRUNTIME: \""
-#: ../version.c:709
msgid "Compilation: "
msgstr "コンパイル: "
-#: ../version.c:712
+msgid "Compiler: "
+msgstr "コンパイラ: "
+
msgid "Linking: "
msgstr "リンク: "
-#: ../version.c:717
msgid " DEBUG BUILD"
msgstr "デãƒãƒƒã‚°ãƒ“ルド"
-#: ../version.c:767
msgid "VIM - Vi IMproved"
msgstr "VIM - Vi IMproved"
-#: ../version.c:769
msgid "version "
msgstr "version "
-#: ../version.c:770
msgid "by Bram Moolenaar et al."
msgstr "by Bram Moolenaar ä»–."
-#: ../version.c:774
msgid "Vim is open source and freely distributable"
msgstr "Vim ã¯ã‚ªãƒ¼ãƒ—ンソースã§ã‚り自由ã«é…布å¯èƒ½ã§ã™"
-#: ../version.c:776
msgid "Help poor children in Uganda!"
msgstr "ã‚¦ã‚¬ãƒ³ãƒ€ã®æµã¾ã‚Œãªã„å­ä¾›ãŸã¡ã«æ´åŠ©ã‚’!"
-#: ../version.c:777
msgid "type :help iccf<Enter> for information "
msgstr "è©³ç´°ãªæƒ…報㯠:help iccf<Enter> "
-#: ../version.c:779
msgid "type :q<Enter> to exit "
msgstr "終了ã™ã‚‹ã«ã¯ :q<Enter> "
-#: ../version.c:780
msgid "type :help<Enter> or <F1> for on-line help"
msgstr "オンラインヘルプ㯠:help<Enter> ㋠<F1> "
-#: ../version.c:781
-msgid "type :help version7<Enter> for version info"
-msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報㯠:help version7<Enter> "
+msgid "type :help version8<Enter> for version info"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報㯠:help version8<Enter> "
-#: ../version.c:784
msgid "Running in Vi compatible mode"
msgstr "Vi互æ›ãƒ¢ãƒ¼ãƒ‰ã§å‹•作中"
-#: ../version.c:785
msgid "type :set nocp<Enter> for Vim defaults"
msgstr "Vim推奨値ã«ã™ã‚‹ã«ã¯ :set nocp<Enter> "
-#: ../version.c:786
msgid "type :help cp-default<Enter> for info on this"
msgstr "è©³ç´°ãªæƒ…報㯠:help cp-default<Enter>"
-#: ../version.c:827
+msgid "menu Help->Orphans for information "
+msgstr "詳細ã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã® ヘルプ->å­¤å… ã‚’å‚ç…§ã—ã¦ä¸‹ã•ã„ "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "モード無ã§å®Ÿè¡Œä¸­, タイプã—ãŸæ–‡å­—ãŒæŒ¿å…¥ã•れã¾ã™"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "メニュー㮠編集->全体設定->挿入(åˆå¿ƒè€…)モード切替 "
+
+msgid " for two modes "
+msgstr " ã§ãƒ¢ãƒ¼ãƒ‰æœ‰ã« "
+
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "メニュー㮠編集->全体設定->Vi互æ›ãƒ¢ãƒ¼ãƒ‰åˆ‡æ›¿ "
+
+msgid " for Vim defaults "
+msgstr " ã§Vimã¨ã—ã¦å‹•作 "
+
msgid "Sponsor Vim development!"
msgstr "Vimã®é–‹ç™ºã‚’応æ´ã—ã¦ãã ã•ã„!"
-#: ../version.c:828
msgid "Become a registered Vim user!"
msgstr "Vimã®ç™»éŒ²ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ãªã£ã¦ãã ã•ã„!"
-#: ../version.c:831
msgid "type :help sponsor<Enter> for information "
msgstr "è©³ç´°ãªæƒ…報㯠:help sponsor<Enter> "
-#: ../version.c:832
msgid "type :help register<Enter> for information "
msgstr "è©³ç´°ãªæƒ…報㯠:help register<Enter> "
-#: ../version.c:834
msgid "menu Help->Sponsor/Register for information "
msgstr "詳細ã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã® ヘルプ->スãƒãƒ³ã‚µãƒ¼/登録 ã‚’å‚ç…§ã—ã¦ä¸‹ã•ã„"
-#: ../window.c:119
+msgid "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ã¤ã—ã‹ã‚りã¾ã›ã‚“"
-#: ../window.c:224
msgid "E441: There is no preview window"
msgstr "E441: プレビューウィンドウãŒã‚りã¾ã›ã‚“"
-#: ../window.c:559
msgid "E442: Can't split topleft and botright at the same time"
msgstr "E442: 左上ã¨å³ä¸‹ã‚’åŒæ™‚ã«åˆ†å‰²ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-#: ../window.c:1228
msgid "E443: Cannot rotate when another window is split"
msgstr "E443: ä»–ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒåˆ†å‰²ã•れã¦ã„る時ã«ã¯é †å›žã§ãã¾ã›ã‚“"
-#: ../window.c:1803
msgid "E444: Cannot close last window"
msgstr "E444: 最後ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’é–‰ã˜ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-#: ../window.c:1810
msgid "E813: Cannot close autocmd window"
msgstr "E813: autocmdウィンドウã¯é–‰ã˜ã‚‰ã‚Œã¾ã›ã‚“"
-#: ../window.c:1814
msgid "E814: Cannot close window, only autocmd window would remain"
msgstr "E814: autocmdウィンドウã—ã‹æ®‹ã‚‰ãªã„ãŸã‚ã€ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã¯é–‰ã˜ã‚‰ã‚Œã¾ã›ã‚“"
-#: ../window.c:2717
msgid "E445: Other window contains changes"
msgstr "E445: ä»–ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã«ã¯å¤‰æ›´ãŒã‚りã¾ã™"
-#: ../window.c:4805
msgid "E446: No file name under cursor"
msgstr "E446: カーソルã®ä¸‹ã«ãƒ•ァイルåãŒã‚りã¾ã›ã‚“"
-msgid "List or number required"
-msgstr "ãƒªã‚¹ãƒˆã‹æ•°å€¤ãŒå¿…è¦ã§ã™"
-
-#~ msgid "E831: bf_key_init() called with empty password"
-#~ msgstr "E831: bf_key_init() ãŒç©ºãƒ‘スワードã§å‘¼ã³å‡ºã•れã¾ã—ãŸ"
-
-#~ msgid "E820: sizeof(uint32_t) != 4"
-#~ msgstr "E820: sizeof(uint32_t) != 4"
-
-#~ msgid "E817: Blowfish big/little endian use wrong"
-#~ msgstr "E817: Blowfishæš—å·ã®ãƒ“ッグ/リトルエンディアンãŒé–“é•ã£ã¦ã„ã¾ã™"
-
-#~ msgid "E818: sha256 test failed"
-#~ msgstr "E818: sha256ã®ãƒ†ã‚¹ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸ"
-
-#~ msgid "E819: Blowfish test failed"
-#~ msgstr "E819: Blowfishæš—å·ã®ãƒ†ã‚¹ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸ"
-
-#~ msgid "Patch file"
-#~ msgstr "パッãƒãƒ•ァイル"
-
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "決定(&O)\n"
-#~ "キャンセル(&C)"
-
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Vim サーãƒã¸ã®æŽ¥ç¶šãŒã‚りã¾ã›ã‚“"
-
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: %s ã¸é€ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: サーãƒã®å¿œç­”ãŒã‚りã¾ã›ã‚“"
-
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: クライアントã¸é€ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
-
-#~ msgid "Save As"
-#~ msgstr "別åã§ä¿å­˜"
-
-#~ msgid "Edit File"
-#~ msgstr "ファイルを編集"
-
-# Added at 27-Jan-2004.
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (見ã¤ã‹ã‚Šã¾ã›ã‚“)"
-
-#~ msgid "Source Vim script"
-#~ msgstr "Vimスクリプトã®å–è¾¼ã¿"
-
-#~ msgid "unknown"
-#~ msgstr "䏿˜Ž"
-
-#~ msgid "Edit File in new window"
-#~ msgstr "æ–°ã—ã„ウィンドウã§ãƒ•ァイルを編集ã—ã¾ã™"
-
-#~ msgid "Append File"
-#~ msgstr "追加ファイル"
-
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "ウィンドウä½ç½®: X %d, Y %d"
-
-#~ msgid "Save Redirection"
-#~ msgstr "リダイレクトをä¿å­˜ã—ã¾ã™"
-
-#~ msgid "Save View"
-#~ msgstr "ビューをä¿å­˜ã—ã¾ã™"
-
-#~ msgid "Save Session"
-#~ msgstr "セッション情報をä¿å­˜ã—ã¾ã™"
-
-#~ msgid "Save Setup"
-#~ msgstr "設定をä¿å­˜ã—ã¾ã™"
-
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: #< 㯠+eval 機能ãŒç„¡ã„ã¨åˆ©ç”¨ã§ãã¾ã›ã‚“"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«åˆå­—ã¯ã‚りã¾ã›ã‚“"
-
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr " ã¯ãƒ‡ãƒã‚¤ã‚¹ã§ã™ ('opendevice' オプションã§å›žé¿ã§ãã¾ã™)"
-
-#~ msgid "Reading from stdin..."
-#~ msgstr "標準入力ã‹ã‚‰èª­è¾¼ã¿ä¸­..."
-
-#~ msgid "[blowfish]"
-#~ msgstr "[blowfishæš—å·åŒ–]"
-
-#~ msgid "[crypted]"
-#~ msgstr "[æš—å·åŒ–]"
-
-#~ msgid "E821: File is encrypted with unknown method"
-#~ msgstr "E821: ãƒ•ã‚¡ã‚¤ãƒ«ãŒæœªçŸ¥ã®æ–¹æ³•ã§æš—å·åŒ–ã•れã¦ã„ã¾ã™"
-
-# Added at 19-Jan-2004.
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeansã¯æœªå¤‰æ›´ã®ãƒãƒƒãƒ•ァを上書ã™ã‚‹ã“ã¨ã¯è¨±å¯ã—ã¦ã„ã¾ã›ã‚“"
-
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "NetBeansãƒãƒƒãƒ•ã‚¡ã®ä¸€éƒ¨ã‚’書ã出ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "'opendevice' オプションã«ã‚ˆã‚Šãƒ‡ãƒã‚¤ã‚¹ã¸ã®æ›¸ãè¾¼ã¿ã¯ã§ãã¾ã›ã‚“"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: リソースフォークãŒå¤±ã‚れるã‹ã‚‚ã—れã¾ã›ã‚“ (! を追加ã§å¼·åˆ¶)"
-
-#~ msgid "E851: Failed to create a new process for the GUI"
-#~ msgstr "E851: GUI用ã®ãƒ—ロセスã®èµ·å‹•ã«å¤±æ•—ã—ã¾ã—ãŸ"
-
-#~ msgid "E852: The child process failed to start the GUI"
-#~ msgstr "E852: å­ãƒ—ロセスãŒGUIã®èµ·å‹•ã«å¤±æ•—ã—ã¾ã—ãŸ"
-
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: GUIã‚’é–‹å§‹ã§ãã¾ã›ã‚“"
-
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: \"%s\"ã‹ã‚‰èª­è¾¼ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“"
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr "E665: 有効ãªãƒ•ォントãŒè¦‹ã¤ã‹ã‚‰ãªã„ã®ã§, GUIã‚’é–‹å§‹ã§ãã¾ã›ã‚“"
-
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: 'guifontwide' ãŒç„¡åйã§ã™"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: 'imactivatekey' ã«è¨­å®šã•れãŸå€¤ãŒç„¡åйã§ã™"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: %s ã®è‰²ã‚’割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“"
-
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "カーソルã®ä½ç½®ã«ãƒžãƒƒãƒã¯ã‚りã¾ã›ã‚“, 次を検索ã—ã¦ã„ã¾ã™"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<é–‹ã‘ã¾ã›ã‚“> "
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: フォント %s ã‚’å–å¾—ã§ãã¾ã›ã‚“"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æˆ»ã‚Œã¾ã›ã‚“"
-
-#~ msgid "Pathname:"
-#~ msgstr "パスå:"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’å–å¾—ã§ãã¾ã›ã‚“"
-
-#~ msgid "OK"
-#~ msgstr "OK"
-
-#~ msgid "Cancel"
-#~ msgstr "キャンセル"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr "スクロールãƒãƒ¼: ç”»åƒã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ."
-
-#~ msgid "Vim dialog"
-#~ msgstr "Vim ダイアログ"
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: メッセージã¨ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã®ã‚ã‚‹ BalloonEval を作æˆã§ãã¾ã›ã‚“"
-
-#~ msgid "Input _Methods"
-#~ msgstr "インプットメソッド"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - 検索ã¨ç½®æ›..."
-
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - 検索..."
-
-#~ msgid "Find what:"
-#~ msgstr "検索文字列:"
-
-#~ msgid "Replace with:"
-#~ msgstr "ç½®æ›æ–‡å­—列:"
-
-#~ msgid "Match whole word only"
-#~ msgstr "正確ã«è©²å½“ã™ã‚‹ã‚‚ã®ã ã‘"
-
-#~ msgid "Match case"
-#~ msgstr "大文字/å°æ–‡å­—を区別ã™ã‚‹"
-
-#~ msgid "Direction"
-#~ msgstr "æ–¹å‘"
-
-#~ msgid "Up"
-#~ msgstr "上"
-
-#~ msgid "Down"
-#~ msgstr "下"
-
-#~ msgid "Find Next"
-#~ msgstr "次を検索"
-
-#~ msgid "Replace"
-#~ msgstr "ç½®æ›"
-
-#~ msgid "Replace All"
-#~ msgstr "å…¨ã¦ç½®æ›"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: セッションマãƒãƒ¼ã‚¸ãƒ£ã‹ã‚‰ \"die\" è¦æ±‚ã‚’å—ã‘å–りã¾ã—ãŸ\n"
-
-#~ msgid "Close"
-#~ msgstr "é–‰ã˜ã‚‹"
-
-#~ msgid "New tab"
-#~ msgstr "æ–°è¦ã‚¿ãƒ–ページ"
-
-#~ msgid "Open Tab..."
-#~ msgstr "タブページを開ã..."
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: メインウィンドウãŒä¸æ„ã«ç ´å£Šã•れã¾ã—ãŸ\n"
-
-#~ msgid "&Filter"
-#~ msgstr "フィルタ(&F)"
-
-#~ msgid "&Cancel"
-#~ msgstr "キャンセル(&C)"
-
-#~ msgid "Directories"
-#~ msgstr "ディレクトリ"
-
-#~ msgid "Filter"
-#~ msgstr "フィルタ"
-
-#~ msgid "&Help"
-#~ msgstr "ヘルプ(&H)"
-
-#~ msgid "Files"
-#~ msgstr "ファイル"
-
-#~ msgid "&OK"
-#~ msgstr "&OK"
-
-#~ msgid "Selection"
-#~ msgstr "é¸æŠž"
-
-#~ msgid "Find &Next"
-#~ msgstr "次を検索(&N)"
-
-#~ msgid "&Replace"
-#~ msgstr "ç½®æ›(&R)"
-
-#~ msgid "Replace &All"
-#~ msgstr "å…¨ã¦ç½®æ›(&A)"
-
-#~ msgid "&Undo"
-#~ msgstr "アンドゥ(&U)"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: タイトル㌠\"%s\" ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: 引数ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“: \"-%s\"; OLE版を使用ã—ã¦ãã ã•ã„."
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: MDIアプリã®ä¸­ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’é–‹ã‘ã¾ã›ã‚“"
-
-#~ msgid "Close tab"
-#~ msgstr "タブページを閉ã˜ã‚‹"
-
-#~ msgid "Open tab..."
-#~ msgstr "タブページを開ã"
-
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "検索文字列 ('\\' を検索ã™ã‚‹ã«ã¯ '\\\\')"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "æ¤œç´¢ãƒ»ç½®æ› ('\\' を検索ã™ã‚‹ã«ã¯ '\\\\')"
-
-#~ msgid "Not Used"
-#~ msgstr "使ã‚れã¾ã›ã‚“"
-
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "ディレクトリ\t*.nothing\n"
-
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr "Vim E458: è‰²æŒ‡å®šãŒæ­£ã—ããªã„ã®ã§ã‚¨ãƒ³ãƒˆãƒªã‚’割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“"
-
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr "E250: ä»¥ä¸‹ã®æ–‡å­—セットã®ãƒ•ォントãŒã‚りã¾ã›ã‚“ %s:"
-
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: フォントセットå: %s"
-
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "フォント '%s' ã¯å›ºå®šå¹…ã§ã¯ã‚りã¾ã›ã‚“"
-
-#~ msgid "E253: Fontset name: %s"
-#~ msgstr "E253: フォントセットå: %s"
-
-#~ msgid "Font0: %s"
-#~ msgstr "フォント0: %s"
-
-#~ msgid "Font1: %s"
-#~ msgstr "フォント1: %s"
-
-#~ msgid "Font%<PRId64> width is not twice that of font0"
-#~ msgstr "フォント%<PRId64> ã®å¹…ãŒãƒ•ォント0ã®2å€ã§ã¯ã‚りã¾ã›ã‚“"
-
-#~ msgid "Font0 width: %<PRId64>"
-#~ msgstr "フォント0ã®å¹…: %<PRId64>"
-
-#~ msgid "Font1 width: %<PRId64>"
-#~ msgstr "フォント1ã®å¹…: %<PRId64>"
-
-#~ msgid "Invalid font specification"
-#~ msgstr "無効ãªãƒ•ォント指定ã§ã™"
-
-#~ msgid "&Dismiss"
-#~ msgstr "å´ä¸‹ã™ã‚‹(&D)"
-
-#~ msgid "no specific match"
-#~ msgstr "マッãƒã™ã‚‹ã‚‚ã®ãŒã‚りã¾ã›ã‚“"
-
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - ãƒ•ã‚©ãƒ³ãƒˆé¸æŠž"
-
-#~ msgid "Name:"
-#~ msgstr "åå‰:"
-
-#~ msgid "Show size in Points"
-#~ msgstr "サイズをãƒã‚¤ãƒ³ãƒˆã§è¡¨ç¤ºã™ã‚‹"
-
-#~ msgid "Encoding:"
-#~ msgstr "エンコード:"
-
-#~ msgid "Font:"
-#~ msgstr "フォント:"
-
-#~ msgid "Style:"
-#~ msgstr "スタイル:"
-
-#~ msgid "Size:"
-#~ msgstr "サイズ:"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: ãƒãƒ³ã‚°ãƒ«ã‚ªãƒ¼ãƒˆãƒžãƒˆãƒ³ã‚¨ãƒ©ãƒ¼"
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: stat エラー"
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: cscopeデータベース: %s ã‚’é–‹ãã“ã¨ãŒã§ãã¾ã›ã‚“"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: cscopeãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æƒ…報をå–å¾—ã§ãã¾ã›ã‚“"
-
-#~ msgid "Lua library cannot be loaded."
-#~ msgstr "Luaライブラリをロードã§ãã¾ã›ã‚“."
-
-#~ msgid "cannot save undo information"
-#~ msgstr "アンドゥ情報ãŒä¿å­˜ã§ãã¾ã›ã‚“"
-
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr ""
-#~ "E815: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™. MzScheme ライブラリをロードã§ãã¾ã›ã‚“."
-
-#~ msgid "invalid expression"
-#~ msgstr "無効ãªå¼ã§ã™"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "å¼ã¯ã‚³ãƒ³ãƒ‘イル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™"
-
-#~ msgid "hidden option"
-#~ msgstr "éš ã—オプション"
-
-#~ msgid "unknown option"
-#~ msgstr "未知ã®ã‚ªãƒ—ションã§ã™"
-
-#~ msgid "window index is out of range"
-#~ msgstr "範囲外ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ç•ªå·ã§ã™"
-
-#~ msgid "couldn't open buffer"
-#~ msgstr "ãƒãƒƒãƒ•ã‚¡ã‚’é–‹ã‘ã¾ã›ã‚“"
-
-#~ msgid "cannot delete line"
-#~ msgstr "行を消ã›ã¾ã›ã‚“"
-
-#~ msgid "cannot replace line"
-#~ msgstr "行を置æ›ã§ãã¾ã›ã‚“"
-
-#~ msgid "cannot insert line"
-#~ msgstr "行を挿入ã§ãã¾ã›ã‚“"
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "文字列ã«ã¯æ”¹è¡Œæ–‡å­—ã‚’å«ã‚られã¾ã›ã‚“"
-
-#~ msgid "error converting Scheme values to Vim"
-#~ msgstr "Scheme値ã®Vimã¸ã®å¤‰æ›ã‚¨ãƒ©ãƒ¼"
-
-#~ msgid "Vim error: ~a"
-#~ msgstr "Vim エラー: ~a"
-
-#~ msgid "Vim error"
-#~ msgstr "Vim エラー"
-
-#~ msgid "buffer is invalid"
-#~ msgstr "ãƒãƒƒãƒ•ã‚¡ã¯ç„¡åйã§ã™"
-
-#~ msgid "window is invalid"
-#~ msgstr "ウィンドウã¯ç„¡åйã§ã™"
-
-#~ msgid "linenr out of range"
-#~ msgstr "範囲外ã®è¡Œç•ªå·ã§ã™"
-
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "サンドボックスã§ã¯è¨±ã•れã¾ã›ã‚“"
-
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: ライブラリ %s をロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
-
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr ""
-#~ "ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™, ã”ã‚ã‚“ãªã•ã„: Perlライブラリをロードã§ãã¾ã›ã‚“ã§ã—"
-#~ "ãŸ."
-
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr ""
-#~ "E299: サンドボックスã§ã¯ Safe モジュールを使用ã—ãªã„Perlスクリプトã¯ç¦ã˜ã‚‰"
-#~ "れã¦ã„ã¾ã™"
-
-#~ msgid "E836: This Vim cannot execute :python after using :py3"
-#~ msgstr "E836: ã“ã®Vimã§ã¯ :py3 を使ã£ãŸå¾Œã« :python を使ãˆã¾ã›ã‚“"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E263: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™,ã”ã‚ã‚“ãªã•ã„: Pythonライブラリをロードã§ãã¾"
-#~ "ã›ã‚“ã§ã—ãŸ."
-
-# Added at 07-Feb-2004.
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Python ã‚’å†å¸°çš„ã«å®Ÿè¡Œã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-
-#~ msgid "E837: This Vim cannot execute :py3 after using :python"
-#~ msgstr "E837: ã“ã®Vimã§ã¯ :python を使ã£ãŸå¾Œã« :py3 を使ãˆã¾ã›ã‚“"
-
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: $_ ã¯æ–‡å­—列ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E266: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™,ã”ã‚ã‚“ãªã•ã„: Rubyライブラリをロードã§ãã¾ã›"
-#~ "ã‚“ã§ã—ãŸ."
-
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: 予期ã›ã¬ return ã§ã™"
-
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: 予期ã›ã¬ next ã§ã™"
-
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: 予期ã›ã¬ break ã§ã™"
-
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: 予期ã›ã¬ redo ã§ã™"
-
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: rescue ã®å¤–ã® retry ã§ã™"
-
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: å–り扱ã‚れãªã‹ã£ãŸä¾‹å¤–ãŒã‚りã¾ã™"
-
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: 未知ã®longjmp状態: %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "実装ã¨å®šç¾©ã‚’切り替ãˆã‚‹"
-
-#~ msgid "Show base class of"
-#~ msgstr "次ã®ã‚¯ãƒ©ã‚¹ã®åŸºåº•を表示"
-
-#~ msgid "Show overridden member function"
-#~ msgstr "オーãƒãƒ¼ãƒ©ã‚¤ãƒ‰ã•れãŸãƒ¡ãƒ³ãƒé–¢æ•°ã‚’表示"
-
-#~ msgid "Retrieve from file"
-#~ msgstr "ファイルã‹ã‚‰å›žå¾©ã™ã‚‹"
-
-#~ msgid "Retrieve from project"
-#~ msgstr "プロジェクトã‹ã‚‰å›žå¾©ã™ã‚‹"
-
-#~ msgid "Retrieve from all projects"
-#~ msgstr "å…¨ã¦ã®ãƒ—ロジェクトã‹ã‚‰å›žå¾©ã™ã‚‹"
-
-#~ msgid "Retrieve"
-#~ msgstr "回復"
-
-#~ msgid "Show source of"
-#~ msgstr "次ã®ã‚½ãƒ¼ã‚¹ã‚’表示ã™ã‚‹"
-
-#~ msgid "Find symbol"
-#~ msgstr "見ã¤ã‘ãŸã‚·ãƒ³ãƒœãƒ«"
-
-#~ msgid "Browse class"
-#~ msgstr "クラスをå‚ç…§"
-
-#~ msgid "Show class in hierarchy"
-#~ msgstr "階層ã§ã‚¯ãƒ©ã‚¹ã‚’表示"
-
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "é™å®šã•れãŸéšŽå±¤ã§ã‚¯ãƒ©ã‚¹ã‚’表示"
-
-#~ msgid "Xref refers to"
-#~ msgstr "Xref ã®å‚ç…§å…ˆ"
-
-#~ msgid "Xref referred by"
-#~ msgstr "Xref ãŒå‚ç…§ã•れる"
-
-#~ msgid "Xref has a"
-#~ msgstr "Xref ãŒæ¬¡ã®ã‚‚ã®ã‚’ã‚‚ã£ã¦ã„ã¾ã™"
-
-#~ msgid "Xref used by"
-#~ msgstr "Xref ãŒä½¿ç”¨ã•れる"
-
-#~ msgid "Show docu of"
-#~ msgstr "æ¬¡ã®æ–‡ç« ã‚’表示"
-
-#~ msgid "Generate docu for"
-#~ msgstr "æ¬¡ã®æ–‡ç« ã‚’生æˆ"
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "SNiFF+ã«æŽ¥ç¶šã§ãã¾ã›ã‚“. 環境をãƒã‚§ãƒƒã‚¯ã—ã¦ãã ã•ã„(sniffemacs ㌠$PATH ã«"
-#~ "ãªã‘れã°ãªã‚Šã¾ã›ã‚“).\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: 読込中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ. 切断ã—ã¾ã—ãŸ"
-
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "ç¾åœ¨SNiFF+ ã®çŠ¶æ…‹ã¯ã€Œ"
-
-#~ msgid "not "
-#~ msgstr "未"
-
-#~ msgid "connected"
-#~ msgstr "接続ã€ã§ã™"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: 未知㮠SNiFF+ リクエストã§ã™: %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: SNiFF+ ã¸ã®æŽ¥ç¶šä¸­ã®ã‚¨ãƒ©ãƒ¼ã§ã™"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SNiFF+ ã«æŽ¥ç¶šã•れã¦ã„ã¾ã›ã‚“"
-
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: SNiFF+ ãƒãƒƒãƒ•ã‚¡ãŒã‚りã¾ã›ã‚“"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: 書込ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ãŸã®ã§åˆ‡æ–­ã—ã¾ã—ãŸ"
-
-#~ msgid "invalid buffer number"
-#~ msgstr "無効ãªãƒãƒƒãƒ•ァ番å·ã§ã™"
-
-#~ msgid "not implemented yet"
-#~ msgstr "ã¾ã å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "行を設定ã§ãã¾ã›ã‚“"
-
-#~ msgid "invalid mark name"
-#~ msgstr "無効ãªãƒžãƒ¼ã‚¯åã§ã™"
-
-#~ msgid "mark not set"
-#~ msgstr "マークã¯è¨­å®šã•れã¦ã„ã¾ã›ã‚“"
-
-#~ msgid "row %d column %d"
-#~ msgstr "行 %d 列 %d"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "è¡Œã®æŒ¿å…¥/追加をã§ãã¾ã›ã‚“"
-
-#~ msgid "line number out of range"
-#~ msgstr "範囲外ã®è¡Œç•ªå·ã§ã™"
-
-#~ msgid "unknown flag: "
-#~ msgstr "未知ã®ãƒ•ラグ: "
-
-#~ msgid "unknown vimOption"
-#~ msgstr "未知㮠vimOption ã§ã™"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "キーボード割込ã¿"
-
-#~ msgid "vim error"
-#~ msgstr "vim エラー"
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr ""
-#~ "ãƒãƒƒãƒ•ã‚¡/ウィンドウ作æˆã‚³ãƒžãƒ³ãƒ‰ã‚’作æˆã§ãã¾ã›ã‚“: ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒæ¶ˆåŽ»ã•れã¦"
-#~ "ã„ã¾ã—ãŸ"
-
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr ""
-#~ "コールãƒãƒƒã‚¯ã‚³ãƒžãƒ³ãƒ‰ã‚’登録ã§ãã¾ã›ã‚“: ãƒãƒƒãƒ•ã‚¡/ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒæ—¢ã«æ¶ˆåŽ»ã•れã¾"
-#~ "ã—ãŸ"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr ""
-#~ "E280: TCL 致命的エラー: reflist 汚染!? vim-dev@vim.org ã«å ±å‘Šã—ã¦ãã ã•ã„"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr ""
-#~ "コールãƒãƒƒã‚¯ã‚³ãƒžãƒ³ãƒ‰ã‚’登録ã§ãã¾ã›ã‚“: ãƒãƒƒãƒ•ã‚¡/ウィンドウã®å‚ç…§ãŒè¦‹ã¤ã‹ã‚Š"
-#~ "ã¾ã›ã‚“"
-
-#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E571: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™,ã”ã‚ã‚“ãªã•ã„: Tclライブラリをロードã§ãã¾ã›ã‚“"
-#~ "ã§ã—ãŸ."
-
-#~ msgid "E572: exit code %d"
-#~ msgstr "E572: 終了コード %d"
-
-#~ msgid "cannot get line"
-#~ msgstr "行をå–å¾—ã§ãã¾ã›ã‚“"
-
-#~ msgid "Unable to register a command server name"
-#~ msgstr "命令サーãƒã®åå‰ã‚’登録ã§ãã¾ã›ã‚“"
-
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: 目的ã®ãƒ—ログラムã¸ã®ã‚³ãƒžãƒ³ãƒ‰é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ"
-
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: 無効ãªã‚µãƒ¼ãƒIDãŒä½¿ã‚れã¾ã—ãŸ: %s"
-
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr "E251: VIM 実体ã®ç™»éŒ²ãƒ—ロパティãŒä¸æ­£ã§ã™. 消去ã—ã¾ã—ãŸ!"
-
-#~ msgid "netbeans is not supported with this GUI\n"
-#~ msgstr "netbeans ã¯ã“ã®GUIã§ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“\n"
-
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "ã“ã®Vimã«ã¯diff機能ãŒã‚りã¾ã›ã‚“(コンパイル時設定)."
-
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "'-nb' 使用ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™\n"
-
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: エラー: NetBeansã‹ã‚‰gvimをスタートã§ãã¾ã›ã‚“\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
-#~ msgstr ""
-#~ "\n"
-#~ "大尿–‡å­—ãŒç„¡è¦–ã•れる場åˆã¯å¤§æ–‡å­—ã«ã™ã‚‹ãŸã‚ã« / ã‚’å‰ç½®ã—ã¦ãã ã•ã„"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\tã“ã®gvimã‚’OLEã¨ã—ã¦ç™»éŒ²ã™ã‚‹"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tgvimã®OLE登録を解除ã™ã‚‹"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tGUIã§èµ·å‹•ã™ã‚‹ (\"gvim\" ã¨åŒã˜)"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f or --nofork\tフォアグラウンド: GUIã‚’å§‹ã‚ã‚‹ã¨ãã«forkã—ãªã„"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\tウィンドウを開ãã®ã« newcli を使用ã—ãªã„"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <device>\t\tI/Oã« <device> を使用ã™ã‚‹"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\t.gvimrcã®ä»£ã‚り㫠<gvimrc> を使ã†"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\tæš—å·åŒ–ã•れãŸãƒ•ァイルを編集ã™ã‚‹"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <display>\tvimを指定ã—㟠X サーãƒã«æŽ¥ç¶šã™ã‚‹"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tXサーãƒã«æŽ¥ç¶šã—ãªã„"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr "--remote <files>\tå¯èƒ½ãªã‚‰ã°Vimサーãƒã§ <files> を編集ã™ã‚‹"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr "--remote-silent <files> åŒä¸Š, サーãƒãŒç„¡ãã¦ã‚‚警告文を出力ã—ãªã„"
-
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr "--remote-wait <files>\t--remote後 ファイルã®ç·¨é›†ãŒçµ‚ã‚ã‚‹ã®ã‚’å¾…ã¤"
-
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-wait-silent <files> åŒä¸Š, サーãƒãŒç„¡ãã¦ã‚‚警告文を出力ã—ãªã„"
-
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <files> --remoteã§ãƒ•ァイル1ã¤ã«ã¤ã1ã¤ã®ã‚¿ãƒ–"
-#~ "ページを開ã"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr "--remote-send <keys>\tVimサーãƒã« <keys> ã‚’é€ä¿¡ã—ã¦çµ‚了ã™ã‚‹"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr "--remote-expr <expr>\tサーãƒã§ <expr> を実行ã—ã¦çµæžœã‚’表示ã™ã‚‹"
-
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr "--serverlist\t\tVimサーãƒåã®ä¸€è¦§ã‚’表示ã—ã¦çµ‚了ã™ã‚‹"
-
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <name>\tVimサーム<name> ã«é€ä¿¡/åå‰è¨­å®šã™ã‚‹"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvimã«ã‚ˆã£ã¦è§£é‡ˆã•れる引数(Motifãƒãƒ¼ã‚¸ãƒ§ãƒ³):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvimã«ã‚ˆã£ã¦è§£é‡ˆã•れる引数(neXtawãƒãƒ¼ã‚¸ãƒ§ãƒ³):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvimã«ã‚ˆã£ã¦è§£é‡ˆã•れる引数(Athenaãƒãƒ¼ã‚¸ãƒ§ãƒ³):\n"
-
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <display>\t<display> ã§vimを実行ã™ã‚‹"
-
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\t最å°åŒ–ã—ãŸçŠ¶æ…‹ã§vimã‚’èµ·å‹•ã™ã‚‹"
-
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <color>\t背景色㫠<color> を使ã†(åŒç¾©: -bg)"
-
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr "-foreground <color>\t剿™¯è‰²ã« <color> を使ã†(åŒç¾©: -fg)"
-
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <font>\t\tテキスト表示㫠<font> を使ã†(åŒç¾©: -fn)"
-
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <font>\t太字㫠<font> を使ã†"
-
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <for>\t斜体字㫠<font> を使ã†"
-
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr "-geometry <geom>\tåˆæœŸé…置㫠<geom> を使ã†(åŒç¾©: -geom)"
-
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <width>\t境界ã®å¹…ã‚’ <width> ã«ã™ã‚‹(åŒç¾©: -bw)"
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <width> スクロールãƒãƒ¼ã®å¹…ã‚’ <width> ã«ã™ã‚‹(åŒç¾©: -sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr ""
-#~ "-menuheight <height>\tメニューãƒãƒ¼ã®é«˜ã•ã‚’ <height> ã«ã™ã‚‹(åŒç¾©: -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tå転映åƒã‚’使用ã™ã‚‹(åŒç¾©: -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tå転映åƒã‚’使用ã—ãªã„(åŒç¾©: +rv)"
-
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <resource>\t特定ã®ãƒªã‚½ãƒ¼ã‚¹ã‚’使用ã™ã‚‹"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvimã«ã‚ˆã£ã¦è§£é‡ˆã•れる引数(GTK+ãƒãƒ¼ã‚¸ãƒ§ãƒ³):\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <display>\t<display> ã§vimを実行ã™ã‚‹(åŒç¾©: --display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr "--role <role>\tメインウィンドウを識別ã™ã‚‹ä¸€æ„ãªå½¹å‰²(role)を設定ã™ã‚‹"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tç•°ãªã‚‹GTK widgetã§Vimã‚’é–‹ã"
-
-#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
-#~ msgstr "--echo-wid\t\tウィンドウIDを標準出力ã«å‡ºåŠ›ã™ã‚‹"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <親ã®ã‚¿ã‚¤ãƒˆãƒ«>\tVimを親アプリケーションã®ä¸­ã§èµ·å‹•ã™ã‚‹"
-
-#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
-#~ msgstr "--windowid <HWND>\tç•°ãªã‚‹Win32 widgetã®å†…部ã«Vimã‚’é–‹ã"
-
-#~ msgid "No display"
-#~ msgstr "ディスプレイãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr ": é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ.\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ. ローカルã§ã®å®Ÿè¡Œã‚’試ã¿ã¦ã„ã¾ã™\n"
-
-#~ msgid "%d of %d edited"
-#~ msgstr "%d 個 (%d 個中) ã®ãƒ•ァイルを編集ã—ã¾ã—ãŸ"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "ディスプレイãŒã‚りã¾ã›ã‚“: å¼ã®é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ.\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": å¼ã®é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ.\n"
-
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: 無効ãªã‚³ãƒ¼ãƒ‰ãƒšãƒ¼ã‚¸ã§ã™"
-
-#~ msgid "E284: Cannot set IC values"
-#~ msgstr "E284: ICã®å€¤ã‚’設定ã§ãã¾ã›ã‚“"
-
-#~ 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 をサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: pathã«ã¯ \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
-#~ msgid "E843: Error while updating swap file crypt"
-#~ msgstr "E843: ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ã®æš—å·ã‚’更新中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+#, c-format
+msgid "E799: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E799: 無効㪠ID: %ld (1 以上ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“)"
-#~ msgid ""
-#~ "E833: %s is encrypted and this version of Vim does not support encryption"
-#~ msgstr ""
-#~ "E833: %s ã¯ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®Vimã§ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ãªã„å½¢å¼ã§æš—å·åŒ–ã•れã¦ã„ã¾ã™"
+#, c-format
+msgid "E801: ID already taken: %ld"
+msgstr "E801: ID ã¯ã™ã§ã«åˆ©ç”¨ä¸­ã§ã™: %ld"
-#~ msgid "Swap file is encrypted: \"%s\""
-#~ msgstr "ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ã¯æš—å·åŒ–ã•れã¦ã„ã¾ã™: \"%s\""
+msgid "List or number required"
+msgstr "ãƒªã‚¹ãƒˆã‹æ•°å€¤ãŒå¿…è¦ã§ã™"
-#~ msgid ""
-#~ "\n"
-#~ "If you entered a new crypt key but did not write the text file,"
-#~ msgstr ""
-#~ "\n"
-#~ "æ–°ã—ã„æš—å·ã‚­ãƒ¼ã‚’入力ã—ãŸã‚ã¨ã«ãƒ†ã‚­ã‚¹ãƒˆãƒ•ァイルをä¿å­˜ã—ã¦ã„ãªã„å ´åˆã¯,"
+#, c-format
+msgid "E802: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E802: 無効㪠ID: %ld (1 以上ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“)"
-#~ msgid ""
-#~ "\n"
-#~ "enter the new crypt key."
-#~ msgstr ""
-#~ "\n"
-#~ "æ–°ã—ã„æš—å·ã‚­ãƒ¼ã‚’入力ã—ã¦ãã ã•ã„."
+#, c-format
+msgid "E803: ID not found: %ld"
+msgstr "E803: ID ã¯ã‚りã¾ã›ã‚“: %ld"
-#~ msgid ""
-#~ "\n"
-#~ "If you wrote the text file after changing the crypt key press enter"
-#~ msgstr ""
-#~ "\n"
-#~ "æš—å·ã‚­ãƒ¼ã‚’変ãˆãŸã‚ã¨ã«ãƒ†ã‚­ã‚¹ãƒˆãƒ•ァイルをä¿å­˜ã—ãŸå ´åˆã¯, テキストファイルã¨"
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: ライブラリ %s をロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
-#~ msgid ""
-#~ "\n"
-#~ "to use the same key for text file and swap file"
-#~ msgstr ""
-#~ "\n"
-#~ "スワップファイルã«åŒã˜æš—å·ã‚­ãƒ¼ã‚’使ã†ãŸã‚ã«enterã ã‘を押ã—ã¦ãã ã•ã„."
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr ""
+"ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™, ã”ã‚ã‚“ãªã•ã„: Perlライブラリをロードã§ãã¾ã›ã‚“ã§ã—ãŸ."
-#~ msgid "Using crypt key from swap file for the text file.\n"
-#~ msgstr "スワップファイルã‹ã‚‰å–å¾—ã—ãŸæš—å·ã‚­ãƒ¼ã‚’テキストファイルã«ä½¿ã„ã¾ã™.\n"
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr ""
+"E299: サンドボックスã§ã¯ Safe モジュールを使用ã—ãªã„Perlスクリプトã¯ç¦ã˜ã‚‰ã‚Œ"
+"ã¦ã„ã¾ã™"
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [ã“ã®Vimãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“]"
+msgid "Edit with &multiple Vims"
+msgstr "複数ã®Vimã§ç·¨é›†ã™ã‚‹ (&M)"
-#~ msgid "Tear off this menu"
-#~ msgstr "ã“ã®ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚’切りå–ã‚‹"
+msgid "Edit with single &Vim"
+msgstr "1ã¤ã®Vimã§ç·¨é›†ã™ã‚‹ (&V)"
-#~ msgid "Select Directory dialog"
-#~ msgstr "ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªé¸æŠžãƒ€ã‚¤ã‚¢ãƒ­ã‚°"
+msgid "Diff with Vim"
+msgstr "Vimã§å·®åˆ†ã‚’表示ã™ã‚‹"
-#~ msgid "Save File dialog"
-#~ msgstr "ファイルä¿å­˜ãƒ€ã‚¤ã‚¢ãƒ­ã‚°"
+msgid "Edit with &Vim"
+msgstr "Vimã§ç·¨é›†ã™ã‚‹ (&V)"
-#~ msgid "Open File dialog"
-#~ msgstr "ファイル読込ダイアログ"
+#. Now concatenate
+msgid "Edit with existing Vim - "
+msgstr "起動済ã®Vimã§ç·¨é›†ã™ã‚‹ - "
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr ""
-#~ "E338: コンソールモードã§ã¯ãƒ•ァイルブラウザを使ãˆã¾ã›ã‚“, ã”ã‚ã‚“ãªã•ã„"
+msgid "Edits the selected file(s) with Vim"
+msgstr "é¸æŠžã—ãŸãƒ•ァイルをVimã§ç·¨é›†ã™ã‚‹"
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "Vim: ファイルをä¿å­˜ä¸­...\n"
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "プロセスã®ä½œæˆã«å¤±æ•—: gvimãŒç’°å¢ƒå¤‰æ•°PATH上ã«ã‚ã‚‹ã‹ç¢ºèªã—ã¦ãã ã•ã„!"
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "Vim: 終了ã—ã¾ã—ãŸ.\n"
+msgid "gvimext.dll error"
+msgstr "gvimext.dll エラー"
-#~ msgid "ERROR: "
-#~ msgstr "エラー: "
+msgid "Path length too long!"
+msgstr "パスãŒé•·éŽãŽã¾ã™!"
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[メモリ(ãƒã‚¤ãƒˆ)] ç·å‰²å½“-è§£æ”¾é‡ %<PRIu64>-%<PRIu64>, ä½¿ç”¨é‡ %<PRIu64>, ピー"
-#~ "ク時 %<PRIu64>\n"
+msgid "--No lines in buffer--"
+msgstr "--ãƒãƒƒãƒ•ã‚¡ã«è¡ŒãŒã‚りã¾ã›ã‚“--"
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[呼出] ç· re/malloc() 回数 %<PRIu64>, ç· free() 回数 %<PRIu64>\n"
-#~ "\n"
+#.
+#. * 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 "E340: Line is becoming too long"
-#~ msgstr "E340: 行ãŒé•·ããªã‚ŠéŽãŽã¾ã—ãŸ"
+msgid "E471: Argument required"
+msgstr "E471: 引数ãŒå¿…è¦ã§ã™"
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: 内部エラー: lalloc(%<PRId64>,)"
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ ã®å¾Œã¯ / ã‹ ? ã‹ & ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: 䏿­£ãª 'mouseshape' ã§ã™"
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: コマンドラインã§ã¯ç„¡åйã§ã™; <CR>ã§å®Ÿè¡Œ, CTRL-Cã§ã‚„ã‚ã‚‹"
-#~ msgid "Enter encryption key: "
-#~ msgstr "æš—å·åŒ–用ã®ã‚­ãƒ¼ã‚’入力ã—ã¦ãã ã•ã„: "
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚„タグ検索ã§ã¯exrc/vimrcã®ã‚³ãƒžãƒ³ãƒ‰ã¯è¨±å¯ã•れã¾ã›ã‚“"
-#~ msgid "Enter same key again: "
-#~ msgstr "ã‚‚ã†ä¸€åº¦åŒã˜ã‚­ãƒ¼ã‚’入力ã—ã¦ãã ã•ã„: "
+msgid "E171: Missing :endif"
+msgstr "E171: :endif ãŒã‚りã¾ã›ã‚“"
-#~ msgid "Keys don't match!"
-#~ msgstr "キーãŒä¸€è‡´ã—ã¾ã›ã‚“"
+msgid "E600: Missing :endtry"
+msgstr "E600: :endtry ãŒã‚りã¾ã›ã‚“"
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Netbeans #2 ã«æŽ¥ç¶šã§ãã¾ã›ã‚“"
+msgid "E170: Missing :endwhile"
+msgstr "E170: :endwhile ãŒã‚りã¾ã›ã‚“"
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Netbeans ã«æŽ¥ç¶šã§ãã¾ã›ã‚“"
+msgid "E170: Missing :endfor"
+msgstr "E170: :endfor ãŒã‚りã¾ã›ã‚“"
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr ""
-#~ "E668: NetBeansã®æŽ¥ç¶šæƒ…å ±ãƒ•ã‚¡ã‚¤ãƒ«ã®ã‚¢ã‚¯ã‚»ã‚¹ãƒ¢ãƒ¼ãƒ‰ã«å•題ãŒã‚りã¾ã™: \"%s\""
+msgid "E588: :endwhile without :while"
+msgstr "E588: :while ã®ãªã„ :endwhile ãŒã‚りã¾ã™"
-#~ msgid "read from Netbeans socket"
-#~ msgstr "Netbeans ã®ã‚½ã‚±ãƒƒãƒˆã‚’読込ã¿"
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor ã®ãªã„ :for ãŒã‚りã¾ã™"
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: ãƒãƒƒãƒ•ã‚¡ %<PRId64> ã® NetBeans 接続ãŒå¤±ã‚れã¾ã—ãŸ"
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: ファイルãŒå­˜åœ¨ã—ã¾ã™ (! を追加ã§ä¸Šæ›¸)"
-#~ msgid "E838: netbeans is not supported with this GUI"
-#~ msgstr "E838: NetBeansã¯ã“ã®GUIã«ã¯å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“"
+msgid "E472: Command failed"
+msgstr "E472: コマンドãŒå¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "E511: netbeans already connected"
-#~ msgstr "E511: NetBeansã¯æ—¢ã«æŽ¥ç¶šã—ã¦ã„ã¾ã™"
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: 未知ã®ãƒ•ォントセット: %s"
-#~ msgid "E505: %s is read-only (add ! to override)"
-#~ msgstr "E505: %s ã¯èª­è¾¼å°‚用ã§ã™ (強制書込ã«ã¯ ! を追加)"
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: 未知ã®ãƒ•ォント: %s"
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: å¼è©•価機能ãŒç„¡åйã«ãªã£ã¦ã„ã¾ã™"
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: フォント \"%s\" ã¯å›ºå®šå¹…ã§ã¯ã‚りã¾ã›ã‚“"
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "%<PRId64> 行を解放中"
+msgid "E473: Internal error"
+msgstr "E473: 内部エラーã§ã™"
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: GUIã§ã¯ 'term' を変更ã§ãã¾ã›ã‚“"
+msgid "Interrupted"
+msgstr "割込ã¾ã‚Œã¾ã—ãŸ"
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: GUIをスタートã™ã‚‹ã«ã¯ \":gui\" を使用ã—ã¦ãã ã•ã„"
+msgid "E14: Invalid address"
+msgstr "E14: 無効ãªã‚¢ãƒ‰ãƒ¬ã‚¹ã§ã™"
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: GTK+2 GUIã§ã¯å¤‰æ›´ã§ãã¾ã›ã‚“"
+msgid "E474: Invalid argument"
+msgstr "E474: 無効ãªå¼•æ•°ã§ã™"
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: 無効ãªãƒ•ォントã§ã™"
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: 無効ãªå¼•æ•°ã§ã™: %s"
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: ãƒ•ã‚©ãƒ³ãƒˆã‚»ãƒƒãƒˆã‚’é¸æŠžã§ãã¾ã›ã‚“"
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: 無効ãªå¼ã§ã™: %s"
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: 無効ãªãƒ•ォントセットã§ã™"
+msgid "E16: Invalid range"
+msgstr "E16: 無効ãªç¯„囲ã§ã™"
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: ãƒ¯ã‚¤ãƒ‰ãƒ•ã‚©ãƒ³ãƒˆã‚’é¸æŠžã§ãã¾ã›ã‚“"
+msgid "E476: Invalid command"
+msgstr "E476: 無効ãªã‚³ãƒžãƒ³ãƒ‰ã§ã™"
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: 無効ãªãƒ¯ã‚¤ãƒ‰ãƒ•ォントã§ã™"
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã™"
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: マウスã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“"
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: \"%s\"() ã®ãƒ©ã‚¤ãƒ–ラリ呼出ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "cannot open "
-#~ msgstr "é–‹ã‘ã¾ã›ã‚“ "
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: ライブラリã®é–¢æ•° %s をロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: ウィンドウを開ã‘ã¾ã›ã‚“!\n"
+msgid "E19: Mark has invalid line number"
+msgstr "E19: マークã«ç„¡åйãªè¡Œç•ªå·ãŒæŒ‡å®šã•れã¦ã„ã¾ã—ãŸ"
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Amigadosã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 2.04ã‹ãれ以é™ãŒå¿…è¦ã§ã™\n"
+msgid "E20: Mark not set"
+msgstr "E20: マークã¯è¨­å®šã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "%s ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %<PRId64> ãŒå¿…è¦ã§ã™\n"
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: 'modifiable' ãŒã‚ªãƒ•ãªã®ã§, 変更ã§ãã¾ã›ã‚“"
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "NILã‚’é–‹ã‘ã¾ã›ã‚“:\n"
+msgid "E22: Scripts nested too deep"
+msgstr "E22: スクリプトã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
-#~ msgid "Cannot create "
-#~ msgstr "作æˆã§ãã¾ã›ã‚“ "
+msgid "E23: No alternate file"
+msgstr "E23: 副ファイルã¯ã‚りã¾ã›ã‚“"
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim㯠%d ã§çµ‚了ã—ã¾ã™\n"
+msgid "E24: No such abbreviation"
+msgstr "E24: ãã®ã‚ˆã†ãªçŸ­ç¸®å…¥åŠ›ã¯ã‚りã¾ã›ã‚“"
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "コンソールモードを変更ã§ãã¾ã›ã‚“?!\n"
+msgid "E477: No ! allowed"
+msgstr "E477: ! ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: コンソールã§ã¯ãªã„??\n"
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: GUIã¯ä½¿ç”¨ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™"
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: -f オプションã§ã‚·ã‚§ãƒ«ã‚’実行ã§ãã¾ã›ã‚“"
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: ヘブライ語ã¯ä½¿ç”¨ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™\n"
-#~ msgid "Cannot execute "
-#~ msgstr "実行ã§ãã¾ã›ã‚“ "
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: ペルシア語ã¯ä½¿ç”¨ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™\n"
-#~ msgid "shell "
-#~ msgstr "シェル "
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: アラビア語ã¯ä½¿ç”¨ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™\n"
-#~ msgid " returned\n"
-#~ msgstr " 戻りã¾ã—ãŸ\n"
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: ãã®ã‚ˆã†ãªåã®ãƒã‚¤ãƒ©ã‚¤ãƒˆã‚°ãƒ«ãƒ¼ãƒ—ã¯ã‚りã¾ã›ã‚“: %s"
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE ãŒå°ã•éŽãŽã¾ã™."
+msgid "E29: No inserted text yet"
+msgstr "E29: ã¾ã ãƒ†ã‚­ã‚¹ãƒˆãŒæŒ¿å…¥ã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "I/O ERROR"
-#~ msgstr "入出力エラー"
+msgid "E30: No previous command line"
+msgstr "E30: 以å‰ã«ã‚³ãƒžãƒ³ãƒ‰è¡ŒãŒã‚りã¾ã›ã‚“"
-#~ msgid "Message"
-#~ msgstr "メッセージ"
+msgid "E31: No such mapping"
+msgstr "E31: ãã®ã‚ˆã†ãªãƒžãƒƒãƒ”ングã¯ã‚りã¾ã›ã‚“"
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "'columns' ãŒ80ã§ã¯ãªã„ãŸã‚, 外部コマンドを実行ã§ãã¾ã›ã‚“"
+msgid "E479: No match"
+msgstr "E479: 該当ã¯ã‚りã¾ã›ã‚“"
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: プリンタã®é¸æŠžã«å¤±æ•—ã—ã¾ã—ãŸ"
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: 該当ã¯ã‚りã¾ã›ã‚“: %s"
-#~ msgid "to %s on %s"
-#~ msgstr "%s 㸠(%s 上ã®)"
+msgid "E32: No file name"
+msgstr "E32: ファイルåãŒã‚りã¾ã›ã‚“"
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: 未知ã®ãƒ—リンタオプションã§ã™: %s"
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: æ­£è¦è¡¨ç¾ç½®æ›ãŒã¾ã å®Ÿè¡Œã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: å°åˆ·ã‚¨ãƒ©ãƒ¼: %s"
+msgid "E34: No previous command"
+msgstr "E34: コマンドãŒã¾ã å®Ÿè¡Œã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "Printing '%s'"
-#~ msgstr "å°åˆ·ã—ã¦ã„ã¾ã™: '%s'"
+msgid "E35: No previous regular expression"
+msgstr "E35: æ­£è¦è¡¨ç¾ãŒã¾ã å®Ÿè¡Œã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
-#~ msgstr "E244: 文字セットå \"%s\" ã¯ä¸æ­£ã§ã™ (フォントå \"%s\")"
+msgid "E481: No range allowed"
+msgstr "E481: 範囲指定ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: '%c' ã¯ä¸æ­£ãªæ–‡å­—ã§ã™ (フォントå \"%s\")"
+msgid "E36: Not enough room"
+msgstr "E36: ウィンドウã«å分ãªé«˜ã•ã‚‚ã—ãã¯å¹…ãŒã‚りã¾ã›ã‚“"
-#~ msgid "Vim: Double signal, exiting\n"
-#~ msgstr "Vim: 2é‡ã®ã‚·ã‚°ãƒŠãƒ«ã®ãŸã‚, 終了ã—ã¾ã™\n"
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: %s ã¨ã„ã†åå‰ã®ç™»éŒ²ã•れãŸã‚µãƒ¼ãƒãƒ¼ã¯ã‚りã¾ã›ã‚“"
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "Vim: 致命的シグナル %s を検知ã—ã¾ã—ãŸ\n"
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: ファイル %s を作æˆã§ãã¾ã›ã‚“"
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "Vim: 致命的シグナルを検知ã—ã¾ã—ãŸ\n"
+msgid "E483: Can't get temp file name"
+msgstr "E483: 一時ファイルã®åå‰ã‚’å–å¾—ã§ãã¾ã›ã‚“"
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "Xサーãƒã¸ã®æŽ¥ç¶šã« %<PRId64> ミリ秒ã‹ã‹ã‚Šã¾ã—ãŸ"
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: ファイル \"%s\" ã‚’é–‹ã‘ã¾ã›ã‚“"
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim: X ã®ã‚¨ãƒ©ãƒ¼ã‚’検出ã—ã¾ã—ãŸr\n"
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: ファイル %s を読込ã‚ã¾ã›ã‚“"
-#~ msgid "Testing the X display failed"
-#~ msgstr "X display ã®ãƒã‚§ãƒƒã‚¯ã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: 最後ã®å¤‰æ›´ãŒä¿å­˜ã•れã¦ã„ã¾ã›ã‚“ (! を追加ã§å¤‰æ›´ã‚’破棄)"
-#~ msgid "Opening the X display timed out"
-#~ msgstr "X display ã® open ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸ"
+msgid "E37: No write since last change"
+msgstr "E37: 最後ã®å¤‰æ›´ãŒä¿å­˜ã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "sh シェルを実行ã§ãã¾ã›ã‚“\n"
+msgid "E38: Null argument"
+msgstr "E38: 引数ãŒç©ºã§ã™"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "パイプを作æˆã§ãã¾ã›ã‚“\n"
+msgid "E39: Number expected"
+msgstr "E39: 数値ãŒè¦æ±‚ã•れã¦ã„ã¾ã™"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "fork ã§ãã¾ã›ã‚“\n"
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: エラーファイル %s ã‚’é–‹ã‘ã¾ã›ã‚“"
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "コマンドを中断ã—ã¾ã—ãŸ\n"
+msgid "E233: cannot open display"
+msgstr "E233: ディスプレイを開ã‘ã¾ã›ã‚“"
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP ãŒICE接続を失ã„ã¾ã—ãŸ"
+msgid "E41: Out of memory!"
+msgstr "E41: メモリãŒå°½ãæžœã¦ã¾ã—ãŸ!"
-#~ msgid "Opening the X display failed"
-#~ msgstr "X display ã® open ã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "Pattern not found"
+msgstr "パターンã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP ãŒsave-yourselfè¦æ±‚を処ç†ã—ã¦ã„ã¾ã™"
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: パターンã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ: %s"
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP ãŒæŽ¥ç¶šã‚’é–‹å§‹ã—ã¦ã„ã¾ã™"
+msgid "E487: Argument must be positive"
+msgstr "E487: å¼•æ•°ã¯æ­£ã®å€¤ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP ICE接続ãŒå¤±æ•—ã—ãŸã‚ˆã†ã§ã™"
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: å‰ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æˆ»ã‚Œã¾ã›ã‚“"
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP SmcOpenConnectionãŒå¤±æ•—ã—ã¾ã—ãŸ: %s"
+msgid "E42: No Errors"
+msgstr "E42: エラーã¯ã‚りã¾ã›ã‚“"
-#~ msgid "At line"
-#~ msgstr "行"
+msgid "E776: No location list"
+msgstr "E776: ロケーションリストã¯ã‚りã¾ã›ã‚“"
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "vim32.dll をロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
+msgid "E43: Damaged match string"
+msgstr "E43: 該当文字列ãŒç ´æã—ã¦ã„ã¾ã™"
-#~ msgid "VIM Error"
-#~ msgstr "VIMエラー"
+msgid "E44: Corrupted regexp program"
+msgstr "E44: 䏿­£ãªæ­£è¦è¡¨ç¾ãƒ—ログラムã§ã™"
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "DLLã‹ã‚‰é–¢æ•°ãƒã‚¤ãƒ³ã‚¿ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ"
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: 'readonly' オプションãŒè¨­å®šã•れã¦ã„ã¾ã™ (! を追加ã§ä¸Šæ›¸ã)"
-#~ msgid "shell returned %d"
-#~ msgstr "シェルãŒã‚³ãƒ¼ãƒ‰ %d ã§çµ‚了ã—ã¾ã—ãŸ"
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: 読å–専用変数 \"%s\" ã«ã¯å€¤ã‚’設定ã§ãã¾ã›ã‚“"
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: イベント %s を検知\n"
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: サンドボックスã§ã¯å¤‰æ•° \"%s\" ã«å€¤ã‚’設定ã§ãã¾ã›ã‚“"
-#~ msgid "close"
-#~ msgstr "é–‰ã˜ã‚‹"
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: 辞書型ã«ç©ºã®ã‚­ãƒ¼ã‚’使ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-#~ msgid "logoff"
-#~ msgstr "ログオフ"
+msgid "E715: Dictionary required"
+msgstr "E715: 辞書型ãŒå¿…è¦ã§ã™"
-#~ msgid "shutdown"
-#~ msgstr "シャットダウン"
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: リストã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãŒç¯„囲外ã§ã™: %ld"
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: コマンドãŒã‚りã¾ã›ã‚“"
-
-#~ msgid ""
-#~ "VIMRUN.EXE not found in your $PATH.\n"
-#~ "External commands will not pause after completion.\n"
-#~ "See :help win32-vimrun for more information."
-#~ msgstr ""
-#~ "VIMRUN.EXE㌠$PATH ã®ä¸­ã«è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“.\n"
-#~ "外部コマンドã®çµ‚了後ã«ä¸€æ™‚åœæ­¢ã‚’ã—ã¾ã›ã‚“.\n"
-#~ "詳細㯠:help win32-vimrun ã‚’å‚ç…§ã—ã¦ãã ã•ã„."
-
-#~ msgid "Vim Warning"
-#~ msgstr "Vimã®è­¦å‘Š"
-
-#~ msgid "Error file"
-#~ msgstr "エラーファイル"
-
-#~ msgid "E868: Error building NFA with equivalence class!"
-#~ msgstr "E868: 等価クラスをå«ã‚€NFA構築ã«å¤±æ•—ã—ã¾ã—ãŸ!"
-
-#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!"
-#~ msgstr "E878: (NFA) ç¾åœ¨æ¨ªæ–­ä¸­ã®ãƒ–ランãƒã«å分ãªãƒ¡ãƒ¢ãƒªã‚’割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“!"
-
-#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
-#~ msgstr ""
-#~ "警告: å˜èªžãƒªã‚¹ãƒˆ \"%s_%s.spl\" ãŠã‚ˆã³ \"%s_ascii.spl\" ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "%s 内ã®å¤‰æ›ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
-
-#~ msgid "E845: Insufficient memory, word list will be incomplete"
-#~ msgstr "E845: メモリãŒè¶³ã‚Šãªã„ã®ã§ã€å˜èªžãƒªã‚¹ãƒˆã¯ä¸å®Œå…¨ã§ã™"
-
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: タグファイルã®ãƒ‘ス㌠%s ã«åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã—ãŸ\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "æ–°ã—ã„シェルを起動ã—ã¾ã™\n"
-
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "空ã®é¸æŠžé ˜åŸŸã®ã‹ã‚りã«CUT_BUFFER0ãŒä½¿ç”¨ã•れã¾ã—ãŸ"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "å¯èƒ½ãªã‚¢ãƒ³ãƒ‰ã‚¥ã¯ã‚りã¾ã›ã‚“: ã¨ã‚Šã‚ãˆãšç¶šã‘ã¾ã™"
-
-#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
-#~ msgstr ""
-#~ "E832: éžæš—å·åŒ–ãƒ•ã‚¡ã‚¤ãƒ«ãŒæš—å·åŒ–ã•れãŸã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ァイルを使ã£ã¦ã¾ã™: %s"
-
-#~ msgid "E826: Undo file decryption failed: %s"
-#~ msgstr "E826: æš—å·åŒ–ã•れãŸã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ァイルã®è§£èª­ã«å¤±æ•—ã—ã¾ã—ãŸ: %s"
-
-#~ msgid "E827: Undo file is encrypted: %s"
-#~ msgstr "E827: ã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ã‚¡ã‚¤ãƒ«ãŒæš—å·åŒ–ã•れã¦ã„ã¾ã™: %s"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16/32 ビット GUI 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 64 ビット GUI 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32 ビット GUI 版"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " in Win32s モード"
-
-#~ msgid " with OLE support"
-#~ msgstr " with OLE サãƒãƒ¼ãƒˆ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 64 ビット コンソール 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32 ビット コンソール 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16 ビット 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "32 ビット MS-DOS 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "16 ビット MS-DOS 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X (unix) 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "OpenVMS 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Big 版 "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "通常 版 "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Small 版 "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Tiny 版 "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "with GTK2-GNOME GUI."
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: 関数ã®å¼•æ•°ãŒå¤šéŽãŽã¾ã™: %s"
-#~ msgid "with GTK2 GUI."
-#~ msgstr "with GTK2 GUI."
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: 辞書型ã«ã‚­ãƒ¼ãŒå­˜åœ¨ã—ã¾ã›ã‚“: %s"
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "with X11-Motif GUI."
+msgid "E714: List required"
+msgstr "E714: リスト型ãŒå¿…è¦ã§ã™"
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "with X11-neXtaw GUI."
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: %s ã®å¼•æ•°ã¯ãƒªã‚¹ãƒˆåž‹ã¾ãŸã¯è¾žæ›¸åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "with X11-Athena GUI."
+msgid "E47: Error while reading errorfile"
+msgstr "E47: エラーファイルã®èª­è¾¼ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
-#~ msgid "with Photon GUI."
-#~ msgstr "with Photon GUI."
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: サンドボックスã§ã¯è¨±ã•れã¾ã›ã‚“"
-#~ msgid "with GUI."
-#~ msgstr "with GUI."
+msgid "E523: Not allowed here"
+msgstr "E523: ã“ã“ã§ã¯è¨±å¯ã•れã¾ã›ã‚“"
-#~ msgid "with Carbon GUI."
-#~ msgstr "with Carbon GUI."
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: スクリーンモードã®è¨­å®šã«ã¯å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“"
-#~ msgid "with Cocoa GUI."
-#~ msgstr "with Cocoa GUI."
+msgid "E49: Invalid scroll size"
+msgstr "E49: 無効ãªã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«é‡ã§ã™"
-#~ msgid "with (classic) GUI."
-#~ msgstr "with (クラシック) GUI."
+msgid "E91: 'shell' option is empty"
+msgstr "E91: 'shell' オプションãŒç©ºã§ã™"
-#~ msgid " system gvimrc file: \""
-#~ msgstr " システム gvimrc: \""
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: sign ã®ãƒ‡ãƒ¼ã‚¿ã‚’読込ã‚ã¾ã›ã‚“ã§ã—ãŸ"
-#~ msgid " user gvimrc file: \""
-#~ msgstr " ユーザ gvimrc: \""
+msgid "E72: Close error on swap file"
+msgstr "E72: スワップファイルã®ã‚¯ãƒ­ãƒ¼ã‚ºæ™‚エラーã§ã™"
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr " 第2ユーザ gvimrc: \""
+msgid "E73: tag stack empty"
+msgstr "E73: タグスタックãŒç©ºã§ã™"
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr " 第3ユーザ gvimrc: \""
+msgid "E74: Command too complex"
+msgstr "E74: コマンドãŒè¤‡é›‘éŽãŽã¾ã™"
-#~ msgid " system menu file: \""
-#~ msgstr " システムメニュー: \""
+msgid "E75: Name too long"
+msgstr "E75: åå‰ãŒé•·éŽãŽã¾ã™"
-#~ msgid "Compiler: "
-#~ msgstr "コンパイラ: "
+msgid "E76: Too many ["
+msgstr "E76: [ ãŒå¤šéŽãŽã¾ã™"
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "詳細ã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã® ãƒ˜ãƒ«ãƒ—â†’å­¤å… ã‚’å‚ç…§ã—ã¦ä¸‹ã•ã„ "
+msgid "E77: Too many file names"
+msgstr "E77: ファイルåãŒå¤šéŽãŽã¾ã™"
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "モード無ã§å®Ÿè¡Œä¸­, タイプã—ãŸæ–‡å­—ãŒæŒ¿å…¥ã•れã¾ã™"
+msgid "E488: Trailing characters"
+msgstr "E488: ä½™åˆ†ãªæ–‡å­—ãŒå¾Œã‚ã«ã‚りã¾ã™"
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "メニュー㮠編集→全体設定→挿入(åˆå¿ƒè€…)モード切替 "
+msgid "E78: Unknown mark"
+msgstr "E78: 未知ã®ãƒžãƒ¼ã‚¯"
-#~ msgid " for two modes "
-#~ msgstr " ã§ãƒ¢ãƒ¼ãƒ‰æœ‰ã« "
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: ワイルドカードを展開ã§ãã¾ã›ã‚“"
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "メニュー㮠編集→全体設定→Vi互æ›ãƒ¢ãƒ¼ãƒ‰åˆ‡æ›¿ "
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' 㯠'winminheight' よりå°ã•ãã§ãã¾ã›ã‚“"
-#~ msgid " for Vim defaults "
-#~ msgstr " ã§Vimã¨ã—ã¦å‹•作 "
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' 㯠'winminwidth' よりå°ã•ãã§ãã¾ã›ã‚“"
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr " 警告: Windows 95/98/Me を検出 "
+msgid "E80: Error while writing"
+msgstr "E80: 書込ã¿ä¸­ã®ã‚¨ãƒ©ãƒ¼"
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr " è©³ç´°ãªæƒ…報㯠:help windows95<Enter> "
+msgid "Zero count"
+msgstr "ゼロカウント"
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "複数ã®Vimã§ç·¨é›†ã™ã‚‹ (&M)"
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: スクリプト以外ã§<SID>ãŒä½¿ã‚れã¾ã—ãŸ"
-#~ msgid "Edit with single &Vim"
-#~ msgstr "1ã¤ã®Vimã§ç·¨é›†ã™ã‚‹ (&V)"
+msgid "E449: Invalid expression received"
+msgstr "E449: 無効ãªå¼ã‚’å—ã‘å–りã¾ã—ãŸ"
-#~ msgid "Diff with Vim"
-#~ msgstr "Vimã§å·®åˆ†ã‚’表示ã™ã‚‹"
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: 領域ãŒä¿è­·ã•れã¦ã„ã‚‹ã®ã§, 変更ã§ãã¾ã›ã‚“"
-#~ msgid "Edit with &Vim"
-#~ msgstr "Vimã§ç·¨é›†ã™ã‚‹ (&V)"
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans ã¯èª­è¾¼å°‚用ファイルを変更ã™ã‚‹ã“ã¨ã‚’許ã—ã¾ã›ã‚“"
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "起動済ã®Vimã§ç·¨é›†ã™ã‚‹ - "
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: 内部エラーã§ã™: %s"
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "é¸æŠžã—ãŸãƒ•ァイルをVimã§ç·¨é›†ã™ã‚‹"
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: パターン㌠'maxmempattern' 以上ã®ãƒ¡ãƒ¢ãƒªã‚’使用ã—ã¾ã™"
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "プロセスã®ä½œæˆã«å¤±æ•—: gvimãŒç’°å¢ƒå¤‰æ•°PATH上ã«ã‚ã‚‹ã‹ç¢ºèªã—ã¦ãã ã•ã„!"
+msgid "E749: empty buffer"
+msgstr "E749: ãƒãƒƒãƒ•ã‚¡ãŒç©ºã§ã™"
-#~ msgid "gvimext.dll error"
-#~ msgstr "gvimext.dll エラー"
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: ãƒãƒƒãƒ•ã‚¡ %ld ã¯ã‚りã¾ã›ã‚“"
-#~ msgid "Path length too long!"
-#~ msgstr "パスãŒé•·ã™ãŽã¾ã™!"
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: 検索パターンã‹åŒºåˆ‡ã‚Šè¨˜å·ãŒä¸æ­£ã§ã™"
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: 未知ã®ãƒ•ォントセット: %s"
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: åŒã˜åå‰ã®ãƒ•ァイルãŒä»–ã®ãƒãƒƒãƒ•ã‚¡ã§èª­è¾¼ã¾ã‚Œã¦ã„ã¾ã™"
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: 未知ã®ãƒ•ォント: %s"
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: オプション '%s' ã¯è¨­å®šã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: フォント \"%s\" ã¯å›ºå®šå¹…ã§ã¯ã‚りã¾ã›ã‚“"
+msgid "E850: Invalid register name"
+msgstr "E850: 無効ãªãƒ¬ã‚¸ã‚¹ã‚¿åã§ã™"
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: ライブラリã®é–¢æ•° %s をロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
+#, c-format
+msgid "E919: Directory not found in '%s': \"%s\""
+msgstr "E919: ディレクトリ㌠'%s' ã®ä¸­ã«ã‚りã¾ã›ã‚“: \"%s\""
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr "E26: ヘブライ語ã¯ä½¿ç”¨ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™\n"
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "上ã¾ã§æ¤œç´¢ã—ãŸã®ã§ä¸‹ã«æˆ»ã‚Šã¾ã™"
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: ペルシア語ã¯ä½¿ç”¨ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™\n"
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "下ã¾ã§æ¤œç´¢ã—ãŸã®ã§ä¸Šã«æˆ»ã‚Šã¾ã™"
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E800: アラビア語ã¯ä½¿ç”¨ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™\n"
+#, c-format
+msgid "Need encryption key for \"%s\""
+msgstr "æš—å·ã‚­ãƒ¼ãŒå¿…è¦ã§ã™: \"%s\""
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: %s ã¨ã„ã†åå‰ã®ç™»éŒ²ã•れãŸã‚µãƒ¼ãƒã¯ã‚りã¾ã›ã‚“"
+msgid "empty keys are not allowed"
+msgstr "空ã®ã‚­ãƒ¼ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: ディスプレイを開ã‘ã¾ã›ã‚“"
+msgid "dictionary is locked"
+msgstr "辞書ã¯ãƒ­ãƒƒã‚¯ã•れã¦ã„ã¾ã™"
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: 無効ãªå¼ã‚’å—ã‘å–りã¾ã—ãŸ"
+msgid "list is locked"
+msgstr "リストã¯ãƒ­ãƒƒã‚¯ã•れã¦ã„ã¾ã™"
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: 領域ãŒä¿è­·ã•れã¦ã„ã‚‹ã®ã§, 変更ã§ãã¾ã›ã‚“"
+#, c-format
+msgid "failed to add key '%s' to dictionary"
+msgstr "辞書ã«ã‚­ãƒ¼ '%s' を追加ã™ã‚‹ã®ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans ã¯èª­è¾¼å°‚用ファイルを変更ã™ã‚‹ã“ã¨ã‚’許ã—ã¾ã›ã‚“"
+#, c-format
+msgid "index must be int or slice, not %s"
+msgstr "インデックス㯠%s ã§ã¯ãªãæ•´æ•°ã‹ã‚¹ãƒ©ã‚¤ã‚¹ã«ã—ã¦ãã ã•ã„"
-#~ msgid "Need encryption key for \"%s\""
-#~ msgstr "æš—å·ã‚­ãƒ¼ãŒå¿…è¦ã§ã™: \"%s\""
+#, c-format
+msgid "expected str() or unicode() instance, but got %s"
+msgstr "str() ã‚‚ã—ã㯠unicode() ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
-#~ msgid "empty keys are not allowed"
-#~ msgstr "空ã®ã‚­ãƒ¼ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
+#, c-format
+msgid "expected bytes() or str() instance, but got %s"
+msgstr "bytes() ã‚‚ã—ã㯠str() ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
-#~ msgid "dictionary is locked"
-#~ msgstr "辞書ã¯ãƒ­ãƒƒã‚¯ã•れã¦ã„ã¾ã™"
+#, c-format
+msgid ""
+"expected int(), long() or something supporting coercing to long(), but got %s"
+msgstr "long() ã‹ãれã¸å¤‰æ›å¯èƒ½ãªã‚‚ã®ãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
-#~ msgid "list is locked"
-#~ msgstr "リストã¯ãƒ­ãƒƒã‚¯ã•れã¦ã„ã¾ã™"
+#, c-format
+msgid "expected int() or something supporting coercing to int(), but got %s"
+msgstr "int() ã‹ãれã¸å¤‰æ›å¯èƒ½ãªã‚‚ã®ãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
-#~ msgid "failed to add key '%s' to dictionary"
-#~ msgstr "辞書ã«ã‚­ãƒ¼ '%s' を追加ã™ã‚‹ã®ã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "value is too large to fit into C int type"
+msgstr "C言語㮠int åž‹ã¨ã—ã¦ã¯å€¤ãŒå¤§ãéŽãŽã¾ã™"
-#~ msgid "index must be int or slice, not %s"
-#~ msgstr "インデックス㯠%s ã§ã¯ãªãæ•´æ•°ã‹ã‚¹ãƒ©ã‚¤ã‚¹ã«ã—ã¦ãã ã•ã„"
+msgid "value is too small to fit into C int type"
+msgstr "C言語㮠int åž‹ã¨ã—ã¦ã¯å€¤ãŒå°ã•éŽãŽã¾ã™"
-#~ msgid "expected str() or unicode() instance, but got %s"
-#~ msgstr ""
-#~ "str() ã‚‚ã—ã㯠unicode() ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
+msgid "number must be greater than zero"
+msgstr "数値㯠0 より大ãããªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#~ msgid "expected bytes() or str() instance, but got %s"
-#~ msgstr "bytes() ã‚‚ã—ã㯠str() ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
+msgid "number must be greater or equal to zero"
+msgstr "数値㯠0 ã‹ãれ以上ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#~ msgid ""
-#~ "expected int(), long() or something supporting coercing to long(), but "
-#~ "got %s"
-#~ msgstr "long() ã‹ãれã¸å¤‰æ›å¯èƒ½ãªã‚‚ã®ãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
+msgid "can't delete OutputObject attributes"
+msgstr "OutputObject属性を消ã›ã¾ã›ã‚“"
-#~ msgid "expected int() or something supporting coercing to int(), but got %s"
-#~ msgstr "int() ã‹ãれã¸å¤‰æ›å¯èƒ½ãªã‚‚ã®ãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
+#, c-format
+msgid "invalid attribute: %s"
+msgstr "無効ãªå±žæ€§ã§ã™: %s"
-#~ msgid "value is too large to fit into C int type"
-#~ msgstr "C言語㮠int åž‹ã¨ã—ã¦ã¯å€¤ãŒå¤§ãéŽãŽã¾ã™"
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: I/Oオブジェクトã®åˆæœŸåŒ–エラー"
-#~ msgid "value is too small to fit into C int type"
-#~ msgstr "C言語㮠int åž‹ã¨ã—ã¦ã¯å€¤ãŒå°ã•éŽãŽã¾ã™"
+msgid "failed to change directory"
+msgstr "辞書ã®å¤‰æ›´ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "number must be greater then zero"
-#~ msgstr "数値㯠0 より大ãããªã‘れã°ãªã‚Šã¾ã›ã‚“"
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got %s"
+msgstr "imp.find_module() ㌠%s ã‚’è¿”ã—ã¾ã—㟠(期待値: 3 è¦ç´ ã®ã‚¿ãƒ—ル)"
-#~ msgid "number must be greater or equal to zero"
-#~ msgstr "数値㯠0 ã‹ãれ以上ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
+msgstr "imp.find_module() ㌠%d è¦ç´ ã®ã‚¿ãƒ—ルを返ã—ã¾ã—㟠(期待値: 3)"
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "OutputObject属性を消ã›ã¾ã›ã‚“"
+msgid "internal error: imp.find_module returned tuple with NULL"
+msgstr "内部エラー: imp.find_module ㌠NULL ã‚’å«ã‚€ã‚¿ãƒ—ルを返ã—ã¾ã—ãŸ"
-#~ msgid "invalid attribute: %s"
-#~ msgstr "無効ãªå±žæ€§ã§ã™: %s"
+msgid "cannot delete vim.Dictionary attributes"
+msgstr "vim.Dictionaryå±žæ€§ã¯æ¶ˆã›ã¾ã›ã‚“"
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: I/Oオブジェクトã®åˆæœŸåŒ–エラー"
+msgid "cannot modify fixed dictionary"
+msgstr "固定ã•れãŸè¾žæ›¸ã¯å¤‰æ›´ã§ãã¾ã›ã‚“"
-#~ msgid "failed to change directory"
-#~ msgstr "辞書ã®å¤‰æ›´ã«å¤±æ•—ã—ã¾ã—ãŸ"
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "属性 %s ã¯è¨­å®šã§ãã¾ã›ã‚“"
-#~ msgid "expected 3-tuple as imp.find_module() result, but got %s"
-#~ msgstr "imp.find_module() ㌠%s ã‚’è¿”ã—ã¾ã—㟠(期待値: 2 è¦ç´ ã®ã‚¿ãƒ—ル)"
+msgid "hashtab changed during iteration"
+msgstr "イテレーション中㫠hashtab ãŒå¤‰æ›´ã•れã¾ã—ãŸ"
-#~ msgid ""
-#~ "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
-#~ msgstr "impl.find_module() ㌠%d è¦ç´ ã®ã‚¿ãƒ—ルを返ã—ã¾ã—㟠(期待値: 2)"
+#, c-format
+msgid "expected sequence element of size 2, but got sequence of size %d"
+msgstr "シーケンスã®è¦ç´ æ•°ã«ã¯ 2 ãŒæœŸå¾…ã•れã¦ã„ã¾ã—ãŸãŒ %d ã§ã—ãŸ"
-#~ msgid "internal error: imp.find_module returned tuple with NULL"
-#~ msgstr "内部エラー: imp.find_module ㌠NULL ã‚’å«ã‚€ã‚¿ãƒ—ルを返ã—ã¾ã—ãŸ"
+msgid "list constructor does not accept keyword arguments"
+msgstr "リストã®ã‚³ãƒ³ã‚¹ãƒˆãƒ©ã‚¯ã‚¿ã¯ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰å¼•æ•°ã‚’å—ã‘付ã‘ã¾ã›ã‚“"
-#~ msgid "cannot delete vim.Dictionary attributes"
-#~ msgstr "vim.Dictionaryå±žæ€§ã¯æ¶ˆã›ã¾ã›ã‚“"
+msgid "list index out of range"
+msgstr "リスト範囲外ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã™"
-#~ msgid "cannot modify fixed dictionary"
-#~ 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 "cannot set attribute %s"
-#~ msgstr "属性 %s ã¯è¨­å®šã§ãã¾ã›ã‚“"
+msgid "slice step cannot be zero"
+msgstr "スライスã®ã‚¹ãƒ†ãƒƒãƒ—ã« 0 ã¯æŒ‡å®šã§ãã¾ã›ã‚“"
-#~ msgid "hashtab changed during iteration"
-#~ msgstr "イテレーション中㫠hashtab ãŒå¤‰æ›´ã•れã¾ã—ãŸ"
+#, c-format
+msgid "attempt to assign sequence of size greater than %d to extended slice"
+msgstr "é•·ã• %d ã®æ‹¡å¼µã‚¹ãƒ©ã‚¤ã‚¹ã«ã€ã‚ˆã‚Šé•·ã„スライスを割り当ã¦ã‚ˆã†ã¨ã—ã¾ã—ãŸ"
-#~ msgid "expected sequence element of size 2, but got sequence of size %d"
-#~ msgstr "シーケンスã®è¦ç´ æ•°ã«ã¯ 2 ãŒæœŸå¾…ã•れã¦ã„ã¾ã—ãŸãŒ %d ã§ã—ãŸ"
+#, c-format
+msgid "internal error: no vim list item %d"
+msgstr "内部エラー: vimã®ãƒªã‚¹ãƒˆè¦ç´  %d ã¯ã‚りã¾ã›ã‚“"
-#~ msgid "list constructor does not accept keyword arguments"
-#~ msgstr "リストã®ã‚³ãƒ³ã‚¹ãƒˆãƒ©ã‚¯ã‚¿ã¯ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰å¼•æ•°ã‚’å—ã‘付ã‘ã¾ã›ã‚“"
+msgid "internal error: not enough list items"
+msgstr "内部エラー: リストã«å分ãªè¦ç´ ãŒã‚りã¾ã›ã‚“"
-#~ msgid "list index out of range"
-#~ msgstr "リスト範囲外ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã™"
+msgid "internal error: failed to add item to list"
+msgstr "内部エラー: リストã¸ã®è¦ç´ è¿½åŠ ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "internal error: failed to get vim list item %d"
-#~ msgstr "内部エラー: vimã®ãƒªã‚¹ãƒˆè¦ç´  %d ã®å–å¾—ã«å¤±æ•—ã—ã¾ã—ãŸ"
+#, c-format
+msgid "attempt to assign sequence of size %d to extended slice of size %d"
+msgstr "é•·ã• %d ã®ã‚¹ãƒ©ã‚¤ã‚¹ã‚’ %d ã®æ‹¡å¼µã‚¹ãƒ©ã‚¤ã‚¹ã«å‰²ã‚Šå½“ã¦ã‚ˆã†ã¨ã—ã¾ã—ãŸ"
-#~ msgid "failed to add item to list"
-#~ msgstr "リストã¸ã®è¦ç´ è¿½åŠ ã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "failed to add item to list"
+msgstr "リストã¸ã®è¦ç´ è¿½åŠ ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "internal error: no vim list item %d"
-#~ msgstr "内部エラー: vimã®ãƒªã‚¹ãƒˆè¦ç´  %d ã¯ã‚りã¾ã›ã‚“"
+msgid "cannot delete vim.List attributes"
+msgstr "vim.List å±žæ€§ã¯æ¶ˆã›ã¾ã›ã‚“"
-#~ msgid "internal error: failed to add item to list"
-#~ msgstr "内部エラー: リストã¸ã®è¦ç´ è¿½åŠ ã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "cannot modify fixed list"
+msgstr "固定ã•れãŸãƒªã‚¹ãƒˆã¯å¤‰æ›´ã§ãã¾ã›ã‚“"
-#~ msgid "cannot delete vim.List attributes"
-#~ msgstr "vim.List å±žæ€§ã¯æ¶ˆã›ã¾ã›ã‚“"
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "ç„¡å関数 %s ã¯å­˜åœ¨ã—ã¾ã›ã‚“"
-#~ msgid "cannot modify fixed list"
-#~ msgstr "固定ã•れãŸãƒªã‚¹ãƒˆã¯å¤‰æ›´ã§ãã¾ã›ã‚“"
+#, c-format
+msgid "function %s does not exist"
+msgstr "関数 %s ãŒã‚りã¾ã›ã‚“"
-#~ msgid "unnamed function %s does not exist"
-#~ msgstr "ç„¡å関数 %s ã¯å­˜åœ¨ã—ã¾ã›ã‚“"
+#, c-format
+msgid "failed to run function %s"
+msgstr "関数 %s ã®å®Ÿè¡Œã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "function %s does not exist"
-#~ msgstr "関数 %s ãŒã‚りã¾ã›ã‚“"
+msgid "unable to get option value"
+msgstr "オプションã®å€¤ã¯å–å¾—ã§ãã¾ã›ã‚“"
-#~ msgid "function constructor does not accept keyword arguments"
-#~ msgstr "関数ã®ã‚³ãƒ³ã‚¹ãƒˆãƒ©ã‚¯ã‚¿ã¯ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰å¼•æ•°ã‚’å—ã‘付ã‘ã¾ã›ã‚“"
+msgid "internal error: unknown option type"
+msgstr "内部エラー: 未知ã®ã‚ªãƒ—ション型ã§ã™"
-#~ msgid "failed to run function %s"
-#~ msgstr "関数 %s ã®å®Ÿè¡Œã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "problem while switching windows"
+msgstr "ウィンドウを切æ›ä¸­ã«å•題ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
-#~ msgid "problem while switching windows"
-#~ msgstr "ウィンドウを切æ›ä¸­ã«å•題ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+#, c-format
+msgid "unable to unset global option %s"
+msgstr "グローãƒãƒ«ã‚ªãƒ—ション %s ã®è¨­å®šè§£é™¤ã¯ã§ãã¾ã›ã‚“"
-#~ 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 "unable to unset option %s which does not have global value"
-#~ msgstr "グローãƒãƒ«ãªå€¤ã®ç„¡ã„オプション %s ã®è¨­å®šè§£é™¤ã¯ã§ãã¾ã›ã‚“"
+msgid "attempt to refer to deleted tab page"
+msgstr "削除ã•れãŸã‚¿ãƒ–ã‚’å‚ç…§ã—よã†ã¨ã—ã¾ã—ãŸ"
-#~ msgid "attempt to refer to deleted tab page"
-#~ msgstr "削除ã•れãŸã‚¿ãƒ–ã‚’å‚ç…§ã—よã†ã¨ã—ã¾ã—ãŸ"
+msgid "no such tab page"
+msgstr "ãã®ã‚ˆã†ãªã‚¿ãƒ–ページã¯ã‚りã¾ã›ã‚“"
-#~ msgid "no such tab page"
-#~ msgstr "ãã®ã‚ˆã†ãªã‚¿ãƒ–ページã¯ã‚りã¾ã›ã‚“"
+msgid "attempt to refer to deleted window"
+msgstr "削除ã•れãŸã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’å‚ç…§ã—よã†ã¨ã—ã¾ã—ãŸ"
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "削除ã•れãŸã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’å‚ç…§ã—よã†ã¨ã—ã¾ã—ãŸ"
+msgid "readonly attribute: buffer"
+msgstr "読込専用属性: ãƒãƒƒãƒ•ァー"
-#~ msgid "readonly attribute: buffer"
-#~ msgstr "読込専用属性: ãƒãƒƒãƒ•ァー"
+msgid "cursor position outside buffer"
+msgstr "カーソルä½ç½®ãŒãƒãƒƒãƒ•ã‚¡ã®å¤–å´ã§ã™"
-#~ msgid "cursor position outside buffer"
-#~ msgstr "カーソルä½ç½®ãŒãƒãƒƒãƒ•ã‚¡ã®å¤–å´ã§ã™"
+msgid "no such window"
+msgstr "ãã®ã‚ˆã†ãªã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã¯ã‚りã¾ã›ã‚“"
-#~ msgid "no such window"
-#~ msgstr "ãã®ã‚ˆã†ãªã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã¯ã‚りã¾ã›ã‚“"
+msgid "attempt to refer to deleted buffer"
+msgstr "削除ã•れãŸãƒãƒƒãƒ•ã‚¡ã‚’å‚ç…§ã—よã†ã¨ã—ã¾ã—ãŸ"
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "削除ã•れãŸãƒãƒƒãƒ•ã‚¡ã‚’å‚ç…§ã—よã†ã¨ã—ã¾ã—ãŸ"
+msgid "failed to rename buffer"
+msgstr "ãƒãƒƒãƒ•ã‚¡åã®å¤‰æ›´ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "failed to rename buffer"
-#~ msgstr "ãƒãƒƒãƒ•ã‚¡åã®å¤‰æ›´ã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "mark name must be a single character"
+msgstr "マークåã¯1文字ã®ã‚¢ãƒ«ãƒ•ァベットã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#~ msgid "mark name must be a single character"
-#~ msgstr "マークåã¯1文字ã®ã‚¢ãƒ«ãƒ•ァベットã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+#, c-format
+msgid "expected vim.Buffer object, but got %s"
+msgstr "vim.Bufferã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
-#~ msgid "expected vim.Buffer object, but got %s"
-#~ msgstr "vim.Bufferã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
+#, c-format
+msgid "failed to switch to buffer %d"
+msgstr "指定ã•れãŸãƒãƒƒãƒ•ã‚¡ %d ã¸ã®åˆ‡ã‚Šæ›¿ãˆã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "failed to switch to buffer %d"
-#~ msgstr "指定ã•れãŸãƒãƒƒãƒ•ã‚¡ %d ã¸ã®åˆ‡ã‚Šæ›¿ãˆã«å¤±æ•—ã—ã¾ã—ãŸ"
+#, c-format
+msgid "expected vim.Window object, but got %s"
+msgstr "vim.Windowã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
-#~ msgid "expected vim.Window object, but got %s"
-#~ msgstr "vim.Windowã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
+msgid "failed to find window in the current tab page"
+msgstr "ç¾åœ¨ã®ã‚¿ãƒ–ã«ã¯æŒ‡å®šã•れãŸã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ"
-#~ msgid "failed to find window in the current tab page"
-#~ msgstr "ç¾åœ¨ã®ã‚¿ãƒ–ã«ã¯æŒ‡å®šã•れãŸã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ"
+msgid "did not switch to the specified window"
+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 "expected vim.TabPage object, but got %s"
-#~ msgstr "vim.TabPageã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
+msgid "did not switch to the specified tab page"
+msgstr "指定ã•れãŸã‚¿ãƒ–ページã«åˆ‡ã‚Šæ›¿ãˆã¾ã›ã‚“ã§ã—ãŸ"
-#~ msgid "did not switch to the specified tab page"
-#~ msgstr "指定ã•れãŸã‚¿ãƒ–ページã«åˆ‡ã‚Šæ›¿ãˆã¾ã›ã‚“ã§ã—ãŸ"
+msgid "failed to run the code"
+msgstr "コードã®å®Ÿè¡Œã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "failed to run the code"
-#~ msgstr "コードã®å®Ÿè¡Œã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "E858: Eval did not return a valid python object"
+msgstr "E858: å¼è©•ä¾¡ã¯æœ‰åйãªpythonオブジェクトを返ã—ã¾ã›ã‚“ã§ã—ãŸ"
-#~ 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ã®å€¤ã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ"
-#~ 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ã®è¾žæ›¸åž‹ã«å¤‰æ›ã§ãã¾ã›ã‚“"
-#~ msgid "unable to convert %s to vim dictionary"
-#~ msgstr "%s vimã®è¾žæ›¸åž‹ã«å¤‰æ›ã§ãã¾ã›ã‚“"
+#, c-format
+msgid "unable to convert %s to vim list"
+msgstr "%s ã‚’vimã®ãƒªã‚¹ãƒˆã«å¤‰æ›ã§ãã¾ã›ã‚“"
-#~ msgid "unable to convert %s to vim structure"
-#~ 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: NULL reference passed"
+msgstr "内部エラー: NULLå‚ç…§ãŒæ¸¡ã•れã¾ã—ãŸ"
-#~ msgid "internal error: invalid value type"
-#~ msgstr "内部エラー: 無効ãªå€¤åž‹ã§ã™"
+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 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 ã«è¿½åŠ ã—ã¦ãã ã•ã„"
+msgid ""
+"Failed to set path: sys.path is not a list\n"
+"You should now append vim.VIM_SPECIAL_PATH to sys.path"
+msgstr ""
+"パスã®è¨­å®šã«å¤±æ•—ã—ã¾ã—ãŸ: sys.path ãŒãƒªã‚¹ãƒˆã§ã¯ã‚りã¾ã›ã‚“\n"
+"ã™ãã« vim.VIM_SPECIAL_PATH ã‚’ sys.path ã«è¿½åŠ ã—ã¦ãã ã•ã„"
diff --git a/src/nvim/po/uk.po b/src/nvim/po/uk.po
index cff140508b..2c203f808f 100644
--- a/src/nvim/po/uk.po
+++ b/src/nvim/po/uk.po
@@ -82,7 +82,7 @@ msgid "Key length is too high"
msgstr "Довжина ключа завелика"
#, c-format
-msgid "Key \"%s\" doesn't exist"
+msgid "Key does not exist: %s"
msgstr "Ключ «%s» не Ñ–Ñнує"
msgid "Empty option name"
@@ -3719,7 +3719,7 @@ msgid "Calling shell to execute: \"%s\""
msgstr "ВикликаєтьÑÑ Ð¾Ð±Ð¾Ð»Ð¾Ð½ÐºÐ° щоб виконати: «%s»"
#, c-format
-msgid "Invalid channel \"%<PRIu64>\""
+msgid "Invalid channel: %<PRIu64>"
msgstr "Ðекоректний канал «%<PRIu64>»"
msgid "Message is not an array"
@@ -3734,7 +3734,7 @@ msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¼Ð°Ñ” бути цілим чиÑлом"
msgid "Unknown message type"
msgstr "Ðевідомий тип повідомленнÑ"
-msgid "Request array size should be 4 (request) or 3 (notification)"
+msgid "Request array size must be 4 (request) or 3 (notification)"
msgstr "Розмір маÑиву запиту має бути 4 (запит) чи 3 (повідомленнÑ)"
msgid "ID must be a positive integer"
diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c
index 89180f76de..2462975c9b 100644
--- a/src/nvim/popupmnu.c
+++ b/src/nvim/popupmnu.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// @file popupmnu.c
///
/// Popup menu (PUM)
@@ -38,9 +41,7 @@ static int pum_row; // top row of pum
static int pum_col; // left column of pum
static bool pum_is_visible = false;
-
static bool pum_external = false;
-static bool pum_wants_external = false;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "popupmnu.c.generated.h"
@@ -73,12 +74,11 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed)
int above_row;
int below_row;
int redo_count = 0;
- win_T *pvwin;
if (!pum_is_visible) {
// To keep the code simple, we only allow changing the
// draw mode when the popup menu is not being displayed
- pum_external = pum_wants_external;
+ pum_external = ui_is_external(kUIPopupmenu);
}
redo:
@@ -98,7 +98,6 @@ redo:
}
if (pum_external) {
- Array args = ARRAY_DICT_INIT;
if (array_changed) {
Array arr = ARRAY_DICT_INIT;
for (i = 0; i < size; i++) {
@@ -109,14 +108,9 @@ redo:
ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_info)));
ADD(arr, ARRAY_OBJ(item));
}
- ADD(args, ARRAY_OBJ(arr));
- ADD(args, INTEGER_OBJ(selected));
- ADD(args, INTEGER_OBJ(row));
- ADD(args, INTEGER_OBJ(col));
- ui_event("popupmenu_show", args);
+ ui_call_popupmenu_show(arr, selected, row, col);
} else {
- ADD(args, INTEGER_OBJ(selected));
- ui_event("popupmenu_select", args);
+ ui_call_popupmenu_select(selected);
}
return;
}
@@ -126,8 +120,10 @@ redo:
kind_width = 0;
extra_width = 0;
- FOR_ALL_WINDOWS(pvwin) {
- if (pvwin->w_p_pvw) {
+ win_T *pvwin = NULL;
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ if (wp->w_p_pvw) {
+ pvwin = wp;
break;
}
}
@@ -311,10 +307,10 @@ void pum_redraw(void)
{
int row = pum_row;
int col;
- int attr_norm = highlight_attr[HLF_PNI];
- int attr_select = highlight_attr[HLF_PSI];
- int attr_scroll = highlight_attr[HLF_PSB];
- int attr_thumb = highlight_attr[HLF_PST];
+ int attr_norm = win_hl_attr(curwin, HLF_PNI);
+ int attr_select = win_hl_attr(curwin, HLF_PSI);
+ int attr_scroll = win_hl_attr(curwin, HLF_PSB);
+ int attr_thumb = win_hl_attr(curwin, HLF_PST);
int attr;
int i;
int idx;
@@ -609,13 +605,10 @@ static int pum_set_selected(int n, int repeat)
if (res == OK) {
// Edit a new, empty buffer. Set options for a "wipeout"
// buffer.
- set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
- set_option_value((char_u *)"bt", 0L,
- (char_u *)"nofile", OPT_LOCAL);
- set_option_value((char_u *)"bh", 0L,
- (char_u *)"wipe", OPT_LOCAL);
- set_option_value((char_u *)"diff", 0L,
- NULL, OPT_LOCAL);
+ set_option_value("swf", 0L, NULL, OPT_LOCAL);
+ set_option_value("bt", 0L, "nofile", OPT_LOCAL);
+ set_option_value("bh", 0L, "wipe", OPT_LOCAL);
+ set_option_value("diff", 0L, NULL, OPT_LOCAL);
}
}
@@ -714,8 +707,7 @@ void pum_undisplay(void)
pum_array = NULL;
if (pum_external) {
- Array args = ARRAY_DICT_INIT;
- ui_event("popupmenu_hide", args);
+ ui_call_popupmenu_hide();
} else {
redraw_all_later(SOME_VALID);
redraw_tabline = true;
@@ -750,8 +742,3 @@ int pum_get_height(void)
{
return pum_height;
}
-
-void pum_set_external(bool external)
-{
- pum_wants_external = external;
-}
diff --git a/src/nvim/popupmnu.h b/src/nvim/popupmnu.h
index 2b181f2c4a..7e1588dbdd 100644
--- a/src/nvim/popupmnu.h
+++ b/src/nvim/popupmnu.h
@@ -1,6 +1,8 @@
#ifndef NVIM_POPUPMNU_H
#define NVIM_POPUPMNU_H
+#include "nvim/types.h"
+
/// Used for popup menu items.
typedef struct {
char_u *pum_text; // main menu text
diff --git a/src/nvim/pos.h b/src/nvim/pos.h
index 864f3fe866..966255e6a4 100644
--- a/src/nvim/pos.h
+++ b/src/nvim/pos.h
@@ -2,6 +2,8 @@
#define NVIM_POS_H
typedef long linenr_T; // line number type
+/// Format used to print values which have linenr_T type
+#define PRIdLINENR "ld"
/// Column number type
typedef int colnr_T;
diff --git a/src/nvim/profile.c b/src/nvim/profile.c
index 97d7d77359..8fb8e92add 100644
--- a/src/nvim/profile.c
+++ b/src/nvim/profile.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <stdio.h>
#include <math.h>
#include <assert.h>
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 33a84660c1..e6b1e7b95a 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* quickfix.c: functions for quickfix mode, using a file with error messages
*/
@@ -137,6 +140,40 @@ struct efm_S {
int conthere; /* %> used */
};
+enum {
+ QF_FAIL = 0,
+ QF_OK = 1,
+ QF_END_OF_INPUT = 2,
+ QF_NOMEM = 3,
+ QF_IGNORE_LINE = 4
+};
+
+typedef struct {
+ char_u *linebuf;
+ size_t linelen;
+ char_u *growbuf;
+ size_t growbufsiz;
+ FILE *fd;
+ typval_T *tv;
+ char_u *p_str;
+ listitem_T *p_li;
+ buf_T *buf;
+ linenr_T buflnum;
+ linenr_T lnumlast;
+} qfstate_T;
+
+typedef struct {
+ char_u *namebuf;
+ char_u *errmsg;
+ size_t errmsglen;
+ long lnum;
+ int col;
+ bool use_viscol;
+ char_u *pattern;
+ int enr;
+ char_u type;
+ bool valid;
+} qffields_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "quickfix.c.generated.h"
@@ -151,6 +188,11 @@ struct efm_S {
*/
#define GET_LOC_LIST(wp) (IS_LL_WINDOW(wp) ? wp->w_llist_ref : wp->w_llist)
+// Looking up a buffer can be slow if there are many. Remember the last one
+// to make this a lot faster if there are multiple matches in the same file.
+static char_u *qf_last_bufname = NULL;
+static bufref_T qf_last_bufref = { NULL, 0, 0 };
+
/*
* Read the errorfile "efile" into memory, line by line, building the error
* list. Set the error list's title to qf_title.
@@ -179,22 +221,6 @@ qf_init (
// Maximum number of bytes allowed per line while reading an errorfile.
static const size_t LINE_MAXLEN = 4096;
-static char_u *qf_grow_linebuf(char_u **growbuf, size_t *growbufsiz,
- size_t newsz, size_t *allocsz)
-{
- // If the line exceeds LINE_MAXLEN exclude the last
- // byte since it's not a NL character.
- *allocsz = newsz > LINE_MAXLEN ? LINE_MAXLEN - 1 : newsz;
- if (*growbuf == NULL) {
- *growbuf = xmalloc(*allocsz + 1);
- *growbufsiz = *allocsz;
- } else if (*allocsz > *growbufsiz) {
- *growbuf = xrealloc(*growbuf, *allocsz + 1);
- *growbufsiz = *allocsz;
- }
- return *growbuf;
-}
-
static struct fmtpattern
{
char_u convchar;
@@ -357,6 +383,8 @@ static int efm_to_regpat(char_u *efm, int len, efm_T *fmt_ptr,
return 0;
}
+static efm_T *fmt_start = NULL; // cached across qf_parse_line() calls
+
static void free_efm_list(efm_T **efm_first)
{
for (efm_T *efm_ptr = *efm_first; efm_ptr != NULL; efm_ptr = *efm_first) {
@@ -364,6 +392,8 @@ static void free_efm_list(efm_T **efm_first)
vim_regfree(efm_ptr->prog);
xfree(efm_ptr);
}
+
+ fmt_start = NULL;
}
// Parse 'errorformat' option
@@ -428,6 +458,495 @@ parse_efm_end:
return fmt_first;
}
+static char_u *qf_grow_linebuf(qfstate_T *state, size_t newsz)
+{
+ // If the line exceeds LINE_MAXLEN exclude the last
+ // byte since it's not a NL character.
+ state->linelen = newsz > LINE_MAXLEN ? LINE_MAXLEN - 1 : newsz;
+ if (state->growbuf == NULL) {
+ state->growbuf = xmalloc(state->linelen + 1);
+ state->growbufsiz = state->linelen;
+ } else if (state->linelen > state->growbufsiz) {
+ state->growbuf = xrealloc(state->growbuf, state->linelen + 1);
+ state->growbufsiz = state->linelen;
+ }
+ return state->growbuf;
+}
+
+/// Get the next string (separated by newline) from state->p_str.
+static int qf_get_next_str_line(qfstate_T *state)
+{
+ // Get the next line from the supplied string
+ char_u *p_str = state->p_str;
+ char_u *p;
+ size_t len;
+
+ if (*p_str == NUL) { // Reached the end of the string
+ return QF_END_OF_INPUT;
+ }
+
+ p = vim_strchr(p_str, '\n');
+ if (p != NULL) {
+ len = (size_t)(p - p_str) + 1;
+ } else {
+ len = STRLEN(p_str);
+ }
+
+ if (len > IOSIZE - 2) {
+ state->linebuf = qf_grow_linebuf(state, len);
+ } else {
+ state->linebuf = IObuff;
+ state->linelen = len;
+ }
+ STRLCPY(state->linebuf, p_str, state->linelen + 1);
+
+ // Increment using len in order to discard the rest of the line if it
+ // exceeds LINE_MAXLEN.
+ p_str += len;
+ state->p_str = p_str;
+
+ return QF_OK;
+}
+
+/// Get the next string from state->p_Li.
+static int qf_get_next_list_line(qfstate_T *state)
+{
+ listitem_T *p_li = state->p_li;
+ size_t len;
+
+ // Get the next line from the supplied list
+ while (p_li != NULL
+ && (p_li->li_tv.v_type != VAR_STRING
+ || p_li->li_tv.vval.v_string == NULL)) {
+ p_li = p_li->li_next; // Skip non-string items
+ }
+
+ if (p_li == NULL) { // End of the list
+ state->p_li = NULL;
+ return QF_END_OF_INPUT;
+ }
+
+ len = STRLEN(p_li->li_tv.vval.v_string);
+ if (len > IOSIZE - 2) {
+ state->linebuf = qf_grow_linebuf(state, len);
+ } else {
+ state->linebuf = IObuff;
+ state->linelen = len;
+ }
+
+ STRLCPY(state->linebuf, p_li->li_tv.vval.v_string, state->linelen + 1);
+
+ state->p_li = p_li->li_next; // next item
+ return QF_OK;
+}
+
+/// Get the next string from state->buf.
+static int qf_get_next_buf_line(qfstate_T *state)
+{
+ char_u *p_buf = NULL;
+ size_t len;
+
+ // Get the next line from the supplied buffer
+ if (state->buflnum > state->lnumlast) {
+ return QF_END_OF_INPUT;
+ }
+ p_buf = ml_get_buf(state->buf, state->buflnum, false);
+ state->buflnum += 1;
+
+ len = STRLEN(p_buf);
+ if (len > IOSIZE - 2) {
+ state->linebuf = qf_grow_linebuf(state, len);
+ } else {
+ state->linebuf = IObuff;
+ state->linelen = len;
+ }
+ STRLCPY(state->linebuf, p_buf, state->linelen + 1);
+
+ return QF_OK;
+}
+
+/// Get the next string from file state->fd.
+static int qf_get_next_file_line(qfstate_T *state)
+{
+ size_t growbuflen;
+
+ if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL) {
+ return QF_END_OF_INPUT;
+ }
+
+ bool discard = false;
+ state->linelen = STRLEN(IObuff);
+ if (state->linelen == IOSIZE - 1
+ && !(IObuff[state->linelen - 1] == '\n')) {
+ // The current line exceeds IObuff, continue reading using growbuf
+ // until EOL or LINE_MAXLEN bytes is read.
+ if (state->growbuf == NULL) {
+ state->growbufsiz = 2 * (IOSIZE - 1);
+ state->growbuf = xmalloc(state->growbufsiz);
+ }
+
+ // Copy the read part of the line, excluding null-terminator
+ memcpy(state->growbuf, IObuff, IOSIZE - 1);
+ growbuflen = state->linelen;
+
+ for (;;) {
+ if (fgets((char *)state->growbuf + growbuflen,
+ (int)(state->growbufsiz - growbuflen), state->fd) == NULL) {
+ break;
+ }
+ state->linelen = STRLEN(state->growbuf + growbuflen);
+ growbuflen += state->linelen;
+ if (state->growbuf[growbuflen - 1] == '\n') {
+ break;
+ }
+ if (state->growbufsiz == LINE_MAXLEN) {
+ discard = true;
+ break;
+ }
+
+ state->growbufsiz = (2 * state->growbufsiz < LINE_MAXLEN)
+ ? 2 * state->growbufsiz : LINE_MAXLEN;
+ state->growbuf = xrealloc(state->growbuf, state->growbufsiz);
+ }
+
+ while (discard) {
+ // The current line is longer than LINE_MAXLEN, continue reading but
+ // discard everything until EOL or EOF is reached.
+ if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL
+ || STRLEN(IObuff) < IOSIZE - 1
+ || IObuff[IOSIZE - 1] == '\n') {
+ break;
+ }
+ }
+
+ state->linebuf = state->growbuf;
+ state->linelen = growbuflen;
+ } else {
+ state->linebuf = IObuff;
+ }
+ return QF_OK;
+}
+
+/// Get the next string from a file/buffer/list/string.
+static int qf_get_nextline(qfstate_T *state)
+{
+ int status = QF_FAIL;
+
+ if (state->fd == NULL) {
+ if (state->tv != NULL) {
+ if (state->tv->v_type == VAR_STRING) {
+ // Get the next line from the supplied string
+ status = qf_get_next_str_line(state);
+ } else if (state->tv->v_type == VAR_LIST) {
+ // Get the next line from the supplied list
+ status = qf_get_next_list_line(state);
+ }
+ } else {
+ // Get the next line from the supplied buffer
+ status = qf_get_next_buf_line(state);
+ }
+ } else {
+ // Get the next line from the supplied file
+ status = qf_get_next_file_line(state);
+ }
+
+ if (status != QF_OK) {
+ return status;
+ }
+
+ if (state->linelen > 0 && state->linebuf[state->linelen - 1] == '\n') {
+ state->linebuf[state->linelen - 1] = NUL;
+#ifdef USE_CRNL
+ if (state->linelen > 1 && state->linebuf[state->linelen - 2] == '\r') {
+ state->linebuf[state->linelen - 2] = NUL;
+ }
+#endif
+ }
+
+ remove_bom(state->linebuf);
+
+ return QF_OK;
+}
+
+
+/// Parse a line and get the quickfix fields.
+/// Return the QF_ status.
+static int qf_parse_line(qf_info_T *qi, char_u *linebuf, size_t linelen,
+ efm_T *fmt_first, qffields_T *fields)
+{
+ efm_T *fmt_ptr;
+ size_t len;
+ int i;
+ int idx = 0;
+ char_u *tail = NULL;
+ regmatch_T regmatch;
+
+
+ // Always ignore case when looking for a matching error.
+ regmatch.rm_ic = true;
+
+ // If there was no %> item start at the first pattern
+ if (fmt_start == NULL) {
+ fmt_ptr = fmt_first;
+ } else {
+ fmt_ptr = fmt_start;
+ fmt_start = NULL;
+ }
+
+ // Try to match each part of 'errorformat' until we find a complete
+ // match or no match.
+ fields->valid = true;
+restofline:
+ for (; fmt_ptr != NULL; fmt_ptr = fmt_ptr->next) {
+ idx = fmt_ptr->prefix;
+ if (qi->qf_multiscan && vim_strchr((char_u *)"OPQ", idx) == NULL) {
+ continue;
+ }
+ fields->namebuf[0] = NUL;
+ fields->pattern[0] = NUL;
+ if (!qi->qf_multiscan) {
+ fields->errmsg[0] = NUL;
+ }
+ fields->lnum = 0;
+ fields->col = 0;
+ fields->use_viscol = false;
+ fields->enr = -1;
+ fields->type = 0;
+ tail = NULL;
+
+ regmatch.regprog = fmt_ptr->prog;
+ int r = vim_regexec(&regmatch, linebuf, (colnr_T)0);
+ fmt_ptr->prog = regmatch.regprog;
+ if (r) {
+ if ((idx == 'C' || idx == 'Z') && !qi->qf_multiline) {
+ continue;
+ }
+ if (vim_strchr((char_u *)"EWI", idx) != NULL) {
+ fields->type = (char_u)idx;
+ } else {
+ fields->type = 0;
+ }
+ // Extract error message data from matched line.
+ // We check for an actual submatch, because "\[" and "\]" in
+ // the 'errorformat' may cause the wrong submatch to be used.
+ if ((i = (int)fmt_ptr->addr[0]) > 0) { // %f
+ if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) {
+ continue;
+ }
+ // Expand ~/file and $HOME/file to full path.
+ char_u c = *regmatch.endp[i];
+ *regmatch.endp[i] = NUL;
+ expand_env(regmatch.startp[i], fields->namebuf, CMDBUFFSIZE);
+ *regmatch.endp[i] = c;
+
+ if (vim_strchr((char_u *)"OPQ", idx) != NULL
+ && !os_path_exists(fields->namebuf)) {
+ continue;
+ }
+ }
+ if ((i = (int)fmt_ptr->addr[1]) > 0) { // %n
+ if (regmatch.startp[i] == NULL) {
+ continue;
+ }
+ fields->enr = (int)atol((char *)regmatch.startp[i]);
+ }
+ if ((i = (int)fmt_ptr->addr[2]) > 0) { // %l
+ if (regmatch.startp[i] == NULL) {
+ continue;
+ }
+ fields->lnum = atol((char *)regmatch.startp[i]);
+ }
+ if ((i = (int)fmt_ptr->addr[3]) > 0) { // %c
+ if (regmatch.startp[i] == NULL) {
+ continue;
+ }
+ fields->col = (int)atol((char *)regmatch.startp[i]);
+ }
+ if ((i = (int)fmt_ptr->addr[4]) > 0) { // %t
+ if (regmatch.startp[i] == NULL) {
+ continue;
+ }
+ fields->type = *regmatch.startp[i];
+ }
+ if (fmt_ptr->flags == '+' && !qi->qf_multiscan) { // %+
+ if (linelen > fields->errmsglen) {
+ // linelen + null terminator
+ fields->errmsg = xrealloc(fields->errmsg, linelen + 1);
+ fields->errmsglen = linelen + 1;
+ }
+ STRLCPY(fields->errmsg, linebuf, linelen + 1);
+ } else if ((i = (int)fmt_ptr->addr[5]) > 0) { // %m
+ if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) {
+ continue;
+ }
+ len = (size_t)(regmatch.endp[i] - regmatch.startp[i]);
+ if (len > fields->errmsglen) {
+ // len + null terminator
+ fields->errmsg = xrealloc(fields->errmsg, len + 1);
+ fields->errmsglen = len + 1;
+ }
+ STRLCPY(fields->errmsg, regmatch.startp[i], len + 1);
+ }
+ if ((i = (int)fmt_ptr->addr[6]) > 0) { // %r
+ if (regmatch.startp[i] == NULL) {
+ continue;
+ }
+ tail = regmatch.startp[i];
+ }
+ if ((i = (int)fmt_ptr->addr[7]) > 0) { // %p
+ char_u *match_ptr;
+
+ if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) {
+ continue;
+ }
+ fields->col = 0;
+ for (match_ptr = regmatch.startp[i];
+ match_ptr != regmatch.endp[i]; match_ptr++) {
+ fields->col++;
+ if (*match_ptr == TAB) {
+ fields->col += 7;
+ fields->col -= fields->col % 8;
+ }
+ }
+ fields->col++;
+ fields->use_viscol = true;
+ }
+ if ((i = (int)fmt_ptr->addr[8]) > 0) { // %v
+ if (regmatch.startp[i] == NULL) {
+ continue;
+ }
+ fields->col = (int)atol((char *)regmatch.startp[i]);
+ fields->use_viscol = true;
+ }
+ if ((i = (int)fmt_ptr->addr[9]) > 0) { // %s
+ if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) {
+ continue;
+ }
+ len = (size_t)(regmatch.endp[i] - regmatch.startp[i]);
+ if (len > CMDBUFFSIZE - 5) {
+ len = CMDBUFFSIZE - 5;
+ }
+ STRCPY(fields->pattern, "^\\V");
+ xstrlcat((char *)fields->pattern, (char *)regmatch.startp[i],
+ CMDBUFFSIZE+1);
+ fields->pattern[len + 3] = '\\';
+ fields->pattern[len + 4] = '$';
+ fields->pattern[len + 5] = NUL;
+ }
+ break;
+ }
+ }
+ qi->qf_multiscan = false;
+
+ if (fmt_ptr == NULL || idx == 'D' || idx == 'X') {
+ if (fmt_ptr != NULL) {
+ if (idx == 'D') { // enter directory
+ if (*fields->namebuf == NUL) {
+ EMSG(_("E379: Missing or empty directory name"));
+ return QF_FAIL;
+ }
+ qi->qf_directory = qf_push_dir(fields->namebuf, &qi->qf_dir_stack,
+ false);
+ if (qi->qf_directory == NULL) {
+ return QF_FAIL;
+ }
+ } else if (idx == 'X') { // leave directory
+ qi->qf_directory = qf_pop_dir(&qi->qf_dir_stack);
+ }
+ }
+ fields->namebuf[0] = NUL; // no match found, remove file name
+ fields->lnum = 0; // don't jump to this line
+ fields->valid = false;
+ if (linelen > fields->errmsglen) {
+ // linelen + null terminator
+ fields->errmsg = xrealloc(fields->errmsg, linelen + 1);
+ fields->errmsglen = linelen + 1;
+ }
+ // copy whole line to error message
+ STRLCPY(fields->errmsg, linebuf, linelen + 1);
+ if (fmt_ptr == NULL) {
+ qi->qf_multiline = qi->qf_multiignore = false;
+ }
+ } else {
+ // honor %> item
+ if (fmt_ptr->conthere) {
+ fmt_start = fmt_ptr;
+ }
+
+ if (vim_strchr((char_u *)"AEWI", idx) != NULL) {
+ qi->qf_multiline = true; // start of a multi-line message
+ qi->qf_multiignore = false; // reset continuation
+ } else if (vim_strchr((char_u *)"CZ", idx)
+ != NULL) { // continuation of multi-line msg
+ if (!qi->qf_multiignore) {
+ qfline_T *qfprev = qi->qf_lists[qi->qf_curlist].qf_last;
+ if (qfprev == NULL) {
+ return QF_FAIL;
+ }
+ if (*fields->errmsg && !qi->qf_multiignore) {
+ size_t len = STRLEN(qfprev->qf_text);
+ qfprev->qf_text = xrealloc(qfprev->qf_text,
+ len + STRLEN(fields->errmsg) + 2);
+ qfprev->qf_text[len] = '\n';
+ STRCPY(qfprev->qf_text + len + 1, fields->errmsg);
+ }
+ if (qfprev->qf_nr == -1) {
+ qfprev->qf_nr = fields->enr;
+ }
+ if (vim_isprintc(fields->type) && !qfprev->qf_type) {
+ qfprev->qf_type = fields->type; // only printable chars allowed
+ }
+ if (!qfprev->qf_lnum) {
+ qfprev->qf_lnum = fields->lnum;
+ }
+ if (!qfprev->qf_col) {
+ qfprev->qf_col = fields->col;
+ }
+ qfprev->qf_viscol = fields->use_viscol;
+ if (!qfprev->qf_fnum) {
+ qfprev->qf_fnum = qf_get_fnum(qi, qi->qf_directory,
+ *fields->namebuf || qi->qf_directory
+ ? fields->namebuf
+ : qi->qf_currfile && fields->valid
+ ? qi->qf_currfile : 0);
+ }
+ }
+ if (idx == 'Z') {
+ qi->qf_multiline = qi->qf_multiignore = false;
+ }
+
+ line_breakcheck();
+ return QF_IGNORE_LINE;
+ } else if (vim_strchr((char_u *)"OPQ", idx) != NULL) {
+ // global file names
+ fields->valid = false;
+ if (*fields->namebuf == NUL || os_path_exists(fields->namebuf)) {
+ if (*fields->namebuf && idx == 'P') {
+ qi->qf_currfile = qf_push_dir(fields->namebuf, &qi->qf_file_stack,
+ true);
+ } else if (idx == 'Q') {
+ qi->qf_currfile = qf_pop_dir(&qi->qf_file_stack);
+ }
+ *fields->namebuf = NUL;
+ if (tail && *tail) {
+ STRMOVE(IObuff, skipwhite(tail));
+ qi->qf_multiscan = true;
+ goto restofline;
+ }
+ }
+ }
+ if (fmt_ptr->flags == '-') { // generally exclude this line
+ if (qi->qf_multiline) {
+ // also exclude continuation lines
+ qi->qf_multiignore = true;
+ }
+ return QF_IGNORE_LINE;
+ }
+ }
+
+ return QF_OK;
+}
+
// Read the errorfile "efile" into memory, line by line, building the error
// list.
// Alternative: when "efile" is NULL read errors from buffer "buf".
@@ -449,45 +968,27 @@ qf_init_ext(
char_u *qf_title
)
{
- char_u *namebuf;
- char_u *errmsg;
- size_t errmsglen;
- char_u *pattern;
- char_u *growbuf = NULL;
- size_t growbuflen;
- size_t growbufsiz = 0;
- char_u *linebuf = NULL;
- size_t linelen = 0;
- bool discard;
- int col = 0;
- bool use_viscol = false;
- char_u type = 0;
- linenr_T buflnum = lnumfirst;
- long lnum = 0L;
- int enr = 0;
- FILE *fd = NULL;
+ qfstate_T state = { NULL, 0, NULL, 0, NULL, NULL, NULL, NULL,
+ NULL, 0, 0 };
+ qffields_T fields = { NULL, NULL, 0, 0L, 0, false, NULL, 0, 0, 0 };
qfline_T *old_last = NULL;
+ bool adding = false;
static efm_T *fmt_first = NULL;
- efm_T *fmt_ptr;
- efm_T *fmt_start = NULL;
char_u *efm;
static char_u *last_efm = NULL;
- size_t len;
- int i;
- int idx = 0;
int retval = -1; // default: return error flag
- char_u *tail = NULL;
- char_u *p_buf = NULL;
- char_u *p_str = NULL;
- listitem_T *p_li = NULL;
- regmatch_T regmatch;
+ int status;
- namebuf = xmalloc(CMDBUFFSIZE + 1);
- errmsglen = CMDBUFFSIZE + 1;
- errmsg = xmalloc(errmsglen);
- pattern = xmalloc(CMDBUFFSIZE + 1);
+ // Do not used the cached buffer, it may have been wiped out.
+ xfree(qf_last_bufname);
+ qf_last_bufname = NULL;
- if (efile != NULL && (fd = mch_fopen((char *)efile, "r")) == NULL) {
+ fields.namebuf = xmalloc(CMDBUFFSIZE + 1);
+ fields.errmsglen = CMDBUFFSIZE + 1;
+ fields.errmsg = xmalloc(fields.errmsglen);
+ fields.pattern = xmalloc(CMDBUFFSIZE + 1);
+
+ if (efile != NULL && (state.fd = mch_fopen((char *)efile, "r")) == NULL) {
EMSG2(_(e_openerrf), efile);
goto qf_init_end;
}
@@ -497,18 +998,16 @@ qf_init_ext(
qf_new_list(qi, qf_title);
} else if (qi->qf_lists[qi->qf_curlist].qf_count > 0) {
// Adding to existing list, use last entry.
+ adding = true;
old_last = qi->qf_lists[qi->qf_curlist].qf_last;
}
- /*
- * 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)
+ // Use the local value of 'errorformat' if it's set.
+ if (errorformat == p_efm && tv == NULL && buf && *buf->b_p_efm != NUL) {
efm = buf->b_p_efm;
- else
+ } else {
efm = errorformat;
+ }
// If we are not adding or adding to another list: clear the state.
if (newlist || qi->qf_curlist != qi->qf_dir_curlist) {
@@ -547,424 +1046,57 @@ qf_init_ext(
*/
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;
+ if (tv->v_type == VAR_STRING) {
+ state.p_str = tv->vval.v_string;
+ } else if (tv->v_type == VAR_LIST) {
+ state.p_li = tv->vval.v_list->lv_first;
+ }
+ state.tv = tv;
}
+ state.buf = buf;
+ state.buflnum = lnumfirst;
+ state.lnumlast = lnumlast;
/*
* Read the lines in the error file one by one.
* Try to recognize one of the error formats in each line.
*/
while (!got_int) {
- /* Get the next line. */
- 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 == NUL) { // Reached the end of the string
- break;
- }
-
- p = vim_strchr(p_str, '\n');
- if (p != NULL) {
- len = (size_t)(p - p_str) + 1;
- } else {
- len = STRLEN(p_str);
- }
-
- if (len > IOSIZE - 2) {
- linebuf = qf_grow_linebuf(&growbuf, &growbufsiz, len, &linelen);
- } else {
- linebuf = IObuff;
- linelen = len;
- }
- STRLCPY(linebuf, p_str, linelen + 1);
-
- // Increment using len in order to discard the rest of the line if it
- // exceeds LINE_MAXLEN.
- p_str += len;
- } else if (tv->v_type == VAR_LIST) {
- // Get the next line from the supplied list
- while (p_li != NULL
- && (p_li->li_tv.v_type != VAR_STRING
- || p_li->li_tv.vval.v_string == NULL)) {
- p_li = p_li->li_next; // Skip non-string items
- }
-
- if (p_li == NULL) { // End of the list
- break;
- }
-
- len = STRLEN(p_li->li_tv.vval.v_string);
- if (len > IOSIZE - 2) {
- linebuf = qf_grow_linebuf(&growbuf, &growbufsiz, len, &linelen);
- } else {
- linebuf = IObuff;
- linelen = len;
- }
-
- STRLCPY(linebuf, p_li->li_tv.vval.v_string, linelen + 1);
-
- p_li = p_li->li_next; /* next item */
- }
- } else {
- /* Get the next line from the supplied buffer */
- if (buflnum > lnumlast)
- break;
- p_buf = ml_get_buf(buf, buflnum++, false);
- len = STRLEN(p_buf);
- if (len > IOSIZE - 2) {
- linebuf = qf_grow_linebuf(&growbuf, &growbufsiz, len, &linelen);
- } else {
- linebuf = IObuff;
- linelen = len;
- }
- STRLCPY(linebuf, p_buf, linelen + 1);
- }
- } else {
- if (fgets((char *)IObuff, IOSIZE, fd) == NULL) {
- break;
- }
-
- discard = false;
- linelen = STRLEN(IObuff);
- if (linelen == IOSIZE - 1 && !(IObuff[linelen - 1] == '\n'
-#ifdef USE_CRNL
- || IObuff[linelen - 1] == '\r'
-#endif
- )) { // NOLINT(whitespace/parens)
- // The current line exceeds IObuff, continue reading using growbuf
- // until EOL or LINE_MAXLEN bytes is read.
- if (growbuf == NULL) {
- growbufsiz = 2 * (IOSIZE - 1);
- growbuf = xmalloc(growbufsiz);
- }
-
- // Copy the read part of the line, excluding null-terminator
- memcpy(growbuf, IObuff, IOSIZE - 1);
- growbuflen = linelen;
-
- for (;;) {
- if (fgets((char *)growbuf + growbuflen,
- (int)(growbufsiz - growbuflen), fd) == NULL) {
- break;
- }
- linelen = STRLEN(growbuf + growbuflen);
- growbuflen += linelen;
- if (growbuf[growbuflen - 1] == '\n'
-#ifdef USE_CRNL
- || growbuf[growbuflen - 1] == '\r'
-#endif
- ) {
- break;
- }
- if (growbufsiz == LINE_MAXLEN) {
- discard = true;
- break;
- }
-
- growbufsiz = (2 * growbufsiz < LINE_MAXLEN)
- ? 2 * growbufsiz : LINE_MAXLEN;
- growbuf = xrealloc(growbuf, 2 * growbufsiz);
- }
-
- while (discard) {
- // The current line is longer than LINE_MAXLEN, continue reading but
- // discard everything until EOL or EOF is reached.
- if (fgets((char *)IObuff, IOSIZE, fd) == NULL
- || STRLEN(IObuff) < IOSIZE - 1
- || IObuff[IOSIZE - 1] == '\n'
-#ifdef USE_CRNL
- || IObuff[IOSIZE - 1] == '\r'
-#endif
- ) {
- break;
- }
- }
-
- linebuf = growbuf;
- linelen = growbuflen;
- } else {
- linebuf = IObuff;
- }
- }
-
- if (linelen > 0 && linebuf[linelen - 1] == '\n') {
- linebuf[linelen - 1] = NUL;
- }
-#ifdef USE_CRNL
- if (linelen > 0 && linebuf[linelen - 1] == '\r') {
- linebuf[linelen - 1] = NUL;
- }
-#endif
-
- remove_bom(linebuf);
-
- /* 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;
+ // Get the next line from a file/buffer/list/string
+ status = qf_get_nextline(&state);
+ if (status == QF_END_OF_INPUT) { // end of input
+ break;
}
- // Try to match each part of 'errorformat' until we find a complete
- // match or no match.
- bool valid = true;
-restofline:
- for (; fmt_ptr != NULL; fmt_ptr = fmt_ptr->next) {
- idx = fmt_ptr->prefix;
- if (qi->qf_multiscan && vim_strchr((char_u *)"OPQ", idx) == NULL) {
- continue;
- }
- namebuf[0] = NUL;
- pattern[0] = NUL;
- if (!qi->qf_multiscan) {
- errmsg[0] = NUL;
- }
- lnum = 0;
- col = 0;
- use_viscol = false;
- enr = -1;
- type = 0;
- tail = NULL;
-
- regmatch.regprog = fmt_ptr->prog;
- int r = vim_regexec(&regmatch, linebuf, (colnr_T)0);
- fmt_ptr->prog = regmatch.regprog;
- if (r) {
- if ((idx == 'C' || idx == 'Z') && !qi->qf_multiline) {
- continue;
- }
- if (vim_strchr((char_u *)"EWI", idx) != NULL) {
- type = (char_u)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
- if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) {
- continue;
- }
- // Expand ~/file and $HOME/file to full path.
- char_u c = *regmatch.endp[i];
- *regmatch.endp[i] = NUL;
- expand_env(regmatch.startp[i], namebuf, CMDBUFFSIZE);
- *regmatch.endp[i] = c;
-
- if (vim_strchr((char_u *)"OPQ", idx) != NULL
- && !os_path_exists(namebuf)) {
- continue;
- }
- }
- if ((i = (int)fmt_ptr->addr[1]) > 0) { /* %n */
- if (regmatch.startp[i] == NULL)
- continue;
- 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 == '+' && !qi->qf_multiscan) { // %+
- if (linelen > errmsglen) {
- // linelen + null terminator
- errmsg = xrealloc(errmsg, linelen + 1);
- errmsglen = linelen + 1;
- }
- STRLCPY(errmsg, linebuf, linelen + 1);
- } else if ((i = (int)fmt_ptr->addr[5]) > 0) { // %m
- if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) {
- continue;
- }
- len = (size_t)(regmatch.endp[i] - regmatch.startp[i]);
- if (len > errmsglen) {
- // len + null terminator
- errmsg = xrealloc(errmsg, len + 1);
- errmsglen = len + 1;
- }
- STRLCPY(errmsg, regmatch.startp[i], len + 1);
- }
- if ((i = (int)fmt_ptr->addr[6]) > 0) { /* %r */
- if (regmatch.startp[i] == NULL)
- continue;
- tail = regmatch.startp[i];
- }
- if ((i = (int)fmt_ptr->addr[7]) > 0) { /* %p */
- char_u *match_ptr;
-
- if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL)
- continue;
- col = 0;
- for (match_ptr = regmatch.startp[i];
- match_ptr != regmatch.endp[i]; ++match_ptr) {
- ++col;
- if (*match_ptr == TAB) {
- col += 7;
- col -= col % 8;
- }
- }
- 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 = (size_t)(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;
- }
+ status = qf_parse_line(qi, state.linebuf, state.linelen, fmt_first,
+ &fields);
+ if (status == QF_FAIL) {
+ goto error2;
}
- qi->qf_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;
- }
- qi->qf_directory = qf_push_dir(namebuf, &qi->qf_dir_stack, false);
- if (qi->qf_directory == NULL) {
- goto error2;
- }
- } else if (idx == 'X') { // leave directory
- qi->qf_directory = qf_pop_dir(&qi->qf_dir_stack);
- }
- }
- namebuf[0] = NUL; // no match found, remove file name
- lnum = 0; // don't jump to this line
- valid = false;
- if (linelen > errmsglen) {
- // linelen + null terminator
- errmsg = xrealloc(errmsg, linelen + 1);
- }
- // copy whole line to error message
- STRLCPY(errmsg, linebuf, linelen + 1);
- if (fmt_ptr == NULL) {
- qi->qf_multiline = qi->qf_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) {
- qi->qf_multiline = true; // start of a multi-line message
- qi->qf_multiignore = false; // reset continuation
- } else if (vim_strchr((char_u *)"CZ", idx)
- != NULL) { // continuation of multi-line msg
- qfline_T *qfprev = qi->qf_lists[qi->qf_curlist].qf_last;
- if (qfprev == NULL) {
- goto error2;
- }
- if (*errmsg && !qi->qf_multiignore) {
- size_t len = STRLEN(qfprev->qf_text);
- qfprev->qf_text = xrealloc(qfprev->qf_text, len + STRLEN(errmsg) + 2);
- qfprev->qf_text[len] = '\n';
- STRCPY(qfprev->qf_text + len + 1, errmsg);
- }
- if (qfprev->qf_nr == -1)
- qfprev->qf_nr = enr;
- if (vim_isprintc(type) && !qfprev->qf_type)
- qfprev->qf_type = type; /* only printable chars allowed */
- if (!qfprev->qf_lnum)
- qfprev->qf_lnum = lnum;
- if (!qfprev->qf_col)
- qfprev->qf_col = col;
- qfprev->qf_viscol = use_viscol;
- if (!qfprev->qf_fnum) {
- qfprev->qf_fnum = qf_get_fnum(qi, qi->qf_directory,
- *namebuf
- || qi->qf_directory
- ? namebuf : qi->qf_currfile
- && valid ? qi->qf_currfile : 0);
- }
- if (idx == 'Z') {
- qi->qf_multiline = qi->qf_multiignore = false;
- }
- line_breakcheck();
- continue;
- } else if (vim_strchr((char_u *)"OPQ", idx) != NULL) {
- // global file names
- valid = false;
- if (*namebuf == NUL || os_path_exists(namebuf)) {
- if (*namebuf && idx == 'P') {
- qi->qf_currfile = qf_push_dir(namebuf, &qi->qf_file_stack, true);
- } else if (idx == 'Q') {
- qi->qf_currfile = qf_pop_dir(&qi->qf_file_stack);
- }
- *namebuf = NUL;
- if (tail && *tail) {
- STRMOVE(IObuff, skipwhite(tail));
- qi->qf_multiscan = true;
- goto restofline;
- }
- }
- }
- if (fmt_ptr->flags == '-') { // generally exclude this line
- if (qi->qf_multiline) {
- // also exclude continuation lines
- qi->qf_multiignore = true;
- }
- continue;
- }
+ if (status == QF_IGNORE_LINE) {
+ continue;
}
if (qf_add_entry(qi,
qi->qf_directory,
- (*namebuf || qi->qf_directory)
- ? namebuf : ((qi->qf_currfile && valid)
- ? qi->qf_currfile : (char_u *)NULL),
+ (*fields.namebuf || qi->qf_directory)
+ ? fields.namebuf : ((qi->qf_currfile && fields.valid)
+ ? qi->qf_currfile : (char_u *)NULL),
0,
- errmsg,
- lnum,
- col,
- use_viscol,
- pattern,
- enr,
- type,
- valid) == FAIL) {
+ fields.errmsg,
+ fields.lnum,
+ fields.col,
+ fields.use_viscol,
+ fields.pattern,
+ fields.enr,
+ fields.type,
+ fields.valid) == FAIL) {
goto error2;
}
line_breakcheck();
}
- if (fd == NULL || !ferror(fd)) {
+ if (state.fd == NULL || !ferror(state.fd)) {
if (qi->qf_lists[qi->qf_curlist].qf_index == 0) {
/* no valid entry found */
qi->qf_lists[qi->qf_curlist].qf_ptr =
@@ -983,19 +1115,21 @@ restofline:
}
EMSG(_(e_readerrf));
error2:
- qf_free(qi, qi->qf_curlist);
- qi->qf_listcount--;
- if (qi->qf_curlist > 0) {
- qi->qf_curlist--;
+ if (!adding) {
+ qf_free(qi, qi->qf_curlist);
+ qi->qf_listcount--;
+ if (qi->qf_curlist > 0) {
+ qi->qf_curlist--;
+ }
}
qf_init_end:
- if (fd != NULL) {
- fclose(fd);
+ if (state.fd != NULL) {
+ fclose(state.fd);
}
- xfree(namebuf);
- xfree(errmsg);
- xfree(pattern);
- xfree(growbuf);
+ xfree(fields.namebuf);
+ xfree(fields.errmsg);
+ xfree(fields.pattern);
+ xfree(state.growbuf);
qf_update_buffer(qi, old_last);
@@ -1105,7 +1239,8 @@ static int qf_add_entry(qf_info_T *qi, char_u *dir, char_u *fname, int bufnum,
qfp->qf_fnum = bufnum;
if (buf != NULL) {
- buf->b_has_qf_entry = true;
+ buf->b_has_qf_entry |=
+ (qi == &ql_info) ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
}
} else {
qfp->qf_fnum = qf_get_fnum(qi, dir, fname);
@@ -1122,7 +1257,7 @@ static int qf_add_entry(qf_info_T *qi, char_u *dir, char_u *fname, int bufnum,
qfp->qf_nr = nr;
if (type != 1 && !vim_isprintc(type)) /* only printable chars allowed */
type = 0;
- qfp->qf_type = type;
+ qfp->qf_type = (char_u)type;
qfp->qf_valid = valid;
lastp = &qi->qf_lists[qi->qf_curlist].qf_last;
@@ -1282,11 +1417,12 @@ void copy_loclist(win_T *from, win_T *to)
to->w_llist->qf_curlist = qi->qf_curlist; /* current list */
}
-// Get buffer number for file "dir.name".
+// Get buffer number for file "directory/fname".
// Also sets the b_has_qf_entry flag.
static int qf_get_fnum(qf_info_T *qi, char_u *directory, char_u *fname)
{
- char_u *ptr;
+ char_u *ptr = NULL;
+ char_u *bufname;
buf_T *buf;
if (fname == NULL || *fname == NUL) { // no file name
return 0;
@@ -1313,16 +1449,28 @@ static int qf_get_fnum(qf_info_T *qi, char_u *directory, char_u *fname)
ptr = vim_strsave(fname);
}
}
- // Use concatenated directory name and file name
- buf = buflist_new(ptr, NULL, (linenr_T)0, 0);
+ // Use concatenated directory name and file name.
+ bufname = ptr;
+ } else {
+ bufname = fname;
+ }
+
+ if (qf_last_bufname != NULL
+ && STRCMP(bufname, qf_last_bufname) == 0
+ && bufref_valid(&qf_last_bufref)) {
+ buf = qf_last_bufref.br_buf;
xfree(ptr);
} else {
- buf = buflist_new(fname, NULL, (linenr_T)0, 0);
+ xfree(qf_last_bufname);
+ buf = buflist_new(bufname, NULL, (linenr_T)0, BLN_NOOPT);
+ qf_last_bufname = (bufname == ptr) ? bufname : vim_strsave(bufname);
+ set_bufref(&qf_last_bufref, buf);
}
if (buf == NULL) {
return 0;
}
- buf->b_has_qf_entry = true;
+ buf->b_has_qf_entry =
+ (qi == &ql_info) ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
return buf->b_fnum;
}
@@ -1730,7 +1878,7 @@ win_found:
* If there is only one window and it is the quickfix window, create a
* new one above the quickfix window.
*/
- if (((firstwin == lastwin) && bt_quickfix(curbuf)) || !usable_win) {
+ if ((ONE_WINDOW && bt_quickfix(curbuf)) || !usable_win) {
flags = WSP_ABOVE;
if (ll_ref != NULL)
flags |= WSP_NEWLOC;
@@ -1843,7 +1991,7 @@ win_found:
ok = buflist_getfile(qf_ptr->qf_fnum, (linenr_T)1,
GETF_SETMARK | GETF_SWITCH, forceit);
- if (qi != &ql_info && !win_valid(oldwin)) {
+ if (qi != &ql_info && !win_valid_any_tab(oldwin)) {
EMSG(_("E924: Current window was closed"));
is_abort = true;
opened_window = false;
@@ -2049,21 +2197,20 @@ void qf_list(exarg_T *eap)
if (qfp->qf_lnum == 0) {
IObuff[0] = NUL;
} else if (qfp->qf_col == 0) {
- vim_snprintf((char *)IObuff, IOSIZE, ":%" PRId64,
- (int64_t)qfp->qf_lnum);
+ vim_snprintf((char *)IObuff, IOSIZE, ":%" PRIdLINENR, qfp->qf_lnum);
} else {
- vim_snprintf((char *)IObuff, IOSIZE, ":%" PRId64 " col %d",
- (int64_t)qfp->qf_lnum, qfp->qf_col);
+ vim_snprintf((char *)IObuff, IOSIZE, ":%" PRIdLINENR " col %d",
+ qfp->qf_lnum, qfp->qf_col);
}
vim_snprintf((char *)IObuff + STRLEN(IObuff), IOSIZE, "%s:",
(char *)qf_types(qfp->qf_type, qfp->qf_nr));
- msg_puts_attr(IObuff, hl_attr(HLF_N));
+ msg_puts_attr((const char *)IObuff, hl_attr(HLF_N));
if (qfp->qf_pattern != NULL) {
qf_fmt_text(qfp->qf_pattern, IObuff, IOSIZE);
- STRCAT(IObuff, ":");
- msg_puts(IObuff);
+ xstrlcat((char *)IObuff, ":", IOSIZE);
+ msg_puts((const char *)IObuff);
}
- msg_puts((char_u *)" ");
+ msg_puts(" ");
/* Remove newlines and leading whitespace from the text. For an
* unrecognized line keep the indent, the compiler may mark a word
@@ -2105,6 +2252,31 @@ static void qf_fmt_text(char_u *text, char_u *buf, int bufsize)
buf[i] = NUL;
}
+static void qf_msg(qf_info_T *qi, int which, char *lead)
+{
+ char *title = (char *)qi->qf_lists[which].qf_title;
+ int count = qi->qf_lists[which].qf_count;
+ char_u buf[IOSIZE];
+
+ vim_snprintf((char *)buf, IOSIZE, _("%serror list %d of %d; %d errors "),
+ lead,
+ which + 1,
+ qi->qf_listcount,
+ count);
+
+ if (title != NULL) {
+ size_t len = STRLEN(buf);
+
+ if (len < 34) {
+ memset(buf + len, ' ', 34 - len);
+ buf[34] = NUL;
+ }
+ xstrlcat((char *)buf, title, IOSIZE);
+ }
+ trunc_string(buf, buf, (int)Columns - 1, IOSIZE);
+ msg(buf);
+}
+
/*
* ":colder [count]": Up in the quickfix stack.
* ":cnewer [count]": Down in the quickfix stack.
@@ -2145,20 +2317,29 @@ void qf_age(exarg_T *eap)
++qi->qf_curlist;
}
}
- qf_msg(qi);
+ qf_msg(qi, qi->qf_curlist, "");
+ qf_update_buffer(qi, NULL);
}
-static void qf_msg(qf_info_T *qi)
+void qf_history(exarg_T *eap)
{
- smsg(_("error list %d of %d; %d errors"),
- qi->qf_curlist + 1, qi->qf_listcount,
- qi->qf_lists[qi->qf_curlist].qf_count);
- qf_update_buffer(qi, NULL);
+ qf_info_T *qi = &ql_info;
+ int i;
+
+ if (eap->cmdidx == CMD_lhistory) {
+ qi = GET_LOC_LIST(curwin);
+ }
+ if (qi == NULL || (qi->qf_listcount == 0
+ && qi->qf_lists[qi->qf_curlist].qf_count == 0)) {
+ MSG(_("No entries"));
+ } else {
+ for (i = 0; i < qi->qf_listcount; i++) {
+ qf_msg(qi, i, i == qi->qf_curlist ? "> " : " ");
+ }
+ }
}
-/*
- * Free error list "idx".
- */
+/// Free all the entries in the error list "idx".
static void qf_free(qf_info_T *qi, int idx)
{
qfline_T *qfp;
@@ -2190,7 +2371,9 @@ static void qf_free(qf_info_T *qi, int idx)
qi->qf_lists[idx].qf_index = 0;
qf_clean_dir_stack(&qi->qf_dir_stack);
+ qi->qf_directory = NULL;
qf_clean_dir_stack(&qi->qf_file_stack);
+ qi->qf_currfile = NULL;
}
/*
@@ -2203,8 +2386,9 @@ void qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long
int idx;
qf_info_T *qi = &ql_info;
bool found_one = false;
+ int buf_has_flag = wp == NULL ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
- if (!curbuf->b_has_qf_entry) {
+ if (!(curbuf->b_has_qf_entry & buf_has_flag)) {
return;
}
if (wp != NULL) {
@@ -2231,7 +2415,7 @@ void qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long
}
if (!found_one) {
- curbuf->b_has_qf_entry = false;
+ curbuf->b_has_qf_entry &= ~buf_has_flag;
}
}
@@ -2413,15 +2597,13 @@ void ex_copen(exarg_T *eap)
else {
/* Create a new quickfix buffer */
(void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, oldwin);
- /* switch off 'swapfile' */
- set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
- set_option_value((char_u *)"bt", 0L, (char_u *)"quickfix",
- OPT_LOCAL);
- set_option_value((char_u *)"bh", 0L, (char_u *)"wipe", OPT_LOCAL);
+ // Switch off 'swapfile'.
+ set_option_value("swf", 0L, NULL, OPT_LOCAL);
+ set_option_value("bt", 0L, "quickfix", OPT_LOCAL);
+ set_option_value("bh", 0L, "wipe", OPT_LOCAL);
RESET_BINDING(curwin);
- curwin->w_p_diff = FALSE;
- set_option_value((char_u *)"fdm", 0L, (char_u *)"manual",
- OPT_LOCAL);
+ curwin->w_p_diff = false;
+ set_option_value("fdm", 0L, "manual", OPT_LOCAL);
}
/* Only set the height when still in the same tab page and there is no
@@ -2582,6 +2764,19 @@ static buf_T *qf_find_buf(qf_info_T *qi)
return NULL;
}
+/// Update the w:quickfix_title variable in the quickfix/location list window
+static void qf_update_win_titlevar(qf_info_T *qi)
+{
+ win_T *win;
+
+ if ((win = qf_find_win(qi)) != NULL) {
+ win_T *curwin_save = curwin;
+ curwin = win;
+ qf_set_title_var(qi);
+ curwin = curwin_save;
+ }
+}
+
/*
* Find the quickfix buffer. If it exists, update the contents.
*/
@@ -2589,7 +2784,6 @@ static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
{
buf_T *buf;
win_T *win;
- win_T *curwin_save;
aco_save_T aco;
/* Check if a buffer for the quickfix list exists. Update it. */
@@ -2602,12 +2796,7 @@ static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
aucmd_prepbuf(&aco, buf);
}
- if ((win = qf_find_win(qi)) != NULL) {
- curwin_save = curwin;
- curwin = win;
- qf_set_title_var(qi);
- curwin = curwin_save;
- }
+ qf_update_win_titlevar(qi);
qf_fill_buffer(qi, buf, old_last);
@@ -2726,14 +2915,14 @@ static void qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last)
}
}
- /* correct cursor position */
- check_lnums(TRUE);
+ // Correct cursor position.
+ check_lnums(true);
if (old_last == NULL) {
// Set the 'filetype' to "qf" each time after filling the buffer. This
// resembles reading a file into a buffer, it's more logical when using
// autocommands.
- set_option_value((char_u *)"ft", 0L, (char_u *)"qf", OPT_LOCAL);
+ set_option_value("ft", 0L, "qf", OPT_LOCAL);
curbuf->b_p_ma = false;
keep_filetype = true; // don't detect 'filetype'
@@ -2837,11 +3026,11 @@ void ex_make(exarg_T *eap)
case CMD_lgrepadd: au_name = (char_u *)"lgrepadd"; break;
default: break;
}
- if (au_name != NULL) {
- apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
- curbuf->b_fname, TRUE, curbuf);
- if (did_throw || force_abort)
+ if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
+ curbuf->b_fname, true, curbuf)) {
+ if (aborting()) {
return;
+ }
}
if (eap->cmdidx == CMD_lmake || eap->cmdidx == CMD_lgrep
@@ -2938,7 +3127,7 @@ static char_u *get_mef_name(void)
STRCPY(name, p_mef);
sprintf((char *)name + (p - p_mef), "%d%d", start, off);
STRCAT(name, p + 2);
- // Don't accept a symbolic link, its a security risk.
+ // Don't accept a symbolic link, it's a security risk.
FileInfo file_info;
bool file_or_link_found = os_fileinfo_link((char *)name, &file_info);
if (!file_or_link_found) {
@@ -3111,7 +3300,6 @@ void ex_cc(exarg_T *eap)
|| eap->cmdidx == CMD_lrewind
|| eap->cmdidx == CMD_lfirst
|| eap->cmdidx == CMD_llast
- || eap->cmdidx == CMD_llast
|| eap->cmdidx == CMD_ldo
|| eap->cmdidx == CMD_lfdo) {
qi = GET_LOC_LIST(curwin);
@@ -3168,7 +3356,6 @@ void ex_cnext(exarg_T *eap)
|| eap->cmdidx == CMD_lnfile
|| eap->cmdidx == CMD_lNfile
|| eap->cmdidx == CMD_lpfile
- || eap->cmdidx == CMD_lpfile
|| eap->cmdidx == CMD_ldo
|| eap->cmdidx == CMD_lfdo) {
qi = GET_LOC_LIST(curwin);
@@ -3301,11 +3488,11 @@ void ex_vimgrep(exarg_T *eap)
case CMD_lgrepadd: au_name = (char_u *)"lgrepadd"; break;
default: break;
}
- if (au_name != NULL) {
- apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
- curbuf->b_fname, TRUE, curbuf);
- if (did_throw || force_abort)
+ if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
+ curbuf->b_fname, true, curbuf)) {
+ if (aborting()) {
return;
+ }
}
if (eap->cmdidx == CMD_lgrep
@@ -3451,10 +3638,13 @@ void ex_vimgrep(exarg_T *eap)
col = 0;
while (vim_regexec_multi(&regmatch, curwin, buf, lnum,
col, NULL) > 0) {
+ // Pass the buffer number so that it gets used even for a
+ // dummy buffer, unless duplicate_name is set, then the
+ // buffer will be wiped out below.
if (qf_add_entry(qi,
NULL, // dir
fname,
- 0,
+ duplicate_name ? 0 : buf->b_fnum,
ml_get_buf(buf,
regmatch.startpos[0].lnum + lnum, false),
regmatch.startpos[0].lnum + lnum,
@@ -3508,17 +3698,23 @@ void ex_vimgrep(exarg_T *eap)
buf = NULL;
} else if (buf != first_match_buf || (flags & VGR_NOJUMP)) {
unload_dummy_buffer(buf, dirname_start);
+ // Keeping the buffer, remove the dummy flag.
+ buf->b_flags &= ~BF_DUMMY;
buf = NULL;
}
}
if (buf != NULL) {
- /* If the buffer is still loaded we need to use the
- * directory we jumped to below. */
+ // Keeping the buffer, remove the dummy flag.
+ buf->b_flags &= ~BF_DUMMY;
+
+ // If the buffer is still loaded we need to use the
+ // directory we jumped to below.
if (buf == first_match_buf
&& target_dir == NULL
- && STRCMP(dirname_start, dirname_now) != 0)
+ && STRCMP(dirname_start, dirname_now) != 0) {
target_dir = vim_strsave(dirname_now);
+ }
/* The buffer is still loaded, the Filetype autocommands
* need to be done now, in that buffer. And the modelines
@@ -3583,52 +3779,6 @@ theend:
}
/*
- * Skip over the pattern argument of ":vimgrep /pat/[g][j]".
- * Put the start of the pattern in "*s", unless "s" is NULL.
- * If "flags" is not NULL put the flags in it: VGR_GLOBAL, VGR_NOJUMP.
- * If "s" is not NULL terminate the pattern with a NUL.
- * Return a pointer to the char just past the pattern plus flags.
- */
-char_u *skip_vimgrep_pat(char_u *p, char_u **s, int *flags)
-{
- int c;
-
- if (vim_isIDc(*p)) {
- /* ":vimgrep pattern fname" */
- if (s != NULL)
- *s = p;
- p = skiptowhite(p);
- if (s != NULL && *p != NUL)
- *p++ = NUL;
- } else {
- /* ":vimgrep /pattern/[g][j] fname" */
- if (s != NULL)
- *s = p + 1;
- c = *p;
- p = skip_regexp(p + 1, c, TRUE, NULL);
- if (*p != c)
- return NULL;
-
- /* Truncate the pattern. */
- if (s != NULL)
- *p = NUL;
- ++p;
-
- /* Find the flags */
- while (*p == 'g' || *p == 'j') {
- if (flags != NULL) {
- if (*p == 'g')
- *flags |= VGR_GLOBAL;
- else
- *flags |= VGR_NOJUMP;
- }
- ++p;
- }
- }
- return p;
-}
-
-/*
* Restore current working directory to "dirname_start" if they differ, taking
* into account whether it is set locally or globally.
*/
@@ -3669,8 +3819,9 @@ load_dummy_buffer (
)
{
buf_T *newbuf;
- buf_T *newbuf_to_wipe = NULL;
- int failed = TRUE;
+ bufref_T newbufref;
+ bufref_T newbuf_to_wipe;
+ int failed = true;
aco_save_T aco;
// Allocate a buffer without putting it in the buffer list.
@@ -3678,6 +3829,7 @@ load_dummy_buffer (
if (newbuf == NULL) {
return NULL;
}
+ set_bufref(&newbufref, newbuf);
/* Init the options. */
buf_copy_options(newbuf, BCO_ENTER | BCO_NOHELP);
@@ -3697,6 +3849,7 @@ load_dummy_buffer (
* work. */
curbuf->b_flags &= ~BF_DUMMY;
+ newbuf_to_wipe.br_buf = NULL;
if (readfile(fname, NULL,
(linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM,
NULL, READ_NEW | READ_DUMMY) == OK
@@ -3704,19 +3857,24 @@ load_dummy_buffer (
&& !(curbuf->b_flags & BF_NEW)) {
failed = FALSE;
if (curbuf != newbuf) {
- /* Bloody autocommands changed the buffer! Can happen when
- * using netrw and editing a remote file. Use the current
- * buffer instead, delete the dummy one after restoring the
- * window stuff. */
- newbuf_to_wipe = newbuf;
+ // Bloody autocommands changed the buffer! Can happen when
+ // using netrw and editing a remote file. Use the current
+ // buffer instead, delete the dummy one after restoring the
+ // window stuff.
+ set_bufref(&newbuf_to_wipe, newbuf);
newbuf = curbuf;
}
}
- /* restore curwin/curbuf and a few other things */
+ // Restore curwin/curbuf and a few other things.
aucmd_restbuf(&aco);
- if (newbuf_to_wipe != NULL && buf_valid(newbuf_to_wipe))
- wipe_buffer(newbuf_to_wipe, FALSE);
+ if (newbuf_to_wipe.br_buf != NULL && bufref_valid(&newbuf_to_wipe)) {
+ wipe_buffer(newbuf_to_wipe.br_buf, false);
+ }
+
+ // Add back the "dummy" flag, otherwise buflist_findname_file_id()
+ // won't skip it.
+ newbuf->b_flags |= BF_DUMMY;
}
/*
@@ -3727,8 +3885,9 @@ load_dummy_buffer (
os_dirname(resulting_dir, MAXPATHL);
restore_start_dir(dirname_start);
- if (!buf_valid(newbuf))
+ if (!bufref_valid(&newbufref)) {
return NULL;
+ }
if (failed) {
wipe_dummy_buffer(newbuf, dirname_start);
return NULL;
@@ -3776,13 +3935,11 @@ static void unload_dummy_buffer(buf_T *buf, char_u *dirname_start)
}
}
-/*
- * Add each quickfix error to list "list" as a dictionary.
- */
-int get_errorlist(win_T *wp, list_T *list)
+/// Add each quickfix error to list "list" as a dictionary.
+/// If qf_idx is -1, use the current list. Otherwise, use the specified list.
+int get_errorlist(win_T *wp, int qf_idx, list_T *list)
{
qf_info_T *qi = &ql_info;
- dict_T *dict;
char_u buf[2];
qfline_T *qfp;
int i;
@@ -3794,34 +3951,50 @@ int get_errorlist(win_T *wp, list_T *list)
return FAIL;
}
- if (qi->qf_curlist >= qi->qf_listcount
- || qi->qf_lists[qi->qf_curlist].qf_count == 0)
+ if (qf_idx == -1) {
+ qf_idx = qi->qf_curlist;
+ }
+
+ if (qf_idx >= qi->qf_listcount
+ || qi->qf_lists[qf_idx].qf_count == 0) {
return FAIL;
+ }
- qfp = qi->qf_lists[qi->qf_curlist].qf_start;
- for (i = 1; !got_int && i <= qi->qf_lists[qi->qf_curlist].qf_count; ++i) {
- /* Handle entries with a non-existing buffer number. */
+ qfp = qi->qf_lists[qf_idx].qf_start;
+ for (i = 1; !got_int && i <= qi->qf_lists[qf_idx].qf_count; i++) {
+ // Handle entries with a non-existing buffer number.
bufnum = qfp->qf_fnum;
if (bufnum != 0 && (buflist_findnr(bufnum) == NULL))
bufnum = 0;
- dict = dict_alloc();
- list_append_dict(list, dict);
+ dict_T *const dict = tv_dict_alloc();
+ tv_list_append_dict(list, dict);
buf[0] = qfp->qf_type;
buf[1] = NUL;
- if ( dict_add_nr_str(dict, "bufnr", (long)bufnum, NULL) == FAIL
- || dict_add_nr_str(dict, "lnum", (long)qfp->qf_lnum, NULL) == FAIL
- || dict_add_nr_str(dict, "col", (long)qfp->qf_col, NULL) == FAIL
- || dict_add_nr_str(dict, "vcol", (long)qfp->qf_viscol, NULL) == FAIL
- || dict_add_nr_str(dict, "nr", (long)qfp->qf_nr, NULL) == FAIL
- || dict_add_nr_str(dict, "pattern", 0L,
- qfp->qf_pattern == NULL ? (char_u *)"" : qfp->qf_pattern) == FAIL
- || dict_add_nr_str(dict, "text", 0L,
- qfp->qf_text == NULL ? (char_u *)"" : qfp->qf_text) == FAIL
- || dict_add_nr_str(dict, "type", 0L, buf) == FAIL
- || dict_add_nr_str(dict, "valid", (long)qfp->qf_valid, NULL) == FAIL)
- return FAIL;
+ if (tv_dict_add_nr(dict, S_LEN("bufnr"), (varnumber_T)bufnum) == FAIL
+ || (tv_dict_add_nr(dict, S_LEN("lnum"), (varnumber_T)qfp->qf_lnum)
+ == FAIL)
+ || (tv_dict_add_nr(dict, S_LEN("col"), (varnumber_T)qfp->qf_col)
+ == FAIL)
+ || (tv_dict_add_nr(dict, S_LEN("vcol"), (varnumber_T)qfp->qf_viscol)
+ == FAIL)
+ || (tv_dict_add_nr(dict, S_LEN("nr"), (varnumber_T)qfp->qf_nr) == FAIL)
+ || tv_dict_add_str(dict, S_LEN("pattern"),
+ (qfp->qf_pattern == NULL
+ ? ""
+ : (const char *)qfp->qf_pattern)) == FAIL
+ || tv_dict_add_str(dict, S_LEN("text"),
+ (qfp->qf_text == NULL
+ ? ""
+ : (const char *)qfp->qf_text)) == FAIL
+ || tv_dict_add_str(dict, S_LEN("type"), (const char *)buf) == FAIL
+ || (tv_dict_add_nr(dict, S_LEN("valid"), (varnumber_T)qfp->qf_valid)
+ == FAIL)) {
+ // tv_dict_add* fail only if key already exist, but this is a newly
+ // allocated dictionary which is thus guaranteed to have no existing keys.
+ assert(false);
+ }
qfp = qfp->qf_next;
if (qfp == NULL) {
@@ -3831,22 +4004,94 @@ int get_errorlist(win_T *wp, list_T *list)
return OK;
}
-// Populate the quickfix list with the items supplied in the list
-// of dictionaries. "title" will be copied to w:quickfix_title
-// "action" is 'a' for add, 'r' for replace. Otherwise create a new list.
-int set_errorlist(win_T *wp, list_T *list, int action, char_u *title)
+/// Flags used by getqflist()/getloclist() to determine which fields to return.
+enum {
+ QF_GETLIST_NONE = 0x0,
+ QF_GETLIST_TITLE = 0x1,
+ QF_GETLIST_ITEMS = 0x2,
+ QF_GETLIST_NR = 0x4,
+ QF_GETLIST_WINID = 0x8,
+ QF_GETLIST_ALL = 0xFF
+};
+
+/// Return quickfix/location list details (title) as a
+/// dictionary. 'what' contains the details to return. If 'list_idx' is -1,
+/// then current list is used. Otherwise the specified list is used.
+int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
+{
+ qf_info_T *qi = &ql_info;
+
+ if (wp != NULL) {
+ qi = GET_LOC_LIST(wp);
+ if (qi == NULL) {
+ return FAIL;
+ }
+ }
+
+ int status = OK;
+ dictitem_T *di;
+ int flags = QF_GETLIST_NONE;
+
+ int qf_idx = qi->qf_curlist; // default is the current list
+ if ((di = tv_dict_find(what, S_LEN("nr"))) != NULL) {
+ // Use the specified quickfix/location list
+ if (di->di_tv.v_type == VAR_NUMBER) {
+ // for zero use the current list
+ if (di->di_tv.vval.v_number != 0) {
+ qf_idx = (int)di->di_tv.vval.v_number - 1;
+ if (qf_idx < 0 || qf_idx >= qi->qf_listcount) {
+ return FAIL;
+ }
+ }
+ flags |= QF_GETLIST_NR;
+ } else {
+ return FAIL;
+ }
+ }
+
+ if (tv_dict_find(what, S_LEN("all")) != NULL) {
+ flags |= QF_GETLIST_ALL;
+ }
+
+ if (tv_dict_find(what, S_LEN("title")) != NULL) {
+ flags |= QF_GETLIST_TITLE;
+ }
+
+ if (tv_dict_find(what, S_LEN("winid")) != NULL) {
+ flags |= QF_GETLIST_WINID;
+ }
+
+ if (flags & QF_GETLIST_TITLE) {
+ char_u *t = qi->qf_lists[qf_idx].qf_title;
+ if (t == NULL) {
+ t = (char_u *)"";
+ }
+ status = tv_dict_add_str(retdict, S_LEN("title"), (const char *)t);
+ }
+ if ((status == OK) && (flags & QF_GETLIST_NR)) {
+ status = tv_dict_add_nr(retdict, S_LEN("nr"), qf_idx + 1);
+ }
+ if ((status == OK) && (flags & QF_GETLIST_WINID)) {
+ win_T *win = qf_find_win(qi);
+ if (win != NULL) {
+ status = tv_dict_add_nr(retdict, S_LEN("winid"), win->handle);
+ }
+ }
+
+ return status;
+}
+
+/// Add list of entries to quickfix/location list. Each list entry is
+/// a dictionary with item information.
+static int qf_add_entries(qf_info_T *qi, list_T *list, char_u *title,
+ int action)
{
listitem_T *li;
dict_T *d;
qfline_T *old_last = NULL;
int retval = OK;
- qf_info_T *qi = &ql_info;
bool did_bufnr_emsg = false;
- if (wp != NULL) {
- qi = ll_get_or_alloc_list(wp);
- }
-
if (action == ' ' || qi->qf_curlist == qi->qf_listcount) {
// make place for a new list
qf_new_list(qi, title);
@@ -3866,17 +4111,18 @@ int set_errorlist(win_T *wp, list_T *list, int action, char_u *title)
if (d == NULL)
continue;
- char_u *filename = get_dict_string(d, "filename", true);
- int bufnum = (int)get_dict_number(d, "bufnr");
- long lnum = get_dict_number(d, "lnum");
- int col = (int)get_dict_number(d, "col");
- char_u vcol = (char_u)get_dict_number(d, "vcol");
- int nr = (int)get_dict_number(d, "nr");
- char_u *type = get_dict_string(d, "type", true);
- char_u *pattern = get_dict_string(d, "pattern", true);
- char_u *text = get_dict_string(d, "text", true);
+ char *const filename = tv_dict_get_string(d, "filename", true);
+ int bufnum = (int)tv_dict_get_number(d, "bufnr");
+ long lnum = (long)tv_dict_get_number(d, "lnum");
+ int col = (int)tv_dict_get_number(d, "col");
+ char_u vcol = (char_u)tv_dict_get_number(d, "vcol");
+ int nr = (int)tv_dict_get_number(d, "nr");
+ const char *type_str = tv_dict_get_string(d, "type", false);
+ const char_u type = (char_u)(uint8_t)(type_str == NULL ? NUL : *type_str);
+ char *const pattern = tv_dict_get_string(d, "pattern", true);
+ char *text = tv_dict_get_string(d, "text", true);
if (text == NULL) {
- text = vim_strsave((char_u *)"");
+ text = xcalloc(1, 1);
}
bool valid = true;
if ((filename == NULL && bufnum == 0) || (lnum == 0 && pattern == NULL)) {
@@ -3896,21 +4142,20 @@ int set_errorlist(win_T *wp, list_T *list, int action, char_u *title)
int status = qf_add_entry(qi,
NULL, // dir
- filename,
+ (char_u *)filename,
bufnum,
- text,
+ (char_u *)text,
lnum,
col,
vcol, // vis_col
- pattern, // search pattern
+ (char_u *)pattern, // search pattern
nr,
- (char_u)(type == NULL ? NUL : *type),
+ type,
valid);
xfree(filename);
xfree(pattern);
xfree(text);
- xfree(type);
if (status == FAIL) {
retval = FAIL;
@@ -3937,6 +4182,71 @@ int set_errorlist(win_T *wp, list_T *list, int action, char_u *title)
return retval;
}
+static int qf_set_properties(qf_info_T *qi, dict_T *what, int action)
+{
+ dictitem_T *di;
+ int retval = FAIL;
+ int newlist = false;
+
+ if (action == ' ' || qi->qf_curlist == qi->qf_listcount) {
+ newlist = true;
+ }
+ int qf_idx = qi->qf_curlist; // default is the current list
+ if ((di = tv_dict_find(what, S_LEN("nr"))) != NULL) {
+ // Use the specified quickfix/location list
+ if (di->di_tv.v_type == VAR_NUMBER) {
+ qf_idx = (int)di->di_tv.vval.v_number - 1;
+ if (qf_idx < 0 || qf_idx >= qi->qf_listcount) {
+ return FAIL;
+ }
+ } else {
+ return FAIL;
+ }
+ newlist = false; // use the specified list
+ }
+
+ if (newlist) {
+ qf_new_list(qi, NULL);
+ qf_idx = qi->qf_curlist;
+ }
+
+ if ((di = tv_dict_find(what, S_LEN("title"))) != NULL) {
+ if (di->di_tv.v_type == VAR_STRING) {
+ xfree(qi->qf_lists[qf_idx].qf_title);
+ qi->qf_lists[qf_idx].qf_title = (char_u *)tv_dict_get_string(
+ what, "title", true);
+ if (qf_idx == qi->qf_curlist) {
+ qf_update_win_titlevar(qi);
+ }
+ retval = OK;
+ }
+ }
+
+ return retval;
+}
+
+// Populate the quickfix list with the items supplied in the list
+// of dictionaries. "title" will be copied to w:quickfix_title
+// "action" is 'a' for add, 'r' for replace. Otherwise create a new list.
+int set_errorlist(win_T *wp, list_T *list, int action, char_u *title,
+ dict_T *what)
+{
+ qf_info_T *qi = &ql_info;
+ int retval = OK;
+
+ if (wp != NULL) {
+ qi = ll_get_or_alloc_list(wp);
+ }
+
+ if (what != NULL) {
+ retval = qf_set_properties(qi, what, action);
+ } else {
+ retval = qf_add_entries(qi, list, title, action);
+ }
+
+ return retval;
+}
+
/*
* ":[range]cbuffer [bufnr]" command.
* ":[range]caddbuffer [bufnr]" command.
@@ -3947,14 +4257,45 @@ int set_errorlist(win_T *wp, list_T *list, int action, char_u *title)
*/
void ex_cbuffer(exarg_T *eap)
{
- buf_T *buf = NULL;
- qf_info_T *qi = &ql_info;
+ buf_T *buf = NULL;
+ qf_info_T *qi = &ql_info;
+ const char *au_name = NULL;
if (eap->cmdidx == CMD_lbuffer || eap->cmdidx == CMD_lgetbuffer
|| eap->cmdidx == CMD_laddbuffer) {
qi = ll_get_or_alloc_list(curwin);
}
+ switch (eap->cmdidx) {
+ case CMD_cbuffer:
+ au_name = "cbuffer";
+ break;
+ case CMD_cgetbuffer:
+ au_name = "cgetbuffer";
+ break;
+ case CMD_caddbuffer:
+ au_name = "caddbuffer";
+ break;
+ case CMD_lbuffer:
+ au_name = "lbuffer";
+ break;
+ case CMD_lgetbuffer:
+ au_name = "lgetbuffer";
+ break;
+ case CMD_laddbuffer:
+ au_name = "laddbuffer";
+ break;
+ default:
+ break;
+ }
+
+ if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, (char_u *)au_name,
+ curbuf->b_fname, true, curbuf)) {
+ if (aborting()) {
+ return;
+ }
+ }
+
if (*eap->arg == NUL)
buf = curbuf;
else if (*skipwhite(skipdigits(eap->arg)) == NUL)
@@ -3981,13 +4322,17 @@ void ex_cbuffer(exarg_T *eap)
}
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 */
+ (eap->cmdidx != CMD_caddbuffer
+ && eap->cmdidx != CMD_laddbuffer),
+ eap->line1, eap->line2, qf_title) > 0) {
+ if (au_name != NULL) {
+ apply_autocmds(EVENT_QUICKFIXCMDPOST, (char_u *)au_name,
+ curbuf->b_fname, true, curbuf);
+ }
+ if (eap->cmdidx == CMD_cbuffer || eap->cmdidx == CMD_lbuffer) {
+ qf_jump(qi, 0, 0, eap->forceit); // display first error
+ }
+ }
}
}
}
@@ -3998,30 +4343,65 @@ void ex_cbuffer(exarg_T *eap)
*/
void ex_cexpr(exarg_T *eap)
{
- typval_T *tv;
- qf_info_T *qi = &ql_info;
+ qf_info_T *qi = &ql_info;
+ const char *au_name = NULL;
if (eap->cmdidx == CMD_lexpr || eap->cmdidx == CMD_lgetexpr
|| eap->cmdidx == CMD_laddexpr) {
qi = ll_get_or_alloc_list(curwin);
}
+ switch (eap->cmdidx) {
+ case CMD_cexpr:
+ au_name = "cexpr";
+ break;
+ case CMD_cgetexpr:
+ au_name = "cgetexpr";
+ break;
+ case CMD_caddexpr:
+ au_name = "caddexpr";
+ break;
+ case CMD_lexpr:
+ au_name = "lexpr";
+ break;
+ case CMD_lgetexpr:
+ au_name = "lgetexpr";
+ break;
+ case CMD_laddexpr:
+ au_name = "laddexpr";
+ break;
+ default:
+ break;
+ }
+ if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, (char_u *)au_name,
+ curbuf->b_fname, true, curbuf)) {
+ if (aborting()) {
+ return;
+ }
+ }
+
/* Evaluate the expression. When the result is a string or a list we can
* use it to fill the errorlist. */
- tv = eval_expr(eap->arg, NULL);
- if (tv != NULL) {
- if ((tv->v_type == VAR_STRING && tv->vval.v_string != NULL)
- || (tv->v_type == VAR_LIST && tv->vval.v_list != NULL)) {
- if (qf_init_ext(qi, NULL, NULL, tv, p_efm,
- (eap->cmdidx != CMD_caddexpr
- && eap->cmdidx != CMD_laddexpr),
- (linenr_T)0, (linenr_T)0, *eap->cmdlinep) > 0
- && (eap->cmdidx == CMD_cexpr
- || eap->cmdidx == CMD_lexpr))
- qf_jump(qi, 0, 0, eap->forceit); /* display first error */
- } else
+ typval_T tv;
+ if (eval0(eap->arg, &tv, NULL, true) != FAIL) {
+ if ((tv.v_type == VAR_STRING && tv.vval.v_string != NULL)
+ || (tv.v_type == VAR_LIST && 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) {
+ if (au_name != NULL) {
+ apply_autocmds(EVENT_QUICKFIXCMDPOST, (char_u *)au_name,
+ curbuf->b_fname, true, curbuf);
+ }
+ if (eap->cmdidx == CMD_cexpr || eap->cmdidx == CMD_lexpr) {
+ qf_jump(qi, 0, 0, eap->forceit); // display first error
+ }
+ }
+ } else {
EMSG(_("E777: String or List expected"));
- free_tv(tv);
+ }
+ tv_clear(&tv);
}
}
@@ -4051,11 +4431,11 @@ void ex_helpgrep(exarg_T *eap)
case CMD_lhelpgrep: au_name = (char_u *)"lhelpgrep"; break;
default: break;
}
- if (au_name != NULL) {
- apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
- curbuf->b_fname, TRUE, curbuf);
- if (did_throw || force_abort)
+ if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
+ curbuf->b_fname, true, curbuf)) {
+ if (aborting()) {
return;
+ }
}
/* Make 'cpoptions' empty, the 'l' flag should not be used here. */
diff --git a/src/nvim/quickfix.h b/src/nvim/quickfix.h
index bb9c2c3193..fdeb8d1a2f 100644
--- a/src/nvim/quickfix.h
+++ b/src/nvim/quickfix.h
@@ -1,6 +1,9 @@
#ifndef NVIM_QUICKFIX_H
#define NVIM_QUICKFIX_H
+#include "nvim/types.h"
+#include "nvim/ex_cmds_defs.h"
+
/* flags for skip_vimgrep_pat() */
#define VGR_GLOBAL 1
#define VGR_NOJUMP 2
diff --git a/src/nvim/rbuffer.c b/src/nvim/rbuffer.c
index 111af0d0fb..18d453cbe9 100644
--- a/src/nvim/rbuffer.c
+++ b/src/nvim/rbuffer.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <stddef.h>
#include <string.h>
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index 6613d284d7..847b2f273e 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* Handling of regular expressions: vim_regcomp(), vim_regexec(), vim_regsub()
*
@@ -2221,10 +2224,11 @@ collection:
if (*regparse == '[')
endc = get_coll_element(&regparse);
if (endc == 0) {
- if (has_mbyte)
- endc = mb_ptr2char_adv(&regparse);
- else
+ if (has_mbyte) {
+ endc = mb_ptr2char_adv((const char_u **)&regparse);
+ } else {
endc = *regparse++;
+ }
}
/* Handle \o40, \x20 and \u20AC style sequences */
@@ -2349,7 +2353,7 @@ collection:
break;
case CLASS_LOWER:
for (cu = 1; cu <= 255; cu++) {
- if (vim_islower(cu) && cu != 170 && cu != 186) {
+ if (mb_islower(cu) && cu != 170 && cu != 186) {
regmbc(cu);
}
}
@@ -2375,7 +2379,7 @@ collection:
break;
case CLASS_UPPER:
for (cu = 1; cu <= 255; cu++) {
- if (vim_isupper(cu)) {
+ if (mb_isupper(cu)) {
regmbc(cu);
}
}
@@ -2397,7 +2401,7 @@ collection:
regc('\b');
break;
case CLASS_ESCAPE:
- regc('\033');
+ regc(ESC);
break;
}
} else {
@@ -2922,13 +2926,8 @@ static void skipchr(void)
else
prevchr_len = 0;
if (regparse[prevchr_len] != NUL) {
- if (enc_utf8)
- /* exclude composing chars that mb_ptr2len does include */
- prevchr_len += utf_ptr2len(regparse + prevchr_len);
- else if (has_mbyte)
- prevchr_len += (*mb_ptr2len)(regparse + prevchr_len);
- else
- ++prevchr_len;
+ // Exclude composing chars that utfc_ptr2len does include.
+ prevchr_len += utf_ptr2len(regparse + prevchr_len);
}
regparse += prevchr_len;
prev_at_start = at_start;
@@ -3051,7 +3050,7 @@ static int getoctchrs(void)
int c;
int i;
- for (i = 0; i < 3 && nr < 040; ++i) {
+ for (i = 0; i < 3 && nr < 040; i++) { // -V536
c = regparse[0];
if (c < '0' || c > '7')
break;
@@ -3173,61 +3172,56 @@ static int need_clear_zsubexpr = FALSE; /* extmatch subexpressions
int regnarrate = 0;
#endif
-/*
- * Internal copy of 'ignorecase'. It is set at each call to vim_regexec().
- * Normally it gets the value of "rm_ic" or "rmm_ic", but when the pattern
- * contains '\c' or '\C' the value is overruled.
- */
-static int ireg_ic;
-
-/*
- * Similar to ireg_ic, but only for 'combining' characters. Set with \Z flag
- * in the regexp. Defaults to false, always.
- */
-static int ireg_icombine;
-
-/*
- * Copy of "rmm_maxcol": maximum column to search for a match. Zero when
- * there is no maximum.
- */
-static colnr_T ireg_maxcol;
-
-/*
- * Sometimes need to save a copy of a line. Since alloc()/free() is very
- * slow, we keep one allocated piece of memory and only re-allocate it when
- * it's too small. It's freed in bt_regexec_both() when finished.
- */
+// Sometimes need to save a copy of a line. Since alloc()/free() is very
+// slow, we keep one allocated piece of memory and only re-allocate it when
+// it's too small. It's freed in bt_regexec_both() when finished.
static char_u *reg_tofree = NULL;
static unsigned reg_tofreelen;
-/*
- * These variables are set when executing a regexp to speed up the execution.
- * Which ones are set depends on whether a single-line or multi-line match is
- * done:
- * single-line multi-line
- * reg_match &regmatch_T NULL
- * reg_mmatch NULL &regmmatch_T
- * reg_startp reg_match->startp <invalid>
- * reg_endp reg_match->endp <invalid>
- * reg_startpos <invalid> reg_mmatch->startpos
- * reg_endpos <invalid> reg_mmatch->endpos
- * reg_win NULL window in which to search
- * reg_buf curbuf buffer in which to search
- * reg_firstlnum <invalid> first line in which to search
- * reg_maxline 0 last line nr
- * reg_line_lbr FALSE or TRUE FALSE
- */
-static regmatch_T *reg_match;
-static regmmatch_T *reg_mmatch;
-static char_u **reg_startp = NULL;
-static char_u **reg_endp = NULL;
-static lpos_T *reg_startpos = NULL;
-static lpos_T *reg_endpos = NULL;
-static win_T *reg_win;
-static buf_T *reg_buf;
-static linenr_T reg_firstlnum;
-static linenr_T reg_maxline;
-static int reg_line_lbr; /* "\n" in string is line break */
+// Structure used to store the execution state of the regex engine.
+// Which ones are set depends on whether a single-line or multi-line match is
+// done:
+// single-line multi-line
+// reg_match &regmatch_T NULL
+// reg_mmatch NULL &regmmatch_T
+// reg_startp reg_match->startp <invalid>
+// reg_endp reg_match->endp <invalid>
+// reg_startpos <invalid> reg_mmatch->startpos
+// reg_endpos <invalid> reg_mmatch->endpos
+// reg_win NULL window in which to search
+// reg_buf curbuf buffer in which to search
+// reg_firstlnum <invalid> first line in which to search
+// reg_maxline 0 last line nr
+// reg_line_lbr false or true false
+typedef struct {
+ regmatch_T *reg_match;
+ regmmatch_T *reg_mmatch;
+ char_u **reg_startp;
+ char_u **reg_endp;
+ lpos_T *reg_startpos;
+ lpos_T *reg_endpos;
+ win_T *reg_win;
+ buf_T *reg_buf;
+ linenr_T reg_firstlnum;
+ linenr_T reg_maxline;
+ bool reg_line_lbr; // "\n" in string is line break
+
+ // Internal copy of 'ignorecase'. It is set at each call to vim_regexec().
+ // Normally it gets the value of "rm_ic" or "rmm_ic", but when the pattern
+ // contains '\c' or '\C' the value is overruled.
+ bool reg_ic;
+
+ // Similar to rex.reg_ic, but only for 'combining' characters. Set with \Z
+ // flag in the regexp. Defaults to false, always.
+ bool reg_icombine;
+
+ // Copy of "rmm_maxcol": maximum column to search for a match. Zero when
+ // there is no maximum.
+ colnr_T reg_maxcol;
+} regexec_T;
+
+static regexec_T rex;
+static bool rex_in_use = false;
/*
* "regstack" and "backpos" are used by regmatch(). They are kept over calls
@@ -3269,14 +3263,16 @@ void free_regexp_stuff(void)
*/
static char_u *reg_getline(linenr_T lnum)
{
- /* when looking behind for a match/no-match lnum is negative. But we
- * can't go before line 1 */
- if (reg_firstlnum + lnum < 1)
+ // when looking behind for a match/no-match lnum is negative. But we
+ // can't go before line 1
+ if (rex.reg_firstlnum + lnum < 1) {
return NULL;
- if (lnum > reg_maxline)
- /* Must have matched the "\n" in the last line. */
+ }
+ if (lnum > rex.reg_maxline) {
+ // Must have matched the "\n" in the last line.
return (char_u *)"";
- return ml_get_buf(reg_buf, reg_firstlnum + lnum, FALSE);
+ }
+ return ml_get_buf(rex.reg_buf, rex.reg_firstlnum + lnum, false);
}
static regsave_T behind_pos;
@@ -3286,9 +3282,8 @@ static char_u *reg_endzp[NSUBEXP]; /* and end of \z(...\) matches */
static lpos_T reg_startzpos[NSUBEXP]; /* idem, beginning pos */
static lpos_T reg_endzpos[NSUBEXP]; /* idem, end pos */
-/* TRUE if using multi-line regexp. */
-#define REG_MULTI (reg_match == NULL)
-
+// TRUE if using multi-line regexp.
+#define REG_MULTI (rex.reg_match == NULL)
/*
* Match a regexp against a string.
@@ -3306,15 +3301,15 @@ bt_regexec_nl (
bool line_lbr
)
{
- reg_match = rmp;
- reg_mmatch = NULL;
- reg_maxline = 0;
- reg_line_lbr = line_lbr;
- reg_buf = curbuf;
- reg_win = NULL;
- ireg_ic = rmp->rm_ic;
- ireg_icombine = FALSE;
- ireg_maxcol = 0;
+ rex.reg_match = rmp;
+ rex.reg_mmatch = NULL;
+ rex.reg_maxline = 0;
+ rex.reg_line_lbr = line_lbr;
+ rex.reg_buf = curbuf;
+ rex.reg_win = NULL;
+ rex.reg_ic = rmp->rm_ic;
+ rex.reg_icombine = false;
+ rex.reg_maxcol = 0;
long r = bt_regexec_both(line, col, NULL);
assert(r <= INT_MAX);
@@ -3337,16 +3332,16 @@ bt_regexec_nl (
static long bt_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf,
linenr_T lnum, colnr_T col, proftime_T *tm)
{
- reg_match = NULL;
- reg_mmatch = rmp;
- reg_buf = buf;
- reg_win = win;
- reg_firstlnum = lnum;
- reg_maxline = reg_buf->b_ml.ml_line_count - lnum;
- reg_line_lbr = FALSE;
- ireg_ic = rmp->rmm_ic;
- ireg_icombine = FALSE;
- ireg_maxcol = rmp->rmm_maxcol;
+ rex.reg_match = NULL;
+ rex.reg_mmatch = rmp;
+ rex.reg_buf = buf;
+ rex.reg_win = win;
+ rex.reg_firstlnum = lnum;
+ rex.reg_maxline = rex.reg_buf->b_ml.ml_line_count - lnum;
+ rex.reg_line_lbr = false;
+ rex.reg_ic = rmp->rmm_ic;
+ rex.reg_icombine = false;
+ rex.reg_maxcol = rmp->rmm_maxcol;
return bt_regexec_both(NULL, col, tm);
}
@@ -3384,14 +3379,14 @@ static long bt_regexec_both(char_u *line,
}
if (REG_MULTI) {
- prog = (bt_regprog_T *)reg_mmatch->regprog;
+ prog = (bt_regprog_T *)rex.reg_mmatch->regprog;
line = reg_getline((linenr_T)0);
- reg_startpos = reg_mmatch->startpos;
- reg_endpos = reg_mmatch->endpos;
+ rex.reg_startpos = rex.reg_mmatch->startpos;
+ rex.reg_endpos = rex.reg_mmatch->endpos;
} else {
- prog = (bt_regprog_T *)reg_match->regprog;
- reg_startp = reg_match->startp;
- reg_endp = reg_match->endp;
+ prog = (bt_regprog_T *)rex.reg_match->regprog;
+ rex.reg_startp = rex.reg_match->startp;
+ rex.reg_endp = rex.reg_match->endp;
}
/* Be paranoid... */
@@ -3404,19 +3399,22 @@ static long bt_regexec_both(char_u *line,
if (prog_magic_wrong())
goto theend;
- /* If the start column is past the maximum column: no need to try. */
- if (ireg_maxcol > 0 && col >= ireg_maxcol)
+ // If the start column is past the maximum column: no need to try.
+ if (rex.reg_maxcol > 0 && col >= rex.reg_maxcol) {
goto theend;
+ }
- /* If pattern contains "\c" or "\C": overrule value of ireg_ic */
- if (prog->regflags & RF_ICASE)
- ireg_ic = TRUE;
- else if (prog->regflags & RF_NOICASE)
- ireg_ic = FALSE;
+ // If pattern contains "\c" or "\C": overrule value of rex.reg_ic
+ if (prog->regflags & RF_ICASE) {
+ rex.reg_ic = true;
+ } else if (prog->regflags & RF_NOICASE) {
+ rex.reg_ic = false;
+ }
- /* If pattern contains "\Z" overrule value of ireg_icombine */
- if (prog->regflags & RF_ICOMBINE)
- ireg_icombine = TRUE;
+ // If pattern contains "\Z" overrule value of rex.reg_icombine
+ if (prog->regflags & RF_ICOMBINE) {
+ rex.reg_icombine = true;
+ }
/* If there is a "must appear" string, look for it. */
if (prog->regmust != NULL) {
@@ -3428,32 +3426,26 @@ static long bt_regexec_both(char_u *line,
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))
+ // This is used very often, esp. for ":global". Use two versions of
+ // the loop to avoid overhead of conditions.
+ if (!rex.reg_ic) {
while ((s = vim_strchr(s, c)) != NULL) {
- if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0)
- break; /* Found it. */
+ if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0) {
+ break; // Found it.
+ }
mb_ptr_adv(s);
}
- else
+ } else {
while ((s = cstrchr(s, c)) != NULL) {
- if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0)
- break; /* Found it. */
+ if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0) {
+ break; // Found it.
+ }
mb_ptr_adv(s);
}
- if (s == NULL) /* Not present. */
+ }
+ if (s == NULL) { // Not present.
goto theend;
+ }
}
regline = line;
@@ -3470,10 +3462,10 @@ static long bt_regexec_both(char_u *line,
c = regline[col];
if (prog->regstart == NUL
|| prog->regstart == c
- || (ireg_ic
+ || (rex.reg_ic
&& (((enc_utf8 && utf_fold(prog->regstart) == utf_fold(c)))
|| (c < 255 && prog->regstart < 255
- && vim_tolower(prog->regstart) == vim_tolower(c))))) {
+ && mb_tolower(prog->regstart) == mb_tolower(c))))) {
retval = regtry(prog, col);
} else {
retval = 0;
@@ -3483,14 +3475,8 @@ static long bt_regexec_both(char_u *line,
/* Messy cases: unanchored match. */
while (!got_int) {
if (prog->regstart != NUL) {
- /* Skip until the char we know it must start with.
- * Used often, do some work to avoid call overhead. */
- if (!ireg_ic
- && !has_mbyte
- )
- s = vim_strbyte(regline + col, prog->regstart);
- else
- s = cstrchr(regline + col, prog->regstart);
+ // Skip until the char we know it must start with.
+ s = cstrchr(regline + col, prog->regstart);
if (s == NULL) {
retval = 0;
break;
@@ -3498,8 +3484,8 @@ static long bt_regexec_both(char_u *line,
col = (int)(s - regline);
}
- /* Check for maximum column to try. */
- if (ireg_maxcol > 0 && col >= ireg_maxcol) {
+ // Check for maximum column to try.
+ if (rex.reg_maxcol > 0 && col >= rex.reg_maxcol) {
retval = 0;
break;
}
@@ -3596,21 +3582,24 @@ static long regtry(bt_regprog_T *prog, colnr_T col)
cleanup_subexpr();
if (REG_MULTI) {
- if (reg_startpos[0].lnum < 0) {
- reg_startpos[0].lnum = 0;
- reg_startpos[0].col = col;
+ if (rex.reg_startpos[0].lnum < 0) {
+ rex.reg_startpos[0].lnum = 0;
+ rex.reg_startpos[0].col = col;
+ }
+ if (rex.reg_endpos[0].lnum < 0) {
+ rex.reg_endpos[0].lnum = reglnum;
+ rex.reg_endpos[0].col = (int)(reginput - regline);
+ } else {
+ // Use line number of "\ze".
+ reglnum = rex.reg_endpos[0].lnum;
}
- if (reg_endpos[0].lnum < 0) {
- reg_endpos[0].lnum = reglnum;
- reg_endpos[0].col = (int)(reginput - regline);
- } else
- /* Use line number of "\ze". */
- reglnum = reg_endpos[0].lnum;
} else {
- if (reg_startp[0] == NULL)
- reg_startp[0] = regline + col;
- if (reg_endp[0] == NULL)
- reg_endp[0] = reginput;
+ if (rex.reg_startp[0] == NULL) {
+ rex.reg_startp[0] = regline + col;
+ }
+ if (rex.reg_endp[0] == NULL) {
+ rex.reg_endp[0] = reginput;
+ }
}
/* Package any found \z(...\) matches for export. Default is none. */
unref_extmatch(re_extmatch_out);
@@ -3645,34 +3634,33 @@ static long regtry(bt_regprog_T *prog, colnr_T col)
}
-/*
- * Get class of previous character.
- */
+// Get class of previous character.
static int reg_prev_class(void)
{
- if (reginput > regline)
- return mb_get_class_buf(reginput - 1
- - (*mb_head_off)(regline, reginput - 1), reg_buf);
+ if (reginput > regline) {
+ return mb_get_class_tab(reginput - 1 - (*mb_head_off)(regline,
+ reginput - 1),
+ rex.reg_buf->b_chartab);
+ }
return -1;
}
-/*
- * Return TRUE if the current reginput position matches the Visual area.
- */
+// Return TRUE if the current reginput position matches the Visual area.
static int reg_match_visual(void)
{
pos_T top, bot;
linenr_T lnum;
colnr_T col;
- win_T *wp = reg_win == NULL ? curwin : reg_win;
+ win_T *wp = rex.reg_win == NULL ? curwin : rex.reg_win;
int mode;
colnr_T start, end;
colnr_T start2, end2;
- /* Check if the buffer is the current buffer. */
- if (reg_buf != curbuf || VIsual.lnum == 0)
- return FALSE;
+ // Check if the buffer is the current buffer.
+ if (rex.reg_buf != curbuf || VIsual.lnum == 0) {
+ return false;
+ }
if (VIsual_active) {
if (lt(VIsual, wp->w_cursor)) {
@@ -3693,9 +3681,10 @@ static int reg_match_visual(void)
}
mode = curbuf->b_visual.vi_mode;
}
- lnum = reglnum + reg_firstlnum;
- if (lnum < top.lnum || lnum > bot.lnum)
- return FALSE;
+ lnum = reglnum + rex.reg_firstlnum;
+ if (lnum < top.lnum || lnum > bot.lnum) {
+ return false;
+ }
if (mode == 'v') {
col = (colnr_T)(reginput - regline);
@@ -3814,11 +3803,11 @@ regmatch (
next = regnext(scan);
op = OP(scan);
- /* Check for character class with NL added. */
- if (!reg_line_lbr && WITH_NL(op) && REG_MULTI
- && *reginput == NUL && reglnum <= reg_maxline) {
+ // Check for character class with NL added.
+ if (!rex.reg_line_lbr && WITH_NL(op) && REG_MULTI
+ && *reginput == NUL && reglnum <= rex.reg_maxline) {
reg_nextline();
- } else if (reg_line_lbr && WITH_NL(op) && *reginput == '\n') {
+ } else if (rex.reg_line_lbr && WITH_NL(op) && *reginput == '\n') {
ADVANCE_REGINPUT();
} else {
if (WITH_NL(op))
@@ -3839,26 +3828,29 @@ regmatch (
break;
case RE_BOF:
- /* We're not at the beginning of the file when below the first
- * line where we started, not at the start of the line or we
- * didn't start at the first line of the buffer. */
+ // We're not at the beginning of the file when below the first
+ // line where we started, not at the start of the line or we
+ // didn't start at the first line of the buffer.
if (reglnum != 0 || reginput != regline
- || (REG_MULTI && reg_firstlnum > 1))
+ || (REG_MULTI && rex.reg_firstlnum > 1)) {
status = RA_NOMATCH;
+ }
break;
case RE_EOF:
- if (reglnum != reg_maxline || c != NUL)
+ if (reglnum != rex.reg_maxline || c != NUL) {
status = RA_NOMATCH;
+ }
break;
case CURSOR:
- /* Check if the buffer is in a window and compare the
- * reg_win->w_cursor position to the match position. */
- if (reg_win == NULL
- || (reglnum + reg_firstlnum != reg_win->w_cursor.lnum)
- || ((colnr_T)(reginput - regline) != reg_win->w_cursor.col))
+ // Check if the buffer is in a window and compare the
+ // rex.reg_win->w_cursor position to the match position.
+ if (rex.reg_win == NULL
+ || (reglnum + rex.reg_firstlnum != rex.reg_win->w_cursor.lnum)
+ || ((colnr_T)(reginput - regline) != rex.reg_win->w_cursor.col)) {
status = RA_NOMATCH;
+ }
break;
case RE_MARK:
@@ -3868,19 +3860,20 @@ regmatch (
int cmp = OPERAND(scan)[1];
pos_T *pos;
- pos = getmark_buf(reg_buf, mark, FALSE);
- if (pos == NULL /* mark doesn't exist */
- || pos->lnum <= 0 /* mark isn't set in reg_buf */
- || (pos->lnum == reglnum + reg_firstlnum
+ pos = getmark_buf(rex.reg_buf, mark, false);
+ if (pos == NULL // mark doesn't exist
+ || pos->lnum <= 0 // mark isn't set in reg_buf
+ || (pos->lnum == reglnum + rex.reg_firstlnum
? (pos->col == (colnr_T)(reginput - regline)
? (cmp == '<' || cmp == '>')
: (pos->col < (colnr_T)(reginput - regline)
? cmp != '>'
: cmp != '<'))
- : (pos->lnum < reglnum + reg_firstlnum
+ : (pos->lnum < reglnum + rex.reg_firstlnum
? cmp != '>'
- : cmp != '<')))
+ : cmp != '<'))) {
status = RA_NOMATCH;
+ }
}
break;
@@ -3890,11 +3883,12 @@ regmatch (
break;
case RE_LNUM:
- assert(reglnum + reg_firstlnum >= 0
- && (uintmax_t)(reglnum + reg_firstlnum) <= UINT32_MAX);
- if (!REG_MULTI || !re_num_cmp((uint32_t)(reglnum + reg_firstlnum),
- scan))
+ assert(reglnum + rex.reg_firstlnum >= 0
+ && (uintmax_t)(reglnum + rex.reg_firstlnum) <= UINT32_MAX);
+ if (!REG_MULTI
+ || !re_num_cmp((uint32_t)(reglnum + rex.reg_firstlnum), scan)) {
status = RA_NOMATCH;
+ }
break;
case RE_COL:
@@ -3905,11 +3899,13 @@ regmatch (
break;
case RE_VCOL:
- if (!re_num_cmp(win_linetabsize(reg_win == NULL ? curwin : reg_win,
+ if (!re_num_cmp(win_linetabsize(rex.reg_win == NULL
+ ? curwin : rex.reg_win,
regline,
(colnr_T)(reginput - regline)) + 1,
- scan))
+ scan)) {
status = RA_NOMATCH;
+ }
break;
case BOW: /* \<word; reginput points to w */
@@ -3918,17 +3914,19 @@ regmatch (
else if (has_mbyte) {
int this_class;
- /* Get class of current and previous char (if it exists). */
- this_class = mb_get_class_buf(reginput, reg_buf);
- if (this_class <= 1)
- status = RA_NOMATCH; /* not on a word at all */
- else if (reg_prev_class() == this_class)
- status = RA_NOMATCH; /* previous char is in same word */
+ // Get class of current and previous char (if it exists).
+ this_class = mb_get_class_tab(reginput, rex.reg_buf->b_chartab);
+ if (this_class <= 1) {
+ status = RA_NOMATCH; // Not on a word at all.
+ } else if (reg_prev_class() == this_class) {
+ status = RA_NOMATCH; // Previous char is in same word.
+ }
} else {
- if (!vim_iswordc_buf(c, reg_buf) || (reginput > regline
- && vim_iswordc_buf(reginput[-1
- ], reg_buf)))
+ if (!vim_iswordc_buf(c, rex.reg_buf)
+ || (reginput > regline
+ && vim_iswordc_buf(reginput[-1], rex.reg_buf))) {
status = RA_NOMATCH;
+ }
}
break;
@@ -3938,16 +3936,17 @@ regmatch (
else if (has_mbyte) {
int this_class, prev_class;
- /* Get class of current and previous char (if it exists). */
- this_class = mb_get_class_buf(reginput, reg_buf);
+ // Get class of current and previous char (if it exists).
+ this_class = mb_get_class_tab(reginput, rex.reg_buf->b_chartab);
prev_class = reg_prev_class();
if (this_class == prev_class
|| prev_class == 0 || prev_class == 1)
status = RA_NOMATCH;
} else {
- if (!vim_iswordc_buf(reginput[-1], reg_buf)
- || (reginput[0] != NUL && vim_iswordc_buf(c, reg_buf)))
+ if (!vim_iswordc_buf(reginput[-1], rex.reg_buf)
+ || (reginput[0] != NUL && vim_iswordc_buf(c, rex.reg_buf))) {
status = RA_NOMATCH;
+ }
}
break; /* Matched with EOW */
@@ -3974,17 +3973,20 @@ regmatch (
break;
case KWORD:
- if (!vim_iswordp_buf(reginput, reg_buf))
+ if (!vim_iswordp_buf(reginput, rex.reg_buf)) {
status = RA_NOMATCH;
- else
+ } else {
ADVANCE_REGINPUT();
+ }
break;
case SKWORD:
- if (ascii_isdigit(*reginput) || !vim_iswordp_buf(reginput, reg_buf))
+ if (ascii_isdigit(*reginput)
+ || !vim_iswordp_buf(reginput, rex.reg_buf)) {
status = RA_NOMATCH;
- else
+ } else {
ADVANCE_REGINPUT();
+ }
break;
case FNAME:
@@ -4149,16 +4151,16 @@ regmatch (
opnd = OPERAND(scan);
// Inline the first byte, for speed.
if (*opnd != *reginput
- && (!ireg_ic
+ && (!rex.reg_ic
|| (!enc_utf8
- && vim_tolower(*opnd) != vim_tolower(*reginput)))) {
+ && mb_tolower(*opnd) != mb_tolower(*reginput)))) {
status = RA_NOMATCH;
} else if (*opnd == NUL) {
// match empty string always works; happens when "~" is
// empty.
} else {
- if (opnd[1] == NUL && !(enc_utf8 && ireg_ic)) {
- len = 1; /* matched a single byte above */
+ if (opnd[1] == NUL && !(enc_utf8 && rex.reg_ic)) {
+ len = 1; // matched a single byte above
} else {
// Need to match first byte again for multi-byte.
len = (int)STRLEN(opnd);
@@ -4170,7 +4172,7 @@ regmatch (
// follows (skips over all composing chars).
if (status != RA_NOMATCH && enc_utf8
&& UTF_COMPOSINGLIKE(reginput, reginput + len)
- && !ireg_icombine
+ && !rex.reg_icombine
&& OP(next) != RE_COMPOSING) {
// raaron: This code makes a composing character get
// ignored, which is the correct behavior (sometimes)
@@ -4294,9 +4296,9 @@ regmatch (
status = RA_FAIL;
else {
rp->rs_no = no;
- save_se(&rp->rs_un.sesave, &reg_startpos[no],
- &reg_startp[no]);
- /* We simply continue and handle the result when done. */
+ save_se(&rp->rs_un.sesave, &rex.reg_startpos[no],
+ &rex.reg_startp[no]);
+ // We simply continue and handle the result when done.
}
}
break;
@@ -4346,12 +4348,12 @@ regmatch (
no = op - MCLOSE;
cleanup_subexpr();
rp = regstack_push(RS_MCLOSE, scan);
- if (rp == NULL)
+ if (rp == NULL) {
status = RA_FAIL;
- else {
+ } else {
rp->rs_no = no;
- save_se(&rp->rs_un.sesave, &reg_endpos[no], &reg_endp[no]);
- /* We simply continue and handle the result when done. */
+ save_se(&rp->rs_un.sesave, &rex.reg_endpos[no], &rex.reg_endp[no]);
+ // We simply continue and handle the result when done.
}
}
break;
@@ -4394,41 +4396,40 @@ regmatch (
no = op - BACKREF;
cleanup_subexpr();
- if (!REG_MULTI) { /* Single-line regexp */
- if (reg_startp[no] == NULL || reg_endp[no] == NULL) {
- /* Backref was not set: Match an empty string. */
+ if (!REG_MULTI) { // Single-line regexp
+ if (rex.reg_startp[no] == NULL || rex.reg_endp[no] == NULL) {
+ // Backref was not set: Match an empty string.
len = 0;
} else {
- /* Compare current input with back-ref in the same
- * line. */
- len = (int)(reg_endp[no] - reg_startp[no]);
- if (cstrncmp(reg_startp[no], reginput, &len) != 0)
+ // Compare current input with back-ref in the same line.
+ len = (int)(rex.reg_endp[no] - rex.reg_startp[no]);
+ if (cstrncmp(rex.reg_startp[no], reginput, &len) != 0) {
status = RA_NOMATCH;
+ }
}
- } else { /* Multi-line regexp */
- if (reg_startpos[no].lnum < 0 || reg_endpos[no].lnum < 0) {
- /* Backref was not set: Match an empty string. */
+ } else { // Multi-line regexp
+ if (rex.reg_startpos[no].lnum < 0 || rex.reg_endpos[no].lnum < 0) {
+ // Backref was not set: Match an empty string.
len = 0;
} else {
- if (reg_startpos[no].lnum == reglnum
- && reg_endpos[no].lnum == reglnum) {
- /* Compare back-ref within the current line. */
- len = reg_endpos[no].col - reg_startpos[no].col;
- if (cstrncmp(regline + reg_startpos[no].col,
- reginput, &len) != 0)
+ if (rex.reg_startpos[no].lnum == reglnum
+ && rex.reg_endpos[no].lnum == reglnum) {
+ // Compare back-ref within the current line.
+ len = rex.reg_endpos[no].col - rex.reg_startpos[no].col;
+ if (cstrncmp(regline + rex.reg_startpos[no].col,
+ reginput, &len) != 0) {
status = RA_NOMATCH;
+ }
} else {
- /* Messy situation: Need to compare between two
- * lines. */
- int r = match_with_backref(
- reg_startpos[no].lnum,
- reg_startpos[no].col,
- reg_endpos[no].lnum,
- reg_endpos[no].col,
- &len);
-
- if (r != RA_MATCH)
+ // Messy situation: Need to compare between two lines.
+ int r = match_with_backref(rex.reg_startpos[no].lnum,
+ rex.reg_startpos[no].col,
+ rex.reg_endpos[no].lnum,
+ rex.reg_endpos[no].col,
+ &len);
+ if (r != RA_MATCH) {
status = r;
+ }
}
}
}
@@ -4568,13 +4569,15 @@ regmatch (
*/
if (OP(next) == EXACTLY) {
rst.nextb = *OPERAND(next);
- if (ireg_ic) {
- if (vim_isupper(rst.nextb))
- rst.nextb_ic = vim_tolower(rst.nextb);
- else
- rst.nextb_ic = vim_toupper(rst.nextb);
- } else
+ if (rex.reg_ic) {
+ if (mb_isupper(rst.nextb)) {
+ rst.nextb_ic = mb_tolower(rst.nextb);
+ } else {
+ rst.nextb_ic = mb_toupper(rst.nextb);
+ }
+ } else {
rst.nextb_ic = rst.nextb;
+ }
} else {
rst.nextb = NUL;
rst.nextb_ic = NUL;
@@ -4673,13 +4676,14 @@ regmatch (
break;
case NEWL:
- if ((c != NUL || !REG_MULTI || reglnum > reg_maxline
- || reg_line_lbr) && (c != '\n' || !reg_line_lbr))
+ if ((c != NUL || !REG_MULTI || reglnum > rex.reg_maxline
+ || rex.reg_line_lbr) && (c != '\n' || !rex.reg_line_lbr)) {
status = RA_NOMATCH;
- else if (reg_line_lbr)
+ } else if (rex.reg_line_lbr) {
ADVANCE_REGINPUT();
- else
+ } else {
reg_nextline();
+ }
break;
case END:
@@ -4718,10 +4722,11 @@ regmatch (
break;
case RS_MOPEN:
- /* Pop the state. Restore pointers when there is no match. */
- if (status == RA_NOMATCH)
- restore_se(&rp->rs_un.sesave, &reg_startpos[rp->rs_no],
- &reg_startp[rp->rs_no]);
+ // Pop the state. Restore pointers when there is no match.
+ if (status == RA_NOMATCH) {
+ restore_se(&rp->rs_un.sesave, &rex.reg_startpos[rp->rs_no],
+ &rex.reg_startp[rp->rs_no]);
+ }
regstack_pop(&scan);
break;
@@ -4734,10 +4739,11 @@ regmatch (
break;
case RS_MCLOSE:
- /* Pop the state. Restore pointers when there is no match. */
- if (status == RA_NOMATCH)
- restore_se(&rp->rs_un.sesave, &reg_endpos[rp->rs_no],
- &reg_endp[rp->rs_no]);
+ // Pop the state. Restore pointers when there is no match.
+ if (status == RA_NOMATCH) {
+ restore_se(&rp->rs_un.sesave, &rex.reg_endpos[rp->rs_no],
+ &rex.reg_endp[rp->rs_no]);
+ }
regstack_pop(&scan);
break;
@@ -5117,10 +5123,11 @@ regrepeat (
++count;
mb_ptr_adv(scan);
}
- if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
- || reg_line_lbr || count == maxcount)
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline
+ || rex.reg_line_lbr || count == maxcount) {
break;
- ++count; /* count the line-break */
+ }
+ count++; // count the line-break
reg_nextline();
scan = reginput;
if (got_int)
@@ -5138,17 +5145,19 @@ regrepeat (
if (vim_isIDc(PTR2CHAR(scan)) && (testval || !ascii_isdigit(*scan))) {
mb_ptr_adv(scan);
} else if (*scan == NUL) {
- if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
- || reg_line_lbr)
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline
+ || rex.reg_line_lbr) {
break;
+ }
reg_nextline();
scan = reginput;
if (got_int)
break;
- } else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
- ++scan;
- else
+ } else if (rex.reg_line_lbr && *scan == '\n' && WITH_NL(OP(p))) {
+ scan++;
+ } else {
break;
+ }
++count;
}
break;
@@ -5160,22 +5169,25 @@ regrepeat (
case SKWORD:
case SKWORD + ADD_NL:
while (count < maxcount) {
- if (vim_iswordp_buf(scan, reg_buf)
+ if (vim_iswordp_buf(scan, rex.reg_buf)
&& (testval || !ascii_isdigit(*scan))) {
mb_ptr_adv(scan);
} else if (*scan == NUL) {
- if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
- || reg_line_lbr)
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline
+ || rex.reg_line_lbr) {
break;
+ }
reg_nextline();
scan = reginput;
- if (got_int)
+ if (got_int) {
break;
- } else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
- ++scan;
- else
+ }
+ } else if (rex.reg_line_lbr && *scan == '\n' && WITH_NL(OP(p))) {
+ scan++;
+ } else {
break;
- ++count;
+ }
+ count++;
}
break;
@@ -5189,18 +5201,21 @@ regrepeat (
if (vim_isfilec(PTR2CHAR(scan)) && (testval || !ascii_isdigit(*scan))) {
mb_ptr_adv(scan);
} else if (*scan == NUL) {
- if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
- || reg_line_lbr)
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline
+ || rex.reg_line_lbr) {
break;
+ }
reg_nextline();
scan = reginput;
- if (got_int)
+ if (got_int) {
break;
- } else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
- ++scan;
- else
+ }
+ } else if (rex.reg_line_lbr && *scan == '\n' && WITH_NL(OP(p))) {
+ scan++;
+ } else {
break;
- ++count;
+ }
+ count++;
}
break;
@@ -5212,21 +5227,24 @@ regrepeat (
case SPRINT + ADD_NL:
while (count < maxcount) {
if (*scan == NUL) {
- if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
- || reg_line_lbr)
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline
+ || rex.reg_line_lbr) {
break;
+ }
reg_nextline();
scan = reginput;
- if (got_int)
+ if (got_int) {
break;
+ }
} else if (vim_isprintc(PTR2CHAR(scan)) == 1
&& (testval || !ascii_isdigit(*scan))) {
mb_ptr_adv(scan);
- } else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
- ++scan;
- else
+ } else if (rex.reg_line_lbr && *scan == '\n' && WITH_NL(OP(p))) {
+ scan++;
+ } else {
break;
- ++count;
+ }
+ count++;
}
break;
@@ -5237,9 +5255,10 @@ do_class:
while (count < maxcount) {
int l;
if (*scan == NUL) {
- if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
- || reg_line_lbr)
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline
+ || rex.reg_line_lbr) {
break;
+ }
reg_nextline();
scan = reginput;
if (got_int)
@@ -5248,12 +5267,13 @@ do_class:
if (testval != 0)
break;
scan += l;
- } else if ((class_tab[*scan] & mask) == testval)
- ++scan;
- else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
- ++scan;
- else
+ } else if ((class_tab[*scan] & mask) == testval) {
+ scan++;
+ } else if (rex.reg_line_lbr && *scan == '\n' && WITH_NL(OP(p))) {
+ scan++;
+ } else {
break;
+ }
++count;
}
break;
@@ -5331,12 +5351,12 @@ do_class:
{
int cu, cl;
- /* This doesn't do a multi-byte character, because a MULTIBYTECODE
- * would have been used for it. It does handle single-byte
- * characters, such as latin1. */
- if (ireg_ic) {
- cu = vim_toupper(*opnd);
- cl = vim_tolower(*opnd);
+ // This doesn't do a multi-byte character, because a MULTIBYTECODE
+ // would have been used for it. It does handle single-byte
+ // characters, such as latin1.
+ if (rex.reg_ic) {
+ cu = mb_toupper(*opnd);
+ cl = mb_tolower(*opnd);
while (count < maxcount && (*scan == cu || *scan == cl)) {
count++;
scan++;
@@ -5358,17 +5378,19 @@ do_class:
/* Safety check (just in case 'encoding' was changed since
* compiling the program). */
if ((len = (*mb_ptr2len)(opnd)) > 1) {
- if (ireg_ic && enc_utf8)
+ if (rex.reg_ic && enc_utf8) {
cf = utf_fold(utf_ptr2char(opnd));
+ }
while (count < maxcount && (*mb_ptr2len)(scan) >= len) {
for (i = 0; i < len; ++i) {
if (opnd[i] != scan[i]) {
break;
}
}
- if (i < len && (!ireg_ic || !enc_utf8
- || utf_fold(utf_ptr2char(scan)) != cf))
+ if (i < len && (!rex.reg_ic || !enc_utf8
+ || utf_fold(utf_ptr2char(scan)) != cf)) {
break;
+ }
scan += len;
++count;
}
@@ -5386,18 +5408,21 @@ do_class:
while (count < maxcount) {
int len;
if (*scan == NUL) {
- if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
- || reg_line_lbr)
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline
+ || rex.reg_line_lbr) {
break;
+ }
reg_nextline();
scan = reginput;
- if (got_int)
+ if (got_int) {
break;
- } else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
- ++scan;
- else if (has_mbyte && (len = (*mb_ptr2len)(scan)) > 1) {
- if ((cstrchr(opnd, (*mb_ptr2char)(scan)) == NULL) == testval)
+ }
+ } else if (rex.reg_line_lbr && *scan == '\n' && WITH_NL(OP(p))) {
+ scan++;
+ } else if (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)
@@ -5410,13 +5435,14 @@ do_class:
case NEWL:
while (count < maxcount
- && ((*scan == NUL && reglnum <= reg_maxline && !reg_line_lbr
- && REG_MULTI) || (*scan == '\n' && reg_line_lbr))) {
+ && ((*scan == NUL && reglnum <= rex.reg_maxline && !rex.reg_line_lbr
+ && REG_MULTI) || (*scan == '\n' && rex.reg_line_lbr))) {
count++;
- if (reg_line_lbr)
+ if (rex.reg_line_lbr) {
ADVANCE_REGINPUT();
- else
+ } else {
reg_nextline();
+ }
scan = reginput;
if (got_int)
break;
@@ -5466,10 +5492,11 @@ static int prog_magic_wrong(void)
{
regprog_T *prog;
- prog = REG_MULTI ? reg_mmatch->regprog : reg_match->regprog;
- if (prog->engine == &nfa_regengine)
- /* For NFA matcher we don't check the magic */
- return FALSE;
+ prog = REG_MULTI ? rex.reg_mmatch->regprog : rex.reg_match->regprog;
+ if (prog->engine == &nfa_regengine) {
+ // For NFA matcher we don't check the magic
+ return false;
+ }
if (UCHARAT(((bt_regprog_T *)prog)->program) != REGMAGIC) {
EMSG(_(e_re_corr));
@@ -5487,12 +5514,12 @@ static void cleanup_subexpr(void)
{
if (need_clear_subexpr) {
if (REG_MULTI) {
- /* Use 0xff to set lnum to -1 */
- memset(reg_startpos, 0xff, sizeof(lpos_T) * NSUBEXP);
- memset(reg_endpos, 0xff, sizeof(lpos_T) * NSUBEXP);
+ // Use 0xff to set lnum to -1
+ memset(rex.reg_startpos, 0xff, sizeof(lpos_T) * NSUBEXP);
+ memset(rex.reg_endpos, 0xff, sizeof(lpos_T) * NSUBEXP);
} else {
- memset(reg_startp, 0, sizeof(char_u *) * NSUBEXP);
- memset(reg_endp, 0, sizeof(char_u *) * NSUBEXP);
+ memset(rex.reg_startp, 0, sizeof(char_u *) * NSUBEXP);
+ memset(rex.reg_endp, 0, sizeof(char_u *) * NSUBEXP);
}
need_clear_subexpr = FALSE;
}
@@ -5521,17 +5548,17 @@ static void save_subexpr(regbehind_T *bp)
{
int i;
- /* When "need_clear_subexpr" is set we don't need to save the values, only
- * remember that this flag needs to be set again when restoring. */
+ // When "need_clear_subexpr" is set we don't need to save the values, only
+ // remember that this flag needs to be set again when restoring.
bp->save_need_clear_subexpr = need_clear_subexpr;
if (!need_clear_subexpr) {
for (i = 0; i < NSUBEXP; ++i) {
if (REG_MULTI) {
- bp->save_start[i].se_u.pos = reg_startpos[i];
- bp->save_end[i].se_u.pos = reg_endpos[i];
+ bp->save_start[i].se_u.pos = rex.reg_startpos[i];
+ bp->save_end[i].se_u.pos = rex.reg_endpos[i];
} else {
- bp->save_start[i].se_u.ptr = reg_startp[i];
- bp->save_end[i].se_u.ptr = reg_endp[i];
+ bp->save_start[i].se_u.ptr = rex.reg_startp[i];
+ bp->save_end[i].se_u.ptr = rex.reg_endp[i];
}
}
}
@@ -5549,11 +5576,11 @@ static void restore_subexpr(regbehind_T *bp)
if (!need_clear_subexpr) {
for (i = 0; i < NSUBEXP; ++i) {
if (REG_MULTI) {
- reg_startpos[i] = bp->save_start[i].se_u.pos;
- reg_endpos[i] = bp->save_end[i].se_u.pos;
+ rex.reg_startpos[i] = bp->save_start[i].se_u.pos;
+ rex.reg_endpos[i] = bp->save_end[i].se_u.pos;
} else {
- reg_startp[i] = bp->save_start[i].se_u.ptr;
- reg_endp[i] = bp->save_end[i].se_u.ptr;
+ rex.reg_startp[i] = bp->save_start[i].se_u.ptr;
+ rex.reg_endp[i] = bp->save_end[i].se_u.ptr;
}
}
}
@@ -5689,10 +5716,12 @@ static int match_with_backref(linenr_T start_lnum, colnr_T start_col, linenr_T e
return RA_NOMATCH; /* doesn't match */
if (bytelen != NULL)
*bytelen += len;
- if (clnum == end_lnum)
- break; /* match and at end! */
- if (reglnum >= reg_maxline)
- return RA_NOMATCH; /* text too short */
+ if (clnum == end_lnum) {
+ break; // match and at end!
+ }
+ if (reglnum >= rex.reg_maxline) {
+ return RA_NOMATCH; // text too short
+ }
/* Advance to next line. */
reg_nextline();
@@ -6240,24 +6269,22 @@ static void mb_decompose(int c, int *c1, int *c2, int *c3)
}
}
-/*
- * Compare two strings, ignore case if ireg_ic set.
- * Return 0 if strings match, non-zero otherwise.
- * Correct the length "*n" when composing characters are ignored.
- */
+// Compare two strings, ignore case if rex.reg_ic set.
+// Return 0 if strings match, non-zero otherwise.
+// Correct the length "*n" when composing characters are ignored.
static int cstrncmp(char_u *s1, char_u *s2, int *n)
{
int result;
- if (!ireg_ic)
+ if (!rex.reg_ic) {
result = STRNCMP(s1, s2, *n);
- else {
+ } else {
assert(*n >= 0);
result = mb_strnicmp(s1, s2, (size_t)*n);
}
- /* if it failed and it's utf8 and we want to combineignore: */
- if (result != 0 && enc_utf8 && ireg_icombine) {
+ // if it failed and it's utf8 and we want to combineignore:
+ if (result != 0 && enc_utf8 && rex.reg_icombine) {
char_u *str1, *str2;
int c1, c2, c11, c12;
int junk;
@@ -6268,20 +6295,21 @@ static int cstrncmp(char_u *s1, char_u *s2, int *n)
str2 = s2;
c1 = c2 = 0;
while ((int)(str1 - s1) < *n) {
- c1 = mb_ptr2char_adv(&str1);
- c2 = mb_ptr2char_adv(&str2);
+ c1 = mb_ptr2char_adv((const char_u **)&str1);
+ c2 = mb_ptr2char_adv((const char_u **)&str2);
/* decompose the character if necessary, into 'base' characters
* because I don't care about Arabic, I will hard-code the Hebrew
* which I *do* care about! So sue me... */
- if (c1 != c2 && (!ireg_ic || utf_fold(c1) != utf_fold(c2))) {
- /* decomposition necessary? */
+ if (c1 != c2 && (!rex.reg_ic || utf_fold(c1) != utf_fold(c2))) {
+ // decomposition necessary?
mb_decompose(c1, &c11, &junk, &junk);
mb_decompose(c2, &c12, &junk, &junk);
c1 = c11;
c2 = c12;
- if (c11 != c12 && (!ireg_ic || utf_fold(c11) != utf_fold(c12)))
+ if (c11 != c12 && (!rex.reg_ic || utf_fold(c11) != utf_fold(c12))) {
break;
+ }
}
}
result = c2 - c1;
@@ -6295,43 +6323,37 @@ static int cstrncmp(char_u *s1, char_u *s2, int *n)
/*
* cstrchr: This function is used a lot for simple searches, keep it fast!
*/
-static char_u *cstrchr(char_u *s, int c)
+static inline char_u *cstrchr(const char_u *const s, const int c)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_ALWAYS_INLINE
{
- char_u *p;
- int cc;
-
- if (!ireg_ic
- || (!enc_utf8 && mb_char2len(c) > 1)
- )
- return vim_strchr(s, c);
-
- /* tolower() and toupper() can be slow, comparing twice should be a lot
- * faster (esp. when using MS Visual C++!).
- * For UTF-8 need to use folded case. */
- if (enc_utf8 && c > 0x80)
- cc = utf_fold(c);
- else if (vim_isupper(c))
- cc = vim_tolower(c);
- else if (vim_islower(c))
- cc = vim_toupper(c);
- else
+ if (!rex.reg_ic) {
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;
+ // Use folded case for UTF-8, slow! For ASCII use libc strpbrk which is
+ // expected to be highly optimized.
+ if (c > 0x80) {
+ const int folded_c = utf_fold(c);
+ for (const char_u *p = s; *p != NUL; p += utfc_ptr2len(p)) {
+ if (utf_fold(utf_ptr2char(p)) == folded_c) {
+ return (char_u *)p;
+ }
}
- } 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;
+ }
+
+ int cc;
+ if (ASCII_ISUPPER(c)) {
+ cc = TOLOWER_ASC(c);
+ } else if (ASCII_ISLOWER(c)) {
+ cc = TOUPPER_ASC(c);
+ } else {
+ return vim_strchr(s, c);
+ }
- return NULL;
+ char tofind[] = { (char)c, (char)cc, NUL };
+ return (char_u *)strpbrk((const char *)s, tofind);
}
/***************************************************************
@@ -6344,28 +6366,28 @@ static char_u *cstrchr(char_u *s, int c)
static fptr_T do_upper(int *d, int c)
{
- *d = vim_toupper(c);
+ *d = mb_toupper(c);
return (fptr_T)NULL;
}
static fptr_T do_Upper(int *d, int c)
{
- *d = vim_toupper(c);
+ *d = mb_toupper(c);
return (fptr_T)do_Upper;
}
static fptr_T do_lower(int *d, int c)
{
- *d = vim_tolower(c);
+ *d = mb_tolower(c);
return (fptr_T)NULL;
}
static fptr_T do_Lower(int *d, int c)
{
- *d = vim_tolower(c);
+ *d = mb_tolower(c);
return (fptr_T)do_Lower;
}
@@ -6433,55 +6455,132 @@ char_u *regtilde(char_u *source, int magic)
static int can_f_submatch = FALSE; /* TRUE when submatch() can be used */
-/* These pointers are used instead of reg_match and reg_mmatch for
- * reg_submatch(). Needed for when the substitution string is an expression
- * that contains a call to substitute() and submatch(). */
-static regmatch_T *submatch_match;
-static regmmatch_T *submatch_mmatch;
-static linenr_T submatch_firstlnum;
-static linenr_T submatch_maxline;
-static int submatch_line_lbr;
+// These pointers are used for reg_submatch(). Needed for when the
+// substitution string is an expression that contains a call to substitute()
+// and submatch().
+typedef struct {
+ regmatch_T *sm_match;
+ regmmatch_T *sm_mmatch;
+ linenr_T sm_firstlnum;
+ linenr_T sm_maxline;
+ int sm_line_lbr;
+} regsubmatch_T;
+
+static regsubmatch_T rsm; // can only be used when can_f_submatch is true
+
+/// Put the submatches in "argv[0]" which is a list passed into call_func() by
+/// vim_regsub_both().
+static int fill_submatch_list(int argc, typval_T *argv, int argcount)
+{
+ listitem_T *li;
+ int i;
+ char_u *s;
-/*
- * vim_regsub() - perform substitutions after a vim_regexec() or
- * vim_regexec_multi() match.
- *
- * If "copy" is TRUE really copy into "dest".
- * If "copy" is FALSE nothing is copied, this is just to find out the length
- * of the result.
- *
- * If "backslash" is TRUE, a backslash will be removed later, need to double
- * them to keep them, and insert a backslash before a CR to avoid it being
- * replaced with a line break later.
- *
- * Note: The matched text must not change between the call of
- * vim_regexec()/vim_regexec_multi() and vim_regsub()! It would make the back
- * references invalid!
- *
- * Returns the size of the replacement, including terminating NUL.
- */
-int vim_regsub(regmatch_T *rmp, char_u *source, char_u *dest, int copy, int magic, int backslash)
+ if (argcount == 0) {
+ // called function doesn't take an argument
+ return 0;
+ }
+
+ // Relies on sl_list to be the first item in staticList10_T.
+ init_static_list((staticList10_T *)(argv->vval.v_list));
+
+ // There are always 10 list items in staticList10_T.
+ li = argv->vval.v_list->lv_first;
+ for (i = 0; i < 10; i++) {
+ s = rsm.sm_match->startp[i];
+ if (s == NULL || rsm.sm_match->endp[i] == NULL) {
+ s = NULL;
+ } else {
+ s = vim_strnsave(s, (int)(rsm.sm_match->endp[i] - s));
+ }
+ li->li_tv.v_type = VAR_STRING;
+ li->li_tv.vval.v_string = s;
+ li = li->li_next;
+ }
+ return 1;
+}
+
+static void clear_submatch_list(staticList10_T *sl)
+{
+ int i;
+
+ for (i = 0; i < 10; i++) {
+ xfree(sl->sl_items[i].li_tv.vval.v_string);
+ }
+}
+
+/// vim_regsub() - perform substitutions after a vim_regexec() or
+/// vim_regexec_multi() match.
+///
+/// If "copy" is TRUE really copy into "dest".
+/// If "copy" is FALSE nothing is copied, this is just to find out the length
+/// of the result.
+///
+/// If "backslash" is TRUE, a backslash will be removed later, need to double
+/// them to keep them, and insert a backslash before a CR to avoid it being
+/// replaced with a line break later.
+///
+/// Note: The matched text must not change between the call of
+/// vim_regexec()/vim_regexec_multi() and vim_regsub()! It would make the back
+/// references invalid!
+///
+/// Returns the size of the replacement, including terminating NUL.
+int vim_regsub(regmatch_T *rmp, char_u *source, typval_T *expr, char_u *dest,
+ int copy, int magic, int backslash)
{
- reg_match = rmp;
- reg_mmatch = NULL;
- reg_maxline = 0;
- reg_buf = curbuf;
- reg_line_lbr = TRUE;
- return vim_regsub_both(source, dest, copy, magic, backslash);
+ regexec_T rex_save;
+ bool rex_in_use_save = rex_in_use;
+
+ if (rex_in_use) {
+ // Being called recursively, save the state.
+ rex_save = rex;
+ }
+ rex_in_use = true;
+
+ rex.reg_match = rmp;
+ rex.reg_mmatch = NULL;
+ rex.reg_maxline = 0;
+ rex.reg_buf = curbuf;
+ rex.reg_line_lbr = true;
+ int result = vim_regsub_both(source, expr, dest, copy, magic, backslash);
+
+ rex_in_use = rex_in_use_save;
+ if (rex_in_use) {
+ rex = rex_save;
+ }
+
+ return result;
}
int vim_regsub_multi(regmmatch_T *rmp, linenr_T lnum, char_u *source, char_u *dest, int copy, int magic, int backslash)
{
- reg_match = NULL;
- reg_mmatch = rmp;
- reg_buf = curbuf; /* always works on the current buffer! */
- reg_firstlnum = lnum;
- reg_maxline = curbuf->b_ml.ml_line_count - lnum;
- reg_line_lbr = FALSE;
- return vim_regsub_both(source, dest, copy, magic, backslash);
+ regexec_T rex_save;
+ bool rex_in_use_save = rex_in_use;
+
+ if (rex_in_use) {
+ // Being called recursively, save the state.
+ rex_save = rex;
+ }
+ rex_in_use = true;
+
+ rex.reg_match = NULL;
+ rex.reg_mmatch = rmp;
+ rex.reg_buf = curbuf; // always works on the current buffer!
+ rex.reg_firstlnum = lnum;
+ rex.reg_maxline = curbuf->b_ml.ml_line_count - lnum;
+ rex.reg_line_lbr = false;
+ int result = vim_regsub_both(source, NULL, dest, copy, magic, backslash);
+
+ rex_in_use = rex_in_use_save;
+ if (rex_in_use) {
+ rex = rex_save;
+ }
+
+ return result;
}
-static int vim_regsub_both(char_u *source, char_u *dest, int copy, int magic, int backslash)
+static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest,
+ int copy, int magic, int backslash)
{
char_u *src;
char_u *dst;
@@ -6495,8 +6594,8 @@ static int vim_regsub_both(char_u *source, char_u *dest, int copy, int magic, in
int len = 0; /* init for GCC */
static char_u *eval_result = NULL;
- /* Be paranoid... */
- if (source == NULL || dest == NULL) {
+ // Be paranoid...
+ if ((source == NULL && expr == NULL) || dest == NULL) {
EMSG(_(e_null));
return 0;
}
@@ -6505,16 +6604,12 @@ static int vim_regsub_both(char_u *source, char_u *dest, int copy, int magic, in
src = source;
dst = dest;
- /*
- * When the substitute part starts with "\=" evaluate it as an expression.
- */
- if (source[0] == '\\' && source[1] == '='
- && !can_f_submatch /* can't do this recursively */
- ) {
- /* To make sure that the length doesn't change between checking the
- * length and copying the string, and to speed up things, the
- * resulting string is saved from the call with "copy" == FALSE to the
- * call with "copy" == TRUE. */
+ // When the substitute part starts with "\=" evaluate it as an expression.
+ if (expr != NULL || (source[0] == '\\' && source[1] == '=')) {
+ // To make sure that the length doesn't change between checking the
+ // length and copying the string, and to speed up things, the
+ // resulting string is saved from the call with "copy" == FALSE to the
+ // call with "copy" == TRUE.
if (copy) {
if (eval_result != NULL) {
STRCPY(dest, eval_result);
@@ -6523,45 +6618,83 @@ static int vim_regsub_both(char_u *source, char_u *dest, int copy, int magic, in
eval_result = NULL;
}
} else {
- win_T *save_reg_win;
- int save_ireg_ic;
+ int prev_can_f_submatch = can_f_submatch;
+ regsubmatch_T rsm_save;
xfree(eval_result);
- /* The expression may contain substitute(), which calls us
- * recursively. Make sure submatch() gets the text from the first
- * level. Don't need to save "reg_buf", because
- * vim_regexec_multi() can't be called recursively. */
- submatch_match = reg_match;
- submatch_mmatch = reg_mmatch;
- submatch_firstlnum = reg_firstlnum;
- submatch_maxline = reg_maxline;
- submatch_line_lbr = reg_line_lbr;
- save_reg_win = reg_win;
- save_ireg_ic = ireg_ic;
- can_f_submatch = TRUE;
-
- eval_result = eval_to_string(source + 2, NULL, TRUE);
+ // The expression may contain substitute(), which calls us
+ // recursively. Make sure submatch() gets the text from the first
+ // level.
+ if (can_f_submatch) {
+ rsm_save = rsm;
+ }
+ can_f_submatch = true;
+ rsm.sm_match = rex.reg_match;
+ rsm.sm_mmatch = rex.reg_mmatch;
+ rsm.sm_firstlnum = rex.reg_firstlnum;
+ rsm.sm_maxline = rex.reg_maxline;
+ rsm.sm_line_lbr = rex.reg_line_lbr;
+
+ if (expr != NULL) {
+ typval_T argv[2];
+ int dummy;
+ typval_T rettv;
+ staticList10_T matchList;
+
+ rettv.v_type = VAR_STRING;
+ rettv.vval.v_string = NULL;
+ argv[0].v_type = VAR_LIST;
+ argv[0].vval.v_list = &matchList.sl_list;
+ matchList.sl_list.lv_len = 0;
+ if (expr->v_type == VAR_FUNC) {
+ s = expr->vval.v_string;
+ call_func(s, (int)STRLEN(s), &rettv, 1, argv,
+ fill_submatch_list, 0L, 0L, &dummy,
+ true, NULL, NULL);
+ } else if (expr->v_type == VAR_PARTIAL) {
+ partial_T *partial = expr->vval.v_partial;
+
+ s = partial_name(partial);
+ call_func(s, (int)STRLEN(s), &rettv, 1, argv,
+ fill_submatch_list, 0L, 0L, &dummy,
+ true, partial, NULL);
+ }
+ if (matchList.sl_list.lv_len > 0) {
+ // fill_submatch_list() was called.
+ clear_submatch_list(&matchList);
+ }
+ char buf[NUMBUFLEN];
+ eval_result = (char_u *)tv_get_string_buf_chk(&rettv, buf);
+ if (eval_result != NULL) {
+ eval_result = vim_strsave(eval_result);
+ }
+ tv_clear(&rettv);
+ } else {
+ eval_result = eval_to_string(source + 2, NULL, true);
+ }
+
if (eval_result != NULL) {
int had_backslash = FALSE;
for (s = eval_result; *s != NUL; mb_ptr_adv(s)) {
- /* Change NL to CR, so that it becomes a line break,
- * unless called from vim_regexec_nl().
- * Skip over a backslashed character. */
- if (*s == NL && !submatch_line_lbr)
+ // Change NL to CR, so that it becomes a line break,
+ // unless called from vim_regexec_nl().
+ // Skip over a backslashed character.
+ if (*s == NL && !rsm.sm_line_lbr) {
*s = CAR;
- else if (*s == '\\' && s[1] != NUL) {
- ++s;
+ } else if (*s == '\\' && s[1] != NUL) {
+ s++;
/* Change NL to CR here too, so that this works:
* :s/abc\\\ndef/\="aaa\\\nbbb"/ on text:
* abc\
* def
* Not when called from vim_regexec_nl().
*/
- if (*s == NL && !submatch_line_lbr)
+ if (*s == NL && !rsm.sm_line_lbr) {
*s = CAR;
- had_backslash = TRUE;
+ }
+ had_backslash = true;
}
}
if (had_backslash && backslash) {
@@ -6574,14 +6707,10 @@ static int vim_regsub_both(char_u *source, char_u *dest, int copy, int magic, in
dst += STRLEN(eval_result);
}
- reg_match = submatch_match;
- reg_mmatch = submatch_mmatch;
- reg_firstlnum = submatch_firstlnum;
- reg_maxline = submatch_maxline;
- reg_line_lbr = submatch_line_lbr;
- reg_win = save_reg_win;
- ireg_ic = save_ireg_ic;
- can_f_submatch = FALSE;
+ can_f_submatch = prev_can_f_submatch;
+ if (can_f_submatch) {
+ rsm = rsm_save;
+ }
}
} else
while ((c = *src++) != NUL) {
@@ -6679,43 +6808,50 @@ static int vim_regsub_both(char_u *source, char_u *dest, int copy, int magic, in
dst++;
} else {
if (REG_MULTI) {
- clnum = reg_mmatch->startpos[no].lnum;
- if (clnum < 0 || reg_mmatch->endpos[no].lnum < 0)
+ clnum = rex.reg_mmatch->startpos[no].lnum;
+ if (clnum < 0 || rex.reg_mmatch->endpos[no].lnum < 0) {
s = NULL;
- else {
- s = reg_getline(clnum) + reg_mmatch->startpos[no].col;
- if (reg_mmatch->endpos[no].lnum == clnum)
- len = reg_mmatch->endpos[no].col
- - reg_mmatch->startpos[no].col;
- else
+ } else {
+ s = reg_getline(clnum) + rex.reg_mmatch->startpos[no].col;
+ if (rex.reg_mmatch->endpos[no].lnum == clnum) {
+ len = rex.reg_mmatch->endpos[no].col
+ - rex.reg_mmatch->startpos[no].col;
+ } else {
len = (int)STRLEN(s);
+ }
}
} else {
- s = reg_match->startp[no];
- if (reg_match->endp[no] == NULL)
+ s = rex.reg_match->startp[no];
+ if (rex.reg_match->endp[no] == NULL) {
s = NULL;
- else
- len = (int)(reg_match->endp[no] - s);
+ } else {
+ len = (int)(rex.reg_match->endp[no] - s);
+ }
}
if (s != NULL) {
for (;; ) {
if (len == 0) {
if (REG_MULTI) {
- if (reg_mmatch->endpos[no].lnum == clnum)
+ if (rex.reg_mmatch->endpos[no].lnum == clnum) {
break;
- if (copy)
+ }
+ if (copy) {
*dst = CAR;
- ++dst;
+ }
+ dst++;
s = reg_getline(++clnum);
- if (reg_mmatch->endpos[no].lnum == clnum)
- len = reg_mmatch->endpos[no].col;
- else
+ if (rex.reg_mmatch->endpos[no].lnum == clnum) {
+ len = rex.reg_mmatch->endpos[no].col;
+ } else {
len = (int)STRLEN(s);
- } else
+ }
+ } else {
break;
- } else if (*s == NUL) { /* we hit NUL. */
- if (copy)
+ }
+ } else if (*s == NUL) { // we hit NUL.
+ if (copy) {
EMSG(_(e_re_damg));
+ }
goto exit;
} else {
if (backslash && (*s == CAR || *s == '\\')) {
@@ -6789,16 +6925,16 @@ exit:
static char_u *reg_getline_submatch(linenr_T lnum)
{
char_u *s;
- linenr_T save_first = reg_firstlnum;
- linenr_T save_max = reg_maxline;
+ linenr_T save_first = rex.reg_firstlnum;
+ linenr_T save_max = rex.reg_maxline;
- reg_firstlnum = submatch_firstlnum;
- reg_maxline = submatch_maxline;
+ rex.reg_firstlnum = rsm.sm_firstlnum;
+ rex.reg_maxline = rsm.sm_maxline;
s = reg_getline(lnum);
- reg_firstlnum = save_first;
- reg_maxline = save_max;
+ rex.reg_firstlnum = save_first;
+ rex.reg_maxline = save_max;
return s;
}
@@ -6817,39 +6953,41 @@ char_u *reg_submatch(int no)
if (!can_f_submatch || no < 0)
return NULL;
- if (submatch_match == NULL) {
+ if (rsm.sm_match == NULL) {
ssize_t len;
/*
* First round: compute the length and allocate memory.
* Second round: copy the text.
*/
- for (round = 1; round <= 2; ++round) {
- lnum = submatch_mmatch->startpos[no].lnum;
- if (lnum < 0 || submatch_mmatch->endpos[no].lnum < 0)
+ for (round = 1; round <= 2; round++) {
+ lnum = rsm.sm_mmatch->startpos[no].lnum;
+ if (lnum < 0 || rsm.sm_mmatch->endpos[no].lnum < 0) {
return NULL;
+ }
- s = reg_getline_submatch(lnum) + submatch_mmatch->startpos[no].col;
- if (s == NULL) /* anti-crash check, cannot happen? */
+ s = reg_getline_submatch(lnum) + rsm.sm_mmatch->startpos[no].col;
+ if (s == NULL) { // anti-crash check, cannot happen?
break;
- if (submatch_mmatch->endpos[no].lnum == lnum) {
- /* Within one line: take form start to end col. */
- len = submatch_mmatch->endpos[no].col
- - submatch_mmatch->startpos[no].col;
- if (round == 2)
+ }
+ if (rsm.sm_mmatch->endpos[no].lnum == lnum) {
+ // Within one line: take form start to end col.
+ len = rsm.sm_mmatch->endpos[no].col - rsm.sm_mmatch->startpos[no].col;
+ if (round == 2) {
STRLCPY(retval, s, len + 1);
- ++len;
+ }
+ len++;
} else {
- /* Multiple lines: take start line from start col, middle
- * lines completely and end line up to end col. */
- len = STRLEN(s);
+ // Multiple lines: take start line from start col, middle
+ // lines completely and end line up to end col.
+ len = (ssize_t)STRLEN(s);
if (round == 2) {
STRCPY(retval, s);
retval[len] = '\n';
}
- ++len;
- ++lnum;
- while (lnum < submatch_mmatch->endpos[no].lnum) {
+ len++;
+ lnum++;
+ while (lnum < rsm.sm_mmatch->endpos[no].lnum) {
s = reg_getline_submatch(lnum++);
if (round == 2)
STRCPY(retval + len, s);
@@ -6858,13 +6996,15 @@ char_u *reg_submatch(int no)
retval[len] = '\n';
++len;
}
- if (round == 2)
+ if (round == 2) {
STRNCPY(retval + len, reg_getline_submatch(lnum),
- submatch_mmatch->endpos[no].col);
- len += submatch_mmatch->endpos[no].col;
- if (round == 2)
- retval[len] = NUL;
- ++len;
+ rsm.sm_mmatch->endpos[no].col);
+ }
+ len += rsm.sm_mmatch->endpos[no].col;
+ if (round == 2) {
+ retval[len] = NUL; // -V595
+ }
+ len++;
}
if (retval == NULL) {
@@ -6872,11 +7012,12 @@ char_u *reg_submatch(int no)
}
}
} else {
- s = submatch_match->startp[no];
- if (s == NULL || submatch_match->endp[no] == NULL)
+ s = rsm.sm_match->startp[no];
+ if (s == NULL || rsm.sm_match->endp[no] == NULL) {
retval = NULL;
- else
- retval = vim_strnsave(s, (int)(submatch_match->endp[no] - s));
+ } else {
+ retval = vim_strnsave(s, (int)(rsm.sm_match->endp[no] - s));
+ }
}
return retval;
@@ -6896,39 +7037,39 @@ list_T *reg_submatch_list(int no)
linenr_T slnum;
linenr_T elnum;
list_T *list;
- char_u *s;
+ const char *s;
- if (submatch_match == NULL) {
- slnum = submatch_mmatch->startpos[no].lnum;
- elnum = submatch_mmatch->endpos[no].lnum;
+ if (rsm.sm_match == NULL) {
+ slnum = rsm.sm_mmatch->startpos[no].lnum;
+ elnum = rsm.sm_mmatch->endpos[no].lnum;
if (slnum < 0 || elnum < 0) {
return NULL;
}
- colnr_T scol = submatch_mmatch->startpos[no].col;
- colnr_T ecol = submatch_mmatch->endpos[no].col;
+ colnr_T scol = rsm.sm_mmatch->startpos[no].col;
+ colnr_T ecol = rsm.sm_mmatch->endpos[no].col;
- list = list_alloc();
+ list = tv_list_alloc();
- s = reg_getline_submatch(slnum) + scol;
+ s = (const char *)reg_getline_submatch(slnum) + scol;
if (slnum == elnum) {
- list_append_string(list, s, ecol - scol);
+ tv_list_append_string(list, s, ecol - scol);
} else {
- list_append_string(list, s, -1);
+ tv_list_append_string(list, s, -1);
for (int i = 1; i < elnum - slnum; i++) {
- s = reg_getline_submatch(slnum + i);
- list_append_string(list, s, -1);
+ s = (const char *)reg_getline_submatch(slnum + i);
+ tv_list_append_string(list, s, -1);
}
- s = reg_getline_submatch(elnum);
- list_append_string(list, s, ecol);
+ s = (const char *)reg_getline_submatch(elnum);
+ tv_list_append_string(list, s, ecol);
}
} else {
- s = submatch_match->startp[no];
- if (s == NULL || submatch_match->endp[no] == NULL) {
+ s = (const char *)rsm.sm_match->startp[no];
+ if (s == NULL || rsm.sm_match->endp[no] == NULL) {
return NULL;
}
- list = list_alloc();
- list_append_string(list, s, (int)(submatch_match->endp[no] - s));
+ list = tv_list_alloc();
+ tv_list_append_string(list, s, (const char *)rsm.sm_match->endp[no] - s);
}
return list;
@@ -7082,6 +7223,19 @@ static void report_re_switch(char_u *pat)
/// @return TRUE if there is a match, FALSE if not.
static int vim_regexec_both(regmatch_T *rmp, char_u *line, colnr_T col, bool nl)
{
+ regexec_T rex_save;
+ bool rex_in_use_save = rex_in_use;
+
+ if (rex_in_use) {
+ // Being called recursively, save the state.
+ rex_save = rex;
+ }
+ rex_in_use = true;
+ rex.reg_startp = NULL;
+ rex.reg_endp = NULL;
+ rex.reg_startpos = NULL;
+ rex.reg_endpos = NULL;
+
int result = rmp->regprog->engine->regexec_nl(rmp, line, col, nl);
// NFA engine aborted because it's very slow, use backtracking engine instead.
@@ -7103,6 +7257,11 @@ static int vim_regexec_both(regmatch_T *rmp, char_u *line, colnr_T col, bool nl)
p_re = save_p_re;
}
+ rex_in_use = rex_in_use_save;
+ if (rex_in_use) {
+ rex = rex_save;
+ }
+
return result > 0;
}
@@ -7150,6 +7309,15 @@ long vim_regexec_multi(
proftime_T *tm /* timeout limit or NULL */
)
{
+ regexec_T rex_save;
+ bool rex_in_use_save = rex_in_use;
+
+ if (rex_in_use) {
+ // Being called recursively, save the state.
+ rex_save = rex;
+ }
+ rex_in_use = true;
+
int result = rmp->regprog->engine->regexec_multi(rmp, win, buf, lnum, col,
tm);
@@ -7173,5 +7341,10 @@ long vim_regexec_multi(
p_re = save_p_re;
}
+ rex_in_use = rex_in_use_save;
+ if (rex_in_use) {
+ rex = rex_save;
+ }
+
return result <= 0 ? 0 : result;
}
diff --git a/src/nvim/regexp.h b/src/nvim/regexp.h
index 37513d8c27..97595c4d29 100644
--- a/src/nvim/regexp.h
+++ b/src/nvim/regexp.h
@@ -1,6 +1,10 @@
#ifndef NVIM_REGEXP_H
#define NVIM_REGEXP_H
+#include "nvim/types.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/regexp_defs.h"
+
/* Second argument for vim_regcomp(). */
#define RE_MAGIC 1 /* 'magic' option */
#define RE_STRING 2 /* match in string instead of buffer text */
diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c
index 474f3df32a..93ba9ce097 100644
--- a/src/nvim/regexp_nfa.c
+++ b/src/nvim/regexp_nfa.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* NFA regular expression implementation.
*
@@ -53,13 +56,13 @@ enum {
NFA_RANGE_MIN, /* low end of a range */
NFA_RANGE_MAX, /* high end of a range */
- NFA_CONCAT, /* concatenate two previous items (postfix
- * only) */
- NFA_OR, /* \| (postfix only) */
- NFA_STAR, /* greedy * (posfix only) */
- NFA_STAR_NONGREEDY, /* non-greedy * (postfix only) */
- NFA_QUEST, /* greedy \? (postfix only) */
- NFA_QUEST_NONGREEDY, /* non-greedy \? (postfix only) */
+ NFA_CONCAT, // concatenate two previous items (postfix
+ // only)
+ NFA_OR, // \| (postfix only)
+ NFA_STAR, // greedy * (postfix only)
+ NFA_STAR_NONGREEDY, // non-greedy * (postfix only)
+ NFA_QUEST, // greedy \? (postfix only)
+ NFA_QUEST_NONGREEDY, // non-greedy \? (postfix only)
NFA_BOL, /* ^ Begin line */
NFA_EOL, /* $ End line */
@@ -631,6 +634,7 @@ static int nfa_recognize_char_class(char_u *start, char_u *end, int extra_newl)
config |= CLASS_o7;
break;
}
+ return FAIL;
case 'a':
if (*(p + 2) == 'z') {
config |= CLASS_az;
@@ -639,6 +643,7 @@ static int nfa_recognize_char_class(char_u *start, char_u *end, int extra_newl)
config |= CLASS_af;
break;
}
+ return FAIL;
case 'A':
if (*(p + 2) == 'Z') {
config |= CLASS_AZ;
@@ -647,7 +652,7 @@ static int nfa_recognize_char_class(char_u *start, char_u *end, int extra_newl)
config |= CLASS_AF;
break;
}
- /* FALLTHROUGH */
+ return FAIL;
default:
return FAIL;
}
@@ -1983,7 +1988,7 @@ static int nfa_regpiece(void)
// The engine is very inefficient (uses too many states) when the maximum
// is much larger than the minimum and when the maximum is large. Bail out
// if we can use the other engine.
- if ((nfa_re_flags & RE_AUTO) && (maxval > minval + 200 || maxval > 500)) {
+ if ((nfa_re_flags & RE_AUTO) && (maxval > 500 || maxval > minval + 200)) {
return FAIL;
}
@@ -2772,15 +2777,10 @@ static int nfa_max_width(nfa_state_T *startstate, int depth)
case NFA_ANY:
case NFA_START_COLL:
case NFA_START_NEG_COLL:
- /* matches some character, including composing chars */
- if (enc_utf8)
- len += MB_MAXBYTES;
- else if (has_mbyte)
- len += 2;
- else
- ++len;
+ // Matches some character, including composing chars.
+ len += MB_MAXBYTES;
if (state->c != NFA_ANY) {
- /* skip over the characters */
+ // Skip over the characters.
state = state->out1->out;
continue;
}
@@ -3893,23 +3893,27 @@ state_in_list (
return FALSE;
}
-/*
- * Add "state" and possibly what follows to state list ".".
- * Returns "subs_arg", possibly copied into temp_subs.
- */
+// Offset used for "off" by addstate_here().
+#define ADDSTATE_HERE_OFFSET 10
+// Add "state" and possibly what follows to state list ".".
+// Returns "subs_arg", possibly copied into temp_subs.
static regsubs_T *
addstate (
nfa_list_T *l, /* runtime state list */
nfa_state_T *state, /* state to update */
regsubs_T *subs_arg, /* pointers to subexpressions */
nfa_pim_T *pim, /* postponed look-behind match */
- int off /* byte offset, when -1 go to next line */
-)
+ int off_arg) /* byte offset, when -1 go to next line */
{
int subidx;
+ int off = off_arg;
+ int add_here = FALSE;
+ int listindex = 0;
+ int k;
+ int found = FALSE;
nfa_thread_T *thread;
- lpos_T save_lpos;
+ struct multipos save_multipos;
int save_in_use;
char_u *save_ptr;
int i;
@@ -3920,6 +3924,12 @@ addstate (
int did_print = FALSE;
#endif
+ if (off_arg <= -ADDSTATE_HERE_OFFSET) {
+ add_here = true;
+ off = 0;
+ listindex = -(off_arg + ADDSTATE_HERE_OFFSET);
+ }
+
switch (state->c) {
case NFA_NCLOSE:
case NFA_MCLOSE:
@@ -3996,13 +4006,28 @@ addstate (
* lower position is preferred. */
if (!nfa_has_backref && pim == NULL && !l->has_pim
&& state->c != NFA_MATCH) {
+
+ /* When called from addstate_here() do insert before
+ * existing states. */
+ if (add_here) {
+ for (k = 0; k < l->n && k < listindex; ++k) {
+ if (l->t[k].state->id == state->id) {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (!add_here || found) {
skip_add:
#ifdef REGEXP_DEBUG
- nfa_set_code(state->c);
- fprintf(log_fd, "> Not adding state %d to list %d. char %d: %s\n",
- abs(state->id), l->id, state->c, code);
+ nfa_set_code(state->c);
+ fprintf(log_fd, "> Not adding state %d to list %d. char %d: %s pim: %s has_pim: %d found: %d\n",
+ abs(state->id), l->id, state->c, code,
+ pim == NULL ? "NULL" : "yes", l->has_pim, found);
#endif
return subs;
+ }
}
/* Do not add the state again when it exists with the same
@@ -4058,14 +4083,14 @@ skip_add:
case NFA_SPLIT:
/* order matters here */
- subs = addstate(l, state->out, subs, pim, off);
- subs = addstate(l, state->out1, subs, pim, off);
+ subs = addstate(l, state->out, subs, pim, off_arg);
+ subs = addstate(l, state->out1, subs, pim, off_arg);
break;
case NFA_EMPTY:
case NFA_NOPEN:
case NFA_NCLOSE:
- subs = addstate(l, state->out, subs, pim, off);
+ subs = addstate(l, state->out, subs, pim, off_arg);
break;
case NFA_MOPEN:
@@ -4102,15 +4127,13 @@ skip_add:
/* avoid compiler warnings */
save_ptr = NULL;
- save_lpos.lnum = 0;
- save_lpos.col = 0;
+ memset(&save_multipos, 0, sizeof(save_multipos));
/* Set the position (with "off" added) in the subexpression. Save
* and restore it when it was in use. Otherwise fill any gap. */
if (REG_MULTI) {
if (subidx < sub->in_use) {
- save_lpos.lnum = sub->list.multi[subidx].start_lnum;
- save_lpos.col = sub->list.multi[subidx].start_col;
+ save_multipos = sub->list.multi[subidx];
save_in_use = -1;
} else {
save_in_use = sub->in_use;
@@ -4145,7 +4168,7 @@ skip_add:
sub->list.line[subidx].start = reginput + off;
}
- subs = addstate(l, state->out, subs, pim, off);
+ subs = addstate(l, state->out, subs, pim, off_arg);
/* "subs" may have changed, need to set "sub" again */
if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9)
sub = &subs->synt;
@@ -4153,9 +4176,8 @@ skip_add:
sub = &subs->norm;
if (save_in_use == -1) {
- if (REG_MULTI){
- sub->list.multi[subidx].start_lnum = save_lpos.lnum;
- sub->list.multi[subidx].start_col = save_lpos.col;
+ if (REG_MULTI) {
+ sub->list.multi[subidx] = save_multipos;
}
else
sub->list.line[subidx].start = save_ptr;
@@ -4168,9 +4190,10 @@ skip_add:
? subs->norm.list.multi[0].end_lnum >= 0
: subs->norm.list.line[0].end != NULL)) {
/* Do not overwrite the position set by \ze. */
- subs = addstate(l, state->out, subs, pim, off);
+ subs = addstate(l, state->out, subs, pim, off_arg);
break;
}
+ // fallthrough
case NFA_MCLOSE1:
case NFA_MCLOSE2:
case NFA_MCLOSE3:
@@ -4208,8 +4231,7 @@ skip_add:
if (sub->in_use <= subidx)
sub->in_use = subidx + 1;
if (REG_MULTI) {
- save_lpos.lnum = sub->list.multi[subidx].end_lnum;
- save_lpos.col = sub->list.multi[subidx].end_col;
+ save_multipos = sub->list.multi[subidx];
if (off == -1) {
sub->list.multi[subidx].end_lnum = reglnum + 1;
sub->list.multi[subidx].end_col = 0;
@@ -4223,21 +4245,19 @@ skip_add:
} else {
save_ptr = sub->list.line[subidx].end;
sub->list.line[subidx].end = reginput + off;
- /* avoid compiler warnings */
- save_lpos.lnum = 0;
- save_lpos.col = 0;
+ // avoid compiler warnings
+ memset(&save_multipos, 0, sizeof(save_multipos));
}
- subs = addstate(l, state->out, subs, pim, off);
+ subs = addstate(l, state->out, subs, pim, off_arg);
/* "subs" may have changed, need to set "sub" again */
if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9)
sub = &subs->synt;
else
sub = &subs->norm;
- if (REG_MULTI){
- sub->list.multi[subidx].end_lnum = save_lpos.lnum;
- sub->list.multi[subidx].end_col = save_lpos.col;
+ if (REG_MULTI) {
+ sub->list.multi[subidx] = save_multipos;
}
else
sub->list.line[subidx].end = save_ptr;
@@ -4266,8 +4286,10 @@ addstate_here (
int count;
int listidx = *ip;
- /* first add the state(s) at the end, so that we know how many there are */
- addstate(l, state, subs, pim, 0);
+ /* First add the state(s) at the end, so that we know how many there are.
+ * Pass the listidx as offset (avoids adding another argument to
+ * addstate(). */
+ addstate(l, state, subs, pim, -listidx - ADDSTATE_HERE_OFFSET);
/* when "*ip" was at the end of the list, nothing to do */
if (listidx + 1 == tlen)
@@ -4346,7 +4368,7 @@ static int check_char_class(int class, int c)
return OK;
break;
case NFA_CLASS_LOWER:
- if (vim_islower(c) && c != 170 && c != 186) {
+ if (mb_islower(c) && c != 170 && c != 186) {
return OK;
}
break;
@@ -4364,8 +4386,9 @@ static int check_char_class(int class, int c)
return OK;
break;
case NFA_CLASS_UPPER:
- if (vim_isupper(c))
+ if (mb_isupper(c)) {
return OK;
+ }
break;
case NFA_CLASS_XDIGIT:
if (ascii_isxdigit(c))
@@ -4384,8 +4407,9 @@ static int check_char_class(int class, int c)
return OK;
break;
case NFA_CLASS_ESCAPE:
- if (c == '\033')
+ if (c == ESC) {
return OK;
+ }
break;
default:
@@ -4828,17 +4852,10 @@ static int failure_chance(nfa_state_T *state, int depth)
*/
static int skip_to_start(int c, colnr_T *colp)
{
- char_u *s;
-
- /* Used often, do some work to avoid call overhead. */
- if (!ireg_ic
- && !has_mbyte
- )
- s = vim_strbyte(regline + *colp, c);
- else
- s = cstrchr(regline + *colp, c);
- if (s == NULL)
+ const char_u *const s = cstrchr(regline + *colp, c);
+ if (s == NULL) {
return FAIL;
+ }
*colp = (int)(s - regline);
return OK;
}
@@ -4865,7 +4882,7 @@ static long find_match_text(colnr_T startcol, int regstart, char_u *match_text)
int c2_len = PTR2LEN(s2);
int c2 = PTR2CHAR(s2);
- if ((c1 != c2 && (!ireg_ic || vim_tolower(c1) != vim_tolower(c2)))
+ if ((c1 != c2 && (!rex.reg_ic || mb_tolower(c1) != mb_tolower(c2)))
|| c1_len != c2_len) {
match = false;
break;
@@ -4878,13 +4895,13 @@ static long find_match_text(colnr_T startcol, int regstart, char_u *match_text)
&& !(enc_utf8 && utf_iscomposing(PTR2CHAR(s2)))) {
cleanup_subexpr();
if (REG_MULTI) {
- reg_startpos[0].lnum = reglnum;
- reg_startpos[0].col = col;
- reg_endpos[0].lnum = reglnum;
- reg_endpos[0].col = s2 - regline;
+ rex.reg_startpos[0].lnum = reglnum;
+ rex.reg_startpos[0].col = col;
+ rex.reg_endpos[0].lnum = reglnum;
+ rex.reg_endpos[0].col = s2 - regline;
} else {
- reg_startp[0] = regline + col;
- reg_endp[0] = s2;
+ rex.reg_startp[0] = regline + col;
+ rex.reg_endp[0] = s2;
}
return 1L;
}
@@ -5099,8 +5116,8 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
case NFA_MATCH:
{
// If the match ends before a composing characters and
- // ireg_icombine is not set, that is not really a match.
- if (enc_utf8 && !ireg_icombine && utf_iscomposing(curc)) {
+ // rex.reg_icombine is not set, that is not really a match.
+ if (enc_utf8 && !rex.reg_icombine && utf_iscomposing(curc)) {
break;
}
nfa_match = true;
@@ -5383,15 +5400,15 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
int this_class;
// Get class of current and previous char (if it exists).
- this_class = mb_get_class_buf(reginput, reg_buf);
+ this_class = mb_get_class_tab(reginput, rex.reg_buf->b_chartab);
if (this_class <= 1) {
result = false;
} else if (reg_prev_class() == this_class) {
result = false;
}
- } else if (!vim_iswordc_buf(curc, reg_buf)
+ } else if (!vim_iswordc_buf(curc, rex.reg_buf)
|| (reginput > regline
- && vim_iswordc_buf(reginput[-1], reg_buf))) {
+ && vim_iswordc_buf(reginput[-1], rex.reg_buf))) {
result = false;
}
if (result) {
@@ -5408,15 +5425,15 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
int this_class, prev_class;
// Get class of current and previous char (if it exists).
- this_class = mb_get_class_buf(reginput, reg_buf);
+ this_class = mb_get_class_tab(reginput, rex.reg_buf->b_chartab);
prev_class = reg_prev_class();
if (this_class == prev_class
|| prev_class == 0 || prev_class == 1) {
result = false;
}
- } else if (!vim_iswordc_buf(reginput[-1], reg_buf)
+ } else if (!vim_iswordc_buf(reginput[-1], rex.reg_buf)
|| (reginput[0] != NUL
- && vim_iswordc_buf(curc, reg_buf))) {
+ && vim_iswordc_buf(curc, rex.reg_buf))) {
result = false;
}
if (result) {
@@ -5427,14 +5444,14 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
case NFA_BOF:
if (reglnum == 0 && reginput == regline
- && (!REG_MULTI || reg_firstlnum == 1)) {
+ && (!REG_MULTI || rex.reg_firstlnum == 1)) {
add_here = true;
add_state = t->state->out;
}
break;
case NFA_EOF:
- if (reglnum == reg_maxline && curc == NUL) {
+ if (reglnum == rex.reg_maxline && curc == NUL) {
add_here = true;
add_state = t->state->out;
}
@@ -5458,7 +5475,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
// (no preceding character).
len += mb_char2len(mc);
}
- if (ireg_icombine && len == 0) {
+ if (rex.reg_icombine && len == 0) {
// If \Z was present, then ignore composing characters.
// When ignoring the base character this always matches.
if (sta->c != curc) {
@@ -5509,14 +5526,14 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
}
case NFA_NEWL:
- if (curc == NUL && !reg_line_lbr && REG_MULTI
- && reglnum <= reg_maxline) {
+ if (curc == NUL && !rex.reg_line_lbr && REG_MULTI
+ && reglnum <= rex.reg_maxline) {
go_to_nextline = true;
// Pass -1 for the offset, which means taking the position
// at the start of the next line.
add_state = t->state->out;
add_off = -1;
- } else if (curc == '\n' && reg_line_lbr) {
+ } else if (curc == '\n' && rex.reg_line_lbr) {
// match \n as if it is an ordinary character
add_state = t->state->out;
add_off = 1;
@@ -5557,23 +5574,25 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
result = result_if_matched;
break;
}
- if (ireg_ic) {
- int curc_low = vim_tolower(curc);
- int done = FALSE;
+ if (rex.reg_ic) {
+ int curc_low = mb_tolower(curc);
+ int done = false;
- for (; c1 <= c2; ++c1)
- if (vim_tolower(c1) == curc_low) {
+ for (; c1 <= c2; c1++) {
+ if (mb_tolower(c1) == curc_low) {
result = result_if_matched;
done = TRUE;
break;
}
- if (done)
+ }
+ if (done) {
break;
+ }
}
} else if (state->c < 0 ? check_char_class(state->c, curc)
: (curc == state->c
- || (ireg_ic && vim_tolower(curc)
- == vim_tolower(state->c)))) {
+ || (rex.reg_ic && mb_tolower(curc)
+ == mb_tolower(state->c)))) {
result = result_if_matched;
break;
}
@@ -5620,13 +5639,13 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
break;
case NFA_KWORD: // \k
- result = vim_iswordp_buf(reginput, reg_buf);
+ result = vim_iswordp_buf(reginput, rex.reg_buf);
ADD_STATE_IF_MATCH(t->state);
break;
case NFA_SKWORD: // \K
result = !ascii_isdigit(curc)
- && vim_iswordp_buf(reginput, reg_buf);
+ && vim_iswordp_buf(reginput, rex.reg_buf);
ADD_STATE_IF_MATCH(t->state);
break;
@@ -5741,24 +5760,24 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
break;
case NFA_LOWER_IC: // [a-z]
- result = ri_lower(curc) || (ireg_ic && ri_upper(curc));
+ result = ri_lower(curc) || (rex.reg_ic && ri_upper(curc));
ADD_STATE_IF_MATCH(t->state);
break;
case NFA_NLOWER_IC: // [^a-z]
result = curc != NUL
- && !(ri_lower(curc) || (ireg_ic && ri_upper(curc)));
+ && !(ri_lower(curc) || (rex.reg_ic && ri_upper(curc)));
ADD_STATE_IF_MATCH(t->state);
break;
case NFA_UPPER_IC: // [A-Z]
- result = ri_upper(curc) || (ireg_ic && ri_lower(curc));
+ result = ri_upper(curc) || (rex.reg_ic && ri_lower(curc));
ADD_STATE_IF_MATCH(t->state);
break;
case NFA_NUPPER_IC: // [^A-Z]
result = curc != NUL
- && !(ri_upper(curc) || (ireg_ic && ri_lower(curc)));
+ && !(ri_upper(curc) || (rex.reg_ic && ri_lower(curc)));
ADD_STATE_IF_MATCH(t->state);
break;
@@ -5832,13 +5851,15 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
case NFA_LNUM_GT:
case NFA_LNUM_LT:
assert(t->state->val >= 0
- && !((reg_firstlnum > 0 && reglnum > LONG_MAX - reg_firstlnum)
- || (reg_firstlnum <0 && reglnum < LONG_MIN + reg_firstlnum))
- && reglnum + reg_firstlnum >= 0);
+ && !((rex.reg_firstlnum > 0
+ && reglnum > LONG_MAX - rex.reg_firstlnum)
+ || (rex.reg_firstlnum < 0
+ && reglnum < LONG_MIN + rex.reg_firstlnum))
+ && reglnum + rex.reg_firstlnum >= 0);
result = (REG_MULTI
&& nfa_re_num_cmp((uintmax_t)t->state->val,
t->state->c - NFA_LNUM,
- (uintmax_t)(reglnum + reg_firstlnum)));
+ (uintmax_t)(reglnum + rex.reg_firstlnum)));
if (result) {
add_here = true;
add_state = t->state->out;
@@ -5874,7 +5895,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
}
result = false;
- win_T *wp = reg_win == NULL ? curwin : reg_win;
+ win_T *wp = rex.reg_win == NULL ? curwin : rex.reg_win;
if (op == 1 && col - 1 > t->state->val && col > 100) {
long ts = wp->w_buffer->b_p_ts;
@@ -5901,18 +5922,18 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
case NFA_MARK_GT:
case NFA_MARK_LT:
{
- pos_T *pos = getmark_buf(reg_buf, t->state->val, FALSE);
+ pos_T *pos = getmark_buf(rex.reg_buf, t->state->val, false);
// Compare the mark position to the match position.
result = (pos != NULL // mark doesn't exist
&& pos->lnum > 0 // mark isn't set in reg_buf
- && (pos->lnum == reglnum + reg_firstlnum
+ && (pos->lnum == reglnum + rex.reg_firstlnum
? (pos->col == (colnr_T)(reginput - regline)
? t->state->c == NFA_MARK
: (pos->col < (colnr_T)(reginput - regline)
? t->state->c == NFA_MARK_GT
: t->state->c == NFA_MARK_LT))
- : (pos->lnum < reglnum + reg_firstlnum
+ : (pos->lnum < reglnum + rex.reg_firstlnum
? t->state->c == NFA_MARK_GT
: t->state->c == NFA_MARK_LT)));
if (result) {
@@ -5923,10 +5944,10 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
}
case NFA_CURSOR:
- result = (reg_win != NULL
- && (reglnum + reg_firstlnum == reg_win->w_cursor.lnum)
+ result = (rex.reg_win != NULL
+ && (reglnum + rex.reg_firstlnum == rex.reg_win->w_cursor.lnum)
&& ((colnr_T)(reginput - regline)
- == reg_win->w_cursor.col));
+ == rex.reg_win->w_cursor.col));
if (result) {
add_here = true;
add_state = t->state->out;
@@ -5976,12 +5997,13 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
#endif
result = (c == curc);
- if (!result && ireg_ic)
- result = vim_tolower(c) == vim_tolower(curc);
+ if (!result && rex.reg_ic) {
+ result = mb_tolower(c) == mb_tolower(curc);
+ }
- // If ireg_icombine is not set only skip over the character
+ // If rex.reg_icombine is not set only skip over the character
// itself. When it is set skip over composing characters.
- if (result && enc_utf8 && !ireg_icombine) {
+ if (result && enc_utf8 && !rex.reg_icombine) {
clen = utf_ptr2len(reginput);
}
@@ -6089,8 +6111,8 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
&& ((toplevel
&& reglnum == 0
&& clen != 0
- && (ireg_maxcol == 0
- || (colnr_T)(reginput - regline) < ireg_maxcol))
+ && (rex.reg_maxcol == 0
+ || (colnr_T)(reginput - regline) < rex.reg_maxcol))
|| (nfa_endp != NULL
&& (REG_MULTI
? (reglnum < nfa_endp->se_u.pos.lnum
@@ -6125,8 +6147,8 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
// Checking if the required start character matches is
// cheaper than adding a state that won't match.
c = PTR2CHAR(reginput + clen);
- if (c != prog->regstart && (!ireg_ic || vim_tolower(c)
- != vim_tolower(prog->regstart))) {
+ if (c != prog->regstart && (!rex.reg_ic || mb_tolower(c)
+ != mb_tolower(prog->regstart))) {
#ifdef REGEXP_DEBUG
fprintf(log_fd,
" Skipping start state, regstart does not match\n");
@@ -6251,34 +6273,37 @@ static long nfa_regtry(nfa_regprog_T *prog, colnr_T col, proftime_T *tm)
cleanup_subexpr();
if (REG_MULTI) {
for (i = 0; i < subs.norm.in_use; i++) {
- reg_startpos[i].lnum = subs.norm.list.multi[i].start_lnum;
- reg_startpos[i].col = subs.norm.list.multi[i].start_col;
+ rex.reg_startpos[i].lnum = subs.norm.list.multi[i].start_lnum;
+ rex.reg_startpos[i].col = subs.norm.list.multi[i].start_col;
- reg_endpos[i].lnum = subs.norm.list.multi[i].end_lnum;
- reg_endpos[i].col = subs.norm.list.multi[i].end_col;
+ rex.reg_endpos[i].lnum = subs.norm.list.multi[i].end_lnum;
+ rex.reg_endpos[i].col = subs.norm.list.multi[i].end_col;
}
- if (reg_startpos[0].lnum < 0) {
- reg_startpos[0].lnum = 0;
- reg_startpos[0].col = col;
+ if (rex.reg_startpos[0].lnum < 0) {
+ rex.reg_startpos[0].lnum = 0;
+ rex.reg_startpos[0].col = col;
+ }
+ if (rex.reg_endpos[0].lnum < 0) {
+ // pattern has a \ze but it didn't match, use current end
+ rex.reg_endpos[0].lnum = reglnum;
+ rex.reg_endpos[0].col = (int)(reginput - regline);
+ } else {
+ // Use line number of "\ze".
+ reglnum = rex.reg_endpos[0].lnum;
}
- if (reg_endpos[0].lnum < 0) {
- /* pattern has a \ze but it didn't match, use current end */
- reg_endpos[0].lnum = reglnum;
- reg_endpos[0].col = (int)(reginput - regline);
- } else
- /* Use line number of "\ze". */
- reglnum = reg_endpos[0].lnum;
} else {
for (i = 0; i < subs.norm.in_use; i++) {
- reg_startp[i] = subs.norm.list.line[i].start;
- reg_endp[i] = subs.norm.list.line[i].end;
+ rex.reg_startp[i] = subs.norm.list.line[i].start;
+ rex.reg_endp[i] = subs.norm.list.line[i].end;
}
- if (reg_startp[0] == NULL)
- reg_startp[0] = regline + col;
- if (reg_endp[0] == NULL)
- reg_endp[0] = reginput;
+ if (rex.reg_startp[0] == NULL) {
+ rex.reg_startp[0] = regline + col;
+ }
+ if (rex.reg_endp[0] == NULL) {
+ rex.reg_endp[0] = reginput;
+ }
}
/* Package any found \z(...\) matches for export. Default is none. */
@@ -6332,14 +6357,14 @@ static long nfa_regexec_both(char_u *line, colnr_T startcol, proftime_T *tm)
colnr_T col = startcol;
if (REG_MULTI) {
- prog = (nfa_regprog_T *)reg_mmatch->regprog;
- line = reg_getline((linenr_T)0); /* relative to the cursor */
- reg_startpos = reg_mmatch->startpos;
- reg_endpos = reg_mmatch->endpos;
+ prog = (nfa_regprog_T *)rex.reg_mmatch->regprog;
+ line = reg_getline((linenr_T)0); // relative to the cursor
+ rex.reg_startpos = rex.reg_mmatch->startpos;
+ rex.reg_endpos = rex.reg_mmatch->endpos;
} else {
- prog = (nfa_regprog_T *)reg_match->regprog;
- reg_startp = reg_match->startp;
- reg_endp = reg_match->endp;
+ prog = (nfa_regprog_T *)rex.reg_match->regprog;
+ rex.reg_startp = rex.reg_match->startp;
+ rex.reg_endp = rex.reg_match->endp;
}
/* Be paranoid... */
@@ -6348,15 +6373,17 @@ static long nfa_regexec_both(char_u *line, colnr_T startcol, proftime_T *tm)
goto theend;
}
- /* If pattern contains "\c" or "\C": overrule value of ireg_ic */
- if (prog->regflags & RF_ICASE)
- ireg_ic = TRUE;
- else if (prog->regflags & RF_NOICASE)
- ireg_ic = FALSE;
+ // If pattern contains "\c" or "\C": overrule value of rex.reg_ic
+ if (prog->regflags & RF_ICASE) {
+ rex.reg_ic = true;
+ } else if (prog->regflags & RF_NOICASE) {
+ rex.reg_ic = false;
+ }
- /* If pattern contains "\Z" overrule value of ireg_icombine */
- if (prog->regflags & RF_ICOMBINE)
- ireg_icombine = TRUE;
+ // If pattern contains "\Z" overrule value of rex.reg_icombine
+ if (prog->regflags & RF_ICOMBINE) {
+ rex.reg_icombine = true;
+ }
regline = line;
reglnum = 0; /* relative to line */
@@ -6385,17 +6412,17 @@ static long nfa_regexec_both(char_u *line, colnr_T startcol, proftime_T *tm)
if (skip_to_start(prog->regstart, &col) == FAIL)
return 0L;
- /* If match_text is set it contains the full text that must match.
- * Nothing else to try. Doesn't handle combining chars well. */
- if (prog->match_text != NULL
- && !ireg_icombine
- )
+ // If match_text is set it contains the full text that must match.
+ // Nothing else to try. Doesn't handle combining chars well.
+ if (prog->match_text != NULL && !rex.reg_icombine) {
return find_match_text(col, prog->regstart, prog->match_text);
+ }
}
- /* If the start column is past the maximum column: no need to try. */
- if (ireg_maxcol > 0 && col >= ireg_maxcol)
+ // If the start column is past the maximum column: no need to try.
+ if (rex.reg_maxcol > 0 && col >= rex.reg_maxcol) {
goto theend;
+ }
nstate = prog->nstate;
for (i = 0; i < nstate; ++i) {
@@ -6547,15 +6574,15 @@ nfa_regexec_nl (
bool line_lbr
)
{
- reg_match = rmp;
- reg_mmatch = NULL;
- reg_maxline = 0;
- reg_line_lbr = line_lbr;
- reg_buf = curbuf;
- reg_win = NULL;
- ireg_ic = rmp->rm_ic;
- ireg_icombine = FALSE;
- ireg_maxcol = 0;
+ rex.reg_match = rmp;
+ rex.reg_mmatch = NULL;
+ rex.reg_maxline = 0;
+ rex.reg_line_lbr = line_lbr;
+ rex.reg_buf = curbuf;
+ rex.reg_win = NULL;
+ rex.reg_ic = rmp->rm_ic;
+ rex.reg_icombine = false;
+ rex.reg_maxcol = 0;
return nfa_regexec_both(line, col, NULL);
}
@@ -6596,16 +6623,16 @@ nfa_regexec_nl (
static long nfa_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf,
linenr_T lnum, colnr_T col, proftime_T *tm)
{
- reg_match = NULL;
- reg_mmatch = rmp;
- reg_buf = buf;
- reg_win = win;
- reg_firstlnum = lnum;
- reg_maxline = reg_buf->b_ml.ml_line_count - lnum;
- reg_line_lbr = FALSE;
- ireg_ic = rmp->rmm_ic;
- ireg_icombine = FALSE;
- ireg_maxcol = rmp->rmm_maxcol;
+ rex.reg_match = NULL;
+ rex.reg_mmatch = rmp;
+ rex.reg_buf = buf;
+ rex.reg_win = win;
+ rex.reg_firstlnum = lnum;
+ rex.reg_maxline = rex.reg_buf->b_ml.ml_line_count - lnum;
+ rex.reg_line_lbr = false;
+ rex.reg_ic = rmp->rmm_ic;
+ rex.reg_icombine = false;
+ rex.reg_maxcol = rmp->rmm_maxcol;
return nfa_regexec_both(NULL, col, tm);
}
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 41acc48f97..95973354bc 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* screen.c: code for displaying on the screen
*
@@ -83,6 +86,7 @@
#include <stdbool.h>
#include <string.h>
+#include "nvim/log.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/arabic.h"
@@ -102,6 +106,7 @@
#include "nvim/indent.h"
#include "nvim/getchar.h"
#include "nvim/main.h"
+#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
@@ -128,6 +133,7 @@
#include "nvim/version.h"
#include "nvim/window.h"
#include "nvim/os/time.h"
+#include "nvim/api/private/helpers.h"
#define MB_FILLER_CHAR '<' /* character used when a double-width character
* doesn't fit. */
@@ -150,7 +156,6 @@ static schar_T *current_ScreenLine;
StlClickDefinition *tab_page_click_defs = NULL;
long tab_page_click_defs_size = 0;
-# define SCREEN_LINE(r, o, e, c, rl) screen_line((r), (o), (e), (c), (rl))
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "screen.c.generated.h"
#endif
@@ -375,15 +380,24 @@ void update_screen(int type)
))
curwin->w_redr_type = type;
- /* Redraw the tab pages line if needed. */
- if (redraw_tabline || type >= NOT_VALID)
+ // Redraw the tab pages line if needed.
+ if (redraw_tabline || type >= NOT_VALID) {
+ update_window_hl(curwin, type >= NOT_VALID);
+ FOR_ALL_TABS(tp) {
+ if (tp != curtab) {
+ update_window_hl(tp->tp_curwin, type >= NOT_VALID);
+ }
+ }
draw_tabline();
+ }
/*
* Correct stored syntax highlighting info for changes in each displayed
* buffer. Each buffer must only be done once.
*/
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ update_window_hl(wp, type >= NOT_VALID);
+
if (wp->w_buffer->b_mod_set) {
win_T *wwp;
@@ -487,9 +501,10 @@ void update_single_line(win_T *wp, linenr_T lnum)
int j;
// Don't do anything if the screen structures are (not yet) valid.
- if (!screen_valid(true)) {
+ if (!screen_valid(true) || updating_screen) {
return;
}
+ updating_screen = true;
if (lnum >= wp->w_topline && lnum < wp->w_botline
&& foldedCount(wp, lnum, &win_foldinfo) == 0) {
@@ -506,7 +521,8 @@ void update_single_line(win_T *wp, linenr_T lnum)
row += wp->w_lines[j].wl_size;
}
}
- need_cursor_line_redraw = FALSE;
+ need_cursor_line_redraw = false;
+ updating_screen = false;
}
@@ -976,7 +992,7 @@ static void win_update(win_T *wp)
* first. */
if (mid_start == 0) {
mid_end = wp->w_height;
- if (lastwin == firstwin) {
+ if (ONE_WINDOW) {
/* Clear the screen when it was not done by win_del_lines() or
* win_ins_lines() above, "screen_cleared" is FALSE or MAYBE
* then. */
@@ -1013,14 +1029,10 @@ static void win_update(win_T *wp)
linenr_T from, to;
if (VIsual_active) {
- if (VIsual_active
- && (VIsual_mode != wp->w_old_visual_mode
- || type == INVERTED_ALL)) {
- /*
- * If the type of Visual selection changed, redraw the whole
- * selection. Also when the ownership of the X selection is
- * gained or lost.
- */
+ if (VIsual_mode != wp->w_old_visual_mode || type == INVERTED_ALL) {
+ // If the type of Visual selection changed, redraw the whole
+ // selection. Also when the ownership of the X selection is
+ // gained or lost.
if (curwin->w_cursor.lnum < VIsual.lnum) {
from = curwin->w_cursor.lnum;
to = VIsual.lnum;
@@ -1485,11 +1497,11 @@ static void win_update(win_T *wp)
// Last line isn't finished: Display "@@@" in the last screen line.
screen_puts_len((char_u *)"@@", 2, scr_row, wp->w_wincol,
- hl_attr(HLF_AT));
+ win_hl_attr(wp, HLF_AT));
screen_fill(scr_row, scr_row + 1,
(int)wp->w_wincol + 2, (int)W_ENDCOL(wp),
- '@', ' ', hl_attr(HLF_AT));
+ '@', ' ', win_hl_attr(wp, HLF_AT));
set_empty_rows(wp, srow);
wp->w_botline = lnum;
} else if (dy_flags & DY_LASTLINE) { // 'display' has "lastline"
@@ -1497,7 +1509,7 @@ static void win_update(win_T *wp)
screen_fill(wp->w_winrow + wp->w_height - 1,
wp->w_winrow + wp->w_height,
W_ENDCOL(wp) - 3, W_ENDCOL(wp),
- '@', '@', hl_attr(HLF_AT));
+ '@', '@', win_hl_attr(wp, HLF_AT));
set_empty_rows(wp, srow);
wp->w_botline = lnum;
} else {
@@ -1581,6 +1593,8 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h
# define FDC_OFF n
int fdc = compute_foldcolumn(wp, 0);
+ int attr = win_hl_attr(wp, hl);
+
if (wp->w_p_rl) {
// No check for cmdline window: should never be right-left.
n = fdc;
@@ -1591,7 +1605,7 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h
n = wp->w_width;
screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
W_ENDCOL(wp) - n, W_ENDCOL(wp),
- ' ', ' ', hl_attr(HLF_FC));
+ ' ', ' ', win_hl_attr(wp, HLF_FC));
}
if (signcolumn_on(wp)) {
@@ -1603,16 +1617,16 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h
}
screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
W_ENDCOL(wp) - nn, W_ENDCOL(wp) - n,
- ' ', ' ', hl_attr(HLF_SC));
+ ' ', ' ', win_hl_attr(wp, HLF_SC));
n = nn;
}
screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
wp->w_wincol, W_ENDCOL(wp) - 1 - FDC_OFF,
- c2, c2, hl_attr(hl));
+ c2, c2, attr);
screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
W_ENDCOL(wp) - 1 - FDC_OFF, W_ENDCOL(wp) - FDC_OFF,
- c1, c2, hl_attr(hl));
+ c1, c2, attr);
} else {
if (cmdwin_type != 0 && wp == curwin) {
/* draw the cmdline character in the leftmost column */
@@ -1621,7 +1635,7 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h
n = wp->w_width;
screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
wp->w_wincol, wp->w_wincol + n,
- cmdwin_type, ' ', hl_attr(HLF_AT));
+ cmdwin_type, ' ', win_hl_attr(wp, HLF_AT));
}
if (fdc > 0) {
int nn = n + fdc;
@@ -1631,7 +1645,7 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h
nn = wp->w_width;
screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
wp->w_wincol + n, wp->w_wincol + nn,
- ' ', ' ', hl_attr(HLF_FC));
+ ' ', ' ', win_hl_attr(wp, HLF_FC));
n = nn;
}
@@ -1644,13 +1658,13 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h
}
screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
wp->w_wincol + n, wp->w_wincol + nn,
- ' ', ' ', hl_attr(HLF_SC));
+ ' ', ' ', win_hl_attr(wp, HLF_SC));
n = nn;
}
screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
wp->w_wincol + FDC_OFF, W_ENDCOL(wp),
- c1, c2, hl_attr(hl));
+ c1, c2, attr);
}
set_empty_rows(wp, row);
}
@@ -1685,7 +1699,7 @@ static int compute_foldcolumn(win_T *wp, int col)
*/
static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T lnum, int row)
{
- char_u buf[51];
+ char_u buf[FOLD_TEXT_LEN];
pos_T *top, *bot;
linenr_T lnume = lnum + fold_count - 1;
int len;
@@ -1712,10 +1726,9 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
*/
if (cmdwin_type != 0 && wp == curwin) {
ScreenLines[off] = cmdwin_type;
- ScreenAttrs[off] = hl_attr(HLF_AT);
- if (enc_utf8)
- ScreenLinesUC[off] = 0;
- ++col;
+ ScreenAttrs[off] = win_hl_attr(wp, HLF_AT);
+ ScreenLinesUC[off] = 0;
+ col++;
}
// 2. Add the 'foldcolumn'
@@ -1727,12 +1740,14 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
int i;
copy_text_attr(off + wp->w_width - fdc - col, buf, fdc,
- hl_attr(HLF_FC));
- /* reverse the fold column */
- for (i = 0; i < fdc; ++i)
+ win_hl_attr(wp, HLF_FC));
+ // reverse the fold column
+ for (i = 0; i < fdc; i++) {
ScreenLines[off + wp->w_width - i - 1 - col] = buf[i];
- } else
- copy_text_attr(off + col, buf, fdc, hl_attr(HLF_FC));
+ }
+ } else {
+ copy_text_attr(off + col, buf, fdc, win_hl_attr(wp, HLF_FC));
+ }
col += fdc;
}
@@ -1745,7 +1760,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
/* Set all attributes of the 'number' or 'relativenumber' column and the
* text */
- RL_MEMSET(col, hl_attr(HLF_FL), wp->w_width - col);
+ RL_MEMSET(col, win_hl_attr(wp, HLF_FL), wp->w_width - col);
// If signs are being displayed, add two spaces.
if (signcolumn_on(wp)) {
@@ -1754,7 +1769,8 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
if (len > 2) {
len = 2;
}
- copy_text_attr(off + col, (char_u *)" ", len, hl_attr(HLF_FL));
+ copy_text_attr(off + col, (char_u *)" ", len,
+ win_hl_attr(wp, HLF_FL));
col += len;
}
}
@@ -1786,13 +1802,14 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
}
}
- sprintf((char *)buf, fmt, w, num);
- if (wp->w_p_rl)
- /* the line number isn't reversed */
+ snprintf((char *)buf, FOLD_TEXT_LEN, fmt, w, num);
+ if (wp->w_p_rl) {
+ // the line number isn't reversed
copy_text_attr(off + wp->w_width - len - col, buf, len,
- hl_attr(HLF_FL));
- else
- copy_text_attr(off + col, buf, len, hl_attr(HLF_FL));
+ win_hl_attr(wp, HLF_FL));
+ } else {
+ copy_text_attr(off + col, buf, len, win_hl_attr(wp, HLF_FL));
+ }
col += len;
}
}
@@ -1907,10 +1924,15 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
if (fill_fold >= 0x80) {
ScreenLinesUC[off + col] = fill_fold;
ScreenLinesC[0][off + col] = 0;
- } else
+ ScreenLines[off + col] = 0x80; // avoid storing zero
+ } else {
ScreenLinesUC[off + col] = 0;
+ ScreenLines[off + col] = fill_fold;
+ }
+ col++;
+ } else {
+ ScreenLines[off + col++] = fill_fold;
}
- ScreenLines[off + col++] = fill_fold;
}
if (text != buf)
@@ -1950,12 +1972,12 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
len = wp->w_old_cursor_lcol;
else
len = wp->w_width - txtcol;
- RL_MEMSET(wp->w_old_cursor_fcol + txtcol, hl_attr(HLF_V),
- len - (int)wp->w_old_cursor_fcol);
+ RL_MEMSET(wp->w_old_cursor_fcol + txtcol, win_hl_attr(wp, HLF_V),
+ len - (int)wp->w_old_cursor_fcol);
}
} else {
- /* Set all attributes of the text */
- RL_MEMSET(txtcol, hl_attr(HLF_V), wp->w_width - txtcol);
+ // Set all attributes of the text
+ RL_MEMSET(txtcol, win_hl_attr(wp, HLF_V), wp->w_width - txtcol);
}
}
}
@@ -1975,7 +1997,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
}
if (txtcol >= 0 && txtcol < wp->w_width) {
ScreenAttrs[off + txtcol] =
- hl_combine_attr(ScreenAttrs[off + txtcol], hl_attr(HLF_MC));
+ hl_combine_attr(ScreenAttrs[off + txtcol], win_hl_attr(wp, HLF_MC));
}
txtcol = old_txtcol;
j = wp->w_p_cc_cols[++i];
@@ -1991,11 +2013,11 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
txtcol -= wp->w_leftcol;
if (txtcol >= 0 && txtcol < wp->w_width)
ScreenAttrs[off + txtcol] = hl_combine_attr(
- ScreenAttrs[off + txtcol], hl_attr(HLF_CUC));
+ ScreenAttrs[off + txtcol], win_hl_attr(wp, HLF_CUC));
}
- SCREEN_LINE(row + wp->w_winrow, wp->w_wincol, wp->w_width,
- wp->w_width, FALSE);
+ screen_line(row + wp->w_winrow, wp->w_wincol, wp->w_width,
+ wp->w_width, false, wp);
/*
* Update w_cline_height and w_cline_folded if the cursor line was
@@ -2095,16 +2117,16 @@ win_line (
bool nochange /* 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) */
+ int col = 0; // 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_sbr = -1; // virtual column after showbreak
- long vcol_prev = -1; /* "vcol" of previous character */
- char_u *line; /* current line */
- char_u *ptr; /* current position in "line" */
- int row; /* row in the window, excl w_winrow */
- int screen_row; /* row on the screen, incl w_winrow */
+ long vcol_prev = -1; // "vcol" of previous character
+ char_u *line; // current line
+ char_u *ptr; // current position in "line"
+ int row; // row in the window, excl w_winrow
+ int screen_row; // row on the screen, incl w_winrow
char_u extra[18]; /* line number and 'fdc' must fit in here */
int n_extra = 0; /* number of extra chars */
@@ -2178,7 +2200,7 @@ win_line (
int change_start = MAXCOL; /* first col of changed area */
int change_end = -1; /* last col of changed area */
colnr_T trailcol = MAXCOL; /* start of trailing spaces */
- int need_showbreak = FALSE;
+ int need_showbreak = false; // overlong line, skip first x chars
int line_attr = 0; /* attribute for the whole line */
matchitem_T *cur; /* points to the match list */
match_T *shl; /* points to search_hl or a match */
@@ -2191,9 +2213,10 @@ win_line (
int prev_c1 = 0; /* first composing char for prev_c */
int did_line_attr = 0;
- bool has_bufhl = false; // this buffer has highlight matches
+ bool search_attr_from_match = false; // if search_attr is from :match
+ bool has_bufhl = false; // this buffer has highlight matches
int bufhl_attr = 0; // attributes desired by bufhl
- bufhl_lineinfo_T bufhl_info; // bufhl data for this line
+ BufhlLineInfo bufhl_info; // bufhl data for this line
/* draw_state: items that are drawn in sequence: */
#define WL_START 0 /* nothing done yet */
@@ -2209,7 +2232,7 @@ win_line (
int syntax_flags = 0;
int syntax_seqnr = 0;
int prev_syntax_id = 0;
- int conceal_attr = hl_attr(HLF_CONCEAL);
+ int conceal_attr = win_hl_attr(wp, HLF_CONCEAL);
int is_concealing = false;
int boguscols = 0; ///< nonexistent columns added to
///< force wrapping
@@ -2357,8 +2380,8 @@ win_line (
/* if inverting in this line set area_highlighting */
if (fromcol >= 0) {
- area_highlighting = TRUE;
- attr = hl_attr(HLF_V);
+ area_highlighting = true;
+ attr = win_hl_attr(wp, HLF_V);
}
}
/*
@@ -2382,8 +2405,8 @@ win_line (
/* 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);
+ area_highlighting = true;
+ attr = win_hl_attr(wp, HLF_I);
}
filler_lines = diff_check(wp, lnum);
@@ -2411,7 +2434,11 @@ win_line (
// Highlight the current line in the quickfix window.
if (bt_quickfix(wp->w_buffer) && qf_current_entry(wp) == lnum) {
- line_attr = hl_attr(HLF_QFL);
+ line_attr = win_hl_attr(wp, HLF_QFL);
+ }
+
+ if (wp->w_hl_attr_normal != 0) {
+ line_attr = hl_combine_attr(wp->w_hl_attr_normal, line_attr);
}
if (line_attr != 0) {
@@ -2445,7 +2472,7 @@ win_line (
} else {
/* Long line, use only the last SPWORDLEN bytes. */
nextlinecol = v - SPWORDLEN;
- memmove(nextline, line + nextlinecol, SPWORDLEN);
+ memmove(nextline, line + nextlinecol, SPWORDLEN); // -V512
nextline_idx = SPWORDLEN + 1;
}
}
@@ -2500,7 +2527,11 @@ win_line (
if (vcol > v) {
vcol -= c;
ptr = prev_ptr;
- n_skip = v - vcol;
+ // If the character fits on the screen, don't need to skip it.
+ // Except for a TAB.
+ if (((*mb_ptr2cells)(ptr) >= c || *ptr == TAB) && col == 0) {
+ n_skip = v - vcol;
+ }
}
/*
@@ -2577,13 +2608,14 @@ win_line (
* Do this for both search_hl and the match list.
*/
cur = wp->w_match_head;
- shl_flag = FALSE;
- while (cur != NULL || shl_flag == FALSE) {
- if (shl_flag == FALSE) {
+ shl_flag = false;
+ while (cur != NULL || !shl_flag) {
+ if (!shl_flag) {
shl = &search_hl;
- shl_flag = TRUE;
- } else
- shl = &cur->hl;
+ shl_flag = true;
+ } else {
+ shl = &cur->hl; // -V595
+ }
shl->startcol = MAXCOL;
shl->endcol = MAXCOL;
shl->attr_cur = 0;
@@ -2623,6 +2655,7 @@ win_line (
if ((long)shl->startcol < v) { // match at leftcol
shl->attr_cur = shl->attr;
search_attr = shl->attr;
+ search_attr_from_match = shl != &search_hl;
}
area_highlighting = true;
}
@@ -2637,9 +2670,9 @@ win_line (
&& !(wp == curwin && VIsual_active)) {
if (line_attr != 0 && !(State & INSERT) && bt_quickfix(wp->w_buffer)
&& qf_current_entry(wp) == lnum) {
- line_attr = hl_combine_attr(hl_attr(HLF_CUL), line_attr);
+ line_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), line_attr);
} else {
- line_attr = hl_attr(HLF_CUL);
+ line_attr = win_hl_attr(wp, HLF_CUL);
}
area_highlighting = true;
}
@@ -2672,7 +2705,7 @@ win_line (
/* Draw the cmdline character. */
n_extra = 1;
c_extra = cmdwin_type;
- char_attr = hl_attr(HLF_AT);
+ char_attr = win_hl_attr(wp, HLF_AT);
}
}
@@ -2681,13 +2714,16 @@ win_line (
draw_state = WL_FOLD;
if (fdc > 0) {
- // Draw the 'foldcolumn'.
- fill_foldcolumn(extra, wp, false, lnum);
+ // Draw the 'foldcolumn'. Allocate a buffer, "extra" may
+ // already be in use.
+ xfree(p_extra_free);
+ p_extra_free = xmalloc(12 + 1);
+ fill_foldcolumn(p_extra_free, wp, false, lnum);
n_extra = fdc;
- p_extra = extra;
- p_extra[n_extra] = NUL;
+ p_extra_free[n_extra] = NUL;
+ p_extra = p_extra_free;
c_extra = NUL;
- char_attr = hl_attr(HLF_FC);
+ char_attr = win_hl_attr(wp, HLF_FC);
}
}
@@ -2700,7 +2736,7 @@ win_line (
int text_sign;
/* Draw two cells with the sign value or blank. */
c_extra = ' ';
- char_attr = hl_attr(HLF_SC);
+ char_attr = win_hl_attr(wp, HLF_SC);
n_extra = 2;
if (row == startrow + filler_lines && filler_todo <= 0) {
@@ -2757,14 +2793,15 @@ win_line (
} else
c_extra = ' ';
n_extra = number_width(wp) + 1;
- char_attr = hl_attr(HLF_N);
- /* When 'cursorline' is set highlight the line number of
- * the current line differently.
- * TODO: Can we use CursorLine instead of CursorLineNr
- * when CursorLineNr isn't set? */
+ char_attr = win_hl_attr(wp, HLF_N);
+ // When 'cursorline' is set highlight the line number of
+ // the current line differently.
+ // TODO(vim): Can we use CursorLine instead of CursorLineNr
+ // when CursorLineNr isn't set?
if ((wp->w_p_cul || wp->w_p_rnu)
- && lnum == wp->w_cursor.lnum)
- char_attr = hl_attr(HLF_CLN);
+ && lnum == wp->w_cursor.lnum) {
+ char_attr = win_hl_attr(wp, HLF_CLN);
+ }
}
}
@@ -2780,13 +2817,15 @@ win_line (
// draw 'breakindent': indent wrapped text accodringly
if (draw_state == WL_BRI - 1 && n_extra == 0) {
draw_state = WL_BRI;
- if (wp->w_p_bri && n_extra == 0 && row != startrow && filler_lines == 0) {
- char_attr = 0; // was: hl_attr(HLF_AT);
+ // if need_showbreak is set, breakindent also applies
+ if (wp->w_p_bri && (row != startrow || need_showbreak)
+ && filler_lines == 0) {
+ char_attr = wp->w_hl_attr_normal;
if (diff_hlf != (hlf_T)0) {
- char_attr = hl_attr(diff_hlf);
+ char_attr = win_hl_attr(wp, diff_hlf);
if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
- char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUL));
+ char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, HLF_CUL));
}
}
p_extra = NULL;
@@ -2811,15 +2850,15 @@ win_line (
n_extra = col + 1;
else
n_extra = wp->w_width - col;
- char_attr = hl_attr(HLF_DED);
+ char_attr = win_hl_attr(wp, HLF_DED);
}
if (*p_sbr != NUL && need_showbreak) {
/* Draw 'showbreak' at the start of each broken line. */
p_extra = p_sbr;
c_extra = NUL;
n_extra = (int)STRLEN(p_sbr);
- char_attr = hl_attr(HLF_AT);
- need_showbreak = FALSE;
+ char_attr = win_hl_attr(wp, HLF_AT);
+ need_showbreak = false;
vcol_sbr = vcol + MB_CHARLEN(p_sbr);
/* Correct end of highlighted area for 'showbreak',
* required when 'linebreak' is also set. */
@@ -2827,7 +2866,7 @@ win_line (
tocol += n_extra;
/* combine 'showbreak' with 'cursorline' */
if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
- char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUL));
+ char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, HLF_CUL));
}
}
}
@@ -2840,8 +2879,9 @@ win_line (
c_extra = saved_c_extra;
p_extra = saved_p_extra;
char_attr = saved_char_attr;
- } else
- char_attr = 0;
+ } else {
+ char_attr = wp->w_hl_attr_normal;
+ }
}
}
@@ -2850,13 +2890,14 @@ win_line (
&& lnum == wp->w_cursor.lnum && vcol >= (long)wp->w_virtcol
&& filler_todo <= 0
) {
- SCREEN_LINE(screen_row, wp->w_wincol, col, -wp->w_width, wp->w_p_rl);
- /* Pretend we have finished updating the window. Except when
- * 'cursorcolumn' is set. */
- if (wp->w_p_cuc)
+ screen_line(screen_row, wp->w_wincol, col, -wp->w_width, wp->w_p_rl, wp);
+ // 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
+ } else {
row = wp->w_height;
+ }
break;
}
@@ -2920,7 +2961,6 @@ win_line (
}
} else if (v == (long)shl->endcol) {
shl->attr_cur = 0;
- prev_syntax_id = 0;
next_search_hl(wp, shl, lnum, (colnr_T)v,
shl == &search_hl ? NULL : cur);
@@ -2961,6 +3001,7 @@ win_line (
/* Use attributes from match with highest priority among
* 'search_hl' and the match list. */
+ search_attr_from_match = false;
search_attr = search_hl.attr_cur;
cur = wp->w_match_head;
shl_flag = FALSE;
@@ -2973,8 +3014,10 @@ win_line (
shl_flag = TRUE;
} else
shl = &cur->hl;
- if (shl->attr_cur != 0)
+ if (shl->attr_cur != 0) {
search_attr = shl->attr_cur;
+ search_attr_from_match = shl != &search_hl;
+ }
if (shl != &search_hl && cur != NULL)
cur = cur->next;
}
@@ -2982,14 +3025,16 @@ win_line (
if (diff_hlf != (hlf_T)0) {
if (diff_hlf == HLF_CHD && ptr - line >= change_start
- && n_extra == 0)
- diff_hlf = HLF_TXD; /* changed text */
+ && n_extra == 0) {
+ diff_hlf = HLF_TXD; // changed text
+ }
if (diff_hlf == HLF_TXD && ptr - line > change_end
- && n_extra == 0)
- diff_hlf = HLF_CHD; /* changed line */
- line_attr = hl_attr(diff_hlf);
+ && n_extra == 0) {
+ diff_hlf = HLF_CHD; // changed line
+ }
+ line_attr = win_hl_attr(wp, diff_hlf);
if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
- line_attr = hl_combine_attr(line_attr, hl_attr(HLF_CUL));
+ line_attr = hl_combine_attr(line_attr, win_hl_attr(wp, HLF_CUL));
}
}
@@ -3005,14 +3050,15 @@ win_line (
// (area_attr may be 0 when "noinvcur" is set).
else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL)
|| vcol < fromcol || vcol_prev < fromcol_prev
- || vcol >= tocol))
+ || vcol >= tocol)) {
char_attr = line_attr;
- else {
- attr_pri = FALSE;
- if (has_syntax)
+ } else {
+ attr_pri = false;
+ if (has_syntax) {
char_attr = syntax_attr;
- else
- char_attr = 0;
+ } else {
+ char_attr = wp->w_hl_attr_normal;
+ }
}
}
@@ -3073,12 +3119,13 @@ win_line (
c = '>';
mb_c = c;
mb_l = 1;
- mb_utf8 = FALSE;
- multi_attr = hl_attr(HLF_AT);
- /* put the pointer back to output the double-width
- * character at the start of the next line. */
- ++n_extra;
- --p_extra;
+ mb_utf8 = false;
+ multi_attr = win_hl_attr(wp, HLF_AT);
+
+ // put the pointer back to output the double-width
+ // character at the start of the next line.
+ n_extra++;
+ p_extra--;
} else {
n_extra -= mb_l - 1;
p_extra += mb_l - 1;
@@ -3135,14 +3182,14 @@ win_line (
p_extra = extra;
c = *p_extra;
- mb_c = mb_ptr2char_adv(&p_extra);
+ mb_c = mb_ptr2char_adv((const char_u **)&p_extra);
mb_utf8 = (c >= 0x80);
n_extra = (int)STRLEN(p_extra);
c_extra = NUL;
if (area_attr == 0 && search_attr == 0) {
n_attr = n_extra + 1;
- extra_attr = hl_attr(HLF_8);
- saved_attr2 = char_attr; /* save current attr */
+ extra_attr = win_hl_attr(wp, HLF_8);
+ saved_attr2 = char_attr; // save current attr
}
} else if (mb_l == 0) /* at the NUL at end-of-line */
mb_l = 1;
@@ -3194,8 +3241,8 @@ win_line (
c = *p_extra++;
if (area_attr == 0 && search_attr == 0) {
n_attr = n_extra + 1;
- extra_attr = hl_attr(HLF_8);
- saved_attr2 = char_attr; /* save current attr */
+ extra_attr = win_hl_attr(wp, HLF_8);
+ saved_attr2 = char_attr; // save current attr
}
mb_c = c;
}
@@ -3212,12 +3259,13 @@ win_line (
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)
+ multi_attr = win_hl_attr(wp, HLF_AT);
+ // Put pointer back so that the character will be
+ // displayed at the start of the next line.
+ ptr--;
+ } else if (*ptr != NUL) {
ptr += mb_l - 1;
+ }
/* If a double-width char doesn't fit at the left side display
* a '<' in the first column. Don't do this for unprintable
@@ -3228,8 +3276,8 @@ win_line (
c = ' ';
if (area_attr == 0 && search_attr == 0) {
n_attr = n_extra + 1;
- extra_attr = hl_attr(HLF_AT);
- saved_attr2 = char_attr; /* save current attr */
+ extra_attr = win_hl_attr(wp, HLF_AT);
+ saved_attr2 = char_attr; // save current attr
}
mb_c = c;
mb_utf8 = FALSE;
@@ -3277,7 +3325,7 @@ win_line (
else
syntax_flags = get_syntax_info(&syntax_seqnr);
} else if (!attr_pri) {
- char_attr = 0;
+ char_attr = wp->w_hl_attr_normal;
}
/* Check spelling (unless at the end of the line).
@@ -3403,7 +3451,7 @@ win_line (
|| (c == ' ' && lcs_space && ptr - line <= trailcol))) {
c = (c == ' ') ? lcs_space : lcs_nbsp;
n_attr = 1;
- extra_attr = hl_attr(HLF_8);
+ extra_attr = win_hl_attr(wp, HLF_0);
saved_attr2 = char_attr; // save current attr
mb_c = c;
if (enc_utf8 && (*mb_char2len)(c) > 1) {
@@ -3418,7 +3466,7 @@ win_line (
if (trailcol != MAXCOL && ptr > line + trailcol && c == ' ') {
c = lcs_trail;
n_attr = 1;
- extra_attr = hl_attr(HLF_8);
+ extra_attr = win_hl_attr(wp, HLF_0);
saved_attr2 = char_attr; // save current attr
mb_c = c;
if (enc_utf8 && (*mb_char2len)(c) > 1) {
@@ -3476,6 +3524,7 @@ win_line (
p = xmalloc(len + 1);
memset(p, ' ', len);
p[len] = NUL;
+ xfree(p_extra_free);
p_extra_free = p;
for (i = 0; i < tab_len; i++) {
mb_char2bytes(lcs_tab2, p);
@@ -3519,8 +3568,8 @@ win_line (
c_extra = lcs_tab2;
}
n_attr = tab_len + 1;
- extra_attr = hl_attr(HLF_8);
- saved_attr2 = char_attr; /* save current attr */
+ extra_attr = win_hl_attr(wp, HLF_0);
+ saved_attr2 = char_attr; // save current attr
mb_c = c;
if (enc_utf8 && (*mb_char2len)(c) > 1) {
mb_utf8 = TRUE;
@@ -3566,7 +3615,7 @@ win_line (
}
lcs_eol_one = -1;
ptr--; // put it back at the NUL
- extra_attr = hl_attr(HLF_AT);
+ extra_attr = win_hl_attr(wp, HLF_AT);
n_attr = 1;
mb_c = c;
if (enc_utf8 && (*mb_char2len)(c) > 1) {
@@ -3591,13 +3640,14 @@ win_line (
memset(p, ' ', n_extra);
STRNCPY(p, p_extra + 1, STRLEN(p_extra) - 1);
p[n_extra] = NUL;
+ xfree(p_extra_free);
p_extra_free = p_extra = p;
} else {
n_extra = byte2cells(c) - 1;
c = *p_extra++;
}
n_attr = n_extra + 1;
- extra_attr = hl_attr(HLF_8);
+ extra_attr = win_hl_attr(wp, HLF_8);
saved_attr2 = char_attr; // save current attr
mb_utf8 = false; // don't draw as UTF-8
} else if (VIsual_active
@@ -3629,9 +3679,10 @@ win_line (
if (diff_hlf == HLF_TXD) {
diff_hlf = HLF_CHD;
if (attr == 0 || char_attr != attr) {
- char_attr = hl_attr(diff_hlf);
+ char_attr = win_hl_attr(wp, diff_hlf);
if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
- char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUL));
+ char_attr = hl_combine_attr(char_attr,
+ win_hl_attr(wp, HLF_CUL));
}
}
}
@@ -3710,7 +3761,7 @@ win_line (
}
// Don't override visual selection highlighting.
- if (n_attr > 0 && draw_state == WL_LINE) {
+ if (n_attr > 0 && draw_state == WL_LINE && !search_attr_from_match) {
char_attr = hl_combine_attr(char_attr, extra_attr);
}
@@ -3733,7 +3784,7 @@ win_line (
c_extra = MB_FILLER_CHAR;
n_extra = 1;
n_attr = 2;
- extra_attr = hl_attr(HLF_AT);
+ extra_attr = win_hl_attr(wp, HLF_AT);
}
mb_c = c;
if (enc_utf8 && (*mb_char2len)(c) > 1) {
@@ -3744,7 +3795,7 @@ win_line (
mb_utf8 = false; // don't draw as UTF-8
}
saved_attr3 = char_attr; // save current attr
- char_attr = hl_attr(HLF_AT); // later copied to char_attr
+ char_attr = win_hl_attr(wp, HLF_AT); // overwriting char_attr
n_attr3 = 1;
}
@@ -3828,6 +3879,10 @@ win_line (
}
}
}
+
+ if (wp->w_hl_attr_normal != 0) {
+ char_attr = hl_combine_attr(wp->w_hl_attr_normal, char_attr);
+ }
ScreenAttrs[off] = char_attr;
if (wp->w_p_rl) {
--col;
@@ -3889,6 +3944,9 @@ win_line (
if (rightmost_vcol < color_cols[i])
rightmost_vcol = color_cols[i];
+ int cuc_attr = win_hl_attr(wp, HLF_CUC);
+ int mc_attr = win_hl_attr(wp, HLF_MC);
+
while (col < wp->w_width) {
ScreenLines[off] = ' ';
if (enc_utf8)
@@ -3898,12 +3956,13 @@ win_line (
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 (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol) {
+ ScreenAttrs[off++] = cuc_attr;
+ } else if (draw_color_col && VCOL_HLC == *color_cols) {
+ ScreenAttrs[off++] = mc_attr;
+ } else {
+ ScreenAttrs[off++] = wp->w_hl_attr_normal;
+ }
if (VCOL_HLC >= rightmost_vcol)
break;
@@ -3912,6 +3971,7 @@ win_line (
}
}
+ // TODO(bfredl): integrate with the common beyond-the-end-loop
if (wp->w_buffer->terminal) {
// terminal buffers may need to highlight beyond the end of the
// logical line
@@ -3924,7 +3984,7 @@ win_line (
col++;
}
}
- SCREEN_LINE(screen_row, wp->w_wincol, col, wp->w_width, wp->w_p_rl);
+ screen_line(screen_row, wp->w_wincol, col, wp->w_width, wp->w_p_rl, wp);
row++;
/*
@@ -3952,7 +4012,7 @@ win_line (
|| (wp->w_p_list && lcs_eol_one > 0)
|| (n_extra && (c_extra != NUL || *p_extra != NUL)))) {
c = lcs_ext;
- char_attr = hl_attr(HLF_AT);
+ char_attr = win_hl_attr(wp, HLF_AT);
mb_c = c;
if (enc_utf8 && (*mb_char2len)(c) > 1) {
mb_utf8 = TRUE;
@@ -3975,10 +4035,10 @@ win_line (
if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol
&& lnum != wp->w_cursor.lnum) {
vcol_save_attr = char_attr;
- char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUC));
+ char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, 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));
+ char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, HLF_MC));
}
}
@@ -4146,8 +4206,8 @@ win_line (
|| (wp->w_p_list && lcs_eol != NUL && p_extra != at_end_str)
|| (n_extra != 0 && (c_extra != NUL || *p_extra != NUL)))
) {
- SCREEN_LINE(screen_row, wp->w_wincol, col - boguscols,
- wp->w_width, wp->w_p_rl);
+ screen_line(screen_row, wp->w_wincol, col - boguscols,
+ wp->w_width, wp->w_p_rl, wp);
boguscols = 0;
++row;
++screen_row;
@@ -4187,7 +4247,6 @@ win_line (
* (regardless of the xn,am settings).
* Only do this if the cursor is on the current line
* (something has been written in it).
- * Don't do this for the GUI.
* Don't do this for double-width characters.
* Don't do this for a window not at the right screen border.
*/
@@ -4255,6 +4314,7 @@ win_line (
cap_col = 0;
}
+ xfree(p_extra_free);
return row;
}
@@ -4315,7 +4375,8 @@ static int char_needs_redraw(int off_from, int off_to, int cols)
* When TRUE and "clear_width" > 0, clear columns 0 to "endcol"
* When FALSE and "clear_width" > 0, clear columns "endcol" to "clear_width"
*/
-static void screen_line(int row, int coloff, int endcol, int clear_width, int rlflag)
+static void screen_line(int row, int coloff, int endcol,
+ int clear_width, int rlflag, win_T *wp)
{
unsigned off_from;
unsigned off_to;
@@ -4477,11 +4538,11 @@ static void screen_line(int row, int coloff, int endcol, int clear_width, int rl
}
if (clear_width > 0) {
- /* For a window that's left of another, draw the separator char. */
- if (col + coloff < Columns) {
+ // For a window that's left of another, draw the separator char.
+ if (col + coloff < Columns && wp->w_vsep_width > 0) {
int c;
- c = fillchar_vsep(&hl);
+ c = fillchar_vsep(wp, &hl);
if (ScreenLines[off_to] != (schar_T)c
|| (enc_utf8 && (int)ScreenLinesUC[off_to]
!= (c >= 0x80 ? c : 0))
@@ -4586,8 +4647,8 @@ static void draw_vsep_win(win_T *wp, int row)
int c;
if (wp->w_vsep_width) {
- /* draw the vertical separator right of this window */
- c = fillchar_vsep(&hl);
+ // draw the vertical separator right of this window
+ c = fillchar_vsep(wp, &hl);
screen_fill(wp->w_winrow + row, wp->w_winrow + wp->w_height,
W_ENDCOL(wp), W_ENDCOL(wp) + 1,
c, ' ', hl);
@@ -4717,7 +4778,7 @@ win_redr_status_matches (
--first_match;
}
- fillchar = fillchar_status(&attr, TRUE);
+ fillchar = fillchar_status(&attr, curwin);
if (first_match == 0) {
*buf = NUL;
@@ -4831,11 +4892,14 @@ void win_redr_status(win_T *wp)
int this_ru_col;
static int busy = FALSE;
- /* It's possible to get here recursively when 'statusline' (indirectly)
- * invokes ":redrawstatus". Simply ignore the call then. */
- if (busy)
+ // May get here recursively when 'statusline' (indirectly)
+ // invokes ":redrawstatus". Simply ignore the call then.
+ if (busy
+ // Also ignore if wildmenu is showing.
+ || (wild_menu_showing != 0 && !ui_is_external(kUIWildmenu))) {
return;
- busy = TRUE;
+ }
+ busy = true;
wp->w_redr_status = FALSE;
if (wp->w_status_height == 0) {
@@ -4849,7 +4913,7 @@ void win_redr_status(win_T *wp)
/* redraw custom status line */
redraw_custom_statusline(wp);
} else {
- fillchar = fillchar_status(&attr, wp == curwin);
+ fillchar = fillchar_status(&attr, wp);
get_trans_bufname(wp->w_buffer);
p = NameBuff;
@@ -4874,37 +4938,34 @@ void win_redr_status(win_T *wp)
}
if (wp->w_buffer->b_p_ro) {
STRCPY(p + len, _("[RO]"));
- len += 4;
+ len += (int)STRLEN(p + len);
}
this_ru_col = ru_col - (Columns - wp->w_width);
- if (this_ru_col < (wp->w_width + 1) / 2)
+ if (this_ru_col < (wp->w_width + 1) / 2) {
this_ru_col = (wp->w_width + 1) / 2;
+ }
if (this_ru_col <= 1) {
- p = (char_u *)"<"; /* No room for file name! */
+ p = (char_u *)"<"; // No room for file name!
len = 1;
- } else if (has_mbyte) {
+ } else {
int clen = 0, i;
- /* Count total number of display cells. */
- clen = (int) mb_string2cells(p);
+ // Count total number of display cells.
+ clen = (int)mb_string2cells(p);
- /* Find first character that will fit.
- * Going from start to end is much faster for DBCS. */
+ // Find first character that will fit.
+ // Going from start to end is much faster for DBCS.
for (i = 0; p[i] != NUL && clen >= this_ru_col - 1;
- i += (*mb_ptr2len)(p + i))
+ 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 = wp->w_winrow + wp->w_height;
@@ -4912,7 +4973,7 @@ void win_redr_status(win_T *wp)
screen_fill(row, row + 1, len + wp->w_wincol,
this_ru_col + wp->w_wincol, fillchar, fillchar, attr);
- if (get_keymap_str(wp, NameBuff, MAXPATHL)
+ if (get_keymap_str(wp, (char_u *)"<%s>", NameBuff, MAXPATHL)
&& this_ru_col - len > (int)(STRLEN(NameBuff) + 1))
screen_puts(NameBuff, row, (int)(this_ru_col - STRLEN(NameBuff)
- 1 + wp->w_wincol), attr);
@@ -4924,10 +4985,11 @@ void win_redr_status(win_T *wp)
* May need to draw the character below the vertical separator.
*/
if (wp->w_vsep_width != 0 && wp->w_status_height != 0 && redrawing()) {
- if (stl_connected(wp))
- fillchar = fillchar_status(&attr, wp == curwin);
- else
- fillchar = fillchar_vsep(&attr);
+ if (stl_connected(wp)) {
+ fillchar = fillchar_status(&attr, wp);
+ } else {
+ fillchar = fillchar_vsep(wp, &attr);
+ }
screen_putchar(fillchar, wp->w_winrow + wp->w_height,
W_ENDCOL(wp), attr);
}
@@ -4993,8 +5055,9 @@ int stl_connected(win_T *wp)
int
get_keymap_str (
win_T *wp,
- char_u *buf, /* buffer for the result */
- int len /* length of buffer */
+ char_u *fmt, // format string containing one %s item
+ char_u *buf, // buffer for the result
+ int len // length of buffer
)
{
char_u *p;
@@ -5021,10 +5084,9 @@ get_keymap_str (
else
p = (char_u *)"lang";
}
- if ((int)(STRLEN(p) + 3) < len)
- sprintf((char *)buf, "<%s>", p);
- else
+ if (vim_snprintf((char *)buf, len, (char *)fmt, p) > len - 1) {
buf[0] = NUL;
+ }
xfree(s);
}
return buf[0] != NUL;
@@ -5077,7 +5139,7 @@ win_redr_custom (
use_sandbox = was_set_insecurely((char_u *)"tabline", 0);
} else {
row = wp->w_winrow + wp->w_height;
- fillchar = fillchar_status(&attr, wp == curwin);
+ fillchar = fillchar_status(&attr, wp);
maxwidth = wp->w_width;
if (draw_ruler) {
@@ -5327,43 +5389,39 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr)
c = *ptr;
/* check if this is the first byte of a multibyte */
if (l_has_mbyte) {
- if (l_enc_utf8 && len > 0)
+ if (len > 0) {
mbyte_blen = utfc_ptr2len_len(ptr, (int)((text + len) - ptr));
- else
- mbyte_blen = (*mb_ptr2len)(ptr);
- if (l_enc_dbcs == DBCS_JPNU && c == 0x8e)
- mbyte_cells = 1;
- else if (l_enc_dbcs != 0)
- mbyte_cells = mbyte_blen;
- else { /* enc_utf8 */
- if (len >= 0)
- u8c = utfc_ptr2char_len(ptr, u8cc,
- (int)((text + len) - ptr));
- else
- u8c = utfc_ptr2char(ptr, u8cc);
- mbyte_cells = utf_char2cells(u8c);
- if (p_arshape && !p_tbidi && arabic_char(u8c)) {
- /* Do Arabic shaping. */
- if (len >= 0 && (int)(ptr - text) + mbyte_blen >= len) {
- /* Past end of string to be displayed. */
- nc = NUL;
- nc1 = NUL;
- } else {
- nc = utfc_ptr2char_len(ptr + mbyte_blen, pcc,
- (int)((text + len) - ptr - mbyte_blen));
- nc1 = pcc[0];
- }
- pc = prev_c;
- prev_c = u8c;
- u8c = arabic_shape(u8c, &c, &u8cc[0], nc, nc1, pc);
- } else
- prev_c = u8c;
- if (col + mbyte_cells > screen_Columns) {
- /* Only 1 cell left, but character requires 2 cells:
- * display a '>' in the last column to avoid wrapping. */
- c = '>';
- mbyte_cells = 1;
+ } else {
+ mbyte_blen = utfc_ptr2len(ptr);
+ }
+ if (len >= 0) {
+ u8c = utfc_ptr2char_len(ptr, u8cc, (int)((text + len) - ptr));
+ } else {
+ u8c = utfc_ptr2char(ptr, u8cc);
+ }
+ mbyte_cells = utf_char2cells(u8c);
+ if (p_arshape && !p_tbidi && arabic_char(u8c)) {
+ // Do Arabic shaping.
+ if (len >= 0 && (int)(ptr - text) + mbyte_blen >= len) {
+ // Past end of string to be displayed.
+ nc = NUL;
+ nc1 = NUL;
+ } else {
+ nc = utfc_ptr2char_len(ptr + mbyte_blen, pcc,
+ (int)((text + len) - ptr - mbyte_blen));
+ nc1 = pcc[0];
}
+ pc = prev_c;
+ prev_c = u8c;
+ u8c = arabic_shape(u8c, &c, &u8cc[0], nc, nc1, pc);
+ } else {
+ prev_c = u8c;
+ }
+ if (col + mbyte_cells > screen_Columns) {
+ // Only 1 cell left, but character requires 2 cells:
+ // display a '>' in the last column to avoid wrapping. */
+ c = '>';
+ mbyte_cells = 1;
}
}
@@ -5371,16 +5429,11 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr)
force_redraw_next = FALSE;
need_redraw = ScreenLines[off] != c
- || (mbyte_cells == 2
- && ScreenLines[off + 1] != (l_enc_dbcs ? ptr[1] : 0))
- || (l_enc_dbcs == DBCS_JPNU
- && c == 0x8e
- && ScreenLines2[off] != ptr[1])
- || (l_enc_utf8
- && (ScreenLinesUC[off] !=
- (u8char_T)(c < 0x80 && u8cc[0] == 0 ? 0 : u8c)
- || (ScreenLinesUC[off] != 0
- && screen_comp_differs(off, u8cc))))
+ || (mbyte_cells == 2 && ScreenLines[off + 1] != 0)
+ || (ScreenLinesUC[off] !=
+ (u8char_T)(c < 0x80 && u8cc[0] == 0 ? 0 : u8c)
+ || (ScreenLinesUC[off] != 0
+ && screen_comp_differs(off, u8cc)))
|| ScreenAttrs[off] != attr
|| exmode_active;
@@ -5471,8 +5524,7 @@ static void start_search_hl(void)
{
if (p_hls && !no_hlsearch) {
last_pat_prog(&search_hl.rm);
- search_hl.attr = hl_attr(HLF_L);
- /* Set the time limit to 'redrawtime'. */
+ // Set the time limit to 'redrawtime'.
search_hl.tm = profile_setlimit(p_rdt);
}
}
@@ -5488,6 +5540,42 @@ static void end_search_hl(void)
}
}
+static void update_window_hl(win_T *wp, bool invalid)
+{
+ if (!wp->w_hl_needs_update && !invalid) {
+ return;
+ }
+ wp->w_hl_needs_update = false;
+
+ // determine window specific background set in 'winhighlight'
+ if (wp != curwin && wp->w_hl_ids[HLF_INACTIVE] > 0) {
+ wp->w_hl_attr_normal = syn_id2attr(wp->w_hl_ids[HLF_INACTIVE]);
+ } else if (wp->w_hl_id_normal > 0) {
+ wp->w_hl_attr_normal = syn_id2attr(wp->w_hl_id_normal);
+ } else {
+ wp->w_hl_attr_normal = 0;
+ }
+ if (wp != curwin) {
+ wp->w_hl_attr_normal = hl_combine_attr(hl_attr(HLF_INACTIVE),
+ wp->w_hl_attr_normal);
+ }
+
+ for (int hlf = 0; hlf < (int)HLF_COUNT; hlf++) {
+ int attr;
+ if (wp->w_hl_ids[hlf] > 0) {
+ attr = syn_id2attr(wp->w_hl_ids[hlf]);
+ } else {
+ attr = hl_attr(hlf);
+ }
+ if (wp->w_hl_attr_normal != 0) {
+ attr = hl_combine_attr(wp->w_hl_attr_normal, attr);
+ }
+ wp->w_hl_attrs[hlf] = attr;
+ }
+}
+
+
+
/*
* Init for calling prepare_search_hl().
*/
@@ -5514,7 +5602,9 @@ static void init_search_hl(win_T *wp)
search_hl.buf = wp->w_buffer;
search_hl.lnum = 0;
search_hl.first_lnum = 0;
- /* time limit is set at the toplevel, for all windows */
+ search_hl.attr = win_hl_attr(wp, HLF_L);
+
+ // time limit is set at the toplevel, for all windows
}
/*
@@ -5534,13 +5624,14 @@ static void prepare_search_hl(win_T *wp, linenr_T lnum)
* Do this both for search_hl and the match list.
*/
cur = wp->w_match_head;
- shl_flag = FALSE;
- while (cur != NULL || shl_flag == FALSE) {
- if (shl_flag == FALSE) {
+ shl_flag = false;
+ while (cur != NULL || shl_flag == false) {
+ if (shl_flag == false) {
shl = &search_hl;
- shl_flag = TRUE;
- } else
- shl = &cur->hl;
+ shl_flag = true;
+ } else {
+ shl = &cur->hl; // -V595
+ }
if (shl->rm.regprog != NULL
&& shl->lnum == 0
&& re_multiline(shl->rm.regprog)) {
@@ -5775,12 +5866,12 @@ static void screen_char(unsigned off, int row, int col)
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) */
+ // Outputting the last character on the screen may scrollup the screen.
+ // Don't to it! Mark the character invalid (update it when scrolled up)
+ // FIXME: The premise here is not actually true (cf. deferred wrap).
if (row == screen_Rows - 1 && col == screen_Columns - 1
- /* account for first command-line character in rightleft mode */
- && !cmdmsg_rl
- ) {
+ // account for first command-line character in rightleft mode
+ && !cmdmsg_rl) {
ScreenAttrs[off] = (sattr_T)-1;
return;
}
@@ -5906,7 +5997,7 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1,
col = off - LineOffset[row];
screen_stop_highlight();
ui_cursor_goto(row, col); // clear rest of this screen line
- ui_eol_clear();
+ ui_call_eol_clear();
col = end_col - col;
while (col--) { /* clear chars in ScreenLines */
ScreenLines[off] = ' ';
@@ -6099,8 +6190,7 @@ retry:
if (new_ScreenLinesC[i] == NULL)
break;
if (new_ScreenLines == NULL
- || (l_enc_utf8 && (new_ScreenLinesUC == NULL || i != p_mco))
- || (l_enc_dbcs == DBCS_JPNU && new_ScreenLines2 == NULL)
+ || (new_ScreenLinesUC == NULL || i != p_mco)
|| new_ScreenAttrs == NULL
|| new_LineOffset == NULL
|| new_LineWraps == NULL
@@ -6185,13 +6275,14 @@ retry:
ScreenLinesC[i] + LineOffset[old_row],
(size_t)len * sizeof(u8char_T));
}
- if (l_enc_dbcs == DBCS_JPNU && ScreenLines2 != NULL)
+ if (ScreenLines2 != NULL) {
memmove(new_ScreenLines2 + new_LineOffset[new_row],
- ScreenLines2 + LineOffset[old_row],
- (size_t)len * sizeof(schar_T));
+ ScreenLines2 + LineOffset[old_row],
+ (size_t)len * sizeof(schar_T));
+ }
memmove(new_ScreenAttrs + new_LineOffset[new_row],
- ScreenAttrs + LineOffset[old_row],
- (size_t)len * sizeof(sattr_T));
+ ScreenAttrs + LineOffset[old_row],
+ (size_t)len * sizeof(sattr_T));
}
}
}
@@ -6295,10 +6386,10 @@ static void screenclear2(void)
LineWraps[i] = FALSE;
}
- ui_clear(); // clear the display
- clear_cmdline = FALSE;
- mode_displayed = FALSE;
- screen_cleared = TRUE; /* can use contents of ScreenLines now */
+ ui_call_clear(); // clear the display
+ clear_cmdline = false;
+ mode_displayed = false;
+ screen_cleared = true; // can use contents of ScreenLines now
win_rest_invalid(firstwin);
redraw_cmdline = TRUE;
@@ -6371,13 +6462,11 @@ void setcursor(void)
}
}
-/*
- * 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.
- */
+/// Insert 'line_count' lines at 'row' in window 'wp'.
+/// If 'invalid' is TRUE the wp->w_lines[].wl_lnum is invalidated.
+/// If 'mayclear' is TRUE the screen will be cleared if it is faster than
+/// scrolling.
+/// Returns FAIL if the lines are not inserted, OK for success.
int win_ins_lines(win_T *wp, int row, int line_count, int invalid, int mayclear)
{
int did_delete;
@@ -6440,13 +6529,11 @@ int win_ins_lines(win_T *wp, int row, int line_count, int invalid, int mayclear)
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.
- */
+/// Delete "line_count" window lines at "row" in window "wp".
+/// If "invalid" is TRUE curwin->w_lines[] is invalidated.
+/// If "mayclear" is TRUE the screen will be cleared if it is faster than
+/// scrolling
+/// Return OK for success, FAIL if the lines are not deleted.
int win_del_lines(win_T *wp, int row, int line_count, int invalid, int mayclear)
{
int retval;
@@ -6597,7 +6684,7 @@ int screen_ins_lines (
}
}
- ui_append_lines(line_count);
+ ui_call_scroll(-line_count);
return OK;
}
@@ -6652,7 +6739,7 @@ int screen_del_lines (
}
}
- ui_delete_lines(line_count);
+ ui_call_scroll(line_count);
return OK;
}
@@ -6717,17 +6804,19 @@ int showmode(void)
if (edit_submode_pre != NULL)
length -= vim_strsize(edit_submode_pre);
if (length - vim_strsize(edit_submode) > 0) {
- if (edit_submode_pre != NULL)
- msg_puts_attr(edit_submode_pre, attr);
- msg_puts_attr(edit_submode, attr);
+ if (edit_submode_pre != NULL) {
+ msg_puts_attr((const char *)edit_submode_pre, attr);
+ }
+ msg_puts_attr((const char *)edit_submode, attr);
}
if (edit_submode_extra != NULL) {
- MSG_PUTS_ATTR(" ", attr); /* add a space in between */
- if ((int)edit_submode_highl < (int)HLF_COUNT)
- sub_attr = hl_attr(edit_submode_highl);
- else
+ MSG_PUTS_ATTR(" ", attr); // Add a space in between.
+ if ((int)edit_submode_highl < (int)HLF_COUNT) {
+ sub_attr = win_hl_attr(curwin, edit_submode_highl);
+ } else {
sub_attr = attr;
- msg_puts_attr(edit_submode_extra, sub_attr);
+ }
+ msg_puts_attr((const char *)edit_submode_extra, sub_attr);
}
}
} else {
@@ -6752,10 +6841,12 @@ int showmode(void)
if (p_fkmap)
MSG_PUTS_ATTR(farsi_text_5, attr);
if (State & LANGMAP) {
- if (curwin->w_p_arab)
+ if (curwin->w_p_arab) {
MSG_PUTS_ATTR(_(" Arabic"), attr);
- else
- MSG_PUTS_ATTR(_(" (lang)"), attr);
+ } else if (get_keymap_str(curwin, (char_u *)" (%s)",
+ NameBuff, MAXPATHL)) {
+ MSG_PUTS_ATTR(NameBuff, attr);
+ }
}
if ((State & INSERT) && p_paste)
MSG_PUTS_ATTR(_(" (paste)"), attr);
@@ -6874,7 +6965,6 @@ static void draw_tabline(void)
int modified;
int c;
int len;
- int attr_sel = hl_attr(HLF_TPS);
int attr_nosel = hl_attr(HLF_TP);
int attr_fill = hl_attr(HLF_TPF);
char_u *p;
@@ -6882,8 +6972,15 @@ static void draw_tabline(void)
int use_sep_chars = (t_colors < 8
);
- redraw_tabline = FALSE;
+ if (ScreenLines == NULL) {
+ return;
+ }
+ redraw_tabline = false;
+ if (ui_is_external(kUITabline)) {
+ ui_ext_tabline_update();
+ return;
+ }
if (tabline_height() < 1)
return;
@@ -6929,16 +7026,6 @@ static void draw_tabline(void)
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;
@@ -6947,10 +7034,29 @@ static void draw_tabline(void)
wp = tp->tp_firstwin;
}
- modified = FALSE;
- for (wincount = 0; wp != NULL; wp = wp->w_next, ++wincount)
- if (bufIsChanged(wp->w_buffer))
- modified = TRUE;
+
+ if (tp->tp_topframe == topframe) {
+ attr = win_hl_attr(cwp, HLF_TPS);
+ }
+ if (use_sep_chars && col > 0) {
+ screen_putchar('|', 0, col++, attr);
+ }
+
+ if (tp->tp_topframe != topframe) {
+ attr = win_hl_attr(cwp, HLF_TP);
+ }
+
+ screen_putchar(' ', 0, col++, attr);
+
+ modified = false;
+
+ for (wincount = 0; wp != NULL; wp = wp->w_next, ++wincount) {
+ if (bufIsChanged(wp->w_buffer)) {
+ modified = true;
+ }
+ }
+
+
if (modified || wincount > 1) {
if (wincount > 1) {
vim_snprintf((char *)NameBuff, MAXPATHL, "%d", wincount);
@@ -6958,7 +7064,7 @@ static void draw_tabline(void)
if (col + len >= Columns - 3)
break;
screen_puts_len(NameBuff, len, 0, col,
- hl_combine_attr(attr, hl_attr(HLF_T)));
+ hl_combine_attr(attr, win_hl_attr(cwp, HLF_T)));
col += len;
}
if (modified)
@@ -7024,6 +7130,22 @@ static void draw_tabline(void)
redraw_tabline = FALSE;
}
+void ui_ext_tabline_update(void)
+{
+ Array tabs = ARRAY_DICT_INIT;
+ FOR_ALL_TABS(tp) {
+ Dictionary tab_info = ARRAY_DICT_INIT;
+ PUT(tab_info, "tab", TABPAGE_OBJ(tp->handle));
+
+ win_T *cwp = (tp == curtab) ? curwin : tp->tp_curwin;
+ get_trans_bufname(cwp->w_buffer);
+ PUT(tab_info, "name", STRING_OBJ(cstr_to_string((char *)NameBuff)));
+
+ ADD(tabs, DICTIONARY_OBJ(tab_info));
+ }
+ ui_call_tabline_update(curtab->handle, tabs);
+}
+
/*
* Get buffer name for "buf" into NameBuff[].
* Takes care of special buffer names and translates special characters.
@@ -7040,25 +7162,28 @@ void get_trans_bufname(buf_T *buf)
/*
* Get the character to use in a status line. Get its attributes in "*attr".
*/
-static int fillchar_status(int *attr, int is_curwin)
+static int fillchar_status(int *attr, win_T *wp)
{
int fill;
+ bool is_curwin = (wp == curwin);
if (is_curwin) {
- *attr = hl_attr(HLF_S);
+ *attr = win_hl_attr(wp, HLF_S);
fill = fill_stl;
} else {
- *attr = hl_attr(HLF_SNC);
+ *attr = win_hl_attr(wp, HLF_SNC);
fill = fill_stlnc;
}
/* Use fill when there is highlighting, and highlighting of current
* window differs, or the fillchars differ, or this is not the
* current window */
- if (*attr != 0 && ((hl_attr(HLF_S) != hl_attr(HLF_SNC)
- || !is_curwin || firstwin == lastwin)
- || (fill_stl != fill_stlnc)))
+ if (*attr != 0 && ((win_hl_attr(wp, HLF_S) != win_hl_attr(wp, HLF_SNC)
+ || !is_curwin || ONE_WINDOW)
+ || (fill_stl != fill_stlnc))) {
return fill;
- if (is_curwin)
+ }
+ if (is_curwin) {
return '^';
+ }
return '=';
}
@@ -7066,13 +7191,14 @@ static int fillchar_status(int *attr, int is_curwin)
* Get the character to use in a separator between vertically split windows.
* Get its attributes in "*attr".
*/
-static int fillchar_vsep(int *attr)
+static int fillchar_vsep(win_T *wp, int *attr)
{
- *attr = hl_attr(HLF_C);
- if (*attr == 0 && fill_vert == ' ')
+ *attr = win_hl_attr(wp, HLF_C);
+ if (*attr == 0 && fill_vert == ' ') {
return '|';
- else
+ } else {
return fill_vert;
+ }
}
/*
@@ -7107,8 +7233,9 @@ void showruler(int always)
}
if ((*p_stl != NUL || *curwin->w_p_stl != NUL) && curwin->w_status_height) {
redraw_custom_statusline(curwin);
- } else
+ } else {
win_redr_ruler(curwin, always);
+ }
if (need_maketitle
|| (p_icon && (stl_syntax & STL_IN_ICON))
@@ -7186,7 +7313,7 @@ static void win_redr_ruler(win_T *wp, int always)
if (wp->w_status_height) {
row = wp->w_winrow + wp->w_height;
- fillchar = fillchar_status(&attr, wp == curwin);
+ fillchar = fillchar_status(&attr, wp);
off = wp->w_wincol;
width = wp->w_width;
} else {
@@ -7313,23 +7440,16 @@ int number_width(win_T *wp)
return n;
}
-/*
- * Set size of the Vim shell.
- * If 'mustset' is TRUE, we must set Rows and Columns, do not get the real
- * window size (this is used for the :win command).
- * If 'mustset' is FALSE, we may try to get the real window size and if
- * it fails use 'width' and 'height'.
- */
+/// Set dimensions of the Nvim application "shell".
void screen_resize(int width, int height)
{
static int busy = FALSE;
- /*
- * Avoid recursiveness, can happen when setting the window size causes
- * another window-changed signal.
- */
- if (busy)
+ // Avoid recursiveness, can happen when setting the window size causes
+ // another window-changed signal.
+ if (updating_screen || busy) {
return;
+ }
if (width < 0 || height < 0) /* just checking... */
return;
@@ -7405,8 +7525,8 @@ void screen_resize(int width, int height)
--busy;
}
-// Check if the new shell size is valid, correct it if it's too small or way
-// too big.
+/// Check if the new Nvim application "shell" dimensions are valid.
+/// Correct it if it's too small or way too big.
void check_shellsize(void)
{
if (Rows < min_rows()) {
diff --git a/src/nvim/screen.h b/src/nvim/screen.h
index 81a8b9ed4c..17515d4253 100644
--- a/src/nvim/screen.h
+++ b/src/nvim/screen.h
@@ -3,6 +3,10 @@
#include <stdbool.h>
+#include "nvim/types.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/pos.h"
+
/*
* flags for update_screen()
* The higher the value, the higher the priority
diff --git a/src/nvim/search.c b/src/nvim/search.c
index 2a087276e7..1bf2317d2a 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* search.c: code for normal mode searching commands
*/
@@ -282,7 +285,7 @@ void restore_search_patterns(void)
static inline void free_spat(struct spat *const spat)
{
xfree(spat->pat);
- dict_unref(spat->additional_data);
+ tv_dict_unref(spat->additional_data);
}
#if defined(EXITFREE)
@@ -308,13 +311,19 @@ void free_search_patterns(void)
*/
int ignorecase(char_u *pat)
{
- int ic = p_ic;
+ return ignorecase_opt(pat, p_ic, p_scs);
+}
- if (ic && !no_smartcase && p_scs
+/// As ignorecase() put pass the "ic" and "scs" flags.
+int ignorecase_opt(char_u *pat, int ic_in, int scs)
+{
+ int ic = ic_in;
+ if (ic && !no_smartcase && scs
&& !(ctrl_x_mode && curbuf->b_p_inf)
- )
+ ) {
ic = !pat_has_uppercase(pat);
- no_smartcase = FALSE;
+ }
+ no_smartcase = false;
return ic;
}
@@ -329,30 +338,34 @@ int pat_has_uppercase(char_u *pat)
while (*p != NUL) {
int l;
- if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) {
- if (enc_utf8 && utf_isupper(utf_ptr2char(p)))
- return TRUE;
+ if ((l = mb_ptr2len(p)) > 1) {
+ if (mb_isupper(utf_ptr2char(p))) {
+ return true;
+ }
p += l;
} else if (*p == '\\') {
- if (p[1] == '_' && p[2] != NUL) /* skip "\_X" */
+ if (p[1] == '_' && p[2] != NUL) { // skip "\_X"
p += 3;
- else if (p[1] == '%' && p[2] != NUL) /* skip "\%X" */
+ } else if (p[1] == '%' && p[2] != NUL) { // skip "\%X"
p += 3;
- else if (p[1] != NUL) /* skip "\X" */
+ } else if (p[1] != NUL) { // skip "\X"
p += 2;
- else
+ } else {
p += 1;
- } else if (vim_isupper(*p))
- return TRUE;
- else
- ++p;
+ }
+ } else if (mb_isupper(*p)) {
+ return true;
+ } else {
+ p++;
+ }
}
return FALSE;
}
-char_u *last_csearch(void)
+const char *last_csearch(void)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- return lastc_bytes;
+ return (const char *)lastc_bytes;
}
int last_csearch_forward(void)
@@ -603,7 +616,7 @@ int searchit(
* otherwise "/$" will get stuck on end of line.
*/
while (matchpos.lnum == 0
- && ((options & SEARCH_END) && first_match
+ && (((options & SEARCH_END) && first_match)
? (nmatched == 1
&& (int)endpos.col - 1
< (int)start_pos.col + extra_col)
@@ -992,14 +1005,13 @@ int do_search(
dircp = NULL;
/* use previous pattern */
if (pat == NULL || *pat == NUL || *pat == dirc) {
- if (spats[RE_SEARCH].pat == NULL) { /* no previous pattern */
- pat = spats[RE_SUBST].pat;
- if (pat == NULL) {
+ if (spats[RE_SEARCH].pat == NULL) { // no previous pattern
+ searchstr = spats[RE_SUBST].pat;
+ if (searchstr == NULL) {
EMSG(_(e_noprevre));
retval = 0;
goto end_do_search;
}
- searchstr = pat;
} else {
/* make search_regcomp() use spats[RE_SEARCH].pat */
searchstr = (char_u *)"";
@@ -1284,10 +1296,11 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, int dir, char_u *pat)
* ignored because we are interested in the next line -- Acevedo */
if ((compl_cont_status & CONT_ADDING)
&& !(compl_cont_status & CONT_SOL)) {
- if ((p_ic ? mb_stricmp(p, pat) : STRCMP(p, pat)) == 0)
+ if (mb_strcmp_ic((bool)p_ic, (const char *)p, (const char *)pat) == 0) {
return OK;
- } else if (*p != NUL) { /* ignore empty lines */
- /* expanding lines or words */
+ }
+ } else if (*p != NUL) { // Ignore empty lines.
+ // Expanding lines or words.
assert(compl_length >= 0);
if ((p_ic ? mb_strnicmp(p, pat, (size_t)compl_length)
: STRNCMP(p, pat, compl_length)) == 0)
@@ -2411,32 +2424,20 @@ static int cls(void)
int c;
c = gchar_cursor();
- if (p_altkeymap && c == F_BLANK)
- return 0;
- if (c == ' ' || c == '\t' || c == NUL)
+ if (p_altkeymap && c == F_BLANK) {
return 0;
- if (enc_dbcs != 0 && c > 0xFF) {
- /* If cls_bigword, report multi-byte chars as class 1. */
- if (enc_dbcs == DBCS_KOR && cls_bigword)
- return 1;
-
- /* process code leading/trailing bytes */
- return dbcs_class(((unsigned)c >> 8), (c & 0xFF));
}
- if (enc_utf8) {
- c = utf_class(c);
- if (c != 0 && cls_bigword)
- return 1;
- return c;
+ if (c == ' ' || c == '\t' || c == NUL) {
+ return 0;
}
- /* If cls_bigword is TRUE, report all non-blanks as class 1. */
- if (cls_bigword)
- return 1;
+ c = utf_class(c);
- if (vim_iswordc(c))
- return 2;
- return 1;
+ // If cls_bigword is TRUE, report all non-blanks as class 1.
+ if (c != 0 && cls_bigword) {
+ return 1;
+ }
+ return c;
}
/*
@@ -3022,7 +3023,8 @@ extend:
++curwin->w_cursor.col;
VIsual = start_pos;
VIsual_mode = 'v';
- redraw_curbuf_later(INVERTED); /* update the inversion */
+ redraw_cmdline = true; // show mode later
+ redraw_curbuf_later(INVERTED); // update the inversion
} else {
/* include a newline after the sentence, if there is one */
if (incl(&curwin->w_cursor) == -1)
@@ -4656,12 +4658,12 @@ static void show_pat_in_path(char_u *line, int type, int did_show, int action, F
*(p + 1) = NUL;
}
if (action == ACTION_SHOW_ALL) {
- sprintf((char *)IObuff, "%3ld: ", count); /* show match nr */
- msg_puts(IObuff);
- sprintf((char *)IObuff, "%4ld", *lnum); /* show line nr */
- /* Highlight line numbers */
- msg_puts_attr(IObuff, hl_attr(HLF_N));
- MSG_PUTS(" ");
+ snprintf((char *)IObuff, IOSIZE, "%3ld: ", count); // Show match nr.
+ msg_puts((const char *)IObuff);
+ snprintf((char *)IObuff, IOSIZE, "%4ld", *lnum); // Show line nr.
+ // Highlight line numbers.
+ msg_puts_attr((const char *)IObuff, hl_attr(HLF_N));
+ msg_puts(" ");
}
msg_prt_line(line, FALSE);
ui_flush(); /* show one line at a time */
diff --git a/src/nvim/search.h b/src/nvim/search.h
index d4e40cb287..cb50742990 100644
--- a/src/nvim/search.h
+++ b/src/nvim/search.h
@@ -4,6 +4,12 @@
#include <stdbool.h>
#include <stdint.h>
+#include "nvim/types.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/eval/typval.h"
+#include "nvim/normal.h"
+#include "nvim/os/time.h"
+
/* Values for the find_pattern_in_path() function args 'type' and 'action': */
#define FIND_ANY 1
#define FIND_DEFINE 2
diff --git a/src/nvim/sha256.c b/src/nvim/sha256.c
index 7670b64468..a2378cc202 100644
--- a/src/nvim/sha256.c
+++ b/src/nvim/sha256.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// @file sha256.c
///
/// FIPS-180-2 compliant SHA-256 implementation
@@ -259,11 +262,11 @@ void sha256_finish(context_sha256_T *ctx, char_u digest[SHA256_SUM_SIZE])
///
/// @returns hex digest of "buf[buf_len]" in a static array.
/// if "salt" is not NULL also do "salt[salt_len]".
-char_u *sha256_bytes(const char_u *restrict buf, size_t buf_len,
- const char_u *restrict salt, size_t salt_len)
+const char *sha256_bytes(const uint8_t *restrict buf, size_t buf_len,
+ const uint8_t *restrict salt, size_t salt_len)
{
char_u sha256sum[SHA256_SUM_SIZE];
- static char_u hexit[SHA256_BUFFER_SIZE + 1]; // buf size + NULL
+ static char hexit[SHA256_BUFFER_SIZE + 1]; // buf size + NULL
context_sha256_T ctx;
sha256_self_test();
@@ -277,7 +280,7 @@ char_u *sha256_bytes(const char_u *restrict buf, size_t buf_len,
sha256_finish(&ctx, sha256sum);
for (size_t j = 0; j < SHA256_SUM_SIZE; j++) {
- snprintf((char *) hexit + j * SHA_STEP, SHA_STEP+1, "%02x", sha256sum[j]);
+ snprintf(hexit + j * SHA_STEP, SHA_STEP + 1, "%02x", sha256sum[j]);
}
hexit[sizeof(hexit) - 1] = '\0';
return hexit;
@@ -308,7 +311,7 @@ bool sha256_self_test(void)
context_sha256_T ctx;
char_u buf[1000];
char_u sha256sum[SHA256_SUM_SIZE];
- char_u *hexit;
+ const char *hexit;
static bool sha256_self_tested = false;
static bool failures = false;
@@ -320,8 +323,8 @@ bool sha256_self_test(void)
for (size_t i = 0; i < 3; i++) {
if (i < 2) {
- hexit = sha256_bytes((char_u *) sha_self_test_msg[i],
- STRLEN(sha_self_test_msg[i]),
+ hexit = sha256_bytes((uint8_t *)sha_self_test_msg[i],
+ strlen(sha_self_test_msg[i]),
NULL, 0);
STRCPY(output, hexit);
} else {
diff --git a/src/nvim/sha256.h b/src/nvim/sha256.h
index a118826542..deb881a288 100644
--- a/src/nvim/sha256.h
+++ b/src/nvim/sha256.h
@@ -2,6 +2,7 @@
#define NVIM_SHA256_H
#include <stdint.h> // for uint32_t
+#include <stddef.h>
#include "nvim/types.h" // for char_u
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index 8cf5976e8b..736d6bf162 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <stdlib.h>
#include <stddef.h>
#include <stdbool.h>
@@ -30,7 +33,7 @@
#include "nvim/ex_getln.h"
#include "nvim/search.h"
#include "nvim/regexp.h"
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
#include "nvim/version.h"
#include "nvim/path.h"
#include "nvim/fileio.h"
@@ -73,17 +76,10 @@ KHASH_SET_INIT_STR(strset)
(vim_rename((char_u *)a, (char_u *)b))
#define mb_strnicmp(a, b, c) \
(mb_strnicmp((char_u *)a, (char_u *)b, c))
-#define has_non_ascii(a) (has_non_ascii((char_u *)a))
-#define string_convert(a, b, c) \
- ((char *)string_convert((vimconv_T *)a, (char_u *)b, c))
#define path_shorten_fname_if_possible(b) \
((char *)path_shorten_fname_if_possible((char_u *)b))
#define buflist_new(ffname, sfname, ...) \
(buflist_new((char_u *)ffname, (char_u *)sfname, __VA_ARGS__))
-#define convert_setup(vcp, from, to) \
- (convert_setup(vcp, (char_u *)from, (char_u *)to))
-#define os_getperm(f) \
- (os_getperm((char_u *) f))
#define os_isdir(f) (os_isdir((char_u *) f))
#define regtilde(s, m) ((char *) regtilde((char_u *) s, m))
#define path_tail_with_sep(f) ((char *) path_tail_with_sep((char_u *)f))
@@ -102,6 +98,7 @@ KHASH_SET_INIT_STR(strset)
#define REG_KEY_TYPE "rt"
#define REG_KEY_WIDTH "rw"
#define REG_KEY_CONTENTS "rc"
+#define REG_KEY_UNNAMED "ru"
#define KEY_LNUM "l"
#define KEY_COL "c"
@@ -288,6 +285,7 @@ typedef struct {
char name;
MotionType type;
char **contents;
+ bool is_unnamed;
size_t contents_size;
size_t width;
dict_T *additional_data;
@@ -415,8 +413,6 @@ typedef struct sd_read_def {
const char *error; ///< Error message in case of error.
uintmax_t fpos; ///< Current position (amount of bytes read since
///< reader structure initialization). May overflow.
- vimconv_T sd_conv; ///< Structure used for converting encodings of some
- ///< items.
} ShaDaReadDef;
struct sd_write_def;
@@ -437,8 +433,6 @@ typedef struct sd_write_def {
ShaDaWriteCloser close; ///< Close function.
void *cookie; ///< Data describing object written to.
const char *error; ///< Error message in case of error.
- vimconv_T sd_conv; ///< Structure used for converting encodings of some
- ///< items.
} ShaDaWriteDef;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -481,6 +475,7 @@ static const ShadaEntry sd_default_values[] = {
.type = kMTCharWise,
.contents = NULL,
.contents_size = 0,
+ .is_unnamed = false,
.width = 0,
.additional_data = NULL),
DEF_SDE(Variable, global_var,
@@ -805,7 +800,7 @@ static int open_shada_file_for_reading(const char *const fname,
return error;
}
- convert_setup(&sd_reader->sd_conv, "utf-8", p_enc);
+ assert(STRCMP(p_enc, "utf-8") == 0);
return 0;
}
@@ -813,7 +808,7 @@ static int open_shada_file_for_reading(const char *const fname,
/// Wrapper for closing file descriptors
static void close_file(void *cookie)
{
- const int error = file_free(cookie);
+ const int error = file_free(cookie, true);
if (error != 0) {
emsgf(_(SERR "System error while closing ShaDa file: %s"),
os_strerror(error));
@@ -1223,7 +1218,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
khash_t(fnamebufs) fname_bufs = KHASH_EMPTY_TABLE(fnamebufs);
khash_t(strset) oldfiles_set = KHASH_EMPTY_TABLE(strset);
if (get_old_files && (oldfiles_list == NULL || force)) {
- oldfiles_list = list_alloc();
+ oldfiles_list = tv_list_alloc();
set_vim_var_list(VV_OLDFILES, oldfiles_list);
}
ShaDaReadResult srni_ret;
@@ -1285,8 +1280,6 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
if (cur_entry.data.search_pattern.is_last_used) {
set_last_used_pattern(
cur_entry.data.search_pattern.is_substitute_pattern);
- }
- if (cur_entry.data.search_pattern.is_last_used) {
SET_NO_HLSEARCH(!cur_entry.data.search_pattern.highlighted);
}
// Do not free shada entry: its allocated memory was saved above.
@@ -1345,7 +1338,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
.y_width = (colnr_T) cur_entry.data.reg.width,
.timestamp = cur_entry.timestamp,
.additional_data = cur_entry.data.reg.additional_data,
- })) {
+ }, cur_entry.data.reg.is_unnamed)) {
shada_free_shada_entry(&cur_entry);
}
// Do not free shada entry: its allocated memory was saved above.
@@ -1435,8 +1428,8 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
fname = xstrdup(fname);
}
int kh_ret;
- (void) kh_put(strset, &oldfiles_set, fname, &kh_ret);
- list_append_allocated_string(oldfiles_list, fname);
+ (void)kh_put(strset, &oldfiles_set, fname, &kh_ret);
+ tv_list_append_allocated_string(oldfiles_list, fname);
if (!want_marks) {
// Avoid free because this string was already used.
cur_entry.data.filemark.fname = NULL;
@@ -1573,7 +1566,9 @@ static char *shada_filename(const char *file)
do { \
const String s_ = (s); \
msgpack_pack_str(spacker, s_.size); \
- msgpack_pack_str_body(spacker, s_.data, s_.size); \
+ if (s_.size) { \
+ msgpack_pack_str_body(spacker, s_.data, s_.size); \
+ } \
} while (0)
#define PACK_BIN(s) \
do { \
@@ -1621,10 +1616,10 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
for (const hashitem_T *hi= d->dv_hashtab.ht_array; todo; hi++) { \
if (!HASHITEM_EMPTY(hi)) { \
todo--; \
- dictitem_T *const di = HI2DI(hi); \
- const size_t key_len = strlen((const char *) hi->hi_key); \
+ dictitem_T *const di = TV_DICT_HI2DI(hi); \
+ const size_t key_len = strlen((const char *)hi->hi_key); \
msgpack_pack_str(spacker, key_len); \
- msgpack_pack_str_body(spacker, (const char *) hi->hi_key, key_len); \
+ msgpack_pack_str_body(spacker, (const char *)hi->hi_key, key_len); \
if (encode_vim_to_msgpack(spacker, &di->di_tv, \
_("additional data of ShaDa " what)) \
== FAIL) { \
@@ -1788,6 +1783,7 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
2 // Register contents and name
+ ONE_IF_NOT_DEFAULT(entry, reg.type)
+ ONE_IF_NOT_DEFAULT(entry, reg.width)
+ + ONE_IF_NOT_DEFAULT(entry, reg.is_unnamed)
// Additional entries, if any:
+ (size_t) (entry.data.reg.additional_data == NULL
? 0
@@ -1808,6 +1804,14 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
PACK_STATIC_STR(REG_KEY_WIDTH);
msgpack_pack_uint64(spacker, (uint64_t) entry.data.reg.width);
}
+ if (!CHECK_DEFAULT(entry, reg.is_unnamed)) {
+ PACK_STATIC_STR(REG_KEY_UNNAMED);
+ if (entry.data.reg.is_unnamed) {
+ msgpack_pack_true(spacker);
+ } else {
+ msgpack_pack_false(spacker);
+ }
+ }
DUMP_ADDITIONAL_DATA(entry.data.reg.additional_data, "register item");
break;
}
@@ -1899,127 +1903,24 @@ shada_pack_entry_error:
}
#undef PACK_STRING
-/// Write single ShaDa entry, converting it if needed
+/// Write single ShaDa entry and free it afterwards
///
-/// @warning Frees entry after packing.
+/// Will not free if entry could not be freed.
///
/// @param[in] packer Packer used to write entry.
-/// @param[in] sd_conv Conversion definitions.
-/// @param[in] entry Entry written. If entry.can_free_entry is false then
-/// it assumes that entry was not converted, otherwise it
-/// is assumed that entry was already converted.
+/// @param[in] entry Entry written.
/// @param[in] max_kbyte Maximum size of an item in KiB. Zero means no
/// restrictions.
-static ShaDaWriteResult shada_pack_encoded_entry(msgpack_packer *const packer,
- const vimconv_T *const sd_conv,
- PossiblyFreedShadaEntry entry,
- const size_t max_kbyte)
- FUNC_ATTR_NONNULL_ALL
+static inline ShaDaWriteResult shada_pack_pfreed_entry(
+ msgpack_packer *const packer, PossiblyFreedShadaEntry entry,
+ const size_t max_kbyte)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
{
ShaDaWriteResult ret = kSDWriteSuccessfull;
+ ret = shada_pack_entry(packer, entry.data, max_kbyte);
if (entry.can_free_entry) {
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
shada_free_shada_entry(&entry.data);
- return ret;
}
-#define RUN_WITH_CONVERTED_STRING(cstr, code) \
- do { \
- bool did_convert = false; \
- if (sd_conv->vc_type != CONV_NONE && has_non_ascii((cstr))) { \
- char *const converted_string = string_convert(sd_conv, (cstr), NULL); \
- if (converted_string != NULL) { \
- (cstr) = converted_string; \
- did_convert = true; \
- } \
- } \
- code \
- if (did_convert) { \
- xfree((cstr)); \
- } \
- } while (0)
- switch (entry.data.type) {
- case kSDItemUnknown:
- case kSDItemMissing: {
- assert(false);
- }
- case kSDItemSearchPattern: {
- RUN_WITH_CONVERTED_STRING(entry.data.data.search_pattern.pat, {
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- });
- break;
- }
- case kSDItemHistoryEntry: {
- RUN_WITH_CONVERTED_STRING(entry.data.data.history_item.string, {
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- });
- break;
- }
- case kSDItemSubString: {
- RUN_WITH_CONVERTED_STRING(entry.data.data.sub_string.sub, {
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- });
- break;
- }
- case kSDItemVariable: {
- if (sd_conv->vc_type != CONV_NONE) {
- typval_T tgttv;
- var_item_copy(sd_conv, &entry.data.data.global_var.value, &tgttv,
- true, 0);
- clear_tv(&entry.data.data.global_var.value);
- entry.data.data.global_var.value = tgttv;
- }
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- break;
- }
- case kSDItemRegister: {
- bool did_convert = false;
- if (sd_conv->vc_type != CONV_NONE) {
- size_t first_non_ascii = 0;
- for (size_t i = 0; i < entry.data.data.reg.contents_size; i++) {
- if (has_non_ascii(entry.data.data.reg.contents[i])) {
- first_non_ascii = i;
- did_convert = true;
- break;
- }
- }
- if (did_convert) {
- entry.data.data.reg.contents =
- xmemdup(entry.data.data.reg.contents,
- (entry.data.data.reg.contents_size
- * sizeof(entry.data.data.reg.contents)));
- for (size_t i = 0; i < entry.data.data.reg.contents_size; i++) {
- if (i >= first_non_ascii) {
- entry.data.data.reg.contents[i] = get_converted_string(
- sd_conv,
- entry.data.data.reg.contents[i],
- strlen(entry.data.data.reg.contents[i]));
- } else {
- entry.data.data.reg.contents[i] =
- xstrdup(entry.data.data.reg.contents[i]);
- }
- }
- }
- }
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- if (did_convert) {
- for (size_t i = 0; i < entry.data.data.reg.contents_size; i++) {
- xfree(entry.data.data.reg.contents[i]);
- }
- xfree(entry.data.data.reg.contents);
- }
- break;
- }
- case kSDItemHeader:
- case kSDItemGlobalMark:
- case kSDItemJump:
- case kSDItemBufferList:
- case kSDItemLocalMark:
- case kSDItemChange: {
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- break;
- }
- }
-#undef RUN_WITH_CONVERTED_STRING
return ret;
}
@@ -2156,7 +2057,7 @@ static inline ShaDaWriteResult shada_read_when_writing(
}
case kSDReadStatusNotShaDa: {
ret = kSDWriteReadNotShada;
- // fallthrough
+ FALLTHROUGH;
}
case kSDReadStatusReadError: {
return ret;
@@ -2429,6 +2330,48 @@ static inline void add_search_pattern(PossiblyFreedShadaEntry *const ret_pse,
}
}
+/// Initialize registers for writing to the ShaDa file
+///
+/// @param[in] wms The WriteMergerState used when writing.
+/// @param[in] max_reg_lines The maximum number of register lines.
+static inline void shada_initialize_registers(WriteMergerState *const wms,
+ int max_reg_lines)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
+{
+ const void *reg_iter = NULL;
+ const bool limit_reg_lines = max_reg_lines >= 0;
+ do {
+ yankreg_T reg;
+ char name = NUL;
+ bool is_unnamed = false;
+ reg_iter = op_register_iter(reg_iter, &name, &reg, &is_unnamed);
+ if (name == NUL) {
+ break;
+ }
+ if (limit_reg_lines && reg.y_size > (size_t)max_reg_lines) {
+ continue;
+ }
+ wms->registers[op_reg_index(name)] = (PossiblyFreedShadaEntry) {
+ .can_free_entry = false,
+ .data = {
+ .type = kSDItemRegister,
+ .timestamp = reg.timestamp,
+ .data = {
+ .reg = {
+ .contents = (char **)reg.y_array,
+ .contents_size = (size_t)reg.y_size,
+ .type = reg.y_type,
+ .width = (size_t)(reg.y_type == kMTBlockWise ? reg.y_width : 0),
+ .additional_data = reg.additional_data,
+ .name = name,
+ .is_unnamed = is_unnamed,
+ }
+ }
+ }
+ };
+ } while (reg_iter != NULL);
+}
+
/// Write ShaDa file
///
/// @param[in] sd_writer Structure containing file writer definition.
@@ -2455,7 +2398,6 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
if (max_reg_lines < 0) {
max_reg_lines = get_shada_parameter('"');
}
- const bool limit_reg_lines = max_reg_lines >= 0;
const bool dump_registers = (max_reg_lines != 0);
khash_t(bufset) removable_bufs = KHASH_EMPTY_TABLE(bufset);
const size_t max_kbyte = (size_t) max_kbyte_i;
@@ -2556,11 +2498,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
break;
}
typval_T tgttv;
- if (sd_writer->sd_conv.vc_type != CONV_NONE) {
- var_item_copy(&sd_writer->sd_conv, &vartv, &tgttv, true, 0);
- } else {
- copy_tv(&vartv, &tgttv);
- }
+ tv_copy(&vartv, &tgttv);
ShaDaWriteResult spe_ret;
if ((spe_ret = shada_pack_entry(packer, (ShadaEntry) {
.type = kSDItemVariable,
@@ -2573,13 +2511,13 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
}
}
}, max_kbyte)) == kSDWriteFailed) {
- clear_tv(&vartv);
- clear_tv(&tgttv);
+ tv_clear(&vartv);
+ tv_clear(&tgttv);
ret = kSDWriteFailed;
goto shada_write_exit;
}
- clear_tv(&vartv);
- clear_tv(&tgttv);
+ tv_clear(&vartv);
+ tv_clear(&tgttv);
if (spe_ret == kSDWriteSuccessfull) {
int kh_ret;
(void) kh_put(strset, &wms->dumped_variables, name, &kh_ret);
@@ -2702,35 +2640,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
// Initialize registers
if (dump_registers) {
- const void *reg_iter = NULL;
- do {
- yankreg_T reg;
- char name = NUL;
- reg_iter = op_register_iter(reg_iter, &name, &reg);
- if (name == NUL) {
- break;
- }
- if (limit_reg_lines && reg.y_size > (size_t)max_reg_lines) {
- continue;
- }
- wms->registers[op_reg_index(name)] = (PossiblyFreedShadaEntry) {
- .can_free_entry = false,
- .data = {
- .type = kSDItemRegister,
- .timestamp = reg.timestamp,
- .data = {
- .reg = {
- .contents = (char **) reg.y_array,
- .contents_size = (size_t) reg.y_size,
- .type = reg.y_type,
- .width = (size_t) (reg.y_type == kMTBlockWise ? reg.y_width : 0),
- .additional_data = reg.additional_data,
- .name = name,
- }
- }
- }
- };
- } while (reg_iter != NULL);
+ shada_initialize_registers(wms, max_reg_lines);
}
// Initialize buffers
@@ -2811,9 +2721,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
do { \
for (size_t i_ = 0; i_ < ARRAY_SIZE(wms_array); i_++) { \
if (wms_array[i_].data.type != kSDItemMissing) { \
- if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv, \
- wms_array[i_], \
- max_kbyte) == kSDWriteFailed) { \
+ if (shada_pack_pfreed_entry(packer, wms_array[i_], max_kbyte) \
+ == kSDWriteFailed) { \
ret = kSDWriteFailed; \
goto shada_write_exit; \
} \
@@ -2823,8 +2732,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
PACK_WMS_ARRAY(wms->global_marks);
PACK_WMS_ARRAY(wms->registers);
for (size_t i = 0; i < wms->jumps_size; i++) {
- if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv, wms->jumps[i],
- max_kbyte) == kSDWriteFailed) {
+ if (shada_pack_pfreed_entry(packer, wms->jumps[i], max_kbyte)
+ == kSDWriteFailed) {
ret = kSDWriteFailed;
goto shada_write_exit;
}
@@ -2832,8 +2741,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
#define PACK_WMS_ENTRY(wms_entry) \
do { \
if (wms_entry.data.type != kSDItemMissing) { \
- if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv, wms_entry, \
- max_kbyte) == kSDWriteFailed) { \
+ if (shada_pack_pfreed_entry(packer, wms_entry, max_kbyte) \
+ == kSDWriteFailed) { \
ret = kSDWriteFailed; \
goto shada_write_exit; \
} \
@@ -2860,9 +2769,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
for (size_t i = 0; i < file_markss_to_dump; i++) {
PACK_WMS_ARRAY(all_file_markss[i]->marks);
for (size_t j = 0; j < all_file_markss[i]->changes_size; j++) {
- if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv,
- all_file_markss[i]->changes[j],
- max_kbyte) == kSDWriteFailed) {
+ if (shada_pack_pfreed_entry(packer, all_file_markss[i]->changes[j],
+ max_kbyte) == kSDWriteFailed) {
ret = kSDWriteFailed;
goto shada_write_exit;
}
@@ -2886,8 +2794,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
if (dump_one_history[i]) {
hms_insert_whole_neovim_history(&wms->hms[i]);
HMS_ITER(&wms->hms[i], cur_entry, {
- if (shada_pack_encoded_entry(
- packer, &sd_writer->sd_conv, (PossiblyFreedShadaEntry) {
+ if (shada_pack_pfreed_entry(
+ packer, (PossiblyFreedShadaEntry) {
.data = cur_entry->data,
.can_free_entry = cur_entry->can_free_entry,
}, max_kbyte) == kSDWriteFailed) {
@@ -3038,8 +2946,6 @@ shada_write_file_nomerge: {}
verbose_leave();
}
- convert_setup(&sd_writer.sd_conv, p_enc, "utf-8");
-
const ShaDaWriteResult sw_ret = shada_write(&sd_writer, (nomerge
? NULL
: &sd_reader));
@@ -3154,17 +3060,17 @@ static void shada_free_shada_entry(ShadaEntry *const entry)
case kSDItemJump:
case kSDItemGlobalMark:
case kSDItemLocalMark: {
- dict_unref(entry->data.filemark.additional_data);
+ tv_dict_unref(entry->data.filemark.additional_data);
xfree(entry->data.filemark.fname);
break;
}
case kSDItemSearchPattern: {
- dict_unref(entry->data.search_pattern.additional_data);
+ tv_dict_unref(entry->data.search_pattern.additional_data);
xfree(entry->data.search_pattern.pat);
break;
}
case kSDItemRegister: {
- dict_unref(entry->data.reg.additional_data);
+ tv_dict_unref(entry->data.reg.additional_data);
for (size_t i = 0; i < entry->data.reg.contents_size; i++) {
xfree(entry->data.reg.contents[i]);
}
@@ -3172,25 +3078,25 @@ static void shada_free_shada_entry(ShadaEntry *const entry)
break;
}
case kSDItemHistoryEntry: {
- list_unref(entry->data.history_item.additional_elements);
+ tv_list_unref(entry->data.history_item.additional_elements);
xfree(entry->data.history_item.string);
break;
}
case kSDItemVariable: {
- list_unref(entry->data.global_var.additional_elements);
+ tv_list_unref(entry->data.global_var.additional_elements);
xfree(entry->data.global_var.name);
- clear_tv(&entry->data.global_var.value);
+ tv_clear(&entry->data.global_var.value);
break;
}
case kSDItemSubString: {
- list_unref(entry->data.sub_string.additional_elements);
+ tv_list_unref(entry->data.sub_string.additional_elements);
xfree(entry->data.sub_string.sub);
break;
}
case kSDItemBufferList: {
for (size_t i = 0; i < entry->data.buffer_list.size; i++) {
xfree(entry->data.buffer_list.buffers[i].fname);
- dict_unref(entry->data.buffer_list.buffers[i].additional_data);
+ tv_dict_unref(entry->data.buffer_list.buffers[i].additional_data);
}
xfree(entry->data.buffer_list.buffers);
break;
@@ -3327,29 +3233,6 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
return kSDReadStatusSuccess;
}
-/// Convert or copy and return a string
-///
-/// @param[in] sd_conv Conversion definition.
-/// @param[in] str String to convert.
-/// @param[in] len String length.
-///
-/// @return [allocated] converted string or copy of the original string.
-static inline char *get_converted_string(const vimconv_T *const sd_conv,
- const char *const str,
- const size_t len)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
-{
- if (!has_non_ascii_len(str, len)) {
- return xmemdupz(str, len);
- }
- size_t new_len = len;
- char *const new_str = string_convert(sd_conv, str, &new_len);
- if (new_str == NULL) {
- return xmemdupz(str, len);
- }
- return new_str;
-}
-
#define READERR(entry_name, error_desc) \
RERR "Error while reading ShaDa file: " \
entry_name " entry at position %" PRIu64 " " \
@@ -3427,10 +3310,7 @@ static inline char *get_converted_string(const vimconv_T *const sd_conv,
sizeof(*unpacked.data.via.map.ptr)); \
ad_ga.ga_len++; \
}
-#define CONVERTED(str, len) ( \
- sd_reader->sd_conv.vc_type != CONV_NONE \
- ? get_converted_string(&sd_reader->sd_conv, (str), (len)) \
- : xmemdupz((str), (len)))
+#define CONVERTED(str, len) (xmemdupz((str), (len)))
#define BIN_CONVERTED(b) CONVERTED(b.ptr, b.size)
#define SET_ADDITIONAL_DATA(tgt, name) \
do { \
@@ -3451,7 +3331,7 @@ static inline char *get_converted_string(const vimconv_T *const sd_conv,
"cannot be converted to a VimL dictionary")), \
initial_fpos); \
ga_clear(&ad_ga); \
- clear_tv(&adtv); \
+ tv_clear(&adtv); \
goto shada_read_next_item_error; \
} \
tgt = adtv.vval.v_dict; \
@@ -3474,7 +3354,7 @@ static inline char *get_converted_string(const vimconv_T *const sd_conv,
if (msgpack_to_vim(obj, &aetv) == FAIL) { \
emsgf(_(READERR(name, "cannot be converted to a VimL list")), \
initial_fpos); \
- clear_tv(&aetv); \
+ tv_clear(&aetv); \
goto shada_read_next_item_error; \
} \
assert(aetv.v_type == VAR_LIST); \
@@ -3533,8 +3413,16 @@ shada_read_next_item_start:
return mru_ret;
}
- const size_t length = (size_t) length_u64;
- entry->timestamp = (Timestamp) timestamp_u64;
+ if (length_u64 > PTRDIFF_MAX) {
+ emsgf(_(RCERR "Error while reading ShaDa file: "
+ "there is an item at position %" PRIu64 " "
+ "that is stated to be too long"),
+ initial_fpos);
+ return kSDReadStatusNotShaDa;
+ }
+
+ const size_t length = (size_t)length_u64;
+ entry->timestamp = (Timestamp)timestamp_u64;
if (type_u64 == 0) {
// kSDItemUnknown cannot possibly pass that far because it is -1 and that
@@ -3739,6 +3627,7 @@ shada_read_next_item_start:
entry->data.reg.contents[i] = BIN_CONVERTED(arr.ptr[i].via.bin);
}
}
+ BOOLEAN_KEY("register", REG_KEY_UNNAMED, entry->data.reg.is_unnamed)
TYPED_KEY("register", REG_KEY_TYPE, "an unsigned integer",
entry->data.reg.type, POSITIVE_INTEGER, u64, TOU8)
TYPED_KEY("register", KEY_NAME_CHAR, "an unsigned integer",
@@ -3803,30 +3692,14 @@ shada_read_next_item_start:
(char) unpacked.data.via.array.ptr[2].via.u64;
}
size_t strsize;
- if (sd_reader->sd_conv.vc_type == CONV_NONE
- || !has_non_ascii_len(unpacked.data.via.array.ptr[1].via.bin.ptr,
- unpacked.data.via.array.ptr[1].via.bin.size)) {
-shada_read_next_item_hist_no_conv:
- strsize = (
- unpacked.data.via.array.ptr[1].via.bin.size
- + 1 // Zero byte
- + 1); // Separator character
- entry->data.history_item.string = xmalloc(strsize);
- memcpy(entry->data.history_item.string,
- unpacked.data.via.array.ptr[1].via.bin.ptr,
- unpacked.data.via.array.ptr[1].via.bin.size);
- } else {
- size_t len = unpacked.data.via.array.ptr[1].via.bin.size;
- char *const converted = string_convert(
- &sd_reader->sd_conv, unpacked.data.via.array.ptr[1].via.bin.ptr,
- &len);
- if (converted != NULL) {
- strsize = len + 2;
- entry->data.history_item.string = xrealloc(converted, strsize);
- } else {
- goto shada_read_next_item_hist_no_conv;
- }
- }
+ strsize = (
+ unpacked.data.via.array.ptr[1].via.bin.size
+ + 1 // Zero byte
+ + 1); // Separator character
+ entry->data.history_item.string = xmalloc(strsize);
+ memcpy(entry->data.history_item.string,
+ unpacked.data.via.array.ptr[1].via.bin.ptr,
+ unpacked.data.via.array.ptr[1].via.bin.size);
entry->data.history_item.string[strsize - 2] = 0;
entry->data.history_item.string[strsize - 1] =
entry->data.history_item.sep;
@@ -3859,16 +3732,6 @@ shada_read_next_item_hist_no_conv:
"be converted to the VimL value")), initial_fpos);
goto shada_read_next_item_error;
}
- if (sd_reader->sd_conv.vc_type != CONV_NONE) {
- typval_T tgttv;
- var_item_copy(&sd_reader->sd_conv,
- &entry->data.global_var.value,
- &tgttv,
- true,
- 0);
- clear_tv(&entry->data.global_var.value);
- entry->data.global_var.value = tgttv;
- }
SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 2,
entry->data.global_var.additional_elements,
"variable");
diff --git a/src/nvim/sign_defs.h b/src/nvim/sign_defs.h
index 7288a48e21..3778f4287e 100644
--- a/src/nvim/sign_defs.h
+++ b/src/nvim/sign_defs.h
@@ -1,6 +1,8 @@
#ifndef NVIM_SIGN_DEFS_H
#define NVIM_SIGN_DEFS_H
+#include "nvim/pos.h"
+
// signs: line annotations
typedef struct signlist signlist_T;
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 7119ac6dc1..42c9bcc0ee 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -1,5 +1,10 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
// spell.c: code for spell checking
//
+// See spellfile.c for the Vim spell file format.
+//
// The spell checking mechanism uses a tree (aka trie). Each node in the tree
// has a list of bytes that can appear (siblings). For each byte there is a
// pointer to the node with the byte that follows in the word (child).
@@ -63,226 +68,6 @@
// compute the maximum word score that can be used.
#define MAXSCORE(word_score, sound_score) ((4 * word_score - sound_score) / 3)
-// Vim spell file format: <HEADER>
-// <SECTIONS>
-// <LWORDTREE>
-// <KWORDTREE>
-// <PREFIXTREE>
-//
-// <HEADER>: <fileID> <versionnr>
-//
-// <fileID> 8 bytes "VIMspell"
-// <versionnr> 1 byte VIMSPELLVERSION
-//
-//
-// Sections make it possible to add information to the .spl file without
-// making it incompatible with previous versions. There are two kinds of
-// sections:
-// 1. Not essential for correct spell checking. E.g. for making suggestions.
-// These are skipped when not supported.
-// 2. Optional information, but essential for spell checking when present.
-// E.g. conditions for affixes. When this section is present but not
-// supported an error message is given.
-//
-// <SECTIONS>: <section> ... <sectionend>
-//
-// <section>: <sectionID> <sectionflags> <sectionlen> (section contents)
-//
-// <sectionID> 1 byte number from 0 to 254 identifying the section
-//
-// <sectionflags> 1 byte SNF_REQUIRED: this section is required for correct
-// spell checking
-//
-// <sectionlen> 4 bytes length of section contents, MSB first
-//
-// <sectionend> 1 byte SN_END
-//
-//
-// sectionID == SN_INFO: <infotext>
-// <infotext> N bytes free format text with spell file info (version,
-// website, etc)
-//
-// sectionID == SN_REGION: <regionname> ...
-// <regionname> 2 bytes Up to 8 region names: ca, au, etc. Lower case.
-// First <regionname> is region 1.
-//
-// sectionID == SN_CHARFLAGS: <charflagslen> <charflags>
-// <folcharslen> <folchars>
-// <charflagslen> 1 byte Number of bytes in <charflags> (should be 128).
-// <charflags> N bytes List of flags (first one is for character 128):
-// 0x01 word character CF_WORD
-// 0x02 upper-case character CF_UPPER
-// <folcharslen> 2 bytes Number of bytes in <folchars>.
-// <folchars> N bytes Folded characters, first one is for character 128.
-//
-// sectionID == SN_MIDWORD: <midword>
-// <midword> N bytes Characters that are word characters only when used
-// in the middle of a word.
-//
-// sectionID == SN_PREFCOND: <prefcondcnt> <prefcond> ...
-// <prefcondcnt> 2 bytes Number of <prefcond> items following.
-// <prefcond> : <condlen> <condstr>
-// <condlen> 1 byte Length of <condstr>.
-// <condstr> N bytes Condition for the prefix.
-//
-// sectionID == SN_REP: <repcount> <rep> ...
-// <repcount> 2 bytes number of <rep> items, MSB first.
-// <rep> : <repfromlen> <repfrom> <reptolen> <repto>
-// <repfromlen> 1 byte length of <repfrom>
-// <repfrom> N bytes "from" part of replacement
-// <reptolen> 1 byte length of <repto>
-// <repto> N bytes "to" part of replacement
-//
-// sectionID == SN_REPSAL: <repcount> <rep> ...
-// just like SN_REP but for soundfolded words
-//
-// sectionID == SN_SAL: <salflags> <salcount> <sal> ...
-// <salflags> 1 byte flags for soundsalike conversion:
-// SAL_F0LLOWUP
-// SAL_COLLAPSE
-// SAL_REM_ACCENTS
-// <salcount> 2 bytes number of <sal> items following
-// <sal> : <salfromlen> <salfrom> <saltolen> <salto>
-// <salfromlen> 1 byte length of <salfrom>
-// <salfrom> N bytes "from" part of soundsalike
-// <saltolen> 1 byte length of <salto>
-// <salto> N bytes "to" part of soundsalike
-//
-// sectionID == SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
-// <sofofromlen> 2 bytes length of <sofofrom>
-// <sofofrom> N bytes "from" part of soundfold
-// <sofotolen> 2 bytes length of <sofoto>
-// <sofoto> N bytes "to" part of soundfold
-//
-// sectionID == SN_SUGFILE: <timestamp>
-// <timestamp> 8 bytes time in seconds that must match with .sug file
-//
-// sectionID == SN_NOSPLITSUGS: nothing
-//
-// sectionID == SN_NOCOMPOUNDSUGS: nothing
-//
-// sectionID == SN_WORDS: <word> ...
-// <word> N bytes NUL terminated common word
-//
-// sectionID == SN_MAP: <mapstr>
-// <mapstr> N bytes String with sequences of similar characters,
-// separated by slashes.
-//
-// sectionID == SN_COMPOUND: <compmax> <compminlen> <compsylmax> <compoptions>
-// <comppatcount> <comppattern> ... <compflags>
-// <compmax> 1 byte Maximum nr of words in compound word.
-// <compminlen> 1 byte Minimal word length for compounding.
-// <compsylmax> 1 byte Maximum nr of syllables in compound word.
-// <compoptions> 2 bytes COMP_ flags.
-// <comppatcount> 2 bytes number of <comppattern> following
-// <compflags> N bytes Flags from COMPOUNDRULE items, separated by
-// slashes.
-//
-// <comppattern>: <comppatlen> <comppattext>
-// <comppatlen> 1 byte length of <comppattext>
-// <comppattext> N bytes end or begin chars from CHECKCOMPOUNDPATTERN
-//
-// sectionID == SN_NOBREAK: (empty, its presence is what matters)
-//
-// sectionID == SN_SYLLABLE: <syllable>
-// <syllable> N bytes String from SYLLABLE item.
-//
-// <LWORDTREE>: <wordtree>
-//
-// <KWORDTREE>: <wordtree>
-//
-// <PREFIXTREE>: <wordtree>
-//
-//
-// <wordtree>: <nodecount> <nodedata> ...
-//
-// <nodecount> 4 bytes Number of nodes following. MSB first.
-//
-// <nodedata>: <siblingcount> <sibling> ...
-//
-// <siblingcount> 1 byte Number of siblings in this node. The siblings
-// follow in sorted order.
-//
-// <sibling>: <byte> [ <nodeidx> <xbyte>
-// | <flags> [<flags2>] [<region>] [<affixID>]
-// | [<pflags>] <affixID> <prefcondnr> ]
-//
-// <byte> 1 byte Byte value of the sibling. Special cases:
-// BY_NOFLAGS: End of word without flags and for all
-// regions.
-// For PREFIXTREE <affixID> and
-// <prefcondnr> follow.
-// BY_FLAGS: End of word, <flags> follow.
-// For PREFIXTREE <pflags>, <affixID>
-// and <prefcondnr> follow.
-// BY_FLAGS2: End of word, <flags> and <flags2>
-// follow. Not used in PREFIXTREE.
-// BY_INDEX: Child of sibling is shared, <nodeidx>
-// and <xbyte> follow.
-//
-// <nodeidx> 3 bytes Index of child for this sibling, MSB first.
-//
-// <xbyte> 1 byte Byte value of the sibling.
-//
-// <flags> 1 byte Bitmask of:
-// WF_ALLCAP word must have only capitals
-// WF_ONECAP first char of word must be capital
-// WF_KEEPCAP keep-case word
-// WF_FIXCAP keep-case word, all caps not allowed
-// WF_RARE rare word
-// WF_BANNED bad word
-// WF_REGION <region> follows
-// WF_AFX <affixID> follows
-//
-// <flags2> 1 byte Bitmask of:
-// WF_HAS_AFF >> 8 word includes affix
-// WF_NEEDCOMP >> 8 word only valid in compound
-// WF_NOSUGGEST >> 8 word not used for suggestions
-// WF_COMPROOT >> 8 word already a compound
-// WF_NOCOMPBEF >> 8 no compounding before this word
-// WF_NOCOMPAFT >> 8 no compounding after this word
-//
-// <pflags> 1 byte Bitmask of:
-// WFP_RARE rare prefix
-// WFP_NC non-combining prefix
-// WFP_UP letter after prefix made upper case
-//
-// <region> 1 byte Bitmask for regions in which word is valid. When
-// omitted it's valid in all regions.
-// Lowest bit is for region 1.
-//
-// <affixID> 1 byte ID of affix that can be used with this word. In
-// PREFIXTREE used for the required prefix ID.
-//
-// <prefcondnr> 2 bytes Prefix condition number, index in <prefcond> list
-// from HEADER.
-//
-// All text characters are in 'encoding', but stored as single bytes.
-
-// Vim .sug file format: <SUGHEADER>
-// <SUGWORDTREE>
-// <SUGTABLE>
-//
-// <SUGHEADER>: <fileID> <versionnr> <timestamp>
-//
-// <fileID> 6 bytes "VIMsug"
-// <versionnr> 1 byte VIMSUGVERSION
-// <timestamp> 8 bytes timestamp that must match with .spl file
-//
-//
-// <SUGWORDTREE>: <wordtree> (see above, no flags or region used)
-//
-//
-// <SUGTABLE>: <sugwcount> <sugline> ...
-//
-// <sugwcount> 4 bytes number of <sugline> following
-//
-// <sugline>: <sugnr> ... NUL
-//
-// <sugnr>: X bytes word number that results in this soundfolded word,
-// stored as an offset to the previous number in as
-// few bytes as possible, see offset2bytes())
-
#include <assert.h>
#include <inttypes.h>
#include <limits.h>
@@ -292,6 +77,9 @@
#include <stdlib.h>
#include <wctype.h>
+/* for offsetof() */
+#include <stddef.h>
+
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/spell.h"
@@ -307,6 +95,7 @@
#include "nvim/func_attr.h"
#include "nvim/getchar.h"
#include "nvim/hashtab.h"
+#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
@@ -320,254 +109,18 @@
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/search.h"
+#include "nvim/spellfile.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
-#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/os/os.h"
#include "nvim/os/input.h"
-#ifndef UNIX // it's in os/unix_defs.h for Unix
-# include <time.h> // for time_t
-#endif
-
-#define MAXWLEN 254 // Assume max. word len is this many bytes.
- // Some places assume a word length fits in a
- // byte, thus it can't be above 255.
-
-// Type used for indexes in the word tree need to be at least 4 bytes. If int
-// is 8 bytes we could use something smaller, but what?
-typedef int idx_T;
-
-# define SPL_FNAME_TMPL "%s.%s.spl"
-# define SPL_FNAME_ADD ".add."
-# define SPL_FNAME_ASCII ".ascii."
-
-// Flags used for a word. Only the lowest byte can be used, the region byte
-// comes above it.
-#define WF_REGION 0x01 // region byte follows
-#define WF_ONECAP 0x02 // word with one capital (or all capitals)
-#define WF_ALLCAP 0x04 // word must be all capitals
-#define WF_RARE 0x08 // rare word
-#define WF_BANNED 0x10 // bad word
-#define WF_AFX 0x20 // affix ID follows
-#define WF_FIXCAP 0x40 // keep-case word, allcap not allowed
-#define WF_KEEPCAP 0x80 // keep-case word
-
-// for <flags2>, shifted up one byte to be used in wn_flags
-#define WF_HAS_AFF 0x0100 // word includes affix
-#define WF_NEEDCOMP 0x0200 // word only valid in compound
-#define WF_NOSUGGEST 0x0400 // word not to be suggested
-#define WF_COMPROOT 0x0800 // already compounded word, COMPOUNDROOT
-#define WF_NOCOMPBEF 0x1000 // no compounding before this word
-#define WF_NOCOMPAFT 0x2000 // no compounding after this word
-
// only used for su_badflags
#define WF_MIXCAP 0x20 // mix of upper and lower case: macaRONI
#define WF_CAPMASK (WF_ONECAP | WF_ALLCAP | WF_KEEPCAP | WF_FIXCAP)
-// flags for <pflags>
-#define WFP_RARE 0x01 // rare prefix
-#define WFP_NC 0x02 // prefix is not combining
-#define WFP_UP 0x04 // to-upper prefix
-#define WFP_COMPPERMIT 0x08 // prefix with COMPOUNDPERMITFLAG
-#define WFP_COMPFORBID 0x10 // prefix with COMPOUNDFORBIDFLAG
-
-// Flags for postponed prefixes in "sl_pidxs". Must be above affixID (one
-// byte) and prefcondnr (two bytes).
-#define WF_RAREPFX (WFP_RARE << 24) // rare postponed prefix
-#define WF_PFX_NC (WFP_NC << 24) // non-combining postponed prefix
-#define WF_PFX_UP (WFP_UP << 24) // to-upper postponed prefix
-#define WF_PFX_COMPPERMIT (WFP_COMPPERMIT << 24) // postponed prefix with
- // COMPOUNDPERMITFLAG
-#define WF_PFX_COMPFORBID (WFP_COMPFORBID << 24) // postponed prefix with
- // COMPOUNDFORBIDFLAG
-
-
-// flags for <compoptions>
-#define COMP_CHECKDUP 1 // CHECKCOMPOUNDDUP
-#define COMP_CHECKREP 2 // CHECKCOMPOUNDREP
-#define COMP_CHECKCASE 4 // CHECKCOMPOUNDCASE
-#define COMP_CHECKTRIPLE 8 // CHECKCOMPOUNDTRIPLE
-
-// Special byte values for <byte>. Some are only used in the tree for
-// postponed prefixes, some only in the other trees. This is a bit messy...
-#define BY_NOFLAGS 0 // end of word without flags or region; for
- // postponed prefix: no <pflags>
-#define BY_INDEX 1 // child is shared, index follows
-#define BY_FLAGS 2 // end of word, <flags> byte follows; for
- // postponed prefix: <pflags> follows
-#define BY_FLAGS2 3 // end of word, <flags> and <flags2> bytes
- // follow; never used in prefix tree
-#define BY_SPECIAL BY_FLAGS2 // highest special byte value
-
-// Info from "REP", "REPSAL" and "SAL" entries in ".aff" file used in si_rep,
-// si_repsal, sl_rep, and si_sal. Not for sl_sal!
-// One replacement: from "ft_from" to "ft_to".
-typedef struct fromto_S {
- char_u *ft_from;
- char_u *ft_to;
-} fromto_T;
-
-// Info from "SAL" entries in ".aff" file used in sl_sal.
-// The info is split for quick processing by spell_soundfold().
-// Note that "sm_oneof" and "sm_rules" point into sm_lead.
-typedef struct salitem_S {
- char_u *sm_lead; // leading letters
- int sm_leadlen; // length of "sm_lead"
- char_u *sm_oneof; // letters from () or NULL
- char_u *sm_rules; // rules like ^, $, priority
- char_u *sm_to; // replacement.
- int *sm_lead_w; // wide character copy of "sm_lead"
- int *sm_oneof_w; // wide character copy of "sm_oneof"
- int *sm_to_w; // wide character copy of "sm_to"
-} salitem_T;
-
-typedef int salfirst_T;
-
-// Values for SP_*ERROR are negative, positive values are used by
-// read_cnt_string().
-#define SP_TRUNCERROR -1 // spell file truncated error
-#define SP_FORMERROR -2 // format error in spell file
-#define SP_OTHERERROR -3 // other error while reading spell file
-
-// Structure used to store words and other info for one language, loaded from
-// a .spl file.
-// The main access is through the tree in "sl_fbyts/sl_fidxs", storing the
-// case-folded words. "sl_kbyts/sl_kidxs" is for keep-case words.
-//
-// The "byts" array stores the possible bytes in each tree node, preceded by
-// the number of possible bytes, sorted on byte value:
-// <len> <byte1> <byte2> ...
-// The "idxs" array stores the index of the child node corresponding to the
-// byte in "byts".
-// Exception: when the byte is zero, the word may end here and "idxs" holds
-// the flags, region mask and affixID for the word. There may be several
-// zeros in sequence for alternative flag/region/affixID combinations.
-typedef struct slang_S slang_T;
-
-struct slang_S {
- slang_T *sl_next; // next language
- char_u *sl_name; // language name "en", "en.rare", "nl", etc.
- char_u *sl_fname; // name of .spl file
- bool sl_add; // true if it's a .add file.
-
- char_u *sl_fbyts; // case-folded word bytes
- idx_T *sl_fidxs; // case-folded word indexes
- char_u *sl_kbyts; // keep-case word bytes
- idx_T *sl_kidxs; // keep-case word indexes
- char_u *sl_pbyts; // prefix tree word bytes
- idx_T *sl_pidxs; // prefix tree word indexes
-
- char_u *sl_info; // infotext string or NULL
-
- char_u sl_regions[17]; // table with up to 8 region names plus NUL
-
- char_u *sl_midword; // MIDWORD string or NULL
-
- hashtab_T sl_wordcount; // hashtable with word count, wordcount_T
-
- int sl_compmax; // COMPOUNDWORDMAX (default: MAXWLEN)
- int sl_compminlen; // COMPOUNDMIN (default: 0)
- int sl_compsylmax; // COMPOUNDSYLMAX (default: MAXWLEN)
- int sl_compoptions; // COMP_* flags
- garray_T sl_comppat; // CHECKCOMPOUNDPATTERN items
- regprog_T *sl_compprog; // COMPOUNDRULE turned into a regexp progrm
- // (NULL when no compounding)
- char_u *sl_comprules; // all COMPOUNDRULE concatenated (or NULL)
- char_u *sl_compstartflags; // flags for first compound word
- char_u *sl_compallflags; // all flags for compound words
- bool sl_nobreak; // When true: no spaces between words
- char_u *sl_syllable; // SYLLABLE repeatable chars or NULL
- garray_T sl_syl_items; // syllable items
-
- int sl_prefixcnt; // number of items in "sl_prefprog"
- regprog_T **sl_prefprog; // table with regprogs for prefixes
-
- garray_T sl_rep; // list of fromto_T entries from REP lines
- int16_t sl_rep_first[256]; // indexes where byte first appears, -1 if
- // there is none
- garray_T sl_sal; // list of salitem_T entries from SAL lines
- salfirst_T sl_sal_first[256]; // indexes where byte first appears, -1 if
- // there is none
- bool sl_followup; // SAL followup
- bool sl_collapse; // SAL collapse_result
- bool sl_rem_accents; // SAL remove_accents
- bool sl_sofo; // SOFOFROM and SOFOTO instead of SAL items:
- // "sl_sal_first" maps chars, when has_mbyte
- // "sl_sal" is a list of wide char lists.
- garray_T sl_repsal; // list of fromto_T entries from REPSAL lines
- int16_t sl_repsal_first[256]; // sl_rep_first for REPSAL lines
- bool sl_nosplitsugs; // don't suggest splitting a word
- bool sl_nocompoundsugs; // don't suggest compounding
-
- // Info from the .sug file. Loaded on demand.
- time_t sl_sugtime; // timestamp for .sug file
- char_u *sl_sbyts; // soundfolded word bytes
- idx_T *sl_sidxs; // soundfolded word indexes
- buf_T *sl_sugbuf; // buffer with word number table
- bool sl_sugloaded; // true when .sug file was loaded or failed to
- // load
-
- bool sl_has_map; // true, if there is a MAP line
- hashtab_T sl_map_hash; // MAP for multi-byte chars
- int sl_map_array[256]; // MAP for first 256 chars
- hashtab_T sl_sounddone; // table with soundfolded words that have
- // handled, see add_sound_suggest()
-};
-
-// First language that is loaded, start of the linked list of loaded
-// languages.
-static slang_T *first_lang = NULL;
-
-// Flags used in .spl file for soundsalike flags.
-#define SAL_F0LLOWUP 1
-#define SAL_COLLAPSE 2
-#define SAL_REM_ACCENTS 4
-
-// Structure used in "b_langp", filled from 'spelllang'.
-typedef struct langp_S {
- slang_T *lp_slang; // info for this language
- slang_T *lp_sallang; // language used for sound folding or NULL
- slang_T *lp_replang; // language used for REP items or NULL
- int lp_region; // bitmask for region or REGION_ALL
-} langp_T;
-
-#define LANGP_ENTRY(ga, i) (((langp_T *)(ga).ga_data) + (i))
-
-#define REGION_ALL 0xff // word valid in all regions
-
-#define VIMSPELLMAGIC "VIMspell" // string at start of Vim spell file
-#define VIMSPELLMAGICL 8
-#define VIMSPELLVERSION 50
-
-#define VIMSUGMAGIC "VIMsug" // string at start of Vim .sug file
-#define VIMSUGMAGICL 6
-#define VIMSUGVERSION 1
-
-// Section IDs. Only renumber them when VIMSPELLVERSION changes!
-#define SN_REGION 0 // <regionname> section
-#define SN_CHARFLAGS 1 // charflags section
-#define SN_MIDWORD 2 // <midword> section
-#define SN_PREFCOND 3 // <prefcond> section
-#define SN_REP 4 // REP items section
-#define SN_SAL 5 // SAL items section
-#define SN_SOFO 6 // soundfolding section
-#define SN_MAP 7 // MAP items section
-#define SN_COMPOUND 8 // compound words section
-#define SN_SYLLABLE 9 // syllable section
-#define SN_NOBREAK 10 // NOBREAK section
-#define SN_SUGFILE 11 // timestamp for .sug file
-#define SN_REPSAL 12 // REPSAL items section
-#define SN_WORDS 13 // common words
-#define SN_NOSPLITSUGS 14 // don't split word for suggestions
-#define SN_INFO 15 // info section
-#define SN_NOCOMPOUNDSUGS 16 // don't compound for suggestions
-#define SN_END 255 // end of sections
-
-#define SNF_REQUIRED 1 // <sectionflags>: required section
-
// Result values. Lower number is accepted over higher one.
#define SP_BANNED -1
#define SP_RARE 0
@@ -575,17 +128,20 @@ typedef struct langp_S {
#define SP_LOCAL 2
#define SP_BAD 3
+// First language that is loaded, start of the linked list of loaded
+// languages.
+slang_T *first_lang = NULL;
+
// file used for "zG" and "zW"
-static char_u *int_wordlist = NULL;
+char_u *int_wordlist = NULL;
typedef struct wordcount_S {
uint16_t wc_count; // nr of times word was seen
char_u wc_word[1]; // word, actually longer
} wordcount_T;
-static wordcount_T dumwc;
-#define WC_KEY_OFF (unsigned)(dumwc.wc_word - (char_u *)&dumwc)
-#define HI2WC(hi) ((wordcount_T *)((hi)->hi_key - WC_KEY_OFF))
+#define WC_KEY_OFF offsetof(wordcount_T, wc_word)
+#define HI2WC(hi) ((wordcount_T *)((hi)->hi_key - WC_KEY_OFF))
#define MAXWORDCOUNT 0xffff
// Information used when looking for suggestions.
@@ -716,65 +272,6 @@ typedef struct matchinf_S {
char_u *mi_end2; // "mi_end" without following word
} matchinf_T;
-// The tables used for recognizing word characters according to spelling.
-// These are only used for the first 256 characters of 'encoding'.
-typedef struct {
- bool st_isw[256]; // flags: is word char
- bool st_isu[256]; // flags: is uppercase char
- char_u st_fold[256]; // chars: folded case
- char_u st_upper[256]; // chars: upper case
-} spelltab_T;
-
-// For finding suggestions: At each node in the tree these states are tried:
-typedef enum {
- STATE_START = 0, // At start of node check for NUL bytes (goodword
- // ends); if badword ends there is a match, otherwise
- // try splitting word.
- STATE_NOPREFIX, // try without prefix
- STATE_SPLITUNDO, // Undo splitting.
- STATE_ENDNUL, // Past NUL bytes at start of the node.
- STATE_PLAIN, // Use each byte of the node.
- STATE_DEL, // Delete a byte from the bad word.
- STATE_INS_PREP, // Prepare for inserting bytes.
- STATE_INS, // Insert a byte in the bad word.
- STATE_SWAP, // Swap two bytes.
- STATE_UNSWAP, // Undo swap two characters.
- STATE_SWAP3, // Swap two characters over three.
- STATE_UNSWAP3, // Undo Swap two characters over three.
- STATE_UNROT3L, // Undo rotate three characters left
- STATE_UNROT3R, // Undo rotate three characters right
- STATE_REP_INI, // Prepare for using REP items.
- STATE_REP, // Use matching REP items from the .aff file.
- STATE_REP_UNDO, // Undo a REP item replacement.
- STATE_FINAL // End of this node.
-} state_T;
-
-// Struct to keep the state at each level in suggest_try_change().
-typedef struct trystate_S {
- state_T ts_state; // state at this level, STATE_
- int ts_score; // score
- idx_T ts_arridx; // index in tree array, start of node
- short ts_curi; // index in list of child nodes
- char_u ts_fidx; // index in fword[], case-folded bad word
- char_u ts_fidxtry; // ts_fidx at which bytes may be changed
- char_u ts_twordlen; // valid length of tword[]
- char_u ts_prefixdepth; // stack depth for end of prefix or
- // PFD_PREFIXTREE or PFD_NOPREFIX
- char_u ts_flags; // TSF_ flags
- char_u ts_tcharlen; // number of bytes in tword character
- char_u ts_tcharidx; // current byte index in tword character
- char_u ts_isdiff; // DIFF_ values
- char_u ts_fcharstart; // index in fword where badword char started
- char_u ts_prewordlen; // length of word in "preword[]"
- char_u ts_splitoff; // index in "tword" after last split
- char_u ts_splitfidx; // "ts_fidx" at word split
- char_u ts_complen; // nr of compound words used
- char_u ts_compsplit; // index for "compflags" where word was spit
- char_u ts_save_badflags; // su_badflags saved here
- char_u ts_delidx; // index in fword for char that was deleted,
- // valid when "ts_flags" has TSF_DIDDEL
-} trystate_T;
-
// Structure used for the cookie argument of do_in_runtimepath().
typedef struct spelload_S {
char_u sl_lang[MAXWLEN + 1]; // language name
@@ -788,200 +285,8 @@ typedef struct syl_item_S {
int sy_len;
} syl_item_T;
-#define MAXLINELEN 500 // Maximum length in bytes of a line in a .aff
- // and .dic file.
-// Main structure to store the contents of a ".aff" file.
-typedef struct afffile_S {
- char_u *af_enc; // "SET", normalized, alloc'ed string or NULL
- int af_flagtype; // AFT_CHAR, AFT_LONG, AFT_NUM or AFT_CAPLONG
- unsigned af_rare; // RARE ID for rare word
- unsigned af_keepcase; // KEEPCASE ID for keep-case word
- unsigned af_bad; // BAD ID for banned word
- unsigned af_needaffix; // NEEDAFFIX ID
- unsigned af_circumfix; // CIRCUMFIX ID
- unsigned af_needcomp; // NEEDCOMPOUND ID
- unsigned af_comproot; // COMPOUNDROOT ID
- unsigned af_compforbid; // COMPOUNDFORBIDFLAG ID
- unsigned af_comppermit; // COMPOUNDPERMITFLAG ID
- unsigned af_nosuggest; // NOSUGGEST ID
- int af_pfxpostpone; // postpone prefixes without chop string and
- // without flags
- bool af_ignoreextra; // IGNOREEXTRA present
- hashtab_T af_pref; // hashtable for prefixes, affheader_T
- hashtab_T af_suff; // hashtable for suffixes, affheader_T
- hashtab_T af_comp; // hashtable for compound flags, compitem_T
-} afffile_T;
-
-#define AFT_CHAR 0 // flags are one character
-#define AFT_LONG 1 // flags are two characters
-#define AFT_CAPLONG 2 // flags are one or two characters
-#define AFT_NUM 3 // flags are numbers, comma separated
-
-typedef struct affentry_S affentry_T;
-// Affix entry from ".aff" file. Used for prefixes and suffixes.
-struct affentry_S {
- affentry_T *ae_next; // next affix with same name/number
- char_u *ae_chop; // text to chop off basic word (can be NULL)
- char_u *ae_add; // text to add to basic word (can be NULL)
- char_u *ae_flags; // flags on the affix (can be NULL)
- char_u *ae_cond; // condition (NULL for ".")
- regprog_T *ae_prog; // regexp program for ae_cond or NULL
- char ae_compforbid; // COMPOUNDFORBIDFLAG found
- char ae_comppermit; // COMPOUNDPERMITFLAG found
-};
-
-# define AH_KEY_LEN 17 // 2 x 8 bytes + NUL
-
-// Affix header from ".aff" file. Used for af_pref and af_suff.
-typedef struct affheader_S {
- char_u ah_key[AH_KEY_LEN]; // key for hashtab == name of affix
- unsigned ah_flag; // affix name as number, uses "af_flagtype"
- int ah_newID; // prefix ID after renumbering; 0 if not used
- int ah_combine; // suffix may combine with prefix
- int ah_follows; // another affix block should be following
- affentry_T *ah_first; // first affix entry
-} affheader_T;
-
-#define HI2AH(hi) ((affheader_T *)(hi)->hi_key)
-
-// Flag used in compound items.
-typedef struct compitem_S {
- char_u ci_key[AH_KEY_LEN]; // key for hashtab == name of compound
- unsigned ci_flag; // affix name as number, uses "af_flagtype"
- int ci_newID; // affix ID after renumbering.
-} compitem_T;
-
-#define HI2CI(hi) ((compitem_T *)(hi)->hi_key)
-
-// Structure that is used to store the items in the word tree. This avoids
-// the need to keep track of each allocated thing, everything is freed all at
-// once after ":mkspell" is done.
-// Note: "sb_next" must be just before "sb_data" to make sure the alignment of
-// "sb_data" is correct for systems where pointers must be aligned on
-// pointer-size boundaries and sizeof(pointer) > sizeof(int) (e.g., Sparc).
-#define SBLOCKSIZE 16000 // size of sb_data
-typedef struct sblock_S sblock_T;
-struct sblock_S {
- int sb_used; // nr of bytes already in use
- sblock_T *sb_next; // next block in list
- char_u sb_data[1]; // data, actually longer
-};
-
-// A node in the tree.
-typedef struct wordnode_S wordnode_T;
-struct wordnode_S {
- union // shared to save space
- {
- char_u hashkey[6]; // the hash key, only used while compressing
- int index; // index in written nodes (valid after first
- // round)
- } wn_u1;
- union // shared to save space
- {
- wordnode_T *next; // next node with same hash key
- wordnode_T *wnode; // parent node that will write this node
- } wn_u2;
- wordnode_T *wn_child; // child (next byte in word)
- wordnode_T *wn_sibling; // next sibling (alternate byte in word,
- // always sorted)
- int wn_refs; // Nr. of references to this node. Only
- // relevant for first node in a list of
- // siblings, in following siblings it is
- // always one.
- char_u wn_byte; // Byte for this node. NUL for word end
-
- // Info for when "wn_byte" is NUL.
- // In PREFIXTREE "wn_region" is used for the prefcondnr.
- // In the soundfolded word tree "wn_flags" has the MSW of the wordnr and
- // "wn_region" the LSW of the wordnr.
- char_u wn_affixID; // supported/required prefix ID or 0
- uint16_t wn_flags; // WF_ flags
- short wn_region; // region mask
-
-#ifdef SPELL_PRINTTREE
- int wn_nr; // sequence nr for printing
-#endif
-};
-
-#define WN_MASK 0xffff // mask relevant bits of "wn_flags"
-
-#define HI2WN(hi) (wordnode_T *)((hi)->hi_key)
-
-// Info used while reading the spell files.
-typedef struct spellinfo_S {
- wordnode_T *si_foldroot; // tree with case-folded words
- long si_foldwcount; // nr of words in si_foldroot
-
- wordnode_T *si_keeproot; // tree with keep-case words
- long si_keepwcount; // nr of words in si_keeproot
-
- wordnode_T *si_prefroot; // tree with postponed prefixes
-
- long si_sugtree; // creating the soundfolding trie
-
- sblock_T *si_blocks; // memory blocks used
- long si_blocks_cnt; // memory blocks allocated
- int si_did_emsg; // TRUE when ran out of memory
-
- long si_compress_cnt; // words to add before lowering
- // compression limit
- wordnode_T *si_first_free; // List of nodes that have been freed during
- // compression, linked by "wn_child" field.
- long si_free_count; // number of nodes in si_first_free
-#ifdef SPELL_PRINTTREE
- int si_wordnode_nr; // sequence nr for nodes
-#endif
- buf_T *si_spellbuf; // buffer used to store soundfold word table
-
- int si_ascii; // handling only ASCII words
- int si_add; // addition file
- int si_clear_chartab; // when TRUE clear char tables
- int si_region; // region mask
- vimconv_T si_conv; // for conversion to 'encoding'
- int si_memtot; // runtime memory used
- int si_verbose; // verbose messages
- int si_msg_count; // number of words added since last message
- char_u *si_info; // info text chars or NULL
- int si_region_count; // number of regions supported (1 when there
- // are no regions)
- char_u si_region_name[17]; // region names; used only if
- // si_region_count > 1)
-
- garray_T si_rep; // list of fromto_T entries from REP lines
- garray_T si_repsal; // list of fromto_T entries from REPSAL lines
- garray_T si_sal; // list of fromto_T entries from SAL lines
- char_u *si_sofofr; // SOFOFROM text
- char_u *si_sofoto; // SOFOTO text
- int si_nosugfile; // NOSUGFILE item found
- int si_nosplitsugs; // NOSPLITSUGS item found
- int si_nocompoundsugs; // NOCOMPOUNDSUGS item found
- int si_followup; // soundsalike: ?
- int si_collapse; // soundsalike: ?
- hashtab_T si_commonwords; // hashtable for common words
- time_t si_sugtime; // timestamp for .sug file
- int si_rem_accents; // soundsalike: remove accents
- garray_T si_map; // MAP info concatenated
- char_u *si_midword; // MIDWORD chars or NULL
- int si_compmax; // max nr of words for compounding
- int si_compminlen; // minimal length for compounding
- int si_compsylmax; // max nr of syllables for compounding
- int si_compoptions; // COMP_ flags
- garray_T si_comppat; // CHECKCOMPOUNDPATTERN items, each stored as
- // a string
- char_u *si_compflags; // flags used for compounding
- char_u si_nobreak; // NOBREAK
- char_u *si_syllable; // syllable string
- garray_T si_prefcond; // table with conditions for postponed
- // prefixes, each stored as a string
- int si_newprefID; // current value for ah_newID
- int si_newcompID; // current value for compound ID
-} spellinfo_T;
-
-static spelltab_T spelltab;
-static int did_set_spelltab;
-
-#define CF_WORD 0x01
-#define CF_UPPER 0x02
+spelltab_T spelltab;
+int did_set_spelltab;
// structure used to store soundfolded words that add_sound_suggest() has
// handled already.
@@ -1023,34 +328,7 @@ typedef struct {
#define FIND_COMPOUND 3 // find case-folded compound word
#define FIND_KEEPCOMPOUND 4 // find keep-case compound word
-
-// Use our own character-case definitions, because the current locale may
-// differ from what the .spl file uses.
-// These must not be called with negative number!
-#include <wchar.h> // for towupper() and towlower()
-// Multi-byte implementation. For Unicode we can call utf_*(), but don't do
-// that for ASCII, because we don't want to use 'casemap' here. Otherwise use
-// the "w" library function for characters above 255.
-#define SPELL_TOFOLD(c) (enc_utf8 && (c) >= 128 ? utf_fold(c) \
- : (c) < \
- 256 ? (int)spelltab.st_fold[c] : (int)towlower(c))
-
-#define SPELL_TOUPPER(c) (enc_utf8 && (c) >= 128 ? utf_toupper(c) \
- : (c) < \
- 256 ? (int)spelltab.st_upper[c] : (int)towupper(c))
-
-#define SPELL_ISUPPER(c) (enc_utf8 && (c) >= 128 ? utf_isupper(c) \
- : (c) < 256 ? spelltab.st_isu[c] : iswupper(c))
-
-
-static char *e_format = N_("E759: Format error in spell file");
-static char *e_spell_trunc = N_("E758: Truncated spell file");
-static char *e_afftrailing = N_("Trailing text in %s line %d: %s");
-static char *e_affname = N_("Affix name too long in %s line %d: %s");
-static char *e_affform = N_("E761: Format error in affix file FOL, LOW or UPP");
-static char *e_affrange = N_(
- "E762: Character in FOL, LOW or UPP is out of range");
-static char *msg_compressing = N_("Compressing word tree...");
+char *e_format = N_("E759: Format error in spell file");
// Remember what "z?" replaced.
static char_u *repl_from = NULL;
@@ -2155,12 +1433,10 @@ spell_move_to (
// the cursor.
if (dir == BACKWARD
|| lnum != wp->w_cursor.lnum
- || (lnum == wp->w_cursor.lnum
- && (wrapped
- || ((colnr_T)(curline
- ? p - buf + (ptrdiff_t)len
- : p - buf)
- > wp->w_cursor.col)))) {
+ || wrapped
+ || ((colnr_T)(curline
+ ? p - buf + (ptrdiff_t)len
+ : p - buf) > wp->w_cursor.col)) {
if (has_syntax) {
col = (int)(p - buf);
(void)syn_get_id(wp, lnum, (colnr_T)col,
@@ -2357,7 +1633,7 @@ static void spell_load_lang(char_u *lang)
// Return the encoding used for spell checking: Use 'encoding', except that we
// use "latin1" for "latin9". And limit to 60 characters (just in case).
-static char_u *spell_enc(void)
+char_u *spell_enc(void)
{
if (STRLEN(p_enc) < 60 && STRCMP(p_enc, "iso-8859-15") != 0)
@@ -2375,7 +1651,7 @@ static void int_wordlist_spl(char_u *fname)
// Allocate a new slang_T for language "lang". "lang" can be NULL.
// Caller must fill "sl_next".
-static slang_T *slang_alloc(char_u *lang)
+slang_T *slang_alloc(char_u *lang)
{
slang_T *lp = xcalloc(1, sizeof(slang_T));
@@ -2391,7 +1667,7 @@ static slang_T *slang_alloc(char_u *lang)
}
// Free the contents of an slang_T and the structure itself.
-static void slang_free(slang_T *lp)
+void slang_free(slang_T *lp)
{
xfree(lp->sl_name);
xfree(lp->sl_fname);
@@ -2416,7 +1692,7 @@ static void free_fromto(fromto_T *ftp) {
}
// Clear an slang_T so that the file can be reloaded.
-static void slang_clear(slang_T *lp)
+void slang_clear(slang_T *lp)
{
garray_T *gap;
@@ -2489,7 +1765,7 @@ static void slang_clear(slang_T *lp)
}
// Clear the info from the .sug file in "lp".
-static void slang_clear_sug(slang_T *lp)
+void slang_clear_sug(slang_T *lp)
{
xfree(lp->sl_sbyts);
lp->sl_sbyts = NULL;
@@ -2521,562 +1797,14 @@ static void spell_load_cb(char_u *fname, void *cookie)
}
}
-// Load one spell file and store the info into a slang_T.
-//
-// This is invoked in three ways:
-// - From spell_load_cb() to load a spell file for the first time. "lang" is
-// the language name, "old_lp" is NULL. Will allocate an slang_T.
-// - To reload a spell file that was changed. "lang" is NULL and "old_lp"
-// points to the existing slang_T.
-// - Just after writing a .spl file; it's read back to produce the .sug file.
-// "old_lp" is NULL and "lang" is NULL. Will allocate an slang_T.
-//
-// Returns the slang_T the spell file was loaded into. NULL for error.
-static slang_T *
-spell_load_file (
- char_u *fname,
- char_u *lang,
- slang_T *old_lp,
- bool silent // no error if file doesn't exist
-)
-{
- FILE *fd;
- char_u buf[VIMSPELLMAGICL];
- char_u *p;
- int i;
- int n;
- int len;
- char_u *save_sourcing_name = sourcing_name;
- linenr_T save_sourcing_lnum = sourcing_lnum;
- slang_T *lp = NULL;
- int c = 0;
- int res;
-
- fd = mch_fopen((char *)fname, "r");
- if (fd == NULL) {
- if (!silent)
- EMSG2(_(e_notopen), fname);
- else if (p_verbose > 2) {
- verbose_enter();
- smsg((char *)e_notopen, fname);
- verbose_leave();
- }
- goto endFAIL;
- }
- if (p_verbose > 2) {
- verbose_enter();
- smsg(_("Reading spell file \"%s\""), fname);
- verbose_leave();
- }
-
- if (old_lp == NULL) {
- lp = slang_alloc(lang);
-
- // Remember the file name, used to reload the file when it's updated.
- lp->sl_fname = vim_strsave(fname);
-
- // Check for .add.spl.
- lp->sl_add = strstr((char *)path_tail(fname), SPL_FNAME_ADD) != NULL;
- } else
- lp = old_lp;
-
- // Set sourcing_name, so that error messages mention the file name.
- sourcing_name = fname;
- sourcing_lnum = 0;
-
- // <HEADER>: <fileID>
- for (i = 0; i < VIMSPELLMAGICL; ++i)
- buf[i] = getc(fd); // <fileID>
- if (STRNCMP(buf, VIMSPELLMAGIC, VIMSPELLMAGICL) != 0) {
- EMSG(_("E757: This does not look like a spell file"));
- goto endFAIL;
- }
- c = getc(fd); // <versionnr>
- if (c < VIMSPELLVERSION) {
- EMSG(_("E771: Old spell file, needs to be updated"));
- goto endFAIL;
- } else if (c > VIMSPELLVERSION) {
- EMSG(_("E772: Spell file is for newer version of Vim"));
- goto endFAIL;
- }
-
-
- // <SECTIONS>: <section> ... <sectionend>
- // <section>: <sectionID> <sectionflags> <sectionlen> (section contents)
- for (;; ) {
- n = getc(fd); // <sectionID> or <sectionend>
- if (n == SN_END)
- break;
- c = getc(fd); // <sectionflags>
- len = get4c(fd); // <sectionlen>
- if (len < 0)
- goto truncerr;
-
- res = 0;
- switch (n) {
- case SN_INFO:
- lp->sl_info = READ_STRING(fd, len); // <infotext>
- if (lp->sl_info == NULL)
- goto endFAIL;
- break;
-
- case SN_REGION:
- res = read_region_section(fd, lp, len);
- break;
-
- case SN_CHARFLAGS:
- res = read_charflags_section(fd);
- break;
-
- case SN_MIDWORD:
- lp->sl_midword = READ_STRING(fd, len); // <midword>
- if (lp->sl_midword == NULL)
- goto endFAIL;
- break;
-
- case SN_PREFCOND:
- res = read_prefcond_section(fd, lp);
- break;
-
- case SN_REP:
- res = read_rep_section(fd, &lp->sl_rep, lp->sl_rep_first);
- break;
-
- case SN_REPSAL:
- res = read_rep_section(fd, &lp->sl_repsal, lp->sl_repsal_first);
- break;
-
- case SN_SAL:
- res = read_sal_section(fd, lp);
- break;
-
- case SN_SOFO:
- res = read_sofo_section(fd, lp);
- break;
-
- case SN_MAP:
- p = READ_STRING(fd, len); // <mapstr>
- if (p == NULL)
- goto endFAIL;
- set_map_str(lp, p);
- xfree(p);
- break;
-
- case SN_WORDS:
- res = read_words_section(fd, lp, len);
- break;
-
- case SN_SUGFILE:
- lp->sl_sugtime = get8ctime(fd); // <timestamp>
- break;
-
- case SN_NOSPLITSUGS:
- lp->sl_nosplitsugs = true;
- break;
-
- case SN_NOCOMPOUNDSUGS:
- lp->sl_nocompoundsugs = true;
- break;
-
- case SN_COMPOUND:
- res = read_compound(fd, lp, len);
- break;
-
- case SN_NOBREAK:
- lp->sl_nobreak = true;
- break;
-
- case SN_SYLLABLE:
- lp->sl_syllable = READ_STRING(fd, len); // <syllable>
- if (lp->sl_syllable == NULL)
- goto endFAIL;
- if (init_syl_tab(lp) == FAIL)
- goto endFAIL;
- break;
-
- default:
- // Unsupported section. When it's required give an error
- // message. When it's not required skip the contents.
- if (c & SNF_REQUIRED) {
- EMSG(_("E770: Unsupported section in spell file"));
- goto endFAIL;
- }
- while (--len >= 0)
- if (getc(fd) < 0)
- goto truncerr;
- break;
- }
-someerror:
- if (res == SP_FORMERROR) {
- EMSG(_(e_format));
- goto endFAIL;
- }
- if (res == SP_TRUNCERROR) {
-truncerr:
- EMSG(_(e_spell_trunc));
- goto endFAIL;
- }
- if (res == SP_OTHERERROR)
- goto endFAIL;
- }
-
- // <LWORDTREE>
- res = spell_read_tree(fd, &lp->sl_fbyts, &lp->sl_fidxs, false, 0);
- if (res != 0)
- goto someerror;
-
- // <KWORDTREE>
- res = spell_read_tree(fd, &lp->sl_kbyts, &lp->sl_kidxs, false, 0);
- if (res != 0)
- goto someerror;
-
- // <PREFIXTREE>
- res = spell_read_tree(fd, &lp->sl_pbyts, &lp->sl_pidxs, true,
- lp->sl_prefixcnt);
- if (res != 0)
- goto someerror;
-
- // For a new file link it in the list of spell files.
- if (old_lp == NULL && lang != NULL) {
- lp->sl_next = first_lang;
- first_lang = lp;
- }
-
- goto endOK;
-
-endFAIL:
- if (lang != NULL)
- // truncating the name signals the error to spell_load_lang()
- *lang = NUL;
- if (lp != NULL && old_lp == NULL)
- slang_free(lp);
- lp = NULL;
-
-endOK:
- if (fd != NULL)
- fclose(fd);
- sourcing_name = save_sourcing_name;
- sourcing_lnum = save_sourcing_lnum;
-
- return lp;
-}
-
-// Read a length field from "fd" in "cnt_bytes" bytes.
-// Allocate memory, read the string into it and add a NUL at the end.
-// Returns NULL when the count is zero.
-// Sets "*cntp" to SP_*ERROR when there is an error, length of the result
-// otherwise.
-static char_u *read_cnt_string(FILE *fd, int cnt_bytes, int *cntp)
-{
- int cnt = 0;
- int i;
- char_u *str;
-
- // read the length bytes, MSB first
- for (i = 0; i < cnt_bytes; ++i)
- cnt = (cnt << 8) + getc(fd);
- if (cnt < 0) {
- *cntp = SP_TRUNCERROR;
- return NULL;
- }
- *cntp = cnt;
- if (cnt == 0)
- return NULL; // nothing to read, return NULL
-
- str = READ_STRING(fd, cnt);
- if (str == NULL)
- *cntp = SP_OTHERERROR;
- return str;
-}
-
-// Read SN_REGION: <regionname> ...
-// Return SP_*ERROR flags.
-static int read_region_section(FILE *fd, slang_T *lp, int len)
-{
- int i;
-
- if (len > 16)
- return SP_FORMERROR;
- for (i = 0; i < len; ++i)
- lp->sl_regions[i] = getc(fd); // <regionname>
- lp->sl_regions[len] = NUL;
- return 0;
-}
-
-// Read SN_CHARFLAGS section: <charflagslen> <charflags>
-// <folcharslen> <folchars>
-// Return SP_*ERROR flags.
-static int read_charflags_section(FILE *fd)
-{
- char_u *flags;
- char_u *fol;
- int flagslen, follen;
-
- // <charflagslen> <charflags>
- flags = read_cnt_string(fd, 1, &flagslen);
- if (flagslen < 0)
- return flagslen;
-
- // <folcharslen> <folchars>
- fol = read_cnt_string(fd, 2, &follen);
- if (follen < 0) {
- xfree(flags);
- return follen;
- }
-
- // Set the word-char flags and fill SPELL_ISUPPER() table.
- if (flags != NULL && fol != NULL)
- set_spell_charflags(flags, flagslen, fol);
-
- xfree(flags);
- xfree(fol);
-
- // When <charflagslen> is zero then <fcharlen> must also be zero.
- if ((flags == NULL) != (fol == NULL))
- return SP_FORMERROR;
- return 0;
-}
-
-// Read SN_PREFCOND section.
-// Return SP_*ERROR flags.
-static int read_prefcond_section(FILE *fd, slang_T *lp)
-{
- int cnt;
- int i;
- int n;
- char_u *p;
- char_u buf[MAXWLEN + 1];
-
- // <prefcondcnt> <prefcond> ...
- cnt = get2c(fd); // <prefcondcnt>
- if (cnt <= 0)
- return SP_FORMERROR;
-
- lp->sl_prefprog = xcalloc(cnt, sizeof(regprog_T *));
- lp->sl_prefixcnt = cnt;
-
- for (i = 0; i < cnt; ++i) {
- // <prefcond> : <condlen> <condstr>
- n = getc(fd); // <condlen>
- if (n < 0 || n >= MAXWLEN)
- return SP_FORMERROR;
-
- // When <condlen> is zero we have an empty condition. Otherwise
- // compile the regexp program used to check for the condition.
- if (n > 0) {
- buf[0] = '^'; // always match at one position only
- p = buf + 1;
- while (n-- > 0)
- *p++ = getc(fd); // <condstr>
- *p = NUL;
- lp->sl_prefprog[i] = vim_regcomp(buf, RE_MAGIC + RE_STRING);
- }
- }
- return 0;
-}
-
-// Read REP or REPSAL items section from "fd": <repcount> <rep> ...
-// Return SP_*ERROR flags.
-static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first)
-{
- int cnt;
- fromto_T *ftp;
-
- cnt = get2c(fd); // <repcount>
- if (cnt < 0)
- return SP_TRUNCERROR;
-
- ga_grow(gap, cnt);
-
- // <rep> : <repfromlen> <repfrom> <reptolen> <repto>
- for (; gap->ga_len < cnt; ++gap->ga_len) {
- int c;
- ftp = &((fromto_T *)gap->ga_data)[gap->ga_len];
- ftp->ft_from = read_cnt_string(fd, 1, &c);
- if (c < 0)
- return c;
- if (c == 0)
- return SP_FORMERROR;
- ftp->ft_to = read_cnt_string(fd, 1, &c);
- if (c <= 0) {
- xfree(ftp->ft_from);
- if (c < 0)
- return c;
- return SP_FORMERROR;
- }
- }
-
- // Fill the first-index table.
- for (int i = 0; i < 256; ++i) {
- first[i] = -1;
- }
- for (int i = 0; i < gap->ga_len; ++i) {
- ftp = &((fromto_T *)gap->ga_data)[i];
- if (first[*ftp->ft_from] == -1)
- first[*ftp->ft_from] = i;
- }
- return 0;
-}
-
-// Read SN_SAL section: <salflags> <salcount> <sal> ...
-// Return SP_*ERROR flags.
-static int read_sal_section(FILE *fd, slang_T *slang)
-{
- int i;
- int cnt;
- garray_T *gap;
- salitem_T *smp;
- int ccnt;
- char_u *p;
- int c = NUL;
-
- slang->sl_sofo = false;
-
- i = getc(fd); // <salflags>
- if (i & SAL_F0LLOWUP)
- slang->sl_followup = true;
- if (i & SAL_COLLAPSE)
- slang->sl_collapse = true;
- if (i & SAL_REM_ACCENTS)
- slang->sl_rem_accents = true;
-
- cnt = get2c(fd); // <salcount>
- if (cnt < 0)
- return SP_TRUNCERROR;
-
- gap = &slang->sl_sal;
- ga_init(gap, sizeof(salitem_T), 10);
- ga_grow(gap, cnt + 1);
-
- // <sal> : <salfromlen> <salfrom> <saltolen> <salto>
- for (; gap->ga_len < cnt; ++gap->ga_len) {
- smp = &((salitem_T *)gap->ga_data)[gap->ga_len];
- ccnt = getc(fd); // <salfromlen>
- if (ccnt < 0)
- return SP_TRUNCERROR;
- p = xmalloc(ccnt + 2);
- smp->sm_lead = p;
-
- // Read up to the first special char into sm_lead.
- for (i = 0; i < ccnt; ++i) {
- c = getc(fd); // <salfrom>
- if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL)
- break;
- *p++ = c;
- }
- smp->sm_leadlen = (int)(p - smp->sm_lead);
- *p++ = NUL;
-
- // Put (abc) chars in sm_oneof, if any.
- if (c == '(') {
- smp->sm_oneof = p;
- for (++i; i < ccnt; ++i) {
- c = getc(fd); // <salfrom>
- if (c == ')')
- break;
- *p++ = c;
- }
- *p++ = NUL;
- if (++i < ccnt)
- c = getc(fd);
- } else
- smp->sm_oneof = NULL;
-
- // Any following chars go in sm_rules.
- smp->sm_rules = p;
- if (i < ccnt)
- // store the char we got while checking for end of sm_lead
- *p++ = c;
- for (++i; i < ccnt; ++i)
- *p++ = getc(fd); // <salfrom>
- *p++ = NUL;
-
- // <saltolen> <salto>
- smp->sm_to = read_cnt_string(fd, 1, &ccnt);
- if (ccnt < 0) {
- xfree(smp->sm_lead);
- return ccnt;
- }
-
- if (has_mbyte) {
- // convert the multi-byte strings to wide char strings
- smp->sm_lead_w = mb_str2wide(smp->sm_lead);
- smp->sm_leadlen = mb_charlen(smp->sm_lead);
- if (smp->sm_oneof == NULL)
- smp->sm_oneof_w = NULL;
- else
- smp->sm_oneof_w = mb_str2wide(smp->sm_oneof);
- if (smp->sm_to == NULL)
- smp->sm_to_w = NULL;
- else
- smp->sm_to_w = mb_str2wide(smp->sm_to);
- }
- }
-
- if (!GA_EMPTY(gap)) {
- // Add one extra entry to mark the end with an empty sm_lead. Avoids
- // that we need to check the index every time.
- smp = &((salitem_T *)gap->ga_data)[gap->ga_len];
- p = xmalloc(1);
- p[0] = NUL;
- smp->sm_lead = p;
- smp->sm_leadlen = 0;
- smp->sm_oneof = NULL;
- smp->sm_rules = p;
- smp->sm_to = NULL;
- if (has_mbyte) {
- smp->sm_lead_w = mb_str2wide(smp->sm_lead);
- smp->sm_leadlen = 0;
- smp->sm_oneof_w = NULL;
- smp->sm_to_w = NULL;
- }
- ++gap->ga_len;
- }
-
- // Fill the first-index table.
- set_sal_first(slang);
-
- return 0;
-}
-
-// Read SN_WORDS: <word> ...
-// Return SP_*ERROR flags.
-static int read_words_section(FILE *fd, slang_T *lp, int len)
-{
- int done = 0;
- int i;
- int c;
- char_u word[MAXWLEN];
-
- while (done < len) {
- // Read one word at a time.
- for (i = 0;; ++i) {
- c = getc(fd);
- if (c == EOF)
- return SP_TRUNCERROR;
- word[i] = c;
- if (word[i] == NUL)
- break;
- if (i == MAXWLEN - 1)
- return SP_FORMERROR;
- }
-
- // Init the count to 10.
- count_common_word(lp, word, -1, 10);
- done += i + 1;
- }
- return 0;
-}
-
-// Add a word to the hashtable of common words.
-// If it's already there then the counter is increased.
-static void
-count_common_word (
- slang_T *lp,
- char_u *word,
- int len, // word length, -1 for upto NUL
- int count // 1 to count once, 10 to init
-)
+/// Add a word to the hashtable of common words.
+/// If it's already there then the counter is increased.
+///
+/// @param[in] lp
+/// @param[in] word added to common words hashtable
+/// @param[in] len length of word or -1 for NUL terminated
+/// @param[in] count 1 to count once, 10 to init
+void count_common_word(slang_T *lp, char_u *word, int len, int count)
{
hash_T hash;
hashitem_T *hi;
@@ -3092,10 +1820,11 @@ count_common_word (
}
hash = hash_hash(p);
- hi = hash_lookup(&lp->sl_wordcount, p, hash);
+ const size_t p_len = STRLEN(p);
+ hi = hash_lookup(&lp->sl_wordcount, (const char *)p, p_len, hash);
if (HASHITEM_EMPTY(hi)) {
- wc = xmalloc(sizeof(wordcount_T) + STRLEN(p));
- STRCPY(wc->wc_word, p);
+ wc = xmalloc(sizeof(wordcount_T) + p_len);
+ memcpy(wc->wc_word, p, p_len + 1);
wc->wc_count = count;
hash_add_item(&lp->sl_wordcount, hi, wc->wc_word, hash);
} else {
@@ -3139,209 +1868,9 @@ score_wordcount_adj (
return score;
}
-// SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
-// Return SP_*ERROR flags.
-static int read_sofo_section(FILE *fd, slang_T *slang)
-{
- int cnt;
- char_u *from, *to;
- int res;
-
- slang->sl_sofo = true;
-
- // <sofofromlen> <sofofrom>
- from = read_cnt_string(fd, 2, &cnt);
- if (cnt < 0)
- return cnt;
-
- // <sofotolen> <sofoto>
- to = read_cnt_string(fd, 2, &cnt);
- if (cnt < 0) {
- xfree(from);
- return cnt;
- }
-
- // Store the info in slang->sl_sal and/or slang->sl_sal_first.
- if (from != NULL && to != NULL)
- res = set_sofo(slang, from, to);
- else if (from != NULL || to != NULL)
- res = SP_FORMERROR; // only one of two strings is an error
- else
- res = 0;
-
- xfree(from);
- xfree(to);
- return res;
-}
-
-// Read the compound section from the .spl file:
-// <compmax> <compminlen> <compsylmax> <compoptions> <compflags>
-// Returns SP_*ERROR flags.
-static int read_compound(FILE *fd, slang_T *slang, int len)
-{
- int todo = len;
- int c;
- int atstart;
- char_u *pat;
- char_u *pp;
- char_u *cp;
- char_u *ap;
- char_u *crp;
- int cnt;
- garray_T *gap;
-
- if (todo < 2)
- return SP_FORMERROR; // need at least two bytes
-
- --todo;
- c = getc(fd); // <compmax>
- if (c < 2)
- c = MAXWLEN;
- slang->sl_compmax = c;
-
- --todo;
- c = getc(fd); // <compminlen>
- if (c < 1)
- c = 0;
- slang->sl_compminlen = c;
-
- --todo;
- c = getc(fd); // <compsylmax>
- if (c < 1)
- c = MAXWLEN;
- slang->sl_compsylmax = c;
-
- c = getc(fd); // <compoptions>
- if (c != 0)
- ungetc(c, fd); // be backwards compatible with Vim 7.0b
- else {
- --todo;
- c = getc(fd); // only use the lower byte for now
- --todo;
- slang->sl_compoptions = c;
-
- gap = &slang->sl_comppat;
- c = get2c(fd); // <comppatcount>
- todo -= 2;
- ga_init(gap, sizeof(char_u *), c);
- ga_grow(gap, c);
- while (--c >= 0) {
- ((char_u **)(gap->ga_data))[gap->ga_len++] =
- read_cnt_string(fd, 1, &cnt);
- // <comppatlen> <comppattext>
- if (cnt < 0)
- return cnt;
- todo -= cnt + 1;
- }
- }
- if (todo < 0)
- return SP_FORMERROR;
-
- // Turn the COMPOUNDRULE items into a regexp pattern:
- // "a[bc]/a*b+" -> "^\(a[bc]\|a*b\+\)$".
- // Inserting backslashes may double the length, "^\(\)$<Nul>" is 7 bytes.
- // Conversion to utf-8 may double the size.
- c = todo * 2 + 7;
- if (enc_utf8)
- c += todo * 2;
- pat = xmalloc(c);
-
- // We also need a list of all flags that can appear at the start and one
- // for all flags.
- cp = xmalloc(todo + 1);
- slang->sl_compstartflags = cp;
- *cp = NUL;
-
- ap = xmalloc(todo + 1);
- slang->sl_compallflags = ap;
- *ap = NUL;
-
- // And a list of all patterns in their original form, for checking whether
- // compounding may work in match_compoundrule(). This is freed when we
- // encounter a wildcard, the check doesn't work then.
- crp = xmalloc(todo + 1);
- slang->sl_comprules = crp;
-
- pp = pat;
- *pp++ = '^';
- *pp++ = '\\';
- *pp++ = '(';
-
- atstart = 1;
- while (todo-- > 0) {
- c = getc(fd); // <compflags>
- if (c == EOF) {
- xfree(pat);
- return SP_TRUNCERROR;
- }
-
- // Add all flags to "sl_compallflags".
- if (vim_strchr((char_u *)"?*+[]/", c) == NULL
- && !byte_in_str(slang->sl_compallflags, c)) {
- *ap++ = c;
- *ap = NUL;
- }
-
- if (atstart != 0) {
- // At start of item: copy flags to "sl_compstartflags". For a
- // [abc] item set "atstart" to 2 and copy up to the ']'.
- if (c == '[')
- atstart = 2;
- else if (c == ']')
- atstart = 0;
- else {
- if (!byte_in_str(slang->sl_compstartflags, c)) {
- *cp++ = c;
- *cp = NUL;
- }
- if (atstart == 1)
- atstart = 0;
- }
- }
-
- // Copy flag to "sl_comprules", unless we run into a wildcard.
- if (crp != NULL) {
- if (c == '?' || c == '+' || c == '*') {
- xfree(slang->sl_comprules);
- slang->sl_comprules = NULL;
- crp = NULL;
- } else
- *crp++ = c;
- }
-
- if (c == '/') { // slash separates two items
- *pp++ = '\\';
- *pp++ = '|';
- atstart = 1;
- } else { // normal char, "[abc]" and '*' are copied as-is
- if (c == '?' || c == '+' || c == '~')
- *pp++ = '\\'; // "a?" becomes "a\?", "a+" becomes "a\+"
- if (enc_utf8)
- pp += mb_char2bytes(c, pp);
- else
- *pp++ = c;
- }
- }
-
- *pp++ = '\\';
- *pp++ = ')';
- *pp++ = '$';
- *pp = NUL;
-
- if (crp != NULL)
- *crp = NUL;
-
- slang->sl_compprog = vim_regcomp(pat, RE_MAGIC + RE_STRING + RE_STRICT);
- xfree(pat);
- if (slang->sl_compprog == NULL)
- return SP_FORMERROR;
-
- return 0;
-}
-
// Returns true if byte "n" appears in "str".
// Like strchr() but independent of locale.
-static bool byte_in_str(char_u *str, int n)
+bool byte_in_str(char_u *str, int n)
{
char_u *p;
@@ -3353,7 +1882,7 @@ static bool byte_in_str(char_u *str, int n)
// Truncate "slang->sl_syllable" at the first slash and put the following items
// in "slang->sl_syl_items".
-static int init_syl_tab(slang_T *slang)
+int init_syl_tab(slang_T *slang)
{
char_u *p;
char_u *s;
@@ -3430,294 +1959,6 @@ static int count_syllables(slang_T *slang, char_u *word)
return cnt;
}
-// Set the SOFOFROM and SOFOTO items in language "lp".
-// Returns SP_*ERROR flags when there is something wrong.
-static int set_sofo(slang_T *lp, char_u *from, char_u *to)
-{
- int i;
-
- garray_T *gap;
- char_u *s;
- char_u *p;
- int c;
- int *inp;
-
- if (has_mbyte) {
- // Use "sl_sal" as an array with 256 pointers to a list of wide
- // characters. The index is the low byte of the character.
- // The list contains from-to pairs with a terminating NUL.
- // sl_sal_first[] is used for latin1 "from" characters.
- gap = &lp->sl_sal;
- ga_init(gap, sizeof(int *), 1);
- ga_grow(gap, 256);
- memset(gap->ga_data, 0, sizeof(int *) * 256);
- gap->ga_len = 256;
-
- // First count the number of items for each list. Temporarily use
- // sl_sal_first[] for this.
- for (p = from, s = to; *p != NUL && *s != NUL; ) {
- c = mb_cptr2char_adv(&p);
- mb_cptr_adv(s);
- if (c >= 256)
- ++lp->sl_sal_first[c & 0xff];
- }
- if (*p != NUL || *s != NUL) // lengths differ
- return SP_FORMERROR;
-
- // Allocate the lists.
- for (i = 0; i < 256; ++i)
- if (lp->sl_sal_first[i] > 0) {
- p = xmalloc(sizeof(int) * (lp->sl_sal_first[i] * 2 + 1));
- ((int **)gap->ga_data)[i] = (int *)p;
- *(int *)p = 0;
- }
-
- // Put the characters up to 255 in sl_sal_first[] the rest in a sl_sal
- // list.
- memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256);
- for (p = from, s = to; *p != NUL && *s != NUL; ) {
- c = mb_cptr2char_adv(&p);
- i = mb_cptr2char_adv(&s);
- if (c >= 256) {
- // Append the from-to chars at the end of the list with
- // the low byte.
- inp = ((int **)gap->ga_data)[c & 0xff];
- while (*inp != 0)
- ++inp;
- *inp++ = c; // from char
- *inp++ = i; // to char
- *inp++ = NUL; // NUL at the end
- } else
- // mapping byte to char is done in sl_sal_first[]
- lp->sl_sal_first[c] = i;
- }
- } else {
- // mapping bytes to bytes is done in sl_sal_first[]
- if (STRLEN(from) != STRLEN(to))
- return SP_FORMERROR;
-
- for (i = 0; to[i] != NUL; ++i)
- lp->sl_sal_first[from[i]] = to[i];
- lp->sl_sal.ga_len = 1; // indicates we have soundfolding
- }
-
- return 0;
-}
-
-// Fill the first-index table for "lp".
-static void set_sal_first(slang_T *lp)
-{
- salfirst_T *sfirst;
- salitem_T *smp;
- int c;
- garray_T *gap = &lp->sl_sal;
-
- sfirst = lp->sl_sal_first;
- for (int i = 0; i < 256; ++i) {
- sfirst[i] = -1;
- }
- smp = (salitem_T *)gap->ga_data;
- for (int i = 0; i < gap->ga_len; ++i) {
- if (has_mbyte)
- // Use the lowest byte of the first character. For latin1 it's
- // the character, for other encodings it should differ for most
- // characters.
- c = *smp[i].sm_lead_w & 0xff;
- else
- c = *smp[i].sm_lead;
- if (sfirst[c] == -1) {
- sfirst[c] = i;
- if (has_mbyte) {
- int n;
-
- // Make sure all entries with this byte are following each
- // other. Move the ones that are in the wrong position. Do
- // keep the same ordering!
- while (i + 1 < gap->ga_len
- && (*smp[i + 1].sm_lead_w & 0xff) == c)
- // Skip over entry with same index byte.
- ++i;
-
- for (n = 1; i + n < gap->ga_len; ++n)
- if ((*smp[i + n].sm_lead_w & 0xff) == c) {
- salitem_T tsal;
-
- // Move entry with same index byte after the entries
- // we already found.
- ++i;
- --n;
- tsal = smp[i + n];
- memmove(smp + i + 1, smp + i,
- sizeof(salitem_T) * n);
- smp[i] = tsal;
- }
- }
- }
- }
-}
-
-// Turn a multi-byte string into a wide character string.
-// Return it in allocated memory.
-static int *mb_str2wide(char_u *s)
-{
- int i = 0;
-
- int *res = xmalloc((mb_charlen(s) + 1) * sizeof(int));
- for (char_u *p = s; *p != NUL; )
- res[i++] = mb_ptr2char_adv(&p);
- res[i] = NUL;
-
- return res;
-}
-
-// Reads a tree from the .spl or .sug file.
-// Allocates the memory and stores pointers in "bytsp" and "idxsp".
-// This is skipped when the tree has zero length.
-// Returns zero when OK, SP_ value for an error.
-static int
-spell_read_tree (
- FILE *fd,
- char_u **bytsp,
- idx_T **idxsp,
- bool prefixtree, // true for the prefix tree
- int prefixcnt // when "prefixtree" is true: prefix count
-)
-{
- int idx;
- char_u *bp;
- idx_T *ip;
-
- // The tree size was computed when writing the file, so that we can
- // allocate it as one long block. <nodecount>
- int len = get4c(fd);
- if (len < 0)
- return SP_TRUNCERROR;
- if (len > 0) {
- // Allocate the byte array.
- bp = xmalloc(len);
- *bytsp = bp;
-
- // Allocate the index array.
- ip = xcalloc(len, sizeof(*ip));
- *idxsp = ip;
-
- // Recursively read the tree and store it in the array.
- idx = read_tree_node(fd, bp, ip, len, 0, prefixtree, prefixcnt);
- if (idx < 0)
- return idx;
- }
- return 0;
-}
-
-// Read one row of siblings from the spell file and store it in the byte array
-// "byts" and index array "idxs". Recursively read the children.
-//
-// NOTE: The code here must match put_node()!
-//
-// Returns the index (>= 0) following the siblings.
-// Returns SP_TRUNCERROR if the file is shorter than expected.
-// Returns SP_FORMERROR if there is a format error.
-static idx_T
-read_tree_node (
- FILE *fd,
- char_u *byts,
- idx_T *idxs,
- int maxidx, // size of arrays
- idx_T startidx, // current index in "byts" and "idxs"
- bool prefixtree, // true for reading PREFIXTREE
- int maxprefcondnr // maximum for <prefcondnr>
-)
-{
- int len;
- int i;
- int n;
- idx_T idx = startidx;
- int c;
- int c2;
-#define SHARED_MASK 0x8000000
-
- len = getc(fd); // <siblingcount>
- if (len <= 0)
- return SP_TRUNCERROR;
-
- if (startidx + len >= maxidx)
- return SP_FORMERROR;
- byts[idx++] = len;
-
- // Read the byte values, flag/region bytes and shared indexes.
- for (i = 1; i <= len; ++i) {
- c = getc(fd); // <byte>
- if (c < 0)
- return SP_TRUNCERROR;
- if (c <= BY_SPECIAL) {
- if (c == BY_NOFLAGS && !prefixtree) {
- // No flags, all regions.
- idxs[idx] = 0;
- c = 0;
- } else if (c != BY_INDEX) {
- if (prefixtree) {
- // Read the optional pflags byte, the prefix ID and the
- // condition nr. In idxs[] store the prefix ID in the low
- // byte, the condition index shifted up 8 bits, the flags
- // shifted up 24 bits.
- if (c == BY_FLAGS)
- c = getc(fd) << 24; // <pflags>
- else
- c = 0;
-
- c |= getc(fd); // <affixID>
-
- n = get2c(fd); // <prefcondnr>
- if (n >= maxprefcondnr)
- return SP_FORMERROR;
- c |= (n << 8);
- } else { // c must be BY_FLAGS or BY_FLAGS2
- // Read flags and optional region and prefix ID. In
- // idxs[] the flags go in the low two bytes, region above
- // that and prefix ID above the region.
- c2 = c;
- c = getc(fd); // <flags>
- if (c2 == BY_FLAGS2)
- c = (getc(fd) << 8) + c; // <flags2>
- if (c & WF_REGION)
- c = (getc(fd) << 16) + c; // <region>
- if (c & WF_AFX)
- c = (getc(fd) << 24) + c; // <affixID>
- }
-
- idxs[idx] = c;
- c = 0;
- } else { // c == BY_INDEX
- // <nodeidx>
- n = get3c(fd);
- if (n < 0 || n >= maxidx)
- return SP_FORMERROR;
- idxs[idx] = n + SHARED_MASK;
- c = getc(fd); // <xbyte>
- }
- }
- byts[idx++] = c;
- }
-
- // Recursively read the children for non-shared siblings.
- // Skip the end-of-word ones (zero byte value) and the shared ones (and
- // remove SHARED_MASK)
- for (i = 1; i <= len; ++i)
- if (byts[startidx + i] != 0) {
- if (idxs[startidx + i] & SHARED_MASK)
- idxs[startidx + i] &= ~SHARED_MASK;
- else {
- idxs[startidx + i] = idx;
- idx = read_tree_node(fd, byts, idxs, maxidx, idx,
- prefixtree, maxprefcondnr);
- if (idx < 0)
- break;
- }
- }
-
- return idx;
-}
-
// Parse 'spelllang' and set w_s->b_langp accordingly.
// Returns NULL if it's OK, an error message otherwise.
char_u *did_set_spelllang(win_T *wp)
@@ -3744,6 +1985,9 @@ char_u *did_set_spelllang(win_T *wp)
char_u *ret_msg = NULL;
char_u *spl_copy;
+ bufref_T bufref;
+ set_bufref(&bufref, wp->w_buffer);
+
// We don't want to do this recursively. May happen when a language is
// not available and the SpellFileMissing autocommand opens a new buffer
// in which 'spell' is set.
@@ -3822,9 +2066,9 @@ char_u *did_set_spelllang(win_T *wp)
spell_load_lang(lang);
// SpellFileMissing autocommands may do anything, including
// destroying the buffer we are using...
- if (!buf_valid(wp->w_buffer)) {
+ if (!bufref_valid(&bufref)) {
ret_msg =
- (char_u *)"E797: SpellFileMissing autocommand deleted buffer";
+ (char_u *)N_("E797: SpellFileMissing autocommand deleted buffer");
goto theend;
}
}
@@ -4045,16 +2289,17 @@ static int find_region(char_u *rp, char_u *region)
return i / 2;
}
-// Return case type of word:
-// w word 0
-// Word WF_ONECAP
-// W WORD WF_ALLCAP
-// WoRd wOrd WF_KEEPCAP
-static int
-captype (
- char_u *word,
- char_u *end // When NULL use up to NUL byte.
-)
+/// Return case type of word:
+/// w word 0
+/// Word WF_ONECAP
+/// W WORD WF_ALLCAP
+/// WoRd wOrd WF_KEEPCAP
+///
+/// @param[in] word
+/// @param[in] end End of word or NULL for NUL delimited string
+///
+/// @returns Case type of word
+int captype(char_u *word, char_u *end)
{
char_u *p;
int c;
@@ -4066,10 +2311,11 @@ captype (
for (p = word; !spell_iswordp_nmw(p, curwin); mb_ptr_adv(p))
if (end == NULL ? *p == NUL : p >= end)
return 0; // only non-word characters, illegal word
- if (has_mbyte)
- c = mb_ptr2char_adv(&p);
- else
+ if (has_mbyte) {
+ c = mb_ptr2char_adv((const char_u **)&p);
+ } else {
c = *p++;
+ }
firstcap = allcap = SPELL_ISUPPER(c);
// Need to check all letters to find a word with mixed upper/lower.
@@ -4196,3221 +2442,6 @@ void spell_reload(void)
}
}
-// Reload the spell file "fname" if it's loaded.
-static void
-spell_reload_one (
- char_u *fname,
- bool added_word // invoked through "zg"
-)
-{
- slang_T *slang;
- bool didit = false;
-
- for (slang = first_lang; slang != NULL; slang = slang->sl_next) {
- if (path_full_compare(fname, slang->sl_fname, FALSE) == kEqualFiles) {
- slang_clear(slang);
- if (spell_load_file(fname, NULL, slang, false) == NULL)
- // reloading failed, clear the language
- slang_clear(slang);
- redraw_all_later(SOME_VALID);
- didit = true;
- }
- }
-
- // When "zg" was used and the file wasn't loaded yet, should redo
- // 'spelllang' to load it now.
- if (added_word && !didit)
- did_set_spelllang(curwin);
-}
-
-
-// Functions for ":mkspell".
-
-
-// In the postponed prefixes tree wn_flags is used to store the WFP_ flags,
-// but it must be negative to indicate the prefix tree to tree_add_word().
-// Use a negative number with the lower 8 bits zero.
-#define PFX_FLAGS -256
-
-// flags for "condit" argument of store_aff_word()
-#define CONDIT_COMB 1 // affix must combine
-#define CONDIT_CFIX 2 // affix must have CIRCUMFIX flag
-#define CONDIT_SUF 4 // add a suffix for matching flags
-#define CONDIT_AFF 8 // word already has an affix
-
-// Tunable parameters for when the tree is compressed. See 'mkspellmem'.
-static long compress_start = 30000; // memory / SBLOCKSIZE
-static long compress_inc = 100; // memory / SBLOCKSIZE
-static long compress_added = 500000; // word count
-
-#ifdef SPELL_PRINTTREE
-// For debugging the tree code: print the current tree in a (more or less)
-// readable format, so that we can see what happens when adding a word and/or
-// compressing the tree.
-// Based on code from Olaf Seibert.
-#define PRINTLINESIZE 1000
-#define PRINTWIDTH 6
-
-#define PRINTSOME(l, depth, fmt, a1, a2) vim_snprintf(l + depth * PRINTWIDTH, \
- PRINTLINESIZE - PRINTWIDTH * depth, fmt, a1, a2)
-
-static char line1[PRINTLINESIZE];
-static char line2[PRINTLINESIZE];
-static char line3[PRINTLINESIZE];
-
-static void spell_clear_flags(wordnode_T *node)
-{
- wordnode_T *np;
-
- for (np = node; np != NULL; np = np->wn_sibling) {
- np->wn_u1.index = FALSE;
- spell_clear_flags(np->wn_child);
- }
-}
-
-static void spell_print_node(wordnode_T *node, int depth)
-{
- if (node->wn_u1.index) {
- // Done this node before, print the reference.
- PRINTSOME(line1, depth, "(%d)", node->wn_nr, 0);
- PRINTSOME(line2, depth, " ", 0, 0);
- PRINTSOME(line3, depth, " ", 0, 0);
- msg((char_u *)line1);
- msg((char_u *)line2);
- msg((char_u *)line3);
- } else {
- node->wn_u1.index = TRUE;
-
- if (node->wn_byte != NUL) {
- if (node->wn_child != NULL)
- PRINTSOME(line1, depth, " %c -> ", node->wn_byte, 0);
- else
- // Cannot happen?
- PRINTSOME(line1, depth, " %c ???", node->wn_byte, 0);
- } else
- PRINTSOME(line1, depth, " $ ", 0, 0);
-
- PRINTSOME(line2, depth, "%d/%d ", node->wn_nr, node->wn_refs);
-
- if (node->wn_sibling != NULL)
- PRINTSOME(line3, depth, " | ", 0, 0);
- else
- PRINTSOME(line3, depth, " ", 0, 0);
-
- if (node->wn_byte == NUL) {
- msg((char_u *)line1);
- msg((char_u *)line2);
- msg((char_u *)line3);
- }
-
- // do the children
- if (node->wn_byte != NUL && node->wn_child != NULL)
- spell_print_node(node->wn_child, depth + 1);
-
- // do the siblings
- if (node->wn_sibling != NULL) {
- // get rid of all parent details except |
- STRCPY(line1, line3);
- STRCPY(line2, line3);
- spell_print_node(node->wn_sibling, depth);
- }
- }
-}
-
-static void spell_print_tree(wordnode_T *root)
-{
- if (root != NULL) {
- // Clear the "wn_u1.index" fields, used to remember what has been
- // done.
- spell_clear_flags(root);
-
- // Recursively print the tree.
- spell_print_node(root, 0);
- }
-}
-
-#endif // SPELL_PRINTTREE
-
-// Reads the affix file "fname".
-// Returns an afffile_T, NULL for complete failure.
-static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
-{
- FILE *fd;
- afffile_T *aff;
- char_u rline[MAXLINELEN];
- char_u *line;
- char_u *pc = NULL;
-#define MAXITEMCNT 30
- char_u *(items[MAXITEMCNT]);
- int itemcnt;
- char_u *p;
- int lnum = 0;
- affheader_T *cur_aff = NULL;
- bool did_postpone_prefix = false;
- int aff_todo = 0;
- hashtab_T *tp;
- char_u *low = NULL;
- char_u *fol = NULL;
- char_u *upp = NULL;
- int do_rep;
- int do_repsal;
- int do_sal;
- int do_mapline;
- bool found_map = false;
- hashitem_T *hi;
- int l;
- int compminlen = 0; // COMPOUNDMIN value
- int compsylmax = 0; // COMPOUNDSYLMAX value
- int compoptions = 0; // COMP_ flags
- int compmax = 0; // COMPOUNDWORDMAX value
- char_u *compflags = NULL; // COMPOUNDFLAG and COMPOUNDRULE
- // concatenated
- char_u *midword = NULL; // MIDWORD value
- char_u *syllable = NULL; // SYLLABLE value
- char_u *sofofrom = NULL; // SOFOFROM value
- char_u *sofoto = NULL; // SOFOTO value
-
- // Open the file.
- fd = mch_fopen((char *)fname, "r");
- if (fd == NULL) {
- EMSG2(_(e_notopen), fname);
- return NULL;
- }
-
- vim_snprintf((char *)IObuff, IOSIZE, _("Reading affix file %s ..."), fname);
- spell_message(spin, IObuff);
-
- // Only do REP lines when not done in another .aff file already.
- do_rep = GA_EMPTY(&spin->si_rep);
-
- // Only do REPSAL lines when not done in another .aff file already.
- do_repsal = GA_EMPTY(&spin->si_repsal);
-
- // Only do SAL lines when not done in another .aff file already.
- do_sal = GA_EMPTY(&spin->si_sal);
-
- // Only do MAP lines when not done in another .aff file already.
- do_mapline = GA_EMPTY(&spin->si_map);
-
- // Allocate and init the afffile_T structure.
- aff = (afffile_T *)getroom(spin, sizeof(afffile_T), true);
- if (aff == NULL) {
- fclose(fd);
- return NULL;
- }
- hash_init(&aff->af_pref);
- hash_init(&aff->af_suff);
- hash_init(&aff->af_comp);
-
- // Read all the lines in the file one by one.
- while (!vim_fgets(rline, MAXLINELEN, fd) && !got_int) {
- line_breakcheck();
- ++lnum;
-
- // Skip comment lines.
- if (*rline == '#')
- continue;
-
- // Convert from "SET" to 'encoding' when needed.
- xfree(pc);
- if (spin->si_conv.vc_type != CONV_NONE) {
- pc = string_convert(&spin->si_conv, rline, NULL);
- if (pc == NULL) {
- smsg(_("Conversion failure for word in %s line %d: %s"),
- fname, lnum, rline);
- continue;
- }
- line = pc;
- } else {
- pc = NULL;
- line = rline;
- }
-
- // Split the line up in white separated items. Put a NUL after each
- // item.
- itemcnt = 0;
- for (p = line;; ) {
- while (*p != NUL && *p <= ' ') // skip white space and CR/NL
- ++p;
- if (*p == NUL)
- break;
- if (itemcnt == MAXITEMCNT) // too many items
- break;
- items[itemcnt++] = p;
- // A few items have arbitrary text argument, don't split them.
- if (itemcnt == 2 && spell_info_item(items[0]))
- while (*p >= ' ' || *p == TAB) // skip until CR/NL
- ++p;
- else
- while (*p > ' ') // skip until white space or CR/NL
- ++p;
- if (*p == NUL)
- break;
- *p++ = NUL;
- }
-
- // Handle non-empty lines.
- if (itemcnt > 0) {
- if (is_aff_rule(items, itemcnt, "SET", 2) && aff->af_enc == NULL) {
- // Setup for conversion from "ENC" to 'encoding'.
- aff->af_enc = enc_canonize(items[1]);
- if (!spin->si_ascii
- && convert_setup(&spin->si_conv, aff->af_enc,
- p_enc) == FAIL)
- smsg(_("Conversion in %s not supported: from %s to %s"),
- fname, aff->af_enc, p_enc);
- spin->si_conv.vc_fail = true;
- } else if (is_aff_rule(items, itemcnt, "FLAG", 2)
- && aff->af_flagtype == AFT_CHAR) {
- if (STRCMP(items[1], "long") == 0)
- aff->af_flagtype = AFT_LONG;
- else if (STRCMP(items[1], "num") == 0)
- aff->af_flagtype = AFT_NUM;
- else if (STRCMP(items[1], "caplong") == 0)
- aff->af_flagtype = AFT_CAPLONG;
- else
- smsg(_("Invalid value for FLAG in %s line %d: %s"),
- fname, lnum, items[1]);
- if (aff->af_rare != 0
- || aff->af_keepcase != 0
- || aff->af_bad != 0
- || aff->af_needaffix != 0
- || aff->af_circumfix != 0
- || aff->af_needcomp != 0
- || aff->af_comproot != 0
- || aff->af_nosuggest != 0
- || compflags != NULL
- || aff->af_suff.ht_used > 0
- || aff->af_pref.ht_used > 0)
- smsg(_("FLAG after using flags in %s line %d: %s"),
- fname, lnum, items[1]);
- } else if (spell_info_item(items[0]) && itemcnt > 1) {
- p = (char_u *)getroom(spin,
- (spin->si_info == NULL ? 0 : STRLEN(spin->si_info))
- + STRLEN(items[0])
- + STRLEN(items[1]) + 3, false);
- if (p != NULL) {
- if (spin->si_info != NULL) {
- STRCPY(p, spin->si_info);
- STRCAT(p, "\n");
- }
- STRCAT(p, items[0]);
- STRCAT(p, " ");
- STRCAT(p, items[1]);
- spin->si_info = p;
- }
- } else if (is_aff_rule(items, itemcnt, "MIDWORD", 2)
- && midword == NULL) {
- midword = getroom_save(spin, items[1]);
- } else if (is_aff_rule(items, itemcnt, "TRY", 2)) {
- // ignored, we look in the tree for what chars may appear
- }
- // TODO: remove "RAR" later
- else if ((is_aff_rule(items, itemcnt, "RAR", 2)
- || is_aff_rule(items, itemcnt, "RARE", 2))
- && aff->af_rare == 0) {
- aff->af_rare = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- }
- // TODO: remove "KEP" later
- else if ((is_aff_rule(items, itemcnt, "KEP", 2)
- || is_aff_rule(items, itemcnt, "KEEPCASE", 2))
- && aff->af_keepcase == 0) {
- aff->af_keepcase = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- } else if ((is_aff_rule(items, itemcnt, "BAD", 2)
- || is_aff_rule(items, itemcnt, "FORBIDDENWORD", 2))
- && aff->af_bad == 0) {
- aff->af_bad = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- } else if (is_aff_rule(items, itemcnt, "NEEDAFFIX", 2)
- && aff->af_needaffix == 0) {
- aff->af_needaffix = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- } else if (is_aff_rule(items, itemcnt, "CIRCUMFIX", 2)
- && aff->af_circumfix == 0) {
- aff->af_circumfix = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- } else if (is_aff_rule(items, itemcnt, "NOSUGGEST", 2)
- && aff->af_nosuggest == 0) {
- aff->af_nosuggest = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- } else if ((is_aff_rule(items, itemcnt, "NEEDCOMPOUND", 2)
- || is_aff_rule(items, itemcnt, "ONLYINCOMPOUND", 2))
- && aff->af_needcomp == 0) {
- aff->af_needcomp = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDROOT", 2)
- && aff->af_comproot == 0) {
- aff->af_comproot = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDFORBIDFLAG", 2)
- && aff->af_compforbid == 0) {
- aff->af_compforbid = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- if (aff->af_pref.ht_used > 0)
- smsg(_("Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line %d"),
- fname, lnum);
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDPERMITFLAG", 2)
- && aff->af_comppermit == 0) {
- aff->af_comppermit = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- if (aff->af_pref.ht_used > 0)
- smsg(_("Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line %d"),
- fname, lnum);
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDFLAG", 2)
- && compflags == NULL) {
- // Turn flag "c" into COMPOUNDRULE compatible string "c+",
- // "Na" into "Na+", "1234" into "1234+".
- p = getroom(spin, STRLEN(items[1]) + 2, false);
- STRCPY(p, items[1]);
- STRCAT(p, "+");
- compflags = p;
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2)) {
- // We don't use the count, but do check that it's a number and
- // not COMPOUNDRULE mistyped.
- if (atoi((char *)items[1]) == 0)
- smsg(_("Wrong COMPOUNDRULES value in %s line %d: %s"),
- fname, lnum, items[1]);
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2)) {
- // Don't use the first rule if it is a number.
- if (compflags != NULL || *skipdigits(items[1]) != NUL) {
- // Concatenate this string to previously defined ones,
- // using a slash to separate them.
- l = (int)STRLEN(items[1]) + 1;
- if (compflags != NULL)
- l += (int)STRLEN(compflags) + 1;
- p = getroom(spin, l, false);
- if (compflags != NULL) {
- STRCPY(p, compflags);
- STRCAT(p, "/");
- }
- STRCAT(p, items[1]);
- compflags = p;
- }
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDWORDMAX", 2)
- && compmax == 0) {
- compmax = atoi((char *)items[1]);
- if (compmax == 0)
- smsg(_("Wrong COMPOUNDWORDMAX value in %s line %d: %s"),
- fname, lnum, items[1]);
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDMIN", 2)
- && compminlen == 0) {
- compminlen = atoi((char *)items[1]);
- if (compminlen == 0)
- smsg(_("Wrong COMPOUNDMIN value in %s line %d: %s"),
- fname, lnum, items[1]);
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDSYLMAX", 2)
- && compsylmax == 0) {
- compsylmax = atoi((char *)items[1]);
- if (compsylmax == 0)
- smsg(_("Wrong COMPOUNDSYLMAX value in %s line %d: %s"),
- fname, lnum, items[1]);
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDDUP", 1)) {
- compoptions |= COMP_CHECKDUP;
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDREP", 1)) {
- compoptions |= COMP_CHECKREP;
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDCASE", 1)) {
- compoptions |= COMP_CHECKCASE;
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDTRIPLE", 1)) {
- compoptions |= COMP_CHECKTRIPLE;
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 2)) {
- if (atoi((char *)items[1]) == 0)
- smsg(_("Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"),
- fname, lnum, items[1]);
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 3)) {
- garray_T *gap = &spin->si_comppat;
- int i;
-
- // Only add the couple if it isn't already there.
- for (i = 0; i < gap->ga_len - 1; i += 2)
- if (STRCMP(((char_u **)(gap->ga_data))[i], items[1]) == 0
- && STRCMP(((char_u **)(gap->ga_data))[i + 1],
- items[2]) == 0)
- break;
- if (i >= gap->ga_len) {
- ga_grow(gap, 2);
- ((char_u **)(gap->ga_data))[gap->ga_len++]
- = getroom_save(spin, items[1]);
- ((char_u **)(gap->ga_data))[gap->ga_len++]
- = getroom_save(spin, items[2]);
- }
- } else if (is_aff_rule(items, itemcnt, "SYLLABLE", 2)
- && syllable == NULL) {
- syllable = getroom_save(spin, items[1]);
- } else if (is_aff_rule(items, itemcnt, "NOBREAK", 1)) {
- spin->si_nobreak = true;
- } else if (is_aff_rule(items, itemcnt, "NOSPLITSUGS", 1)) {
- spin->si_nosplitsugs = true;
- } else if (is_aff_rule(items, itemcnt, "NOCOMPOUNDSUGS", 1)) {
- spin->si_nocompoundsugs = true;
- } else if (is_aff_rule(items, itemcnt, "NOSUGFILE", 1)) {
- spin->si_nosugfile = true;
- } else if (is_aff_rule(items, itemcnt, "PFXPOSTPONE", 1)) {
- aff->af_pfxpostpone = true;
- } else if (is_aff_rule(items, itemcnt, "IGNOREEXTRA", 1)) {
- aff->af_ignoreextra = true;
- } else if ((STRCMP(items[0], "PFX") == 0
- || STRCMP(items[0], "SFX") == 0)
- && aff_todo == 0
- && itemcnt >= 4) {
- int lasti = 4;
- char_u key[AH_KEY_LEN];
-
- if (*items[0] == 'P')
- tp = &aff->af_pref;
- else
- tp = &aff->af_suff;
-
- // Myspell allows the same affix name to be used multiple
- // times. The affix files that do this have an undocumented
- // "S" flag on all but the last block, thus we check for that
- // and store it in ah_follows.
- STRLCPY(key, items[1], AH_KEY_LEN);
- hi = hash_find(tp, key);
- if (!HASHITEM_EMPTY(hi)) {
- cur_aff = HI2AH(hi);
- if (cur_aff->ah_combine != (*items[2] == 'Y'))
- smsg(_("Different combining flag in continued affix block in %s line %d: %s"),
- fname, lnum, items[1]);
- if (!cur_aff->ah_follows)
- smsg(_("Duplicate affix in %s line %d: %s"),
- fname, lnum, items[1]);
- } else {
- // New affix letter.
- cur_aff = (affheader_T *)getroom(spin,
- sizeof(affheader_T), true);
- if (cur_aff == NULL)
- break;
- cur_aff->ah_flag = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- if (cur_aff->ah_flag == 0 || STRLEN(items[1]) >= AH_KEY_LEN)
- break;
- if (cur_aff->ah_flag == aff->af_bad
- || cur_aff->ah_flag == aff->af_rare
- || cur_aff->ah_flag == aff->af_keepcase
- || cur_aff->ah_flag == aff->af_needaffix
- || cur_aff->ah_flag == aff->af_circumfix
- || cur_aff->ah_flag == aff->af_nosuggest
- || cur_aff->ah_flag == aff->af_needcomp
- || cur_aff->ah_flag == aff->af_comproot)
- smsg(_("Affix also used for "
- "BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST"
- "in %s line %d: %s"),
- fname, lnum, items[1]);
- STRCPY(cur_aff->ah_key, items[1]);
- hash_add(tp, cur_aff->ah_key);
-
- cur_aff->ah_combine = (*items[2] == 'Y');
- }
-
- // Check for the "S" flag, which apparently means that another
- // block with the same affix name is following.
- if (itemcnt > lasti && STRCMP(items[lasti], "S") == 0) {
- ++lasti;
- cur_aff->ah_follows = true;
- } else
- cur_aff->ah_follows = false;
-
- // Myspell allows extra text after the item, but that might
- // mean mistakes go unnoticed. Require a comment-starter,
- // unless IGNOREEXTRA is used. Hunspell uses a "-" item.
- if (itemcnt > lasti
- && !aff->af_ignoreextra
- && *items[lasti] != '#')
- smsg(_(e_afftrailing), fname, lnum, items[lasti]);
-
- if (STRCMP(items[2], "Y") != 0 && STRCMP(items[2], "N") != 0)
- smsg(_("Expected Y or N in %s line %d: %s"),
- fname, lnum, items[2]);
-
- if (*items[0] == 'P' && aff->af_pfxpostpone) {
- if (cur_aff->ah_newID == 0) {
- // Use a new number in the .spl file later, to be able
- // to handle multiple .aff files.
- check_renumber(spin);
- cur_aff->ah_newID = ++spin->si_newprefID;
-
- // We only really use ah_newID if the prefix is
- // postponed. We know that only after handling all
- // the items.
- did_postpone_prefix = false;
- } else
- // Did use the ID in a previous block.
- did_postpone_prefix = true;
- }
-
- aff_todo = atoi((char *)items[3]);
- } else if ((STRCMP(items[0], "PFX") == 0
- || STRCMP(items[0], "SFX") == 0)
- && aff_todo > 0
- && STRCMP(cur_aff->ah_key, items[1]) == 0
- && itemcnt >= 5) {
- affentry_T *aff_entry;
- bool upper = false;
- int lasti = 5;
-
- // Myspell allows extra text after the item, but that might
- // mean mistakes go unnoticed. Require a comment-starter.
- // Hunspell uses a "-" item.
- if (itemcnt > lasti && *items[lasti] != '#'
- && (STRCMP(items[lasti], "-") != 0
- || itemcnt != lasti + 1))
- smsg(_(e_afftrailing), fname, lnum, items[lasti]);
-
- // New item for an affix letter.
- --aff_todo;
- aff_entry = (affentry_T *)getroom(spin,
- sizeof(affentry_T), true);
- if (aff_entry == NULL)
- break;
-
- if (STRCMP(items[2], "0") != 0)
- aff_entry->ae_chop = getroom_save(spin, items[2]);
- if (STRCMP(items[3], "0") != 0) {
- aff_entry->ae_add = getroom_save(spin, items[3]);
-
- // Recognize flags on the affix: abcd/XYZ
- aff_entry->ae_flags = vim_strchr(aff_entry->ae_add, '/');
- if (aff_entry->ae_flags != NULL) {
- *aff_entry->ae_flags++ = NUL;
- aff_process_flags(aff, aff_entry);
- }
- }
-
- // Don't use an affix entry with non-ASCII characters when
- // "spin->si_ascii" is true.
- if (!spin->si_ascii || !(has_non_ascii(aff_entry->ae_chop)
- || has_non_ascii(aff_entry->ae_add))) {
- aff_entry->ae_next = cur_aff->ah_first;
- cur_aff->ah_first = aff_entry;
-
- if (STRCMP(items[4], ".") != 0) {
- char_u buf[MAXLINELEN];
-
- aff_entry->ae_cond = getroom_save(spin, items[4]);
- if (*items[0] == 'P')
- sprintf((char *)buf, "^%s", items[4]);
- else
- sprintf((char *)buf, "%s$", items[4]);
- aff_entry->ae_prog = vim_regcomp(buf,
- RE_MAGIC + RE_STRING + RE_STRICT);
- if (aff_entry->ae_prog == NULL)
- smsg(_("Broken condition in %s line %d: %s"),
- fname, lnum, items[4]);
- }
-
- // For postponed prefixes we need an entry in si_prefcond
- // for the condition. Use an existing one if possible.
- // Can't be done for an affix with flags, ignoring
- // COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG.
- if (*items[0] == 'P' && aff->af_pfxpostpone
- && aff_entry->ae_flags == NULL) {
- // When the chop string is one lower-case letter and
- // the add string ends in the upper-case letter we set
- // the "upper" flag, clear "ae_chop" and remove the
- // letters from "ae_add". The condition must either
- // be empty or start with the same letter.
- if (aff_entry->ae_chop != NULL
- && aff_entry->ae_add != NULL
- && aff_entry->ae_chop[(*mb_ptr2len)(
- aff_entry->ae_chop)] == NUL
- ) {
- int c, c_up;
-
- c = PTR2CHAR(aff_entry->ae_chop);
- c_up = SPELL_TOUPPER(c);
- if (c_up != c
- && (aff_entry->ae_cond == NULL
- || PTR2CHAR(aff_entry->ae_cond) == c)) {
- p = aff_entry->ae_add
- + STRLEN(aff_entry->ae_add);
- mb_ptr_back(aff_entry->ae_add, p);
- if (PTR2CHAR(p) == c_up) {
- upper = true;
- aff_entry->ae_chop = NULL;
- *p = NUL;
-
- // The condition is matched with the
- // actual word, thus must check for the
- // upper-case letter.
- if (aff_entry->ae_cond != NULL) {
- char_u buf[MAXLINELEN];
- if (has_mbyte) {
- onecap_copy(items[4], buf, true);
- aff_entry->ae_cond = getroom_save(
- spin, buf);
- } else
- *aff_entry->ae_cond = c_up;
- if (aff_entry->ae_cond != NULL) {
- sprintf((char *)buf, "^%s",
- aff_entry->ae_cond);
- vim_regfree(aff_entry->ae_prog);
- aff_entry->ae_prog = vim_regcomp(
- buf, RE_MAGIC + RE_STRING);
- }
- }
- }
- }
- }
-
- if (aff_entry->ae_chop == NULL
- && aff_entry->ae_flags == NULL) {
- int idx;
- char_u **pp;
- int n;
-
- // Find a previously used condition.
- for (idx = spin->si_prefcond.ga_len - 1; idx >= 0;
- --idx) {
- p = ((char_u **)spin->si_prefcond.ga_data)[idx];
- if (str_equal(p, aff_entry->ae_cond))
- break;
- }
- if (idx < 0) {
- // Not found, add a new condition.
- idx = spin->si_prefcond.ga_len;
- pp = GA_APPEND_VIA_PTR(char_u *, &spin->si_prefcond);
- *pp = (aff_entry->ae_cond == NULL) ?
- NULL : getroom_save(spin, aff_entry->ae_cond);
- }
-
- // Add the prefix to the prefix tree.
- if (aff_entry->ae_add == NULL)
- p = (char_u *)"";
- else
- p = aff_entry->ae_add;
-
- // PFX_FLAGS is a negative number, so that
- // tree_add_word() knows this is the prefix tree.
- n = PFX_FLAGS;
- if (!cur_aff->ah_combine)
- n |= WFP_NC;
- if (upper)
- n |= WFP_UP;
- if (aff_entry->ae_comppermit)
- n |= WFP_COMPPERMIT;
- if (aff_entry->ae_compforbid)
- n |= WFP_COMPFORBID;
- tree_add_word(spin, p, spin->si_prefroot, n,
- idx, cur_aff->ah_newID);
- did_postpone_prefix = true;
- }
-
- // Didn't actually use ah_newID, backup si_newprefID.
- if (aff_todo == 0 && !did_postpone_prefix) {
- --spin->si_newprefID;
- cur_aff->ah_newID = 0;
- }
- }
- }
- } else if (is_aff_rule(items, itemcnt, "FOL", 2) && fol == NULL) {
- fol = vim_strsave(items[1]);
- } else if (is_aff_rule(items, itemcnt, "LOW", 2) && low == NULL) {
- low = vim_strsave(items[1]);
- } else if (is_aff_rule(items, itemcnt, "UPP", 2) && upp == NULL) {
- upp = vim_strsave(items[1]);
- } else if (is_aff_rule(items, itemcnt, "REP", 2)
- || is_aff_rule(items, itemcnt, "REPSAL", 2)) {
- /* Ignore REP/REPSAL count */;
- if (!isdigit(*items[1]))
- smsg(_("Expected REP(SAL) count in %s line %d"),
- fname, lnum);
- } else if ((STRCMP(items[0], "REP") == 0
- || STRCMP(items[0], "REPSAL") == 0)
- && itemcnt >= 3) {
- // REP/REPSAL item
- // Myspell ignores extra arguments, we require it starts with
- // # to detect mistakes.
- if (itemcnt > 3 && items[3][0] != '#')
- smsg(_(e_afftrailing), fname, lnum, items[3]);
- if (items[0][3] == 'S' ? do_repsal : do_rep) {
- // Replace underscore with space (can't include a space
- // directly).
- for (p = items[1]; *p != NUL; mb_ptr_adv(p))
- if (*p == '_')
- *p = ' ';
- for (p = items[2]; *p != NUL; mb_ptr_adv(p))
- if (*p == '_')
- *p = ' ';
- add_fromto(spin, items[0][3] == 'S'
- ? &spin->si_repsal
- : &spin->si_rep, items[1], items[2]);
- }
- } else if (is_aff_rule(items, itemcnt, "MAP", 2)) {
- // MAP item or count
- if (!found_map) {
- // First line contains the count.
- found_map = true;
- if (!isdigit(*items[1]))
- smsg(_("Expected MAP count in %s line %d"),
- fname, lnum);
- } else if (do_mapline) {
- int c;
-
- // Check that every character appears only once.
- for (p = items[1]; *p != NUL; ) {
- c = mb_ptr2char_adv(&p);
- if ((!GA_EMPTY(&spin->si_map)
- && vim_strchr(spin->si_map.ga_data, c)
- != NULL)
- || vim_strchr(p, c) != NULL)
- smsg(_("Duplicate character in MAP in %s line %d"),
- fname, lnum);
- }
-
- // We simply concatenate all the MAP strings, separated by
- // slashes.
- ga_concat(&spin->si_map, items[1]);
- ga_append(&spin->si_map, '/');
- }
- }
- // Accept "SAL from to" and "SAL from to #comment".
- else if (is_aff_rule(items, itemcnt, "SAL", 3)) {
- if (do_sal) {
- // SAL item (sounds-a-like)
- // Either one of the known keys or a from-to pair.
- if (STRCMP(items[1], "followup") == 0)
- spin->si_followup = sal_to_bool(items[2]);
- else if (STRCMP(items[1], "collapse_result") == 0)
- spin->si_collapse = sal_to_bool(items[2]);
- else if (STRCMP(items[1], "remove_accents") == 0)
- spin->si_rem_accents = sal_to_bool(items[2]);
- else
- // when "to" is "_" it means empty
- add_fromto(spin, &spin->si_sal, items[1],
- STRCMP(items[2], "_") == 0 ? (char_u *)""
- : items[2]);
- }
- } else if (is_aff_rule(items, itemcnt, "SOFOFROM", 2)
- && sofofrom == NULL) {
- sofofrom = getroom_save(spin, items[1]);
- } else if (is_aff_rule(items, itemcnt, "SOFOTO", 2)
- && sofoto == NULL) {
- sofoto = getroom_save(spin, items[1]);
- } else if (STRCMP(items[0], "COMMON") == 0) {
- int i;
-
- for (i = 1; i < itemcnt; ++i) {
- if (HASHITEM_EMPTY(hash_find(&spin->si_commonwords,
- items[i]))) {
- p = vim_strsave(items[i]);
- hash_add(&spin->si_commonwords, p);
- }
- }
- } else
- smsg(_("Unrecognized or duplicate item in %s line %d: %s"),
- fname, lnum, items[0]);
- }
- }
-
- if (fol != NULL || low != NULL || upp != NULL) {
- if (spin->si_clear_chartab) {
- // Clear the char type tables, don't want to use any of the
- // currently used spell properties.
- init_spell_chartab();
- spin->si_clear_chartab = false;
- }
-
- // Don't write a word table for an ASCII file, so that we don't check
- // for conflicts with a word table that matches 'encoding'.
- // Don't write one for utf-8 either, we use utf_*() and
- // mb_get_class(), the list of chars in the file will be incomplete.
- if (!spin->si_ascii
- && !enc_utf8
- ) {
- if (fol == NULL || low == NULL || upp == NULL)
- smsg(_("Missing FOL/LOW/UPP line in %s"), fname);
- else
- (void)set_spell_chartab(fol, low, upp);
- }
-
- xfree(fol);
- xfree(low);
- xfree(upp);
- }
-
- // Use compound specifications of the .aff file for the spell info.
- if (compmax != 0) {
- aff_check_number(spin->si_compmax, compmax, "COMPOUNDWORDMAX");
- spin->si_compmax = compmax;
- }
-
- if (compminlen != 0) {
- aff_check_number(spin->si_compminlen, compminlen, "COMPOUNDMIN");
- spin->si_compminlen = compminlen;
- }
-
- if (compsylmax != 0) {
- if (syllable == NULL)
- smsg(_("COMPOUNDSYLMAX used without SYLLABLE"));
- aff_check_number(spin->si_compsylmax, compsylmax, "COMPOUNDSYLMAX");
- spin->si_compsylmax = compsylmax;
- }
-
- if (compoptions != 0) {
- aff_check_number(spin->si_compoptions, compoptions, "COMPOUND options");
- spin->si_compoptions |= compoptions;
- }
-
- if (compflags != NULL)
- process_compflags(spin, aff, compflags);
-
- // Check that we didn't use too many renumbered flags.
- if (spin->si_newcompID < spin->si_newprefID) {
- if (spin->si_newcompID == 127 || spin->si_newcompID == 255)
- MSG(_("Too many postponed prefixes"));
- else if (spin->si_newprefID == 0 || spin->si_newprefID == 127)
- MSG(_("Too many compound flags"));
- else
- MSG(_("Too many postponed prefixes and/or compound flags"));
- }
-
- if (syllable != NULL) {
- aff_check_string(spin->si_syllable, syllable, "SYLLABLE");
- spin->si_syllable = syllable;
- }
-
- if (sofofrom != NULL || sofoto != NULL) {
- if (sofofrom == NULL || sofoto == NULL)
- smsg(_("Missing SOFO%s line in %s"),
- sofofrom == NULL ? "FROM" : "TO", fname);
- else if (!GA_EMPTY(&spin->si_sal))
- smsg(_("Both SAL and SOFO lines in %s"), fname);
- else {
- aff_check_string(spin->si_sofofr, sofofrom, "SOFOFROM");
- aff_check_string(spin->si_sofoto, sofoto, "SOFOTO");
- spin->si_sofofr = sofofrom;
- spin->si_sofoto = sofoto;
- }
- }
-
- if (midword != NULL) {
- aff_check_string(spin->si_midword, midword, "MIDWORD");
- spin->si_midword = midword;
- }
-
- xfree(pc);
- fclose(fd);
- return aff;
-}
-
-// Returns true when items[0] equals "rulename", there are "mincount" items or
-// a comment is following after item "mincount".
-static bool is_aff_rule(char_u **items, int itemcnt, char *rulename, int mincount)
-{
- return STRCMP(items[0], rulename) == 0
- && (itemcnt == mincount
- || (itemcnt > mincount && items[mincount][0] == '#'));
-}
-
-// For affix "entry" move COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG from
-// ae_flags to ae_comppermit and ae_compforbid.
-static void aff_process_flags(afffile_T *affile, affentry_T *entry)
-{
- char_u *p;
- char_u *prevp;
- unsigned flag;
-
- if (entry->ae_flags != NULL
- && (affile->af_compforbid != 0 || affile->af_comppermit != 0)) {
- for (p = entry->ae_flags; *p != NUL; ) {
- prevp = p;
- flag = get_affitem(affile->af_flagtype, &p);
- if (flag == affile->af_comppermit || flag == affile->af_compforbid) {
- STRMOVE(prevp, p);
- p = prevp;
- if (flag == affile->af_comppermit)
- entry->ae_comppermit = true;
- else
- entry->ae_compforbid = true;
- }
- if (affile->af_flagtype == AFT_NUM && *p == ',')
- ++p;
- }
- if (*entry->ae_flags == NUL)
- entry->ae_flags = NULL; // nothing left
- }
-}
-
-// Returns true if "s" is the name of an info item in the affix file.
-static bool spell_info_item(char_u *s)
-{
- return STRCMP(s, "NAME") == 0
- || STRCMP(s, "HOME") == 0
- || STRCMP(s, "VERSION") == 0
- || STRCMP(s, "AUTHOR") == 0
- || STRCMP(s, "EMAIL") == 0
- || STRCMP(s, "COPYRIGHT") == 0;
-}
-
-// Turn an affix flag name into a number, according to the FLAG type.
-// returns zero for failure.
-static unsigned affitem2flag(int flagtype, char_u *item, char_u *fname, int lnum)
-{
- unsigned res;
- char_u *p = item;
-
- res = get_affitem(flagtype, &p);
- if (res == 0) {
- if (flagtype == AFT_NUM)
- smsg(_("Flag is not a number in %s line %d: %s"),
- fname, lnum, item);
- else
- smsg(_("Illegal flag in %s line %d: %s"),
- fname, lnum, item);
- }
- if (*p != NUL) {
- smsg(_(e_affname), fname, lnum, item);
- return 0;
- }
-
- return res;
-}
-
-// Get one affix name from "*pp" and advance the pointer.
-// Returns zero for an error, still advances the pointer then.
-static unsigned get_affitem(int flagtype, char_u **pp)
-{
- int res;
-
- if (flagtype == AFT_NUM) {
- if (!ascii_isdigit(**pp)) {
- ++*pp; // always advance, avoid getting stuck
- return 0;
- }
- res = getdigits_int(pp);
- } else {
- res = mb_ptr2char_adv(pp);
- if (flagtype == AFT_LONG || (flagtype == AFT_CAPLONG
- && res >= 'A' && res <= 'Z')) {
- if (**pp == NUL)
- return 0;
- res = mb_ptr2char_adv(pp) + (res << 16);
- }
- }
- return res;
-}
-
-// Process the "compflags" string used in an affix file and append it to
-// spin->si_compflags.
-// The processing involves changing the affix names to ID numbers, so that
-// they fit in one byte.
-static void process_compflags(spellinfo_T *spin, afffile_T *aff, char_u *compflags)
-{
- char_u *p;
- char_u *prevp;
- unsigned flag;
- compitem_T *ci;
- int id;
- int len;
- char_u *tp;
- char_u key[AH_KEY_LEN];
- hashitem_T *hi;
-
- // Make room for the old and the new compflags, concatenated with a / in
- // between. Processing it makes it shorter, but we don't know by how
- // much, thus allocate the maximum.
- len = (int)STRLEN(compflags) + 1;
- if (spin->si_compflags != NULL)
- len += (int)STRLEN(spin->si_compflags) + 1;
- p = getroom(spin, len, false);
- if (spin->si_compflags != NULL) {
- STRCPY(p, spin->si_compflags);
- STRCAT(p, "/");
- }
- spin->si_compflags = p;
- tp = p + STRLEN(p);
-
- for (p = compflags; *p != NUL; ) {
- if (vim_strchr((char_u *)"/?*+[]", *p) != NULL)
- // Copy non-flag characters directly.
- *tp++ = *p++;
- else {
- // First get the flag number, also checks validity.
- prevp = p;
- flag = get_affitem(aff->af_flagtype, &p);
- if (flag != 0) {
- // Find the flag in the hashtable. If it was used before, use
- // the existing ID. Otherwise add a new entry.
- STRLCPY(key, prevp, p - prevp + 1);
- hi = hash_find(&aff->af_comp, key);
- if (!HASHITEM_EMPTY(hi))
- id = HI2CI(hi)->ci_newID;
- else {
- ci = (compitem_T *)getroom(spin, sizeof(compitem_T), true);
- if (ci == NULL)
- break;
- STRCPY(ci->ci_key, key);
- ci->ci_flag = flag;
- // Avoid using a flag ID that has a special meaning in a
- // regexp (also inside []).
- do {
- check_renumber(spin);
- id = spin->si_newcompID--;
- } while (vim_strchr((char_u *)"/?*+[]\\-^", id) != NULL);
- ci->ci_newID = id;
- hash_add(&aff->af_comp, ci->ci_key);
- }
- *tp++ = id;
- }
- if (aff->af_flagtype == AFT_NUM && *p == ',')
- ++p;
- }
- }
-
- *tp = NUL;
-}
-
-// Check that the new IDs for postponed affixes and compounding don't overrun
-// each other. We have almost 255 available, but start at 0-127 to avoid
-// using two bytes for utf-8. When the 0-127 range is used up go to 128-255.
-// When that is used up an error message is given.
-static void check_renumber(spellinfo_T *spin)
-{
- if (spin->si_newprefID == spin->si_newcompID && spin->si_newcompID < 128) {
- spin->si_newprefID = 127;
- spin->si_newcompID = 255;
- }
-}
-
-// Returns true if flag "flag" appears in affix list "afflist".
-static bool flag_in_afflist(int flagtype, char_u *afflist, unsigned flag)
-{
- char_u *p;
- unsigned n;
-
- switch (flagtype) {
- case AFT_CHAR:
- return vim_strchr(afflist, flag) != NULL;
-
- case AFT_CAPLONG:
- case AFT_LONG:
- for (p = afflist; *p != NUL; ) {
- n = mb_ptr2char_adv(&p);
- if ((flagtype == AFT_LONG || (n >= 'A' && n <= 'Z'))
- && *p != NUL)
- n = mb_ptr2char_adv(&p) + (n << 16);
- if (n == flag)
- return true;
- }
- break;
-
- case AFT_NUM:
- for (p = afflist; *p != NUL; ) {
- int digits = getdigits_int(&p);
- assert(digits >= 0);
- n = (unsigned int)digits;
- if (n == flag)
- return true;
- if (*p != NUL) // skip over comma
- ++p;
- }
- break;
- }
- return false;
-}
-
-// Give a warning when "spinval" and "affval" numbers are set and not the same.
-static void aff_check_number(int spinval, int affval, char *name)
-{
- if (spinval != 0 && spinval != affval)
- smsg(_("%s value differs from what is used in another .aff file"),
- name);
-}
-
-// Give a warning when "spinval" and "affval" strings are set and not the same.
-static void aff_check_string(char_u *spinval, char_u *affval, char *name)
-{
- if (spinval != NULL && STRCMP(spinval, affval) != 0)
- smsg(_("%s value differs from what is used in another .aff file"),
- name);
-}
-
-// Returns true if strings "s1" and "s2" are equal. Also consider both being
-// NULL as equal.
-static bool str_equal(char_u *s1, char_u *s2)
-{
- if (s1 == NULL || s2 == NULL)
- return s1 == s2;
- return STRCMP(s1, s2) == 0;
-}
-
-// Add a from-to item to "gap". Used for REP and SAL items.
-// They are stored case-folded.
-static void add_fromto(spellinfo_T *spin, garray_T *gap, char_u *from, char_u *to)
-{
- char_u word[MAXWLEN];
-
- fromto_T *ftp = GA_APPEND_VIA_PTR(fromto_T, gap);
- (void)spell_casefold(from, (int)STRLEN(from), word, MAXWLEN);
- ftp->ft_from = getroom_save(spin, word);
- (void)spell_casefold(to, (int)STRLEN(to), word, MAXWLEN);
- ftp->ft_to = getroom_save(spin, word);
-}
-
-// Converts a boolean argument in a SAL line to true or false;
-static bool sal_to_bool(char_u *s)
-{
- return STRCMP(s, "1") == 0 || STRCMP(s, "true") == 0;
-}
-
-// Free the structure filled by spell_read_aff().
-static void spell_free_aff(afffile_T *aff)
-{
- hashtab_T *ht;
- hashitem_T *hi;
- int todo;
- affheader_T *ah;
- affentry_T *ae;
-
- xfree(aff->af_enc);
-
- // All this trouble to free the "ae_prog" items...
- for (ht = &aff->af_pref;; ht = &aff->af_suff) {
- todo = (int)ht->ht_used;
- for (hi = ht->ht_array; todo > 0; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- --todo;
- ah = HI2AH(hi);
- for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next)
- vim_regfree(ae->ae_prog);
- }
- }
- if (ht == &aff->af_suff)
- break;
- }
-
- hash_clear(&aff->af_pref);
- hash_clear(&aff->af_suff);
- hash_clear(&aff->af_comp);
-}
-
-// Read dictionary file "fname".
-// Returns OK or FAIL;
-static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile)
-{
- hashtab_T ht;
- char_u line[MAXLINELEN];
- char_u *p;
- char_u *afflist;
- char_u store_afflist[MAXWLEN];
- int pfxlen;
- bool need_affix;
- char_u *dw;
- char_u *pc;
- char_u *w;
- int l;
- hash_T hash;
- hashitem_T *hi;
- FILE *fd;
- int lnum = 1;
- int non_ascii = 0;
- int retval = OK;
- char_u message[MAXLINELEN + MAXWLEN];
- int flags;
- int duplicate = 0;
-
- // Open the file.
- fd = mch_fopen((char *)fname, "r");
- if (fd == NULL) {
- EMSG2(_(e_notopen), fname);
- return FAIL;
- }
-
- // The hashtable is only used to detect duplicated words.
- hash_init(&ht);
-
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Reading dictionary file %s ..."), fname);
- spell_message(spin, IObuff);
-
- // start with a message for the first line
- spin->si_msg_count = 999999;
-
- // Read and ignore the first line: word count.
- (void)vim_fgets(line, MAXLINELEN, fd);
- if (!ascii_isdigit(*skipwhite(line)))
- EMSG2(_("E760: No word count in %s"), fname);
-
- // Read all the lines in the file one by one.
- // The words are converted to 'encoding' here, before being added to
- // the hashtable.
- while (!vim_fgets(line, MAXLINELEN, fd) && !got_int) {
- line_breakcheck();
- ++lnum;
- if (line[0] == '#' || line[0] == '/')
- continue; // comment line
-
- // Remove CR, LF and white space from the end. White space halfway through
- // the word is kept to allow multi-word terms like "et al.".
- l = (int)STRLEN(line);
- while (l > 0 && line[l - 1] <= ' ')
- --l;
- if (l == 0)
- continue; // empty line
- line[l] = NUL;
-
- // Convert from "SET" to 'encoding' when needed.
- if (spin->si_conv.vc_type != CONV_NONE) {
- pc = string_convert(&spin->si_conv, line, NULL);
- if (pc == NULL) {
- smsg(_("Conversion failure for word in %s line %d: %s"),
- fname, lnum, line);
- continue;
- }
- w = pc;
- } else {
- pc = NULL;
- w = line;
- }
-
- // Truncate the word at the "/", set "afflist" to what follows.
- // Replace "\/" by "/" and "\\" by "\".
- afflist = NULL;
- for (p = w; *p != NUL; mb_ptr_adv(p)) {
- if (*p == '\\' && (p[1] == '\\' || p[1] == '/'))
- STRMOVE(p, p + 1);
- else if (*p == '/') {
- *p = NUL;
- afflist = p + 1;
- break;
- }
- }
-
- // Skip non-ASCII words when "spin->si_ascii" is true.
- if (spin->si_ascii && has_non_ascii(w)) {
- ++non_ascii;
- xfree(pc);
- continue;
- }
-
- // This takes time, print a message every 10000 words.
- if (spin->si_verbose && spin->si_msg_count > 10000) {
- spin->si_msg_count = 0;
- vim_snprintf((char *)message, sizeof(message),
- _("line %6d, word %6d - %s"),
- lnum, spin->si_foldwcount + spin->si_keepwcount, w);
- msg_start();
- msg_puts_long_attr(message, 0);
- msg_clr_eos();
- msg_didout = FALSE;
- msg_col = 0;
- ui_flush();
- }
-
- // Store the word in the hashtable to be able to find duplicates.
- dw = getroom_save(spin, w);
- if (dw == NULL) {
- retval = FAIL;
- xfree(pc);
- break;
- }
-
- hash = hash_hash(dw);
- hi = hash_lookup(&ht, dw, hash);
- if (!HASHITEM_EMPTY(hi)) {
- if (p_verbose > 0)
- smsg(_("Duplicate word in %s line %d: %s"),
- fname, lnum, dw);
- else if (duplicate == 0)
- smsg(_("First duplicate word in %s line %d: %s"),
- fname, lnum, dw);
- ++duplicate;
- } else
- hash_add_item(&ht, hi, dw, hash);
-
- flags = 0;
- store_afflist[0] = NUL;
- pfxlen = 0;
- need_affix = false;
- if (afflist != NULL) {
- // Extract flags from the affix list.
- flags |= get_affix_flags(affile, afflist);
-
- if (affile->af_needaffix != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_needaffix))
- need_affix = true;
-
- if (affile->af_pfxpostpone)
- // Need to store the list of prefix IDs with the word.
- pfxlen = get_pfxlist(affile, afflist, store_afflist);
-
- if (spin->si_compflags != NULL)
- // Need to store the list of compound flags with the word.
- // Concatenate them to the list of prefix IDs.
- get_compflags(affile, afflist, store_afflist + pfxlen);
- }
-
- // Add the word to the word tree(s).
- if (store_word(spin, dw, flags, spin->si_region,
- store_afflist, need_affix) == FAIL)
- retval = FAIL;
-
- if (afflist != NULL) {
- // Find all matching suffixes and add the resulting words.
- // Additionally do matching prefixes that combine.
- if (store_aff_word(spin, dw, afflist, affile,
- &affile->af_suff, &affile->af_pref,
- CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL)
- retval = FAIL;
-
- // Find all matching prefixes and add the resulting words.
- if (store_aff_word(spin, dw, afflist, affile,
- &affile->af_pref, NULL,
- CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL)
- retval = FAIL;
- }
-
- xfree(pc);
- }
-
- if (duplicate > 0)
- smsg(_("%d duplicate word(s) in %s"), duplicate, fname);
- if (spin->si_ascii && non_ascii > 0)
- smsg(_("Ignored %d word(s) with non-ASCII characters in %s"),
- non_ascii, fname);
- hash_clear(&ht);
-
- fclose(fd);
- return retval;
-}
-
-// Check for affix flags in "afflist" that are turned into word flags.
-// Return WF_ flags.
-static int get_affix_flags(afffile_T *affile, char_u *afflist)
-{
- int flags = 0;
-
- if (affile->af_keepcase != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_keepcase))
- flags |= WF_KEEPCAP | WF_FIXCAP;
- if (affile->af_rare != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_rare))
- flags |= WF_RARE;
- if (affile->af_bad != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_bad))
- flags |= WF_BANNED;
- if (affile->af_needcomp != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_needcomp))
- flags |= WF_NEEDCOMP;
- if (affile->af_comproot != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_comproot))
- flags |= WF_COMPROOT;
- if (affile->af_nosuggest != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_nosuggest))
- flags |= WF_NOSUGGEST;
- return flags;
-}
-
-// Get the list of prefix IDs from the affix list "afflist".
-// Used for PFXPOSTPONE.
-// Put the resulting flags in "store_afflist[MAXWLEN]" with a terminating NUL
-// and return the number of affixes.
-static int get_pfxlist(afffile_T *affile, char_u *afflist, char_u *store_afflist)
-{
- char_u *p;
- char_u *prevp;
- int cnt = 0;
- int id;
- char_u key[AH_KEY_LEN];
- hashitem_T *hi;
-
- for (p = afflist; *p != NUL; ) {
- prevp = p;
- if (get_affitem(affile->af_flagtype, &p) != 0) {
- // A flag is a postponed prefix flag if it appears in "af_pref"
- // and it's ID is not zero.
- STRLCPY(key, prevp, p - prevp + 1);
- hi = hash_find(&affile->af_pref, key);
- if (!HASHITEM_EMPTY(hi)) {
- id = HI2AH(hi)->ah_newID;
- if (id != 0)
- store_afflist[cnt++] = id;
- }
- }
- if (affile->af_flagtype == AFT_NUM && *p == ',')
- ++p;
- }
-
- store_afflist[cnt] = NUL;
- return cnt;
-}
-
-// Get the list of compound IDs from the affix list "afflist" that are used
-// for compound words.
-// Puts the flags in "store_afflist[]".
-static void get_compflags(afffile_T *affile, char_u *afflist, char_u *store_afflist)
-{
- char_u *p;
- char_u *prevp;
- int cnt = 0;
- char_u key[AH_KEY_LEN];
- hashitem_T *hi;
-
- for (p = afflist; *p != NUL; ) {
- prevp = p;
- if (get_affitem(affile->af_flagtype, &p) != 0) {
- // A flag is a compound flag if it appears in "af_comp".
- STRLCPY(key, prevp, p - prevp + 1);
- hi = hash_find(&affile->af_comp, key);
- if (!HASHITEM_EMPTY(hi))
- store_afflist[cnt++] = HI2CI(hi)->ci_newID;
- }
- if (affile->af_flagtype == AFT_NUM && *p == ',')
- ++p;
- }
-
- store_afflist[cnt] = NUL;
-}
-
-// Apply affixes to a word and store the resulting words.
-// "ht" is the hashtable with affentry_T that need to be applied, either
-// prefixes or suffixes.
-// "xht", when not NULL, is the prefix hashtable, to be used additionally on
-// the resulting words for combining affixes.
-//
-// Returns FAIL when out of memory.
-static int
-store_aff_word (
- spellinfo_T *spin, // spell info
- char_u *word, // basic word start
- char_u *afflist, // list of names of supported affixes
- afffile_T *affile,
- hashtab_T *ht,
- hashtab_T *xht,
- int condit, // CONDIT_SUF et al.
- int flags, // flags for the word
- char_u *pfxlist, // list of prefix IDs
- int pfxlen // nr of flags in "pfxlist" for prefixes, rest
- // is compound flags
-)
-{
- int todo;
- hashitem_T *hi;
- affheader_T *ah;
- affentry_T *ae;
- char_u newword[MAXWLEN];
- int retval = OK;
- int i, j;
- char_u *p;
- int use_flags;
- char_u *use_pfxlist;
- int use_pfxlen;
- bool need_affix;
- char_u store_afflist[MAXWLEN];
- char_u pfx_pfxlist[MAXWLEN];
- size_t wordlen = STRLEN(word);
- int use_condit;
-
- todo = (int)ht->ht_used;
- for (hi = ht->ht_array; todo > 0 && retval == OK; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- --todo;
- ah = HI2AH(hi);
-
- // Check that the affix combines, if required, and that the word
- // supports this affix.
- if (((condit & CONDIT_COMB) == 0 || ah->ah_combine)
- && flag_in_afflist(affile->af_flagtype, afflist,
- ah->ah_flag)) {
- // Loop over all affix entries with this name.
- for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next) {
- // Check the condition. It's not logical to match case
- // here, but it is required for compatibility with
- // Myspell.
- // Another requirement from Myspell is that the chop
- // string is shorter than the word itself.
- // For prefixes, when "PFXPOSTPONE" was used, only do
- // prefixes with a chop string and/or flags.
- // When a previously added affix had CIRCUMFIX this one
- // must have it too, if it had not then this one must not
- // have one either.
- if ((xht != NULL || !affile->af_pfxpostpone
- || ae->ae_chop != NULL
- || ae->ae_flags != NULL)
- && (ae->ae_chop == NULL
- || STRLEN(ae->ae_chop) < wordlen)
- && (ae->ae_prog == NULL
- || vim_regexec_prog(&ae->ae_prog, false, word, (colnr_T)0))
- && (((condit & CONDIT_CFIX) == 0)
- == ((condit & CONDIT_AFF) == 0
- || ae->ae_flags == NULL
- || !flag_in_afflist(affile->af_flagtype,
- ae->ae_flags, affile->af_circumfix)))) {
- // Match. Remove the chop and add the affix.
- if (xht == NULL) {
- // prefix: chop/add at the start of the word
- if (ae->ae_add == NULL)
- *newword = NUL;
- else
- STRLCPY(newword, ae->ae_add, MAXWLEN);
- p = word;
- if (ae->ae_chop != NULL) {
- // Skip chop string.
- if (has_mbyte) {
- i = mb_charlen(ae->ae_chop);
- for (; i > 0; --i)
- mb_ptr_adv(p);
- } else
- p += STRLEN(ae->ae_chop);
- }
- STRCAT(newword, p);
- } else {
- // suffix: chop/add at the end of the word
- STRLCPY(newword, word, MAXWLEN);
- if (ae->ae_chop != NULL) {
- // Remove chop string.
- p = newword + STRLEN(newword);
- i = (int)MB_CHARLEN(ae->ae_chop);
- for (; i > 0; --i)
- mb_ptr_back(newword, p);
- *p = NUL;
- }
- if (ae->ae_add != NULL)
- STRCAT(newword, ae->ae_add);
- }
-
- use_flags = flags;
- use_pfxlist = pfxlist;
- use_pfxlen = pfxlen;
- need_affix = false;
- use_condit = condit | CONDIT_COMB | CONDIT_AFF;
- if (ae->ae_flags != NULL) {
- // Extract flags from the affix list.
- use_flags |= get_affix_flags(affile, ae->ae_flags);
-
- if (affile->af_needaffix != 0 && flag_in_afflist(
- affile->af_flagtype, ae->ae_flags,
- affile->af_needaffix))
- need_affix = true;
-
- // When there is a CIRCUMFIX flag the other affix
- // must also have it and we don't add the word
- // with one affix.
- if (affile->af_circumfix != 0 && flag_in_afflist(
- affile->af_flagtype, ae->ae_flags,
- affile->af_circumfix)) {
- use_condit |= CONDIT_CFIX;
- if ((condit & CONDIT_CFIX) == 0)
- need_affix = true;
- }
-
- if (affile->af_pfxpostpone
- || spin->si_compflags != NULL) {
- if (affile->af_pfxpostpone)
- // Get prefix IDS from the affix list.
- use_pfxlen = get_pfxlist(affile,
- ae->ae_flags, store_afflist);
- else
- use_pfxlen = 0;
- use_pfxlist = store_afflist;
-
- // Combine the prefix IDs. Avoid adding the
- // same ID twice.
- for (i = 0; i < pfxlen; ++i) {
- for (j = 0; j < use_pfxlen; ++j)
- if (pfxlist[i] == use_pfxlist[j])
- break;
- if (j == use_pfxlen)
- use_pfxlist[use_pfxlen++] = pfxlist[i];
- }
-
- if (spin->si_compflags != NULL)
- // Get compound IDS from the affix list.
- get_compflags(affile, ae->ae_flags,
- use_pfxlist + use_pfxlen);
- else
- use_pfxlist[use_pfxlen] = NUL;
-
- // Combine the list of compound flags.
- // Concatenate them to the prefix IDs list.
- // Avoid adding the same ID twice.
- for (i = pfxlen; pfxlist[i] != NUL; ++i) {
- for (j = use_pfxlen;
- use_pfxlist[j] != NUL; ++j)
- if (pfxlist[i] == use_pfxlist[j])
- break;
- if (use_pfxlist[j] == NUL) {
- use_pfxlist[j++] = pfxlist[i];
- use_pfxlist[j] = NUL;
- }
- }
- }
- }
-
- // Obey a "COMPOUNDFORBIDFLAG" of the affix: don't
- // use the compound flags.
- if (use_pfxlist != NULL && ae->ae_compforbid) {
- STRLCPY(pfx_pfxlist, use_pfxlist, use_pfxlen + 1);
- use_pfxlist = pfx_pfxlist;
- }
-
- // When there are postponed prefixes...
- if (spin->si_prefroot != NULL
- && spin->si_prefroot->wn_sibling != NULL) {
- // ... add a flag to indicate an affix was used.
- use_flags |= WF_HAS_AFF;
-
- // ... don't use a prefix list if combining
- // affixes is not allowed. But do use the
- // compound flags after them.
- if (!ah->ah_combine && use_pfxlist != NULL)
- use_pfxlist += use_pfxlen;
- }
-
- // When compounding is supported and there is no
- // "COMPOUNDPERMITFLAG" then forbid compounding on the
- // side where the affix is applied.
- if (spin->si_compflags != NULL && !ae->ae_comppermit) {
- if (xht != NULL)
- use_flags |= WF_NOCOMPAFT;
- else
- use_flags |= WF_NOCOMPBEF;
- }
-
- // Store the modified word.
- if (store_word(spin, newword, use_flags,
- spin->si_region, use_pfxlist,
- need_affix) == FAIL)
- retval = FAIL;
-
- // When added a prefix or a first suffix and the affix
- // has flags may add a(nother) suffix. RECURSIVE!
- if ((condit & CONDIT_SUF) && ae->ae_flags != NULL)
- if (store_aff_word(spin, newword, ae->ae_flags,
- affile, &affile->af_suff, xht,
- use_condit & (xht == NULL
- ? ~0 : ~CONDIT_SUF),
- use_flags, use_pfxlist, pfxlen) == FAIL)
- retval = FAIL;
-
- // When added a suffix and combining is allowed also
- // try adding a prefix additionally. Both for the
- // word flags and for the affix flags. RECURSIVE!
- if (xht != NULL && ah->ah_combine) {
- if (store_aff_word(spin, newword,
- afflist, affile,
- xht, NULL, use_condit,
- use_flags, use_pfxlist,
- pfxlen) == FAIL
- || (ae->ae_flags != NULL
- && store_aff_word(spin, newword,
- ae->ae_flags, affile,
- xht, NULL, use_condit,
- use_flags, use_pfxlist,
- pfxlen) == FAIL))
- retval = FAIL;
- }
- }
- }
- }
- }
- }
-
- return retval;
-}
-
-// Read a file with a list of words.
-static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
-{
- FILE *fd;
- long lnum = 0;
- char_u rline[MAXLINELEN];
- char_u *line;
- char_u *pc = NULL;
- char_u *p;
- int l;
- int retval = OK;
- bool did_word = false;
- int non_ascii = 0;
- int flags;
- int regionmask;
-
- // Open the file.
- fd = mch_fopen((char *)fname, "r");
- if (fd == NULL) {
- EMSG2(_(e_notopen), fname);
- return FAIL;
- }
-
- vim_snprintf((char *)IObuff, IOSIZE, _("Reading word file %s ..."), fname);
- spell_message(spin, IObuff);
-
- // Read all the lines in the file one by one.
- while (!vim_fgets(rline, MAXLINELEN, fd) && !got_int) {
- line_breakcheck();
- ++lnum;
-
- // Skip comment lines.
- if (*rline == '#')
- continue;
-
- // Remove CR, LF and white space from the end.
- l = (int)STRLEN(rline);
- while (l > 0 && rline[l - 1] <= ' ')
- --l;
- if (l == 0)
- continue; // empty or blank line
- rline[l] = NUL;
-
- // Convert from "/encoding={encoding}" to 'encoding' when needed.
- xfree(pc);
- if (spin->si_conv.vc_type != CONV_NONE) {
- pc = string_convert(&spin->si_conv, rline, NULL);
- if (pc == NULL) {
- smsg(_("Conversion failure for word in %s line %d: %s"),
- fname, lnum, rline);
- continue;
- }
- line = pc;
- } else {
- pc = NULL;
- line = rline;
- }
-
- if (*line == '/') {
- ++line;
- if (STRNCMP(line, "encoding=", 9) == 0) {
- if (spin->si_conv.vc_type != CONV_NONE)
- smsg(_("Duplicate /encoding= line ignored in %s line %d: %s"),
- fname, lnum, line - 1);
- else if (did_word)
- smsg(_("/encoding= line after word ignored in %s line %d: %s"),
- fname, lnum, line - 1);
- else {
- char_u *enc;
-
- // Setup for conversion to 'encoding'.
- line += 9;
- enc = enc_canonize(line);
- if (!spin->si_ascii
- && convert_setup(&spin->si_conv, enc,
- p_enc) == FAIL)
- smsg(_("Conversion in %s not supported: from %s to %s"),
- fname, line, p_enc);
- xfree(enc);
- spin->si_conv.vc_fail = true;
- }
- continue;
- }
-
- if (STRNCMP(line, "regions=", 8) == 0) {
- if (spin->si_region_count > 1)
- smsg(_("Duplicate /regions= line ignored in %s line %d: %s"),
- fname, lnum, line);
- else {
- line += 8;
- if (STRLEN(line) > 16)
- smsg(_("Too many regions in %s line %d: %s"),
- fname, lnum, line);
- else {
- spin->si_region_count = (int)STRLEN(line) / 2;
- STRCPY(spin->si_region_name, line);
-
- // Adjust the mask for a word valid in all regions.
- spin->si_region = (1 << spin->si_region_count) - 1;
- }
- }
- continue;
- }
-
- smsg(_("/ line ignored in %s line %d: %s"),
- fname, lnum, line - 1);
- continue;
- }
-
- flags = 0;
- regionmask = spin->si_region;
-
- // Check for flags and region after a slash.
- p = vim_strchr(line, '/');
- if (p != NULL) {
- *p++ = NUL;
- while (*p != NUL) {
- if (*p == '=') // keep-case word
- flags |= WF_KEEPCAP | WF_FIXCAP;
- else if (*p == '!') // Bad, bad, wicked word.
- flags |= WF_BANNED;
- else if (*p == '?') // Rare word.
- flags |= WF_RARE;
- else if (ascii_isdigit(*p)) { // region number(s)
- if ((flags & WF_REGION) == 0) // first one
- regionmask = 0;
- flags |= WF_REGION;
-
- l = *p - '0';
- if (l > spin->si_region_count) {
- smsg(_("Invalid region nr in %s line %d: %s"),
- fname, lnum, p);
- break;
- }
- regionmask |= 1 << (l - 1);
- } else {
- smsg(_("Unrecognized flags in %s line %d: %s"),
- fname, lnum, p);
- break;
- }
- ++p;
- }
- }
-
- // Skip non-ASCII words when "spin->si_ascii" is true.
- if (spin->si_ascii && has_non_ascii(line)) {
- ++non_ascii;
- continue;
- }
-
- // Normal word: store it.
- if (store_word(spin, line, flags, regionmask, NULL, false) == FAIL) {
- retval = FAIL;
- break;
- }
- did_word = true;
- }
-
- xfree(pc);
- fclose(fd);
-
- if (spin->si_ascii && non_ascii > 0) {
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Ignored %d words with non-ASCII characters"), non_ascii);
- spell_message(spin, IObuff);
- }
-
- return retval;
-}
-
-/// Get part of an sblock_T, "len" bytes long.
-/// This avoids calling free() for every little struct we use (and keeping
-/// track of them).
-/// The memory is cleared to all zeros.
-///
-/// @param len Length needed (<= SBLOCKSIZE).
-/// @param align Align for pointer.
-/// @return Pointer into block data.
-static void *getroom(spellinfo_T *spin, size_t len, bool align)
- FUNC_ATTR_NONNULL_RET
-{
- char_u *p;
- sblock_T *bl = spin->si_blocks;
-
- assert(len <= SBLOCKSIZE);
-
- if (align && bl != NULL)
- // Round size up for alignment. On some systems structures need to be
- // aligned to the size of a pointer (e.g., SPARC).
- bl->sb_used = (bl->sb_used + sizeof(char *) - 1)
- & ~(sizeof(char *) - 1);
-
- if (bl == NULL || bl->sb_used + len > SBLOCKSIZE) {
- // Allocate a block of memory. It is not freed until much later.
- bl = xcalloc(1, (sizeof(sblock_T) + SBLOCKSIZE));
- bl->sb_next = spin->si_blocks;
- spin->si_blocks = bl;
- bl->sb_used = 0;
- ++spin->si_blocks_cnt;
- }
-
- p = bl->sb_data + bl->sb_used;
- bl->sb_used += (int)len;
-
- return p;
-}
-
-// Make a copy of a string into memory allocated with getroom().
-// Returns NULL when out of memory.
-static char_u *getroom_save(spellinfo_T *spin, char_u *s)
-{
- char_u *sc;
-
- sc = (char_u *)getroom(spin, STRLEN(s) + 1, false);
- if (sc != NULL)
- STRCPY(sc, s);
- return sc;
-}
-
-
-// Free the list of allocated sblock_T.
-static void free_blocks(sblock_T *bl)
-{
- sblock_T *next;
-
- while (bl != NULL) {
- next = bl->sb_next;
- xfree(bl);
- bl = next;
- }
-}
-
-// Allocate the root of a word tree.
-// Returns NULL when out of memory.
-static wordnode_T *wordtree_alloc(spellinfo_T *spin)
-{
- return (wordnode_T *)getroom(spin, sizeof(wordnode_T), true);
-}
-
-// Store a word in the tree(s).
-// Always store it in the case-folded tree. For a keep-case word this is
-// useful when the word can also be used with all caps (no WF_FIXCAP flag) and
-// used to find suggestions.
-// For a keep-case word also store it in the keep-case tree.
-// When "pfxlist" is not NULL store the word for each postponed prefix ID and
-// compound flag.
-static int
-store_word (
- spellinfo_T *spin,
- char_u *word,
- int flags, // extra flags, WF_BANNED
- int region, // supported region(s)
- char_u *pfxlist, // list of prefix IDs or NULL
- bool need_affix // only store word with affix ID
-)
-{
- int len = (int)STRLEN(word);
- int ct = captype(word, word + len);
- char_u foldword[MAXWLEN];
- int res = OK;
- char_u *p;
-
- (void)spell_casefold(word, len, foldword, MAXWLEN);
- for (p = pfxlist; res == OK; ++p) {
- if (!need_affix || (p != NULL && *p != NUL))
- res = tree_add_word(spin, foldword, spin->si_foldroot, ct | flags,
- region, p == NULL ? 0 : *p);
- if (p == NULL || *p == NUL)
- break;
- }
- ++spin->si_foldwcount;
-
- if (res == OK && (ct == WF_KEEPCAP || (flags & WF_KEEPCAP))) {
- for (p = pfxlist; res == OK; ++p) {
- if (!need_affix || (p != NULL && *p != NUL))
- res = tree_add_word(spin, word, spin->si_keeproot, flags,
- region, p == NULL ? 0 : *p);
- if (p == NULL || *p == NUL)
- break;
- }
- ++spin->si_keepwcount;
- }
- return res;
-}
-
-// Add word "word" to a word tree at "root".
-// When "flags" < 0 we are adding to the prefix tree where "flags" is used for
-// "rare" and "region" is the condition nr.
-// Returns FAIL when out of memory.
-static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int flags, int region, int affixID)
-{
- wordnode_T *node = root;
- wordnode_T *np;
- wordnode_T *copyp, **copyprev;
- wordnode_T **prev = NULL;
- int i;
-
- // Add each byte of the word to the tree, including the NUL at the end.
- for (i = 0;; ++i) {
- // When there is more than one reference to this node we need to make
- // a copy, so that we can modify it. Copy the whole list of siblings
- // (we don't optimize for a partly shared list of siblings).
- if (node != NULL && node->wn_refs > 1) {
- --node->wn_refs;
- copyprev = prev;
- for (copyp = node; copyp != NULL; copyp = copyp->wn_sibling) {
- // Allocate a new node and copy the info.
- np = get_wordnode(spin);
- if (np == NULL)
- return FAIL;
- np->wn_child = copyp->wn_child;
- if (np->wn_child != NULL)
- ++np->wn_child->wn_refs; // child gets extra ref
- np->wn_byte = copyp->wn_byte;
- if (np->wn_byte == NUL) {
- np->wn_flags = copyp->wn_flags;
- np->wn_region = copyp->wn_region;
- np->wn_affixID = copyp->wn_affixID;
- }
-
- // Link the new node in the list, there will be one ref.
- np->wn_refs = 1;
- if (copyprev != NULL)
- *copyprev = np;
- copyprev = &np->wn_sibling;
-
- // Let "node" point to the head of the copied list.
- if (copyp == node)
- node = np;
- }
- }
-
- // Look for the sibling that has the same character. They are sorted
- // on byte value, thus stop searching when a sibling is found with a
- // higher byte value. For zero bytes (end of word) the sorting is
- // done on flags and then on affixID.
- while (node != NULL
- && (node->wn_byte < word[i]
- || (node->wn_byte == NUL
- && (flags < 0
- ? node->wn_affixID < (unsigned)affixID
- : (node->wn_flags < (unsigned)(flags & WN_MASK)
- || (node->wn_flags == (flags & WN_MASK)
- && (spin->si_sugtree
- ? (node->wn_region & 0xffff) < region
- : node->wn_affixID
- < (unsigned)affixID))))))) {
- prev = &node->wn_sibling;
- node = *prev;
- }
- if (node == NULL
- || node->wn_byte != word[i]
- || (word[i] == NUL
- && (flags < 0
- || spin->si_sugtree
- || node->wn_flags != (flags & WN_MASK)
- || node->wn_affixID != affixID))) {
- // Allocate a new node.
- np = get_wordnode(spin);
- if (np == NULL)
- return FAIL;
- np->wn_byte = word[i];
-
- // If "node" is NULL this is a new child or the end of the sibling
- // list: ref count is one. Otherwise use ref count of sibling and
- // make ref count of sibling one (matters when inserting in front
- // of the list of siblings).
- if (node == NULL)
- np->wn_refs = 1;
- else {
- np->wn_refs = node->wn_refs;
- node->wn_refs = 1;
- }
- if (prev != NULL)
- *prev = np;
- np->wn_sibling = node;
- node = np;
- }
-
- if (word[i] == NUL) {
- node->wn_flags = flags;
- node->wn_region |= region;
- node->wn_affixID = affixID;
- break;
- }
- prev = &node->wn_child;
- node = *prev;
- }
-#ifdef SPELL_PRINTTREE
- smsg((char_u *)"Added \"%s\"", word);
- spell_print_tree(root->wn_sibling);
-#endif
-
- // count nr of words added since last message
- ++spin->si_msg_count;
-
- if (spin->si_compress_cnt > 1) {
- if (--spin->si_compress_cnt == 1)
- // Did enough words to lower the block count limit.
- spin->si_blocks_cnt += compress_inc;
- }
-
- // When we have allocated lots of memory we need to compress the word tree
- // to free up some room. But compression is slow, and we might actually
- // need that room, thus only compress in the following situations:
- // 1. When not compressed before (si_compress_cnt == 0): when using
- // "compress_start" blocks.
- // 2. When compressed before and used "compress_inc" blocks before
- // adding "compress_added" words (si_compress_cnt > 1).
- // 3. When compressed before, added "compress_added" words
- // (si_compress_cnt == 1) and the number of free nodes drops below the
- // maximum word length.
-#ifndef SPELL_COMPRESS_ALLWAYS
- if (spin->si_compress_cnt == 1 // NOLINT(readability/braces)
- ? spin->si_free_count < MAXWLEN
- : spin->si_blocks_cnt >= compress_start)
-#endif
- {
- // Decrement the block counter. The effect is that we compress again
- // when the freed up room has been used and another "compress_inc"
- // blocks have been allocated. Unless "compress_added" words have
- // been added, then the limit is put back again.
- spin->si_blocks_cnt -= compress_inc;
- spin->si_compress_cnt = compress_added;
-
- if (spin->si_verbose) {
- msg_start();
- msg_puts((char_u *)_(msg_compressing));
- msg_clr_eos();
- msg_didout = FALSE;
- msg_col = 0;
- ui_flush();
- }
-
- // Compress both trees. Either they both have many nodes, which makes
- // compression useful, or one of them is small, which means
- // compression goes fast. But when filling the soundfold word tree
- // there is no keep-case tree.
- wordtree_compress(spin, spin->si_foldroot);
- if (affixID >= 0)
- wordtree_compress(spin, spin->si_keeproot);
- }
-
- return OK;
-}
-
-// Check the 'mkspellmem' option. Return FAIL if it's wrong.
-// Sets "sps_flags".
-int spell_check_msm(void)
-{
- char_u *p = p_msm;
- long start = 0;
- long incr = 0;
- long added = 0;
-
- if (!ascii_isdigit(*p))
- return FAIL;
- // block count = (value * 1024) / SBLOCKSIZE (but avoid overflow)
- start = (getdigits_long(&p) * 10) / (SBLOCKSIZE / 102);
- if (*p != ',')
- return FAIL;
- ++p;
- if (!ascii_isdigit(*p))
- return FAIL;
- incr = (getdigits_long(&p) * 102) / (SBLOCKSIZE / 10);
- if (*p != ',')
- return FAIL;
- ++p;
- if (!ascii_isdigit(*p))
- return FAIL;
- added = getdigits_long(&p) * 1024;
- if (*p != NUL)
- return FAIL;
-
- if (start == 0 || incr == 0 || added == 0 || incr > start)
- return FAIL;
-
- compress_start = start;
- compress_inc = incr;
- compress_added = added;
- return OK;
-}
-
-// Get a wordnode_T, either from the list of previously freed nodes or
-// allocate a new one.
-// Returns NULL when out of memory.
-static wordnode_T *get_wordnode(spellinfo_T *spin)
-{
- wordnode_T *n;
-
- if (spin->si_first_free == NULL)
- n = (wordnode_T *)getroom(spin, sizeof(wordnode_T), true);
- else {
- n = spin->si_first_free;
- spin->si_first_free = n->wn_child;
- memset(n, 0, sizeof(wordnode_T));
- --spin->si_free_count;
- }
-#ifdef SPELL_PRINTTREE
- if (n != NULL)
- n->wn_nr = ++spin->si_wordnode_nr;
-#endif
- return n;
-}
-
-// Decrement the reference count on a node (which is the head of a list of
-// siblings). If the reference count becomes zero free the node and its
-// siblings.
-// Returns the number of nodes actually freed.
-static int deref_wordnode(spellinfo_T *spin, wordnode_T *node)
-{
- wordnode_T *np;
- int cnt = 0;
-
- if (--node->wn_refs == 0) {
- for (np = node; np != NULL; np = np->wn_sibling) {
- if (np->wn_child != NULL)
- cnt += deref_wordnode(spin, np->wn_child);
- free_wordnode(spin, np);
- ++cnt;
- }
- ++cnt; // length field
- }
- return cnt;
-}
-
-// Free a wordnode_T for re-use later.
-// Only the "wn_child" field becomes invalid.
-static void free_wordnode(spellinfo_T *spin, wordnode_T *n)
-{
- n->wn_child = spin->si_first_free;
- spin->si_first_free = n;
- ++spin->si_free_count;
-}
-
-// Compress a tree: find tails that are identical and can be shared.
-static void wordtree_compress(spellinfo_T *spin, wordnode_T *root)
-{
- hashtab_T ht;
- int n;
- int tot = 0;
- int perc;
-
- // Skip the root itself, it's not actually used. The first sibling is the
- // start of the tree.
- if (root->wn_sibling != NULL) {
- hash_init(&ht);
- n = node_compress(spin, root->wn_sibling, &ht, &tot);
-
-#ifndef SPELL_PRINTTREE
- if (spin->si_verbose || p_verbose > 2)
-#endif
- {
- if (tot > 1000000)
- perc = (tot - n) / (tot / 100);
- else if (tot == 0)
- perc = 0;
- else
- perc = (tot - n) * 100 / tot;
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Compressed %d of %d nodes; %d (%d%%) remaining"),
- n, tot, tot - n, perc);
- spell_message(spin, IObuff);
- }
-#ifdef SPELL_PRINTTREE
- spell_print_tree(root->wn_sibling);
-#endif
- hash_clear(&ht);
- }
-}
-
-// Compress a node, its siblings and its children, depth first.
-// Returns the number of compressed nodes.
-static int
-node_compress (
- spellinfo_T *spin,
- wordnode_T *node,
- hashtab_T *ht,
- int *tot // total count of nodes before compressing,
- // incremented while going through the tree
-)
-{
- wordnode_T *np;
- wordnode_T *tp;
- wordnode_T *child;
- hash_T hash;
- hashitem_T *hi;
- int len = 0;
- unsigned nr, n;
- int compressed = 0;
-
- // Go through the list of siblings. Compress each child and then try
- // finding an identical child to replace it.
- // Note that with "child" we mean not just the node that is pointed to,
- // but the whole list of siblings of which the child node is the first.
- for (np = node; np != NULL && !got_int; np = np->wn_sibling) {
- ++len;
- if ((child = np->wn_child) != NULL) {
- // Compress the child first. This fills hashkey.
- compressed += node_compress(spin, child, ht, tot);
-
- // Try to find an identical child.
- hash = hash_hash(child->wn_u1.hashkey);
- hi = hash_lookup(ht, child->wn_u1.hashkey, hash);
- if (!HASHITEM_EMPTY(hi)) {
- // There are children we encountered before with a hash value
- // identical to the current child. Now check if there is one
- // that is really identical.
- for (tp = HI2WN(hi); tp != NULL; tp = tp->wn_u2.next)
- if (node_equal(child, tp)) {
- // Found one! Now use that child in place of the
- // current one. This means the current child and all
- // its siblings is unlinked from the tree.
- ++tp->wn_refs;
- compressed += deref_wordnode(spin, child);
- np->wn_child = tp;
- break;
- }
- if (tp == NULL) {
- // No other child with this hash value equals the child of
- // the node, add it to the linked list after the first
- // item.
- tp = HI2WN(hi);
- child->wn_u2.next = tp->wn_u2.next;
- tp->wn_u2.next = child;
- }
- } else
- // No other child has this hash value, add it to the
- // hashtable.
- hash_add_item(ht, hi, child->wn_u1.hashkey, hash);
- }
- }
- *tot += len + 1; // add one for the node that stores the length
-
- // Make a hash key for the node and its siblings, so that we can quickly
- // find a lookalike node. This must be done after compressing the sibling
- // list, otherwise the hash key would become invalid by the compression.
- node->wn_u1.hashkey[0] = len;
- nr = 0;
- for (np = node; np != NULL; np = np->wn_sibling) {
- if (np->wn_byte == NUL)
- // end node: use wn_flags, wn_region and wn_affixID
- n = np->wn_flags + (np->wn_region << 8) + (np->wn_affixID << 16);
- else
- // byte node: use the byte value and the child pointer
- n = (unsigned)(np->wn_byte + ((uintptr_t)np->wn_child << 8));
- nr = nr * 101 + n;
- }
-
- // Avoid NUL bytes, it terminates the hash key.
- n = nr & 0xff;
- node->wn_u1.hashkey[1] = n == 0 ? 1 : n;
- n = (nr >> 8) & 0xff;
- node->wn_u1.hashkey[2] = n == 0 ? 1 : n;
- n = (nr >> 16) & 0xff;
- node->wn_u1.hashkey[3] = n == 0 ? 1 : n;
- n = (nr >> 24) & 0xff;
- node->wn_u1.hashkey[4] = n == 0 ? 1 : n;
- node->wn_u1.hashkey[5] = NUL;
-
- // Check for CTRL-C pressed now and then.
- fast_breakcheck();
-
- return compressed;
-}
-
-// Returns true when two nodes have identical siblings and children.
-static bool node_equal(wordnode_T *n1, wordnode_T *n2)
-{
- wordnode_T *p1;
- wordnode_T *p2;
-
- for (p1 = n1, p2 = n2; p1 != NULL && p2 != NULL;
- p1 = p1->wn_sibling, p2 = p2->wn_sibling)
- if (p1->wn_byte != p2->wn_byte
- || (p1->wn_byte == NUL
- ? (p1->wn_flags != p2->wn_flags
- || p1->wn_region != p2->wn_region
- || p1->wn_affixID != p2->wn_affixID)
- : (p1->wn_child != p2->wn_child)))
- break;
-
- return p1 == NULL && p2 == NULL;
-}
-
-
-// Function given to qsort() to sort the REP items on "from" string.
-static int rep_compare(const void *s1, const void *s2)
-{
- fromto_T *p1 = (fromto_T *)s1;
- fromto_T *p2 = (fromto_T *)s2;
-
- return STRCMP(p1->ft_from, p2->ft_from);
-}
-
-// Write the Vim .spl file "fname".
-// Return OK/FAIL.
-static int write_vim_spell(spellinfo_T *spin, char_u *fname)
-{
- int retval = OK;
- int regionmask;
-
- FILE *fd = mch_fopen((char *)fname, "w");
- if (fd == NULL) {
- EMSG2(_(e_notopen), fname);
- return FAIL;
- }
-
- // <HEADER>: <fileID> <versionnr>
- // <fileID>
- size_t fwv = fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, 1, fd);
- if (fwv != (size_t)1)
- // Catch first write error, don't try writing more.
- goto theend;
-
- putc(VIMSPELLVERSION, fd); // <versionnr>
-
- // <SECTIONS>: <section> ... <sectionend>
-
- // SN_INFO: <infotext>
- if (spin->si_info != NULL) {
- putc(SN_INFO, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
- size_t i = STRLEN(spin->si_info);
- put_bytes(fd, i, 4); // <sectionlen>
- fwv &= fwrite(spin->si_info, i, 1, fd); // <infotext>
- }
-
- // SN_REGION: <regionname> ...
- // Write the region names only if there is more than one.
- if (spin->si_region_count > 1) {
- putc(SN_REGION, fd); // <sectionID>
- putc(SNF_REQUIRED, fd); // <sectionflags>
- size_t l = (size_t)spin->si_region_count * 2;
- put_bytes(fd, l, 4); // <sectionlen>
- fwv &= fwrite(spin->si_region_name, l, 1, fd);
- // <regionname> ...
- regionmask = (1 << spin->si_region_count) - 1;
- } else
- regionmask = 0;
-
- // SN_CHARFLAGS: <charflagslen> <charflags> <folcharslen> <folchars>
- //
- // The table with character flags and the table for case folding.
- // This makes sure the same characters are recognized as word characters
- // when generating an when using a spell file.
- // Skip this for ASCII, the table may conflict with the one used for
- // 'encoding'.
- // Also skip this for an .add.spl file, the main spell file must contain
- // the table (avoids that it conflicts). File is shorter too.
- if (!spin->si_ascii && !spin->si_add) {
- char_u folchars[128 * 8];
- int flags;
-
- putc(SN_CHARFLAGS, fd); // <sectionID>
- putc(SNF_REQUIRED, fd); // <sectionflags>
-
- // Form the <folchars> string first, we need to know its length.
- size_t l = 0;
- for (size_t i = 128; i < 256; ++i) {
- if (has_mbyte)
- l += (size_t)mb_char2bytes(spelltab.st_fold[i], folchars + l);
- else
- folchars[l++] = spelltab.st_fold[i];
- }
- put_bytes(fd, 1 + 128 + 2 + l, 4); // <sectionlen>
-
- fputc(128, fd); // <charflagslen>
- for (size_t i = 128; i < 256; ++i) {
- flags = 0;
- if (spelltab.st_isw[i])
- flags |= CF_WORD;
- if (spelltab.st_isu[i])
- flags |= CF_UPPER;
- fputc(flags, fd); // <charflags>
- }
-
- put_bytes(fd, l, 2); // <folcharslen>
- fwv &= fwrite(folchars, l, 1, fd); // <folchars>
- }
-
- // SN_MIDWORD: <midword>
- if (spin->si_midword != NULL) {
- putc(SN_MIDWORD, fd); // <sectionID>
- putc(SNF_REQUIRED, fd); // <sectionflags>
-
- size_t i = STRLEN(spin->si_midword);
- put_bytes(fd, i, 4); // <sectionlen>
- fwv &= fwrite(spin->si_midword, i, 1, fd);
- // <midword>
- }
-
- // SN_PREFCOND: <prefcondcnt> <prefcond> ...
- if (!GA_EMPTY(&spin->si_prefcond)) {
- putc(SN_PREFCOND, fd); // <sectionID>
- putc(SNF_REQUIRED, fd); // <sectionflags>
-
- size_t l = (size_t)write_spell_prefcond(NULL, &spin->si_prefcond);
- put_bytes(fd, l, 4); // <sectionlen>
-
- write_spell_prefcond(fd, &spin->si_prefcond);
- }
-
- // SN_REP: <repcount> <rep> ...
- // SN_SAL: <salflags> <salcount> <sal> ...
- // SN_REPSAL: <repcount> <rep> ...
-
- // round 1: SN_REP section
- // round 2: SN_SAL section (unless SN_SOFO is used)
- // round 3: SN_REPSAL section
- for (unsigned int round = 1; round <= 3; ++round) {
- garray_T *gap;
- if (round == 1)
- gap = &spin->si_rep;
- else if (round == 2) {
- // Don't write SN_SAL when using a SN_SOFO section
- if (spin->si_sofofr != NULL && spin->si_sofoto != NULL)
- continue;
- gap = &spin->si_sal;
- } else
- gap = &spin->si_repsal;
-
- // Don't write the section if there are no items.
- if (GA_EMPTY(gap))
- continue;
-
- // Sort the REP/REPSAL items.
- if (round != 2)
- qsort(gap->ga_data, (size_t)gap->ga_len,
- sizeof(fromto_T), rep_compare);
-
- int i = round == 1 ? SN_REP : (round == 2 ? SN_SAL : SN_REPSAL);
- putc(i, fd); // <sectionID>
-
- // This is for making suggestions, section is not required.
- putc(0, fd); // <sectionflags>
-
- // Compute the length of what follows.
- size_t l = 2; // count <repcount> or <salcount>
- assert(gap->ga_len >= 0);
- for (size_t i = 0; i < (size_t)gap->ga_len; ++i) {
- fromto_T *ftp = &((fromto_T *)gap->ga_data)[i];
- l += 1 + STRLEN(ftp->ft_from); // count <*fromlen> and <*from>
- l += 1 + STRLEN(ftp->ft_to); // count <*tolen> and <*to>
- }
- if (round == 2)
- ++l; // count <salflags>
- put_bytes(fd, l, 4); // <sectionlen>
-
- if (round == 2) {
- int i = 0;
- if (spin->si_followup)
- i |= SAL_F0LLOWUP;
- if (spin->si_collapse)
- i |= SAL_COLLAPSE;
- if (spin->si_rem_accents)
- i |= SAL_REM_ACCENTS;
- putc(i, fd); // <salflags>
- }
-
- put_bytes(fd, (uintmax_t)gap->ga_len, 2); // <repcount> or <salcount>
- for (size_t i = 0; i < (size_t)gap->ga_len; ++i) {
- // <rep> : <repfromlen> <repfrom> <reptolen> <repto>
- // <sal> : <salfromlen> <salfrom> <saltolen> <salto>
- fromto_T *ftp = &((fromto_T *)gap->ga_data)[i];
- for (unsigned int rr = 1; rr <= 2; ++rr) {
- char_u *p = rr == 1 ? ftp->ft_from : ftp->ft_to;
- l = STRLEN(p);
- assert(l < INT_MAX);
- putc((int)l, fd);
- if (l > 0)
- fwv &= fwrite(p, l, 1, fd);
- }
- }
-
- }
-
- // SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
- // This is for making suggestions, section is not required.
- if (spin->si_sofofr != NULL && spin->si_sofoto != NULL) {
- putc(SN_SOFO, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
-
- size_t l = STRLEN(spin->si_sofofr);
- put_bytes(fd, l + STRLEN(spin->si_sofoto) + 4, 4); // <sectionlen>
-
- put_bytes(fd, l, 2); // <sofofromlen>
- fwv &= fwrite(spin->si_sofofr, l, 1, fd); // <sofofrom>
-
- l = STRLEN(spin->si_sofoto);
- put_bytes(fd, l, 2); // <sofotolen>
- fwv &= fwrite(spin->si_sofoto, l, 1, fd); // <sofoto>
- }
-
- // SN_WORDS: <word> ...
- // This is for making suggestions, section is not required.
- if (spin->si_commonwords.ht_used > 0) {
- putc(SN_WORDS, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
-
- // round 1: count the bytes
- // round 2: write the bytes
- for (unsigned int round = 1; round <= 2; ++round) {
- size_t todo;
- size_t len = 0;
- hashitem_T *hi;
-
- todo = spin->si_commonwords.ht_used;
- for (hi = spin->si_commonwords.ht_array; todo > 0; ++hi)
- if (!HASHITEM_EMPTY(hi)) {
- size_t l = STRLEN(hi->hi_key) + 1;
- len += l;
- if (round == 2) // <word>
- fwv &= fwrite(hi->hi_key, l, 1, fd);
- --todo;
- }
- if (round == 1)
- put_bytes(fd, len, 4); // <sectionlen>
- }
- }
-
- // SN_MAP: <mapstr>
- // This is for making suggestions, section is not required.
- if (!GA_EMPTY(&spin->si_map)) {
- putc(SN_MAP, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
- size_t l = (size_t)spin->si_map.ga_len;
- put_bytes(fd, l, 4); // <sectionlen>
- fwv &= fwrite(spin->si_map.ga_data, l, 1, fd); // <mapstr>
- }
-
- // SN_SUGFILE: <timestamp>
- // This is used to notify that a .sug file may be available and at the
- // same time allows for checking that a .sug file that is found matches
- // with this .spl file. That's because the word numbers must be exactly
- // right.
- if (!spin->si_nosugfile
- && (!GA_EMPTY(&spin->si_sal)
- || (spin->si_sofofr != NULL && spin->si_sofoto != NULL))) {
- putc(SN_SUGFILE, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
- put_bytes(fd, 8, 4); // <sectionlen>
-
- // Set si_sugtime and write it to the file.
- spin->si_sugtime = time(NULL);
- put_time(fd, spin->si_sugtime); // <timestamp>
- }
-
- // SN_NOSPLITSUGS: nothing
- // This is used to notify that no suggestions with word splits are to be
- // made.
- if (spin->si_nosplitsugs) {
- putc(SN_NOSPLITSUGS, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
- put_bytes(fd, 0, 4); // <sectionlen>
- }
-
- // SN_NOCOMPUNDSUGS: nothing
- // This is used to notify that no suggestions with compounds are to be
- // made.
- if (spin->si_nocompoundsugs) {
- putc(SN_NOCOMPOUNDSUGS, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
- put_bytes(fd, 0, 4); // <sectionlen>
- }
-
- // SN_COMPOUND: compound info.
- // We don't mark it required, when not supported all compound words will
- // be bad words.
- if (spin->si_compflags != NULL) {
- putc(SN_COMPOUND, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
-
- size_t l = STRLEN(spin->si_compflags);
- assert(spin->si_comppat.ga_len >= 0);
- for (size_t i = 0; i < (size_t)spin->si_comppat.ga_len; ++i) {
- l += STRLEN(((char_u **)(spin->si_comppat.ga_data))[i]) + 1;
- }
- put_bytes(fd, l + 7, 4); // <sectionlen>
-
- putc(spin->si_compmax, fd); // <compmax>
- putc(spin->si_compminlen, fd); // <compminlen>
- putc(spin->si_compsylmax, fd); // <compsylmax>
- putc(0, fd); // for Vim 7.0b compatibility
- putc(spin->si_compoptions, fd); // <compoptions>
- put_bytes(fd, (uintmax_t)spin->si_comppat.ga_len, 2); // <comppatcount>
- for (size_t i = 0; i < (size_t)spin->si_comppat.ga_len; ++i) {
- char_u *p = ((char_u **)(spin->si_comppat.ga_data))[i];
- assert(STRLEN(p) < INT_MAX);
- putc((int)STRLEN(p), fd); // <comppatlen>
- fwv &= fwrite(p, STRLEN(p), 1, fd); // <comppattext>
- }
- // <compflags>
- fwv &= fwrite(spin->si_compflags, STRLEN(spin->si_compflags), 1, fd);
- }
-
- // SN_NOBREAK: NOBREAK flag
- if (spin->si_nobreak) {
- putc(SN_NOBREAK, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
-
- // It's empty, the presence of the section flags the feature.
- put_bytes(fd, 0, 4); // <sectionlen>
- }
-
- // SN_SYLLABLE: syllable info.
- // We don't mark it required, when not supported syllables will not be
- // counted.
- if (spin->si_syllable != NULL) {
- putc(SN_SYLLABLE, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
-
- size_t l = STRLEN(spin->si_syllable);
- put_bytes(fd, l, 4); // <sectionlen>
- fwv &= fwrite(spin->si_syllable, l, 1, fd); // <syllable>
- }
-
- // end of <SECTIONS>
- putc(SN_END, fd); // <sectionend>
-
-
- // <LWORDTREE> <KWORDTREE> <PREFIXTREE>
- spin->si_memtot = 0;
- for (unsigned int round = 1; round <= 3; ++round) {
- wordnode_T *tree;
- if (round == 1)
- tree = spin->si_foldroot->wn_sibling;
- else if (round == 2)
- tree = spin->si_keeproot->wn_sibling;
- else
- tree = spin->si_prefroot->wn_sibling;
-
- // Clear the index and wnode fields in the tree.
- clear_node(tree);
-
- // Count the number of nodes. Needed to be able to allocate the
- // memory when reading the nodes. Also fills in index for shared
- // nodes.
- size_t nodecount = (size_t)put_node(NULL, tree, 0, regionmask, round == 3);
-
- // number of nodes in 4 bytes
- put_bytes(fd, nodecount, 4); // <nodecount>
- assert(nodecount + nodecount * sizeof(int) < INT_MAX);
- spin->si_memtot += (int)(nodecount + nodecount * sizeof(int));
-
- // Write the nodes.
- (void)put_node(fd, tree, 0, regionmask, round == 3);
- }
-
- // Write another byte to check for errors (file system full).
- if (putc(0, fd) == EOF)
- retval = FAIL;
-theend:
- if (fclose(fd) == EOF)
- retval = FAIL;
-
- if (fwv != (size_t)1)
- retval = FAIL;
- if (retval == FAIL)
- EMSG(_(e_write));
-
- return retval;
-}
-
-// Clear the index and wnode fields of "node", it siblings and its
-// children. This is needed because they are a union with other items to save
-// space.
-static void clear_node(wordnode_T *node)
-{
- wordnode_T *np;
-
- if (node != NULL)
- for (np = node; np != NULL; np = np->wn_sibling) {
- np->wn_u1.index = 0;
- np->wn_u2.wnode = NULL;
-
- if (np->wn_byte != NUL)
- clear_node(np->wn_child);
- }
-}
-
-
-// Dump a word tree at node "node".
-//
-// This first writes the list of possible bytes (siblings). Then for each
-// byte recursively write the children.
-//
-// NOTE: The code here must match the code in read_tree_node(), since
-// assumptions are made about the indexes (so that we don't have to write them
-// in the file).
-//
-// Returns the number of nodes used.
-static int
-put_node (
- FILE *fd, // NULL when only counting
- wordnode_T *node,
- int idx,
- int regionmask,
- bool prefixtree // true for PREFIXTREE
-)
-{
- // If "node" is zero the tree is empty.
- if (node == NULL)
- return 0;
-
- // Store the index where this node is written.
- node->wn_u1.index = idx;
-
- // Count the number of siblings.
- int siblingcount = 0;
- for (wordnode_T *np = node; np != NULL; np = np->wn_sibling)
- ++siblingcount;
-
- // Write the sibling count.
- if (fd != NULL)
- putc(siblingcount, fd); // <siblingcount>
-
- // Write each sibling byte and optionally extra info.
- for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) {
- if (np->wn_byte == 0) {
- if (fd != NULL) {
- // For a NUL byte (end of word) write the flags etc.
- if (prefixtree) {
- // In PREFIXTREE write the required affixID and the
- // associated condition nr (stored in wn_region). The
- // byte value is misused to store the "rare" and "not
- // combining" flags
- if (np->wn_flags == (uint16_t)PFX_FLAGS)
- putc(BY_NOFLAGS, fd); // <byte>
- else {
- putc(BY_FLAGS, fd); // <byte>
- putc(np->wn_flags, fd); // <pflags>
- }
- putc(np->wn_affixID, fd); // <affixID>
- put_bytes(fd, (uintmax_t)np->wn_region, 2); // <prefcondnr>
- } else {
- // For word trees we write the flag/region items.
- int flags = np->wn_flags;
- if (regionmask != 0 && np->wn_region != regionmask)
- flags |= WF_REGION;
- if (np->wn_affixID != 0)
- flags |= WF_AFX;
- if (flags == 0) {
- // word without flags or region
- putc(BY_NOFLAGS, fd); // <byte>
- } else {
- if (np->wn_flags >= 0x100) {
- putc(BY_FLAGS2, fd); // <byte>
- putc(flags, fd); // <flags>
- putc((int)((unsigned)flags >> 8), fd); // <flags2>
- } else {
- putc(BY_FLAGS, fd); // <byte>
- putc(flags, fd); // <flags>
- }
- if (flags & WF_REGION)
- putc(np->wn_region, fd); // <region>
- if (flags & WF_AFX)
- putc(np->wn_affixID, fd); // <affixID>
- }
- }
- }
- } else {
- if (np->wn_child->wn_u1.index != 0
- && np->wn_child->wn_u2.wnode != node) {
- // The child is written elsewhere, write the reference.
- if (fd != NULL) {
- putc(BY_INDEX, fd); // <byte>
- put_bytes(fd, (uintmax_t)np->wn_child->wn_u1.index, 3); // <nodeidx>
- }
- } else if (np->wn_child->wn_u2.wnode == NULL)
- // We will write the child below and give it an index.
- np->wn_child->wn_u2.wnode = node;
-
- if (fd != NULL)
- if (putc(np->wn_byte, fd) == EOF) { // <byte> or <xbyte>
- EMSG(_(e_write));
- return 0;
- }
- }
- }
-
- // Space used in the array when reading: one for each sibling and one for
- // the count.
- int newindex = idx + siblingcount + 1;
-
- // Recursively dump the children of each sibling.
- for (wordnode_T *np = node; np != NULL; np = np->wn_sibling)
- if (np->wn_byte != 0 && np->wn_child->wn_u2.wnode == node)
- newindex = put_node(fd, np->wn_child, newindex, regionmask,
- prefixtree);
-
- return newindex;
-}
-
-
-// ":mkspell [-ascii] outfile infile ..."
-// ":mkspell [-ascii] addfile"
-void ex_mkspell(exarg_T *eap)
-{
- int fcount;
- char_u **fnames;
- char_u *arg = eap->arg;
- bool ascii = false;
-
- if (STRNCMP(arg, "-ascii", 6) == 0) {
- ascii = true;
- arg = skipwhite(arg + 6);
- }
-
- // Expand all the remaining arguments (e.g., $VIMRUNTIME).
- if (get_arglist_exp(arg, &fcount, &fnames, false) == OK) {
- mkspell(fcount, fnames, ascii, eap->forceit, false);
- FreeWild(fcount, fnames);
- }
-}
-
-// Create the .sug file.
-// Uses the soundfold info in "spin".
-// Writes the file with the name "wfname", with ".spl" changed to ".sug".
-static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname)
-{
- char_u *fname = NULL;
- int len;
- slang_T *slang;
- bool free_slang = false;
-
- // Read back the .spl file that was written. This fills the required
- // info for soundfolding. This also uses less memory than the
- // pointer-linked version of the trie. And it avoids having two versions
- // of the code for the soundfolding stuff.
- // It might have been done already by spell_reload_one().
- for (slang = first_lang; slang != NULL; slang = slang->sl_next)
- if (path_full_compare(wfname, slang->sl_fname, FALSE) == kEqualFiles)
- break;
- if (slang == NULL) {
- spell_message(spin, (char_u *)_("Reading back spell file..."));
- slang = spell_load_file(wfname, NULL, NULL, false);
- if (slang == NULL)
- return;
- free_slang = true;
- }
-
- // Clear the info in "spin" that is used.
- spin->si_blocks = NULL;
- spin->si_blocks_cnt = 0;
- spin->si_compress_cnt = 0; // will stay at 0 all the time
- spin->si_free_count = 0;
- spin->si_first_free = NULL;
- spin->si_foldwcount = 0;
-
- // Go through the trie of good words, soundfold each word and add it to
- // the soundfold trie.
- spell_message(spin, (char_u *)_("Performing soundfolding..."));
- if (sug_filltree(spin, slang) == FAIL)
- goto theend;
-
- // Create the table which links each soundfold word with a list of the
- // good words it may come from. Creates buffer "spin->si_spellbuf".
- // This also removes the wordnr from the NUL byte entries to make
- // compression possible.
- if (sug_maketable(spin) == FAIL)
- goto theend;
-
- smsg(_("Number of words after soundfolding: %" PRId64),
- (int64_t)spin->si_spellbuf->b_ml.ml_line_count);
-
- // Compress the soundfold trie.
- spell_message(spin, (char_u *)_(msg_compressing));
- wordtree_compress(spin, spin->si_foldroot);
-
- // Write the .sug file.
- // Make the file name by changing ".spl" to ".sug".
- fname = xmalloc(MAXPATHL);
- STRLCPY(fname, wfname, MAXPATHL);
- len = (int)STRLEN(fname);
- fname[len - 2] = 'u';
- fname[len - 1] = 'g';
- sug_write(spin, fname);
-
-theend:
- xfree(fname);
- if (free_slang)
- slang_free(slang);
- free_blocks(spin->si_blocks);
- close_spellbuf(spin->si_spellbuf);
-}
-
-// Build the soundfold trie for language "slang".
-static int sug_filltree(spellinfo_T *spin, slang_T *slang)
-{
- char_u *byts;
- idx_T *idxs;
- int depth;
- idx_T arridx[MAXWLEN];
- int curi[MAXWLEN];
- char_u tword[MAXWLEN];
- char_u tsalword[MAXWLEN];
- int c;
- idx_T n;
- unsigned words_done = 0;
- int wordcount[MAXWLEN];
-
- // We use si_foldroot for the soundfolded trie.
- spin->si_foldroot = wordtree_alloc(spin);
- if (spin->si_foldroot == NULL)
- return FAIL;
-
- // Let tree_add_word() know we're adding to the soundfolded tree
- spin->si_sugtree = true;
-
- // Go through the whole case-folded tree, soundfold each word and put it
- // in the trie.
- byts = slang->sl_fbyts;
- idxs = slang->sl_fidxs;
-
- arridx[0] = 0;
- curi[0] = 1;
- wordcount[0] = 0;
-
- depth = 0;
- while (depth >= 0 && !got_int) {
- if (curi[depth] > byts[arridx[depth]]) {
- // Done all bytes at this node, go up one level.
- idxs[arridx[depth]] = wordcount[depth];
- if (depth > 0)
- wordcount[depth - 1] += wordcount[depth];
-
- --depth;
- line_breakcheck();
- } else {
-
- // Do one more byte at this node.
- n = arridx[depth] + curi[depth];
- ++curi[depth];
-
- c = byts[n];
- if (c == 0) {
- // Sound-fold the word.
- tword[depth] = NUL;
- spell_soundfold(slang, tword, true, tsalword);
-
- // We use the "flags" field for the MSB of the wordnr,
- // "region" for the LSB of the wordnr.
- if (tree_add_word(spin, tsalword, spin->si_foldroot,
- words_done >> 16, words_done & 0xffff,
- 0) == FAIL)
- return FAIL;
-
- ++words_done;
- ++wordcount[depth];
-
- // Reset the block count each time to avoid compression
- // kicking in.
- spin->si_blocks_cnt = 0;
-
- // Skip over any other NUL bytes (same word with different
- // flags).
- while (byts[n + 1] == 0) {
- ++n;
- ++curi[depth];
- }
- } else {
- // Normal char, go one level deeper.
- tword[depth++] = c;
- arridx[depth] = idxs[n];
- curi[depth] = 1;
- wordcount[depth] = 0;
- }
- }
- }
-
- smsg(_("Total number of words: %d"), words_done);
-
- return OK;
-}
-
-// Make the table that links each word in the soundfold trie to the words it
-// can be produced from.
-// This is not unlike lines in a file, thus use a memfile to be able to access
-// the table efficiently.
-// Returns FAIL when out of memory.
-static int sug_maketable(spellinfo_T *spin)
-{
- garray_T ga;
- int res = OK;
-
- // Allocate a buffer, open a memline for it and create the swap file
- // (uses a temp file, not a .swp file).
- spin->si_spellbuf = open_spellbuf();
-
- // Use a buffer to store the line info, avoids allocating many small
- // pieces of memory.
- ga_init(&ga, 1, 100);
-
- // recursively go through the tree
- if (sug_filltable(spin, spin->si_foldroot->wn_sibling, 0, &ga) == -1)
- res = FAIL;
-
- ga_clear(&ga);
- return res;
-}
-
-// Fill the table for one node and its children.
-// Returns the wordnr at the start of the node.
-// Returns -1 when out of memory.
-static int
-sug_filltable (
- spellinfo_T *spin,
- wordnode_T *node,
- int startwordnr,
- garray_T *gap // place to store line of numbers
-)
-{
- wordnode_T *p, *np;
- int wordnr = startwordnr;
- int nr;
- int prev_nr;
-
- for (p = node; p != NULL; p = p->wn_sibling) {
- if (p->wn_byte == NUL) {
- gap->ga_len = 0;
- prev_nr = 0;
- for (np = p; np != NULL && np->wn_byte == NUL; np = np->wn_sibling) {
- ga_grow(gap, 10);
-
- nr = (np->wn_flags << 16) + (np->wn_region & 0xffff);
- // Compute the offset from the previous nr and store the
- // offset in a way that it takes a minimum number of bytes.
- // It's a bit like utf-8, but without the need to mark
- // following bytes.
- nr -= prev_nr;
- prev_nr += nr;
- gap->ga_len += offset2bytes(nr,
- (char_u *)gap->ga_data + gap->ga_len);
- }
-
- // add the NUL byte
- ((char_u *)gap->ga_data)[gap->ga_len++] = NUL;
-
- if (ml_append_buf(spin->si_spellbuf, (linenr_T)wordnr,
- gap->ga_data, gap->ga_len, TRUE) == FAIL)
- return -1;
- ++wordnr;
-
- // Remove extra NUL entries, we no longer need them. We don't
- // bother freeing the nodes, the won't be reused anyway.
- while (p->wn_sibling != NULL && p->wn_sibling->wn_byte == NUL)
- p->wn_sibling = p->wn_sibling->wn_sibling;
-
- // Clear the flags on the remaining NUL node, so that compression
- // works a lot better.
- p->wn_flags = 0;
- p->wn_region = 0;
- } else {
- wordnr = sug_filltable(spin, p->wn_child, wordnr, gap);
- if (wordnr == -1)
- return -1;
- }
- }
- return wordnr;
-}
-
-// Convert an offset into a minimal number of bytes.
-// Similar to utf_char2byters, but use 8 bits in followup bytes and avoid NUL
-// bytes.
-static int offset2bytes(int nr, char_u *buf)
-{
- int rem;
- int b1, b2, b3, b4;
-
- // Split the number in parts of base 255. We need to avoid NUL bytes.
- b1 = nr % 255 + 1;
- rem = nr / 255;
- b2 = rem % 255 + 1;
- rem = rem / 255;
- b3 = rem % 255 + 1;
- b4 = rem / 255 + 1;
-
- if (b4 > 1 || b3 > 0x1f) { // 4 bytes
- buf[0] = 0xe0 + b4;
- buf[1] = b3;
- buf[2] = b2;
- buf[3] = b1;
- return 4;
- }
- if (b3 > 1 || b2 > 0x3f ) { // 3 bytes
- buf[0] = 0xc0 + b3;
- buf[1] = b2;
- buf[2] = b1;
- return 3;
- }
- if (b2 > 1 || b1 > 0x7f ) { // 2 bytes
- buf[0] = 0x80 + b2;
- buf[1] = b1;
- return 2;
- }
- // 1 byte
- buf[0] = b1;
- return 1;
-}
// Opposite of offset2bytes().
// "pp" points to the bytes and is advanced over it.
@@ -7442,86 +2473,12 @@ static int bytes2offset(char_u **pp)
return nr;
}
-// Write the .sug file in "fname".
-static void sug_write(spellinfo_T *spin, char_u *fname)
-{
- // Create the file. Note that an existing file is silently overwritten!
- FILE *fd = mch_fopen((char *)fname, "w");
- if (fd == NULL) {
- EMSG2(_(e_notopen), fname);
- return;
- }
-
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Writing suggestion file %s ..."), fname);
- spell_message(spin, IObuff);
-
- // <SUGHEADER>: <fileID> <versionnr> <timestamp>
- if (fwrite(VIMSUGMAGIC, VIMSUGMAGICL, (size_t)1, fd) != 1) { // <fileID>
- EMSG(_(e_write));
- goto theend;
- }
- putc(VIMSUGVERSION, fd); // <versionnr>
-
- // Write si_sugtime to the file.
- put_time(fd, spin->si_sugtime); // <timestamp>
-
- // <SUGWORDTREE>
- spin->si_memtot = 0;
- wordnode_T *tree = spin->si_foldroot->wn_sibling;
-
- // Clear the index and wnode fields in the tree.
- clear_node(tree);
-
- // Count the number of nodes. Needed to be able to allocate the
- // memory when reading the nodes. Also fills in index for shared
- // nodes.
- size_t nodecount = (size_t)put_node(NULL, tree, 0, 0, false);
-
- // number of nodes in 4 bytes
- put_bytes(fd, nodecount, 4); // <nodecount>
- assert(nodecount + nodecount * sizeof(int) < INT_MAX);
- spin->si_memtot += (int)(nodecount + nodecount * sizeof(int));
-
- // Write the nodes.
- (void)put_node(fd, tree, 0, 0, false);
-
- // <SUGTABLE>: <sugwcount> <sugline> ...
- linenr_T wcount = spin->si_spellbuf->b_ml.ml_line_count;
- assert(wcount >= 0);
- put_bytes(fd, (uintmax_t)wcount, 4); // <sugwcount>
-
- for (linenr_T lnum = 1; lnum <= wcount; ++lnum) {
- // <sugline>: <sugnr> ... NUL
- char_u *line = ml_get_buf(spin->si_spellbuf, lnum, FALSE);
- size_t len = STRLEN(line) + 1;
- if (fwrite(line, len, 1, fd) == 0) {
- EMSG(_(e_write));
- goto theend;
- }
- assert((size_t)spin->si_memtot + len <= INT_MAX);
- spin->si_memtot += (int)len;
- }
-
- // Write another byte to check for errors.
- if (putc(0, fd) == EOF)
- EMSG(_(e_write));
-
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Estimated runtime memory use: %d bytes"), spin->si_memtot);
- spell_message(spin, IObuff);
-
-theend:
- // close the file
- fclose(fd);
-}
-
// Open a spell buffer. This is a nameless buffer that is not in the buffer
// list and only contains text lines. Can use a swapfile to reduce memory
// use.
// Most other fields are invalid! Esp. watch out for string options being
// NULL and there is no undo info.
-static buf_T *open_spellbuf(void)
+buf_T *open_spellbuf(void)
{
buf_T *buf = xcalloc(1, sizeof(buf_T));
@@ -7534,7 +2491,7 @@ static buf_T *open_spellbuf(void)
}
// Close the buffer used for spell info.
-static void close_spellbuf(buf_T *buf)
+void close_spellbuf(buf_T *buf)
{
if (buf != NULL) {
ml_close(buf, TRUE);
@@ -7542,471 +2499,8 @@ static void close_spellbuf(buf_T *buf)
}
}
-
-// Create a Vim spell file from one or more word lists.
-// "fnames[0]" is the output file name.
-// "fnames[fcount - 1]" is the last input file name.
-// Exception: when "fnames[0]" ends in ".add" it's used as the input file name
-// and ".spl" is appended to make the output file name.
-static void
-mkspell (
- int fcount,
- char_u **fnames,
- bool ascii, // -ascii argument given
- bool over_write, // overwrite existing output file
- bool added_word // invoked through "zg"
-)
-{
- char_u *fname = NULL;
- char_u *wfname;
- char_u **innames;
- int incount;
- afffile_T *(afile[8]);
- int i;
- int len;
- bool error = false;
- spellinfo_T spin;
-
- memset(&spin, 0, sizeof(spin));
- spin.si_verbose = !added_word;
- spin.si_ascii = ascii;
- spin.si_followup = true;
- spin.si_rem_accents = true;
- ga_init(&spin.si_rep, (int)sizeof(fromto_T), 20);
- ga_init(&spin.si_repsal, (int)sizeof(fromto_T), 20);
- ga_init(&spin.si_sal, (int)sizeof(fromto_T), 20);
- ga_init(&spin.si_map, (int)sizeof(char_u), 100);
- ga_init(&spin.si_comppat, (int)sizeof(char_u *), 20);
- ga_init(&spin.si_prefcond, (int)sizeof(char_u *), 50);
- hash_init(&spin.si_commonwords);
- spin.si_newcompID = 127; // start compound ID at first maximum
-
- // default: fnames[0] is output file, following are input files
- innames = &fnames[1];
- incount = fcount - 1;
-
- wfname = xmalloc(MAXPATHL);
-
- if (fcount >= 1) {
- len = (int)STRLEN(fnames[0]);
- if (fcount == 1 && len > 4 && STRCMP(fnames[0] + len - 4, ".add") == 0) {
- // For ":mkspell path/en.latin1.add" output file is
- // "path/en.latin1.add.spl".
- innames = &fnames[0];
- incount = 1;
- vim_snprintf((char *)wfname, MAXPATHL, "%s.spl", fnames[0]);
- } else if (fcount == 1) {
- // For ":mkspell path/vim" output file is "path/vim.latin1.spl".
- innames = &fnames[0];
- incount = 1;
- vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL,
- fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc());
- } else if (len > 4 && STRCMP(fnames[0] + len - 4, ".spl") == 0) {
- // Name ends in ".spl", use as the file name.
- STRLCPY(wfname, fnames[0], MAXPATHL);
- } else
- // Name should be language, make the file name from it.
- vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL,
- fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc());
-
- // Check for .ascii.spl.
- if (strstr((char *)path_tail(wfname), SPL_FNAME_ASCII) != NULL)
- spin.si_ascii = true;
-
- // Check for .add.spl.
- if (strstr((char *)path_tail(wfname), SPL_FNAME_ADD) != NULL)
- spin.si_add = true;
- }
-
- if (incount <= 0)
- EMSG(_(e_invarg)); // need at least output and input names
- else if (vim_strchr(path_tail(wfname), '_') != NULL)
- EMSG(_("E751: Output file name must not have region name"));
- else if (incount > 8)
- EMSG(_("E754: Only up to 8 regions supported"));
- else {
- // Check for overwriting before doing things that may take a lot of
- // time.
- if (!over_write && os_path_exists(wfname)) {
- EMSG(_(e_exists));
- goto theend;
- }
- if (os_isdir(wfname)) {
- EMSG2(_(e_isadir2), wfname);
- goto theend;
- }
-
- fname = xmalloc(MAXPATHL);
-
- // Init the aff and dic pointers.
- // Get the region names if there are more than 2 arguments.
- for (i = 0; i < incount; ++i) {
- afile[i] = NULL;
-
- if (incount > 1) {
- len = (int)STRLEN(innames[i]);
- if (STRLEN(path_tail(innames[i])) < 5
- || innames[i][len - 3] != '_') {
- EMSG2(_("E755: Invalid region in %s"), innames[i]);
- goto theend;
- }
- spin.si_region_name[i * 2] = TOLOWER_ASC(innames[i][len - 2]);
- spin.si_region_name[i * 2 + 1] =
- TOLOWER_ASC(innames[i][len - 1]);
- }
- }
- spin.si_region_count = incount;
-
- spin.si_foldroot = wordtree_alloc(&spin);
- spin.si_keeproot = wordtree_alloc(&spin);
- spin.si_prefroot = wordtree_alloc(&spin);
- if (spin.si_foldroot == NULL
- || spin.si_keeproot == NULL
- || spin.si_prefroot == NULL) {
- free_blocks(spin.si_blocks);
- goto theend;
- }
-
- // When not producing a .add.spl file clear the character table when
- // we encounter one in the .aff file. This means we dump the current
- // one in the .spl file if the .aff file doesn't define one. That's
- // better than guessing the contents, the table will match a
- // previously loaded spell file.
- if (!spin.si_add)
- spin.si_clear_chartab = true;
-
- // Read all the .aff and .dic files.
- // Text is converted to 'encoding'.
- // Words are stored in the case-folded and keep-case trees.
- for (i = 0; i < incount && !error; ++i) {
- spin.si_conv.vc_type = CONV_NONE;
- spin.si_region = 1 << i;
-
- vim_snprintf((char *)fname, MAXPATHL, "%s.aff", innames[i]);
- if (os_path_exists(fname)) {
- // Read the .aff file. Will init "spin->si_conv" based on the
- // "SET" line.
- afile[i] = spell_read_aff(&spin, fname);
- if (afile[i] == NULL)
- error = true;
- else {
- // Read the .dic file and store the words in the trees.
- vim_snprintf((char *)fname, MAXPATHL, "%s.dic",
- innames[i]);
- if (spell_read_dic(&spin, fname, afile[i]) == FAIL)
- error = true;
- }
- } else {
- // No .aff file, try reading the file as a word list. Store
- // the words in the trees.
- if (spell_read_wordfile(&spin, innames[i]) == FAIL)
- error = true;
- }
-
- // Free any conversion stuff.
- convert_setup(&spin.si_conv, NULL, NULL);
- }
-
- if (spin.si_compflags != NULL && spin.si_nobreak)
- MSG(_("Warning: both compounding and NOBREAK specified"));
-
- if (!error && !got_int) {
- // Combine tails in the tree.
- spell_message(&spin, (char_u *)_(msg_compressing));
- wordtree_compress(&spin, spin.si_foldroot);
- wordtree_compress(&spin, spin.si_keeproot);
- wordtree_compress(&spin, spin.si_prefroot);
- }
-
- if (!error && !got_int) {
- // Write the info in the spell file.
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Writing spell file %s ..."), wfname);
- spell_message(&spin, IObuff);
-
- error = write_vim_spell(&spin, wfname) == FAIL;
-
- spell_message(&spin, (char_u *)_("Done!"));
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Estimated runtime memory use: %d bytes"), spin.si_memtot);
- spell_message(&spin, IObuff);
-
- // If the file is loaded need to reload it.
- if (!error)
- spell_reload_one(wfname, added_word);
- }
-
- // Free the allocated memory.
- ga_clear(&spin.si_rep);
- ga_clear(&spin.si_repsal);
- ga_clear(&spin.si_sal);
- ga_clear(&spin.si_map);
- ga_clear(&spin.si_comppat);
- ga_clear(&spin.si_prefcond);
- hash_clear_all(&spin.si_commonwords, 0);
-
- // Free the .aff file structures.
- for (i = 0; i < incount; ++i)
- if (afile[i] != NULL)
- spell_free_aff(afile[i]);
-
- // Free all the bits and pieces at once.
- free_blocks(spin.si_blocks);
-
- // If there is soundfolding info and no NOSUGFILE item create the
- // .sug file with the soundfolded word trie.
- if (spin.si_sugtime != 0 && !error && !got_int)
- spell_make_sugfile(&spin, wfname);
-
- }
-
-theend:
- xfree(fname);
- xfree(wfname);
-}
-
-// Display a message for spell file processing when 'verbose' is set or using
-// ":mkspell". "str" can be IObuff.
-static void spell_message(spellinfo_T *spin, char_u *str)
-{
- if (spin->si_verbose || p_verbose > 2) {
- if (!spin->si_verbose)
- verbose_enter();
- MSG(str);
- ui_flush();
- if (!spin->si_verbose)
- verbose_leave();
- }
-}
-
-// ":[count]spellgood {word}"
-// ":[count]spellwrong {word}"
-// ":[count]spellundo {word}"
-void ex_spell(exarg_T *eap)
-{
- spell_add_word(eap->arg, (int)STRLEN(eap->arg), eap->cmdidx == CMD_spellwrong,
- eap->forceit ? 0 : (int)eap->line2,
- eap->cmdidx == CMD_spellundo);
-}
-
-// Add "word[len]" to 'spellfile' as a good or bad word.
-void
-spell_add_word (
- char_u *word,
- int len,
- int bad,
- int idx, // "zG" and "zW": zero, otherwise index in
- // 'spellfile'
- bool undo // true for "zug", "zuG", "zuw" and "zuW"
-)
-{
- FILE *fd = NULL;
- buf_T *buf = NULL;
- bool new_spf = false;
- char_u *fname;
- char_u *fnamebuf = NULL;
- char_u line[MAXWLEN * 2];
- long fpos, fpos_next = 0;
- int i;
- char_u *spf;
-
- if (idx == 0) { // use internal wordlist
- if (int_wordlist == NULL) {
- int_wordlist = vim_tempname();
- if (int_wordlist == NULL)
- return;
- }
- fname = int_wordlist;
- } else {
- // If 'spellfile' isn't set figure out a good default value.
- if (*curwin->w_s->b_p_spf == NUL) {
- init_spellfile();
- new_spf = true;
- }
-
- if (*curwin->w_s->b_p_spf == NUL) {
- EMSG2(_(e_notset), "spellfile");
- return;
- }
- fnamebuf = xmalloc(MAXPATHL);
-
- for (spf = curwin->w_s->b_p_spf, i = 1; *spf != NUL; ++i) {
- copy_option_part(&spf, fnamebuf, MAXPATHL, ",");
- if (i == idx)
- break;
- if (*spf == NUL) {
- EMSGN(_("E765: 'spellfile' does not have %" PRId64 " entries"), idx);
- xfree(fnamebuf);
- return;
- }
- }
-
- // Check that the user isn't editing the .add file somewhere.
- buf = buflist_findname_exp(fnamebuf);
- if (buf != NULL && buf->b_ml.ml_mfp == NULL)
- buf = NULL;
- if (buf != NULL && bufIsChanged(buf)) {
- EMSG(_(e_bufloaded));
- xfree(fnamebuf);
- return;
- }
-
- fname = fnamebuf;
- }
-
- if (bad || undo) {
- // When the word appears as good word we need to remove that one,
- // since its flags sort before the one with WF_BANNED.
- fd = mch_fopen((char *)fname, "r");
- if (fd != NULL) {
- while (!vim_fgets(line, MAXWLEN * 2, fd)) {
- fpos = fpos_next;
- fpos_next = ftell(fd);
- if (STRNCMP(word, line, len) == 0
- && (line[len] == '/' || line[len] < ' ')) {
- // Found duplicate word. Remove it by writing a '#' at
- // the start of the line. Mixing reading and writing
- // doesn't work for all systems, close the file first.
- fclose(fd);
- fd = mch_fopen((char *)fname, "r+");
- if (fd == NULL)
- break;
- if (fseek(fd, fpos, SEEK_SET) == 0) {
- fputc('#', fd);
- if (undo) {
- home_replace(NULL, fname, NameBuff, MAXPATHL, TRUE);
- smsg(_("Word '%.*s' removed from %s"),
- len, word, NameBuff);
- }
- }
- fseek(fd, fpos_next, SEEK_SET);
- }
- }
- if (fd != NULL)
- fclose(fd);
- }
- }
-
- if (!undo) {
- fd = mch_fopen((char *)fname, "a");
- if (fd == NULL && new_spf) {
- char_u *p;
-
- // We just initialized the 'spellfile' option and can't open the
- // file. We may need to create the "spell" directory first. We
- // already checked the runtime directory is writable in
- // init_spellfile().
- if (!dir_of_file_exists(fname) && (p = path_tail_with_sep(fname)) != fname) {
- int c = *p;
-
- // The directory doesn't exist. Try creating it and opening
- // the file again.
- *p = NUL;
- os_mkdir((char *)fname, 0755);
- *p = c;
- fd = mch_fopen((char *)fname, "a");
- }
- }
-
- if (fd == NULL)
- EMSG2(_(e_notopen), fname);
- else {
- if (bad)
- fprintf(fd, "%.*s/!\n", len, word);
- else
- fprintf(fd, "%.*s\n", len, word);
- fclose(fd);
-
- home_replace(NULL, fname, NameBuff, MAXPATHL, TRUE);
- smsg(_("Word '%.*s' added to %s"), len, word, NameBuff);
- }
- }
-
- if (fd != NULL) {
- // Update the .add.spl file.
- mkspell(1, &fname, false, true, true);
-
- // If the .add file is edited somewhere, reload it.
- if (buf != NULL)
- buf_reload(buf, buf->b_orig_mode);
-
- redraw_all_later(SOME_VALID);
- }
- xfree(fnamebuf);
-}
-
-// Initialize 'spellfile' for the current buffer.
-static void init_spellfile(void)
-{
- char_u *buf;
- int l;
- char_u *fname;
- char_u *rtp;
- char_u *lend;
- bool aspath = false;
- char_u *lstart = curbuf->b_s.b_p_spl;
-
- if (*curwin->w_s->b_p_spl != NUL && !GA_EMPTY(&curwin->w_s->b_langp)) {
- buf = xmalloc(MAXPATHL);
-
- // Find the end of the language name. Exclude the region. If there
- // is a path separator remember the start of the tail.
- for (lend = curwin->w_s->b_p_spl; *lend != NUL
- && vim_strchr((char_u *)",._", *lend) == NULL; ++lend)
- if (vim_ispathsep(*lend)) {
- aspath = true;
- lstart = lend + 1;
- }
-
- // Loop over all entries in 'runtimepath'. Use the first one where we
- // are allowed to write.
- rtp = p_rtp;
- while (*rtp != NUL) {
- if (aspath)
- // Use directory of an entry with path, e.g., for
- // "/dir/lg.utf-8.spl" use "/dir".
- STRLCPY(buf, curbuf->b_s.b_p_spl,
- lstart - curbuf->b_s.b_p_spl);
- else
- // Copy the path from 'runtimepath' to buf[].
- copy_option_part(&rtp, buf, MAXPATHL, ",");
- if (os_file_is_writable((char *)buf) == 2) {
- // Use the first language name from 'spelllang' and the
- // encoding used in the first loaded .spl file.
- if (aspath)
- STRLCPY(buf, curbuf->b_s.b_p_spl,
- lend - curbuf->b_s.b_p_spl + 1);
- else {
- // Create the "spell" directory if it doesn't exist yet.
- l = (int)STRLEN(buf);
- vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell");
- if (os_file_is_writable((char *)buf) != 2) {
- os_mkdir((char *)buf, 0755);
- }
-
- l = (int)STRLEN(buf);
- vim_snprintf((char *)buf + l, MAXPATHL - l,
- "/%.*s", (int)(lend - lstart), lstart);
- }
- l = (int)STRLEN(buf);
- fname = LANGP_ENTRY(curwin->w_s->b_langp, 0)
- ->lp_slang->sl_fname;
- vim_snprintf((char *)buf + l, MAXPATHL - l, ".%s.add",
- fname != NULL
- && strstr((char *)path_tail(fname), ".ascii.") != NULL
- ? (char_u *)"ascii" : spell_enc());
- set_option_value((char_u *)"spellfile", 0L, buf, OPT_LOCAL);
- break;
- }
- aspath = false;
- }
-
- xfree(buf);
- }
-}
-
// Init the chartab used for spelling for ASCII.
-static void clear_spell_chartab(spelltab_T *sp)
+void clear_spell_chartab(spelltab_T *sp)
{
int i;
@@ -8034,8 +2528,7 @@ static void clear_spell_chartab(spelltab_T *sp)
}
}
-// Init the chartab used for spelling. Only depends on 'encoding'.
-// Called once while starting up and when 'encoding' changes.
+// Init the chartab used for spelling. Called once while starting up.
// The default is to use isalpha(), but the spell file should define the word
// characters to make it possible that 'encoding' differs from the current
// locale. For utf-8 we don't use isalpha() but our own functions.
@@ -8045,154 +2538,18 @@ void init_spell_chartab(void)
did_set_spelltab = false;
clear_spell_chartab(&spelltab);
- if (enc_dbcs) {
- // DBCS: assume double-wide characters are word characters.
- for (i = 128; i <= 255; ++i)
- if (MB_BYTE2LEN(i) == 2)
- spelltab.st_isw[i] = true;
- } else if (enc_utf8) {
- for (i = 128; i < 256; ++i) {
- int f = utf_fold(i);
- int u = utf_toupper(i);
-
- spelltab.st_isu[i] = utf_isupper(i);
- spelltab.st_isw[i] = spelltab.st_isu[i] || utf_islower(i);
- // The folded/upper-cased value is different between latin1 and
- // utf8 for 0xb5, causing E763 for no good reason. Use the latin1
- // value for utf-8 to avoid this.
- spelltab.st_fold[i] = (f < 256) ? f : i;
- spelltab.st_upper[i] = (u < 256) ? u : i;
- }
- } else {
- // Rough guess: use locale-dependent library functions.
- for (i = 128; i < 256; ++i) {
- if (vim_isupper(i)) {
- spelltab.st_isw[i] = true;
- spelltab.st_isu[i] = true;
- spelltab.st_fold[i] = vim_tolower(i);
- } else if (vim_islower(i)) {
- spelltab.st_isw[i] = true;
- spelltab.st_upper[i] = vim_toupper(i);
- }
- }
- }
-}
-
-// Set the spell character tables from strings in the affix file.
-static int set_spell_chartab(char_u *fol, char_u *low, char_u *upp)
-{
- // We build the new tables here first, so that we can compare with the
- // previous one.
- spelltab_T new_st;
- char_u *pf = fol, *pl = low, *pu = upp;
- int f, l, u;
-
- clear_spell_chartab(&new_st);
-
- while (*pf != NUL) {
- if (*pl == NUL || *pu == NUL) {
- EMSG(_(e_affform));
- return FAIL;
- }
- f = mb_ptr2char_adv(&pf);
- l = mb_ptr2char_adv(&pl);
- u = mb_ptr2char_adv(&pu);
- // Every character that appears is a word character.
- if (f < 256)
- new_st.st_isw[f] = true;
- if (l < 256)
- new_st.st_isw[l] = true;
- if (u < 256)
- new_st.st_isw[u] = true;
-
- // if "LOW" and "FOL" are not the same the "LOW" char needs
- // case-folding
- if (l < 256 && l != f) {
- if (f >= 256) {
- EMSG(_(e_affrange));
- return FAIL;
- }
- new_st.st_fold[l] = f;
- }
-
- // if "UPP" and "FOL" are not the same the "UPP" char needs
- // case-folding, it's upper case and the "UPP" is the upper case of
- // "FOL" .
- if (u < 256 && u != f) {
- if (f >= 256) {
- EMSG(_(e_affrange));
- return FAIL;
- }
- new_st.st_fold[u] = f;
- new_st.st_isu[u] = true;
- new_st.st_upper[f] = u;
- }
- }
+ for (i = 128; i < 256; i++) {
+ int f = utf_fold(i);
+ int u = mb_toupper(i);
- if (*pl != NUL || *pu != NUL) {
- EMSG(_(e_affform));
- return FAIL;
+ spelltab.st_isu[i] = mb_isupper(i);
+ spelltab.st_isw[i] = spelltab.st_isu[i] || mb_islower(i);
+ // The folded/upper-cased value is different between latin1 and
+ // utf8 for 0xb5, causing E763 for no good reason. Use the latin1
+ // value for utf-8 to avoid this.
+ spelltab.st_fold[i] = (f < 256) ? f : i;
+ spelltab.st_upper[i] = (u < 256) ? u : i;
}
-
- return set_spell_finish(&new_st);
-}
-
-// Set the spell character tables from strings in the .spl file.
-static void
-set_spell_charflags (
- char_u *flags,
- int cnt, // length of "flags"
- char_u *fol
-)
-{
- // We build the new tables here first, so that we can compare with the
- // previous one.
- spelltab_T new_st;
- int i;
- char_u *p = fol;
- int c;
-
- clear_spell_chartab(&new_st);
-
- for (i = 0; i < 128; ++i) {
- if (i < cnt) {
- new_st.st_isw[i + 128] = (flags[i] & CF_WORD) != 0;
- new_st.st_isu[i + 128] = (flags[i] & CF_UPPER) != 0;
- }
-
- if (*p != NUL) {
- c = mb_ptr2char_adv(&p);
- new_st.st_fold[i + 128] = c;
- if (i + 128 != c && new_st.st_isu[i + 128] && c < 256)
- new_st.st_upper[c] = i + 128;
- }
- }
-
- (void)set_spell_finish(&new_st);
-}
-
-static int set_spell_finish(spelltab_T *new_st)
-{
- int i;
-
- if (did_set_spelltab) {
- // check that it's the same table
- for (i = 0; i < 256; ++i) {
- if (spelltab.st_isw[i] != new_st->st_isw[i]
- || spelltab.st_isu[i] != new_st->st_isu[i]
- || spelltab.st_fold[i] != new_st->st_fold[i]
- || spelltab.st_upper[i] != new_st->st_upper[i]) {
- EMSG(_("E763: Word characters differ between spell files"));
- return FAIL;
- }
- }
- } else {
- // copy the new spelltab into the one being used
- spelltab = *new_st;
- did_set_spelltab = true;
- }
-
- return OK;
}
/// Returns true if "p" points to a word character.
@@ -8233,14 +2590,15 @@ static bool spell_iswordp(char_u *p, win_T *wp)
// Returns true if "p" points to a word character.
// Unlike spell_iswordp() this doesn't check for "midword" characters.
-static bool spell_iswordp_nmw(char_u *p, win_T *wp)
+bool spell_iswordp_nmw(const char_u *p, win_T *wp)
{
int c;
if (has_mbyte) {
c = mb_ptr2char(p);
- if (c > 255)
+ if (c > 255) {
return spell_mb_isword_class(mb_get_class(p), wp);
+ }
return spelltab.st_isw[c];
}
return spelltab.st_isw[*p];
@@ -8249,7 +2607,7 @@ static bool spell_iswordp_nmw(char_u *p, win_T *wp)
// Returns true if word class indicates a word character.
// Only for characters above 255.
// Unicode subscript and superscript are not considered word characters.
-// See also dbcs_class() and utf_class() in mbyte.c.
+// See also utf_class() in mbyte.c.
static bool spell_mb_isword_class(int cl, win_T *wp)
{
if (wp->w_s->b_cjk)
@@ -8272,51 +2630,16 @@ static bool spell_iswordp_w(int *p, win_T *wp)
s = p;
if (*s > 255) {
- if (enc_utf8)
- return spell_mb_isword_class(utf_class(*s), wp);
- if (enc_dbcs)
- return spell_mb_isword_class(
- dbcs_class((unsigned)*s >> 8, *s & 0xff), wp);
- return false;
+ return spell_mb_isword_class(utf_class(*s), wp);
}
return spelltab.st_isw[*s];
}
-// Write the table with prefix conditions to the .spl file.
-// When "fd" is NULL only count the length of what is written.
-static int write_spell_prefcond(FILE *fd, garray_T *gap)
-{
- assert(gap->ga_len >= 0);
-
- if (fd != NULL)
- put_bytes(fd, (uintmax_t)gap->ga_len, 2); // <prefcondcnt>
-
- size_t totlen = 2 + (size_t)gap->ga_len; // <prefcondcnt> and <condlen> bytes
- size_t x = 1; // collect return value of fwrite()
- for (int i = 0; i < gap->ga_len; ++i) {
- // <prefcond> : <condlen> <condstr>
- char_u *p = ((char_u **)gap->ga_data)[i];
- if (p != NULL) {
- size_t len = STRLEN(p);
- if (fd != NULL) {
- assert(len <= INT_MAX);
- fputc((int)len, fd);
- x &= fwrite(p, len, 1, fd);
- }
- totlen += len;
- } else if (fd != NULL)
- fputc(0, fd);
- }
-
- assert(totlen <= INT_MAX);
- return (int)totlen;
-}
-
// Case-fold "str[len]" into "buf[buflen]". The result is NUL terminated.
// Uses the character definitions from the .spl file.
// When using a multi-byte 'encoding' the length may change!
// Returns FAIL when something wrong.
-static int spell_casefold(char_u *str, int len, char_u *buf, int buflen)
+int spell_casefold(char_u *str, int len, char_u *buf, int buflen)
{
int i;
@@ -8336,7 +2659,7 @@ static int spell_casefold(char_u *str, int len, char_u *buf, int buflen)
buf[outi] = NUL;
return FAIL;
}
- c = mb_cptr2char_adv(&p);
+ c = mb_cptr2char_adv((const char_u **)&p);
outi += mb_char2bytes(SPELL_TOFOLD(c), buf + outi);
}
buf[outi] = NUL;
@@ -8510,7 +2833,7 @@ void spell_suggest(int count)
vim_snprintf((char *)IObuff, IOSIZE, ":ot \"%.*s\" egnahC",
sug.su_badlen, sug.su_badptr);
}
- msg_puts(IObuff);
+ msg_puts((const char *)IObuff);
msg_clr_eos();
msg_putchar('\n');
@@ -8526,18 +2849,19 @@ void spell_suggest(int count)
sug.su_badptr + stp->st_orglen,
sug.su_badlen - stp->st_orglen + 1);
vim_snprintf((char *)IObuff, IOSIZE, "%2d", i + 1);
- if (cmdmsg_rl)
+ if (cmdmsg_rl) {
rl_mirror(IObuff);
- msg_puts(IObuff);
+ }
+ msg_puts((const char *)IObuff);
vim_snprintf((char *)IObuff, IOSIZE, " \"%s\"", wcopy);
- msg_puts(IObuff);
+ msg_puts((const char *)IObuff);
// The word may replace more than "su_badlen".
if (sug.su_badlen < stp->st_orglen) {
vim_snprintf((char *)IObuff, IOSIZE, _(" < \"%.*s\""),
- stp->st_orglen, sug.su_badptr);
- msg_puts(IObuff);
+ stp->st_orglen, sug.su_badptr);
+ msg_puts((const char *)IObuff);
}
if (p_verbose > 0) {
@@ -8553,7 +2877,7 @@ void spell_suggest(int count)
// Mirror the numbers, but keep the leading space.
rl_mirror(IObuff + 1);
msg_advance(30);
- msg_puts(IObuff);
+ msg_puts((const char *)IObuff);
}
msg_putchar('\n');
}
@@ -8597,7 +2921,7 @@ void spell_suggest(int count)
// For redo we use a change-word command.
ResetRedobuff();
- AppendToRedobuff((char_u *)"ciw");
+ AppendToRedobuff("ciw");
AppendToRedobuffLit(p + c,
stp->st_wordlen + sug.su_badlen - stp->st_orglen);
AppendCharToRedobuff(ESC);
@@ -8892,7 +3216,7 @@ static void spell_suggest_expr(suginfo_T *su, char_u *expr)
list_T *list;
listitem_T *li;
int score;
- char_u *p;
+ const char *p;
// The work is split up in a few parts to avoid having to export
// suginfo_T.
@@ -8904,11 +3228,12 @@ static void spell_suggest_expr(suginfo_T *su, char_u *expr)
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);
+ if (score >= 0 && score <= su->su_maxscore) {
+ add_suggestion(su, &su->su_ga, (const char_u *)p, su->su_badlen,
+ score, 0, true, su->su_sallang, false);
+ }
}
- list_unref(list);
+ tv_list_unref(list);
}
// Remove bogus suggestions, sort and truncate at "maxcount".
@@ -9039,174 +3364,6 @@ static void spell_suggest_intern(suginfo_T *su, bool interactive)
}
}
-// Load the .sug files for languages that have one and weren't loaded yet.
-static void suggest_load_files(void)
-{
- langp_T *lp;
- slang_T *slang;
- char_u *dotp;
- FILE *fd;
- char_u buf[MAXWLEN];
- int i;
- time_t timestamp;
- int wcount;
- int wordnr;
- garray_T ga;
- int c;
-
- // Do this for all languages that support sound folding.
- for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) {
- lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
- slang = lp->lp_slang;
- if (slang->sl_sugtime != 0 && !slang->sl_sugloaded) {
- // Change ".spl" to ".sug" and open the file. When the file isn't
- // found silently skip it. Do set "sl_sugloaded" so that we
- // don't try again and again.
- slang->sl_sugloaded = true;
-
- dotp = vim_strrchr(slang->sl_fname, '.');
- if (dotp == NULL || fnamecmp(dotp, ".spl") != 0)
- continue;
- STRCPY(dotp, ".sug");
- fd = mch_fopen((char *)slang->sl_fname, "r");
- if (fd == NULL)
- goto nextone;
-
- // <SUGHEADER>: <fileID> <versionnr> <timestamp>
- for (i = 0; i < VIMSUGMAGICL; ++i)
- buf[i] = getc(fd); // <fileID>
- if (STRNCMP(buf, VIMSUGMAGIC, VIMSUGMAGICL) != 0) {
- EMSG2(_("E778: This does not look like a .sug file: %s"),
- slang->sl_fname);
- goto nextone;
- }
- c = getc(fd); // <versionnr>
- if (c < VIMSUGVERSION) {
- EMSG2(_("E779: Old .sug file, needs to be updated: %s"),
- slang->sl_fname);
- goto nextone;
- } else if (c > VIMSUGVERSION) {
- EMSG2(_("E780: .sug file is for newer version of Vim: %s"),
- slang->sl_fname);
- goto nextone;
- }
-
- // Check the timestamp, it must be exactly the same as the one in
- // the .spl file. Otherwise the word numbers won't match.
- timestamp = get8ctime(fd); // <timestamp>
- if (timestamp != slang->sl_sugtime) {
- EMSG2(_("E781: .sug file doesn't match .spl file: %s"),
- slang->sl_fname);
- goto nextone;
- }
-
- // <SUGWORDTREE>: <wordtree>
- // Read the trie with the soundfolded words.
- if (spell_read_tree(fd, &slang->sl_sbyts, &slang->sl_sidxs,
- false, 0) != 0) {
-someerror:
- EMSG2(_("E782: error while reading .sug file: %s"),
- slang->sl_fname);
- slang_clear_sug(slang);
- goto nextone;
- }
-
- // <SUGTABLE>: <sugwcount> <sugline> ...
- //
- // Read the table with word numbers. We use a file buffer for
- // this, because it's so much like a file with lines. Makes it
- // possible to swap the info and save on memory use.
- slang->sl_sugbuf = open_spellbuf();
-
- // <sugwcount>
- wcount = get4c(fd);
- if (wcount < 0)
- goto someerror;
-
- // Read all the wordnr lists into the buffer, one NUL terminated
- // list per line.
- ga_init(&ga, 1, 100);
- for (wordnr = 0; wordnr < wcount; ++wordnr) {
- ga.ga_len = 0;
- for (;; ) {
- c = getc(fd); // <sugline>
- if (c < 0) {
- goto someerror;
- }
- GA_APPEND(char_u, &ga, c);
- if (c == NUL)
- break;
- }
- if (ml_append_buf(slang->sl_sugbuf, (linenr_T)wordnr,
- ga.ga_data, ga.ga_len, TRUE) == FAIL)
- goto someerror;
- }
- ga_clear(&ga);
-
- // Need to put word counts in the word tries, so that we can find
- // a word by its number.
- tree_count_words(slang->sl_fbyts, slang->sl_fidxs);
- tree_count_words(slang->sl_sbyts, slang->sl_sidxs);
-
-nextone:
- if (fd != NULL)
- fclose(fd);
- STRCPY(dotp, ".spl");
- }
- }
-}
-
-// Fill in the wordcount fields for a trie.
-// Returns the total number of words.
-static void tree_count_words(char_u *byts, idx_T *idxs)
-{
- int depth;
- idx_T arridx[MAXWLEN];
- int curi[MAXWLEN];
- int c;
- idx_T n;
- int wordcount[MAXWLEN];
-
- arridx[0] = 0;
- curi[0] = 1;
- wordcount[0] = 0;
- depth = 0;
- while (depth >= 0 && !got_int) {
- if (curi[depth] > byts[arridx[depth]]) {
- // Done all bytes at this node, go up one level.
- idxs[arridx[depth]] = wordcount[depth];
- if (depth > 0)
- wordcount[depth - 1] += wordcount[depth];
-
- --depth;
- fast_breakcheck();
- } else {
- // Do one more byte at this node.
- n = arridx[depth] + curi[depth];
- ++curi[depth];
-
- c = byts[n];
- if (c == 0) {
- // End of word, count it.
- ++wordcount[depth];
-
- // Skip over any other NUL bytes (same word with different
- // flags).
- while (byts[n + 1] == 0) {
- ++n;
- ++curi[depth];
- }
- } else {
- // Normal char, go one level deeper to count the words.
- ++depth;
- arridx[depth] = idxs[n];
- curi[depth] = 1;
- wordcount[depth] = 0;
- }
- }
- }
-}
-
// Free the info put in "*su" by spell_find_suggest().
static void spell_find_cleanup(suginfo_T *su)
{
@@ -9219,32 +3376,33 @@ static void spell_find_cleanup(suginfo_T *su)
hash_clear_all(&su->su_banned, 0);
}
-// Make a copy of "word", with the first letter upper or lower cased, to
-// "wcopy[MAXWLEN]". "word" must not be empty.
-// The result is NUL terminated.
-static void
-onecap_copy (
- char_u *word,
- char_u *wcopy,
- bool upper // true: first letter made upper case
-)
+/// Make a copy of "word", with the first letter upper or lower cased, to
+/// "wcopy[MAXWLEN]". "word" must not be empty.
+/// The result is NUL terminated.
+///
+/// @param[in] word source string to copy
+/// @param[in,out] wcopy copied string, with case of first letter changed
+/// @param[in] upper True to upper case, otherwise lower case
+void onecap_copy(char_u *word, char_u *wcopy, bool upper)
{
char_u *p;
int c;
int l;
p = word;
- if (has_mbyte)
- c = mb_cptr2char_adv(&p);
- else
+ if (has_mbyte) {
+ c = mb_cptr2char_adv((const char_u **)&p);
+ } else {
c = *p++;
- if (upper)
+ }
+ if (upper) {
c = SPELL_TOUPPER(c);
- else
+ } else {
c = SPELL_TOFOLD(c);
- if (has_mbyte)
+ }
+ if (has_mbyte) {
l = mb_char2bytes(c, wcopy);
- else {
+ } else {
l = 1;
wcopy[0] = c;
}
@@ -9261,10 +3419,11 @@ static void allcap_copy(char_u *word, char_u *wcopy)
d = wcopy;
for (s = word; *s != NUL; ) {
- if (has_mbyte)
- c = mb_cptr2char_adv(&s);
- else
+ if (has_mbyte) {
+ c = mb_cptr2char_adv((const char_u **)&s);
+ } else {
c = *s++;
+ }
if (c == 0xdf) {
c = 'S';
@@ -9474,7 +3633,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// word).
depth = 0;
sp = &stack[0];
- memset(sp, 0, sizeof(trystate_T));
+ memset(sp, 0, sizeof(trystate_T)); // -V512
sp->ts_curi = 1;
if (soundfold) {
@@ -10330,7 +4489,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
}
if (has_mbyte) {
- n = mb_cptr2len(p);
+ n = MB_CPTR2LEN(p);
c = mb_ptr2char(p);
if (p[n] == NUL)
c2 = NUL;
@@ -10407,9 +4566,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// "fword" here, it's changed back afterwards at STATE_UNSWAP3.
p = fword + sp->ts_fidx;
if (has_mbyte) {
- n = mb_cptr2len(p);
+ n = MB_CPTR2LEN(p);
c = mb_ptr2char(p);
- fl = mb_cptr2len(p + n);
+ 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
@@ -10505,10 +4664,10 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
++depth;
p = fword + sp->ts_fidx;
if (has_mbyte) {
- n = mb_cptr2len(p);
+ n = MB_CPTR2LEN(p);
c = mb_ptr2char(p);
- fl = mb_cptr2len(p + n);
- fl += mb_cptr2len(p + n + fl);
+ fl = MB_CPTR2LEN(p + n);
+ fl += MB_CPTR2LEN(p + n + fl);
memmove(p, p + n, fl);
mb_char2bytes(c, p + fl);
stack[depth].ts_fidxtry = sp->ts_fidx + n + fl;
@@ -10557,10 +4716,10 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
++depth;
p = fword + sp->ts_fidx;
if (has_mbyte) {
- n = mb_cptr2len(p);
- n += mb_cptr2len(p + n);
+ n = MB_CPTR2LEN(p);
+ n += MB_CPTR2LEN(p + n);
c = mb_ptr2char(p + n);
- tl = mb_cptr2len(p + n);
+ tl = MB_CPTR2LEN(p + n);
memmove(p + tl, p, n);
mb_char2bytes(c, p);
stack[depth].ts_fidxtry = sp->ts_fidx + n + tl;
@@ -10803,10 +4962,11 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword)
// round[depth] == 1: Try using the folded-case character.
// round[depth] == 2: Try using the upper-case character.
if (has_mbyte) {
- flen = mb_cptr2len(fword + fwordidx[depth]);
- ulen = mb_cptr2len(uword + uwordidx[depth]);
- } else
+ flen = MB_CPTR2LEN(fword + fwordidx[depth]);
+ ulen = MB_CPTR2LEN(uword + uwordidx[depth]);
+ } else {
ulen = flen = 1;
+ }
if (round[depth] == 1) {
p = fword + fwordidx[depth];
l = flen;
@@ -11177,11 +5337,13 @@ add_sound_suggest (
// the words that have a better score than before. Use a hashtable to
// remember the words that have been done.
hash = hash_hash(goodword);
- hi = hash_lookup(&slang->sl_sounddone, goodword, hash);
+ const size_t goodword_len = STRLEN(goodword);
+ hi = hash_lookup(&slang->sl_sounddone, (const char *)goodword, goodword_len,
+ hash);
if (HASHITEM_EMPTY(hi)) {
- sft = xmalloc(sizeof(sftword_T) + STRLEN(goodword));
+ sft = xmalloc(sizeof(sftword_T) + goodword_len);
sft->sft_score = score;
- STRCPY(sft->sft_word, goodword);
+ memcpy(sft->sft_word, goodword, goodword_len + 1);
hash_add_item(&slang->sl_sounddone, hi, sft->sft_word, hash);
} else {
sft = HI2SFT(hi);
@@ -11402,67 +5564,6 @@ static void make_case_word(char_u *fword, char_u *cword, int flags)
STRCPY(cword, fword);
}
-// Use map string "map" for languages "lp".
-static void set_map_str(slang_T *lp, char_u *map)
-{
- char_u *p;
- int headc = 0;
- int c;
- int i;
-
- if (*map == NUL) {
- lp->sl_has_map = false;
- return;
- }
- lp->sl_has_map = true;
-
- // Init the array and hash tables empty.
- for (i = 0; i < 256; ++i)
- lp->sl_map_array[i] = 0;
- hash_init(&lp->sl_map_hash);
-
- // The similar characters are stored separated with slashes:
- // "aaa/bbb/ccc/". Fill sl_map_array[c] with the character before c and
- // before the same slash. For characters above 255 sl_map_hash is used.
- for (p = map; *p != NUL; ) {
- c = mb_cptr2char_adv(&p);
- if (c == '/')
- headc = 0;
- else {
- if (headc == 0)
- headc = c;
-
- // Characters above 255 don't fit in sl_map_array[], put them in
- // the hash table. Each entry is the char, a NUL the headchar and
- // a NUL.
- if (c >= 256) {
- int cl = mb_char2len(c);
- int headcl = mb_char2len(headc);
- char_u *b;
- hash_T hash;
- hashitem_T *hi;
-
- b = xmalloc(cl + headcl + 2);
- mb_char2bytes(c, b);
- b[cl] = NUL;
- mb_char2bytes(headc, b + cl + 1);
- b[cl + 1 + headcl] = NUL;
- hash = hash_hash(b);
- hi = hash_lookup(&lp->sl_map_hash, b, hash);
- if (HASHITEM_EMPTY(hi))
- hash_add_item(&lp->sl_map_hash, hi, b, hash);
- else {
- // This should have been checked when generating the .spl
- // file.
- EMSG(_("E783: duplicate char in MAP entry"));
- xfree(b);
- }
- } else
- lp->sl_map_array[c] = headc;
- }
- }
-}
-
// Returns true if "c1" and "c2" are similar characters according to the MAP
// lines in the .aff file.
static bool similar_chars(slang_T *slang, int c1, int c2)
@@ -11503,7 +5604,7 @@ static void
add_suggestion (
suginfo_T *su,
garray_T *gap, // either su_ga or su_sga
- char_u *goodword,
+ const char_u *goodword,
int badlenarg, // len of bad word replaced with "goodword"
int score,
int altscore,
@@ -11517,13 +5618,11 @@ add_suggestion (
int badlen; // len of bad word changed
suggest_T *stp;
suggest_T new_sug;
- int i;
- char_u *pgood, *pbad;
// Minimize "badlen" for consistency. Avoids that changing "the the" to
// "thee the" is added next to changing the first "the" the "thee".
- pgood = goodword + STRLEN(goodword);
- pbad = su->su_badptr + badlenarg;
+ const char_u *pgood = goodword + STRLEN(goodword);
+ char_u *pbad = su->su_badptr + badlenarg;
for (;; ) {
goodlen = (int)(pgood - goodword);
badlen = (int)(pbad - su->su_badptr);
@@ -11543,9 +5642,10 @@ add_suggestion (
// the first "the" to itself.
return;
- if (GA_EMPTY(gap))
+ int i;
+ if (GA_EMPTY(gap)) {
i = -1;
- else {
+ } else {
// Check if the word is already there. Also check the length that is
// being replaced "thes," -> "these" is a different suggestion from
// "thes" -> "these".
@@ -11656,9 +5756,10 @@ static void add_banned(suginfo_T *su, char_u *word)
hashitem_T *hi;
hash = hash_hash(word);
- hi = hash_lookup(&su->su_banned, word, hash);
+ const size_t word_len = STRLEN(word);
+ hi = hash_lookup(&su->su_banned, (const char *)word, word_len, hash);
if (HASHITEM_EMPTY(hi)) {
- s = vim_strsave(word);
+ s = xmemdupz(word, word_len);
hash_add_item(&su->su_banned, hi, s, hash);
}
}
@@ -11743,46 +5844,49 @@ cleanup_suggestions (
return maxscore;
}
-// Soundfold a string, for soundfold().
-// Result is in allocated memory, NULL for an error.
-char_u *eval_soundfold(char_u *word)
+/// Soundfold a string, for soundfold()
+///
+/// @param[in] word Word to soundfold.
+///
+/// @return [allocated] soundfolded string or NULL in case of error. May return
+/// copy of the input string if soundfolding is not
+/// supported by any of the languages in &spellang.
+char *eval_soundfold(const char *const word)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
- langp_T *lp;
- char_u sound[MAXWLEN];
-
if (curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL) {
// Use the sound-folding of the first language that supports it.
- for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) {
- lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
+ for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; lpi++) {
+ langp_T *const lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
if (!GA_EMPTY(&lp->lp_slang->sl_sal)) {
// soundfold the word
- spell_soundfold(lp->lp_slang, word, false, sound);
- return vim_strsave(sound);
+ char_u sound[MAXWLEN];
+ spell_soundfold(lp->lp_slang, (char_u *)word, false, sound);
+ return xstrdup((const char *)sound);
}
}
}
// No language with sound folding, return word as-is.
- return vim_strsave(word);
+ return xstrdup(word);
}
-// Turn "inword" into its sound-a-like equivalent in "res[MAXWLEN]".
-//
-// There are many ways to turn a word into a sound-a-like representation. The
-// oldest is Soundex (1918!). A nice overview can be found in "Approximate
-// swedish name matching - survey and test of different algorithms" by Klas
-// Erikson.
-//
-// We support two methods:
-// 1. SOFOFROM/SOFOTO do a simple character mapping.
-// 2. SAL items define a more advanced sound-folding (and much slower).
-static void
-spell_soundfold (
- slang_T *slang,
- char_u *inword,
- bool folded, // "inword" is already case-folded
- char_u *res
-)
+/// Turn "inword" into its sound-a-like equivalent in "res[MAXWLEN]".
+///
+/// There are many ways to turn a word into a sound-a-like representation. The
+/// oldest is Soundex (1918!). A nice overview can be found in "Approximate
+/// swedish name matching - survey and test of different algorithms" by Klas
+/// Erikson.
+///
+/// We support two methods:
+/// 1. SOFOFROM/SOFOTO do a simple character mapping.
+/// 2. SAL items define a more advanced sound-folding (and much slower).
+///
+/// @param[in] slang
+/// @param[in] inword word to soundfold
+/// @param[in] folded whether inword is already case-folded
+/// @param[in,out] res destination for soundfolded word
+void spell_soundfold(slang_T *slang, char_u *inword, bool folded, char_u *res)
{
char_u fword[MAXWLEN];
char_u *word;
@@ -11821,12 +5925,12 @@ static void spell_soundfold_sofo(slang_T *slang, char_u *inword, char_u *res)
// The sl_sal_first[] table contains the translation for chars up to
// 255, sl_sal the rest.
for (s = inword; *s != NUL; ) {
- c = mb_cptr2char_adv(&s);
- if (enc_utf8 ? utf_class(c) == 0 : ascii_iswhite(c))
+ c = mb_cptr2char_adv((const char_u **)&s);
+ if (enc_utf8 ? utf_class(c) == 0 : ascii_iswhite(c)) {
c = ' ';
- else if (c < 256)
+ } else if (c < 256) {
c = slang->sl_sal_first[c];
- else {
+ } else {
ip = ((int **)slang->sl_sal.ga_data)[c & 0xff];
if (ip == NULL) // empty list, can't match
c = NUL;
@@ -12111,9 +6215,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
int word[MAXWLEN];
int wres[MAXWLEN];
int l;
- char_u *s;
int *ws;
- char_u *t;
int *pf;
int i, j, z;
int reslen;
@@ -12133,9 +6235,9 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
// Remove accents, if wanted. We actually remove all non-word characters.
// But keep white space.
wordlen = 0;
- for (s = inword; *s != NUL; ) {
- t = s;
- c = mb_cptr2char_adv(&s);
+ for (const char_u *s = inword; *s != NUL; ) {
+ const char_u *t = s;
+ c = mb_cptr2char_adv((const char_u **)&s);
if (slang->sl_rem_accents) {
if (enc_utf8 ? utf_class(c) == 0 : ascii_iswhite(c)) {
if (did_white)
@@ -12144,8 +6246,9 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
did_white = true;
} else {
did_white = false;
- if (!spell_iswordp_nmw(t, curwin))
+ if (!spell_iswordp_nmw(t, curwin)) {
continue;
+ }
}
}
word[wordlen++] = c;
@@ -12192,7 +6295,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
continue;
++k;
}
- s = smp[n].sm_rules;
+ char_u *s = smp[n].sm_rules;
pri = 5; // default priority
p0 = *s;
@@ -12591,25 +6694,30 @@ soundalike_score (
// support multi-byte characters.
static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword)
{
- int *cnt;
- int badlen, goodlen; // lengths including NUL
+ int *cnt;
int j, i;
int t;
int bc, gc;
int pbc, pgc;
- char_u *p;
int wbadword[MAXWLEN];
int wgoodword[MAXWLEN];
const bool l_has_mbyte = has_mbyte;
+ // Lengths with NUL.
+ int badlen;
+ int goodlen;
if (l_has_mbyte) {
// Get the characters from the multi-byte strings and put them in an
// int array for easy access.
- for (p = badword, badlen = 0; *p != NUL; )
+ badlen = 0;
+ for (const char_u *p = badword; *p != NUL; ) {
wbadword[badlen++] = mb_cptr2char_adv(&p);
+ }
wbadword[badlen++] = 0;
- for (p = goodword, goodlen = 0; *p != NUL; )
+ goodlen = 0;
+ for (const char_u *p = goodword; *p != NUL; ) {
wgoodword[goodlen++] = mb_cptr2char_adv(&p);
+ }
wgoodword[goodlen++] = 0;
} else {
badlen = (int)STRLEN(badword) + 1;
@@ -12843,19 +6951,20 @@ static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goo
int score_off;
int minscore;
int round;
- char_u *p;
int wbadword[MAXWLEN];
int wgoodword[MAXWLEN];
// Get the characters from the multi-byte strings and put them in an
// int array for easy access.
bi = 0;
- for (p = badword; *p != NUL; )
+ for (const char_u *p = badword; *p != NUL; ) {
wbadword[bi++] = mb_cptr2char_adv(&p);
+ }
wbadword[bi++] = 0;
gi = 0;
- for (p = goodword; *p != NUL; )
+ for (const char_u *p = goodword; *p != NUL; ) {
wgoodword[gi++] = mb_cptr2char_adv(&p);
+ }
wgoodword[gi++] = 0;
// The idea is to go from start to end over the words. So long as
@@ -12990,19 +7099,17 @@ pop:
// ":spellinfo"
void ex_spellinfo(exarg_T *eap)
{
- langp_T *lp;
- char_u *p;
-
- if (no_spell_checking(curwin))
+ if (no_spell_checking(curwin)) {
return;
+ }
msg_start();
- for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len && !got_int; ++lpi) {
- lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
- msg_puts((char_u *)"file: ");
- msg_puts(lp->lp_slang->sl_fname);
+ for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len && !got_int; lpi++) {
+ langp_T *const lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
+ msg_puts("file: ");
+ msg_puts((const char *)lp->lp_slang->sl_fname);
msg_putchar('\n');
- p = lp->lp_slang->sl_info;
+ const char *const p = (const char *)lp->lp_slang->sl_info;
if (p != NULL) {
msg_puts(p);
msg_putchar('\n');
@@ -13023,20 +7130,22 @@ void ex_spelldump(exarg_T *eap)
char_u *spl;
long dummy;
- if (no_spell_checking(curwin))
+ if (no_spell_checking(curwin)) {
return;
- get_option_value((char_u*)"spl", &dummy, &spl, OPT_LOCAL);
+ }
+ get_option_value((char_u *)"spl", &dummy, &spl, OPT_LOCAL);
// Create a new empty buffer in a new window.
do_cmdline_cmd("new");
// enable spelling locally in the new window
- set_option_value((char_u*)"spell", true, (char_u*)"", OPT_LOCAL);
- set_option_value((char_u*)"spl", dummy, spl, OPT_LOCAL);
+ set_option_value("spell", true, "", OPT_LOCAL);
+ set_option_value("spl", dummy, (char *)spl, OPT_LOCAL);
xfree(spl);
- if (!bufempty() || !buf_valid(curbuf))
+ if (!bufempty()) {
return;
+ }
spell_dump_compl(NULL, 0, NULL, eap->forceit ? DUMPFLAG_COUNT : 0);
diff --git a/src/nvim/spell.h b/src/nvim/spell.h
index 3a03cb2ef6..ad66df4c5d 100644
--- a/src/nvim/spell.h
+++ b/src/nvim/spell.h
@@ -3,6 +3,10 @@
#include <stdbool.h>
+#include "nvim/spell_defs.h"
+#include "nvim/ex_cmds_defs.h"
+#include "nvim/globals.h"
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "spell.h.generated.h"
#endif
diff --git a/src/nvim/spell_defs.h b/src/nvim/spell_defs.h
new file mode 100644
index 0000000000..ddd54c724e
--- /dev/null
+++ b/src/nvim/spell_defs.h
@@ -0,0 +1,287 @@
+#ifndef NVIM_SPELL_DEFS_H
+#define NVIM_SPELL_DEFS_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nvim/buffer_defs.h"
+#include "nvim/garray.h"
+#include "nvim/regexp_defs.h"
+#include "nvim/types.h"
+
+#define MAXWLEN 254 // Assume max. word len is this many bytes.
+ // Some places assume a word length fits in a
+ // byte, thus it can't be above 255.
+
+// Type used for indexes in the word tree need to be at least 4 bytes. If int
+// is 8 bytes we could use something smaller, but what?
+typedef int idx_T;
+
+# define SPL_FNAME_TMPL "%s.%s.spl"
+# define SPL_FNAME_ADD ".add."
+# define SPL_FNAME_ASCII ".ascii."
+
+// Flags used for a word. Only the lowest byte can be used, the region byte
+// comes above it.
+#define WF_REGION 0x01 // region byte follows
+#define WF_ONECAP 0x02 // word with one capital (or all capitals)
+#define WF_ALLCAP 0x04 // word must be all capitals
+#define WF_RARE 0x08 // rare word
+#define WF_BANNED 0x10 // bad word
+#define WF_AFX 0x20 // affix ID follows
+#define WF_FIXCAP 0x40 // keep-case word, allcap not allowed
+#define WF_KEEPCAP 0x80 // keep-case word
+
+// for <flags2>, shifted up one byte to be used in wn_flags
+#define WF_HAS_AFF 0x0100 // word includes affix
+#define WF_NEEDCOMP 0x0200 // word only valid in compound
+#define WF_NOSUGGEST 0x0400 // word not to be suggested
+#define WF_COMPROOT 0x0800 // already compounded word, COMPOUNDROOT
+#define WF_NOCOMPBEF 0x1000 // no compounding before this word
+#define WF_NOCOMPAFT 0x2000 // no compounding after this word
+
+// flags for <pflags>
+#define WFP_RARE 0x01 // rare prefix
+#define WFP_NC 0x02 // prefix is not combining
+#define WFP_UP 0x04 // to-upper prefix
+#define WFP_COMPPERMIT 0x08 // prefix with COMPOUNDPERMITFLAG
+#define WFP_COMPFORBID 0x10 // prefix with COMPOUNDFORBIDFLAG
+
+// Flags for postponed prefixes in "sl_pidxs". Must be above affixID (one
+// byte) and prefcondnr (two bytes).
+#define WF_RAREPFX (WFP_RARE << 24) // rare postponed prefix
+#define WF_PFX_NC (WFP_NC << 24) // non-combining postponed prefix
+#define WF_PFX_UP (WFP_UP << 24) // to-upper postponed prefix
+#define WF_PFX_COMPPERMIT (WFP_COMPPERMIT << 24) // postponed prefix with
+ // COMPOUNDPERMITFLAG
+#define WF_PFX_COMPFORBID (WFP_COMPFORBID << 24) // postponed prefix with
+ // COMPOUNDFORBIDFLAG
+
+
+// flags for <compoptions>
+#define COMP_CHECKDUP 1 // CHECKCOMPOUNDDUP
+#define COMP_CHECKREP 2 // CHECKCOMPOUNDREP
+#define COMP_CHECKCASE 4 // CHECKCOMPOUNDCASE
+#define COMP_CHECKTRIPLE 8 // CHECKCOMPOUNDTRIPLE
+
+// Info from "REP", "REPSAL" and "SAL" entries in ".aff" file used in si_rep,
+// si_repsal, sl_rep, and si_sal. Not for sl_sal!
+// One replacement: from "ft_from" to "ft_to".
+typedef struct fromto_S {
+ char_u *ft_from;
+ char_u *ft_to;
+} fromto_T;
+
+// Info from "SAL" entries in ".aff" file used in sl_sal.
+// The info is split for quick processing by spell_soundfold().
+// Note that "sm_oneof" and "sm_rules" point into sm_lead.
+typedef struct salitem_S {
+ char_u *sm_lead; // leading letters
+ int sm_leadlen; // length of "sm_lead"
+ char_u *sm_oneof; // letters from () or NULL
+ char_u *sm_rules; // rules like ^, $, priority
+ char_u *sm_to; // replacement.
+ int *sm_lead_w; // wide character copy of "sm_lead"
+ int *sm_oneof_w; // wide character copy of "sm_oneof"
+ int *sm_to_w; // wide character copy of "sm_to"
+} salitem_T;
+
+typedef int salfirst_T;
+
+// Values for SP_*ERROR are negative, positive values are used by
+// read_cnt_string().
+#define SP_TRUNCERROR -1 // spell file truncated error
+#define SP_FORMERROR -2 // format error in spell file
+#define SP_OTHERERROR -3 // other error while reading spell file
+
+// Structure used to store words and other info for one language, loaded from
+// a .spl file.
+// The main access is through the tree in "sl_fbyts/sl_fidxs", storing the
+// case-folded words. "sl_kbyts/sl_kidxs" is for keep-case words.
+//
+// The "byts" array stores the possible bytes in each tree node, preceded by
+// the number of possible bytes, sorted on byte value:
+// <len> <byte1> <byte2> ...
+// The "idxs" array stores the index of the child node corresponding to the
+// byte in "byts".
+// Exception: when the byte is zero, the word may end here and "idxs" holds
+// the flags, region mask and affixID for the word. There may be several
+// zeros in sequence for alternative flag/region/affixID combinations.
+typedef struct slang_S slang_T;
+
+struct slang_S {
+ slang_T *sl_next; // next language
+ char_u *sl_name; // language name "en", "en.rare", "nl", etc.
+ char_u *sl_fname; // name of .spl file
+ bool sl_add; // true if it's a .add file.
+
+ char_u *sl_fbyts; // case-folded word bytes
+ idx_T *sl_fidxs; // case-folded word indexes
+ char_u *sl_kbyts; // keep-case word bytes
+ idx_T *sl_kidxs; // keep-case word indexes
+ char_u *sl_pbyts; // prefix tree word bytes
+ idx_T *sl_pidxs; // prefix tree word indexes
+
+ char_u *sl_info; // infotext string or NULL
+
+ char_u sl_regions[17]; // table with up to 8 region names plus NUL
+
+ char_u *sl_midword; // MIDWORD string or NULL
+
+ hashtab_T sl_wordcount; // hashtable with word count, wordcount_T
+
+ int sl_compmax; // COMPOUNDWORDMAX (default: MAXWLEN)
+ int sl_compminlen; // COMPOUNDMIN (default: 0)
+ int sl_compsylmax; // COMPOUNDSYLMAX (default: MAXWLEN)
+ int sl_compoptions; // COMP_* flags
+ garray_T sl_comppat; // CHECKCOMPOUNDPATTERN items
+ regprog_T *sl_compprog; // COMPOUNDRULE turned into a regexp progrm
+ // (NULL when no compounding)
+ char_u *sl_comprules; // all COMPOUNDRULE concatenated (or NULL)
+ char_u *sl_compstartflags; // flags for first compound word
+ char_u *sl_compallflags; // all flags for compound words
+ bool sl_nobreak; // When true: no spaces between words
+ char_u *sl_syllable; // SYLLABLE repeatable chars or NULL
+ garray_T sl_syl_items; // syllable items
+
+ int sl_prefixcnt; // number of items in "sl_prefprog"
+ regprog_T **sl_prefprog; // table with regprogs for prefixes
+
+ garray_T sl_rep; // list of fromto_T entries from REP lines
+ int16_t sl_rep_first[256]; // indexes where byte first appears, -1 if
+ // there is none
+ garray_T sl_sal; // list of salitem_T entries from SAL lines
+ salfirst_T sl_sal_first[256]; // indexes where byte first appears, -1 if
+ // there is none
+ bool sl_followup; // SAL followup
+ bool sl_collapse; // SAL collapse_result
+ bool sl_rem_accents; // SAL remove_accents
+ bool sl_sofo; // SOFOFROM and SOFOTO instead of SAL items:
+ // "sl_sal_first" maps chars, when has_mbyte
+ // "sl_sal" is a list of wide char lists.
+ garray_T sl_repsal; // list of fromto_T entries from REPSAL lines
+ int16_t sl_repsal_first[256]; // sl_rep_first for REPSAL lines
+ bool sl_nosplitsugs; // don't suggest splitting a word
+ bool sl_nocompoundsugs; // don't suggest compounding
+
+ // Info from the .sug file. Loaded on demand.
+ time_t sl_sugtime; // timestamp for .sug file
+ char_u *sl_sbyts; // soundfolded word bytes
+ idx_T *sl_sidxs; // soundfolded word indexes
+ buf_T *sl_sugbuf; // buffer with word number table
+ bool sl_sugloaded; // true when .sug file was loaded or failed to
+ // load
+
+ bool sl_has_map; // true, if there is a MAP line
+ hashtab_T sl_map_hash; // MAP for multi-byte chars
+ int sl_map_array[256]; // MAP for first 256 chars
+ hashtab_T sl_sounddone; // table with soundfolded words that have
+ // handled, see add_sound_suggest()
+};
+
+// Structure used in "b_langp", filled from 'spelllang'.
+typedef struct langp_S {
+ slang_T *lp_slang; // info for this language
+ slang_T *lp_sallang; // language used for sound folding or NULL
+ slang_T *lp_replang; // language used for REP items or NULL
+ int lp_region; // bitmask for region or REGION_ALL
+} langp_T;
+
+#define LANGP_ENTRY(ga, i) (((langp_T *)(ga).ga_data) + (i))
+
+#define VIMSUGMAGIC "VIMsug" // string at start of Vim .sug file
+#define VIMSUGMAGICL 6
+#define VIMSUGVERSION 1
+
+#define REGION_ALL 0xff // word valid in all regions
+
+// The tables used for recognizing word characters according to spelling.
+// These are only used for the first 256 characters of 'encoding'.
+typedef struct {
+ bool st_isw[256]; // flags: is word char
+ bool st_isu[256]; // flags: is uppercase char
+ char_u st_fold[256]; // chars: folded case
+ char_u st_upper[256]; // chars: upper case
+} spelltab_T;
+
+// For finding suggestions: At each node in the tree these states are tried:
+typedef enum {
+ STATE_START = 0, // At start of node check for NUL bytes (goodword
+ // ends); if badword ends there is a match, otherwise
+ // try splitting word.
+ STATE_NOPREFIX, // try without prefix
+ STATE_SPLITUNDO, // Undo splitting.
+ STATE_ENDNUL, // Past NUL bytes at start of the node.
+ STATE_PLAIN, // Use each byte of the node.
+ STATE_DEL, // Delete a byte from the bad word.
+ STATE_INS_PREP, // Prepare for inserting bytes.
+ STATE_INS, // Insert a byte in the bad word.
+ STATE_SWAP, // Swap two bytes.
+ STATE_UNSWAP, // Undo swap two characters.
+ STATE_SWAP3, // Swap two characters over three.
+ STATE_UNSWAP3, // Undo Swap two characters over three.
+ STATE_UNROT3L, // Undo rotate three characters left
+ STATE_UNROT3R, // Undo rotate three characters right
+ STATE_REP_INI, // Prepare for using REP items.
+ STATE_REP, // Use matching REP items from the .aff file.
+ STATE_REP_UNDO, // Undo a REP item replacement.
+ STATE_FINAL // End of this node.
+} state_T;
+
+// Struct to keep the state at each level in suggest_try_change().
+typedef struct trystate_S {
+ state_T ts_state; // state at this level, STATE_
+ int ts_score; // score
+ idx_T ts_arridx; // index in tree array, start of node
+ short ts_curi; // index in list of child nodes
+ char_u ts_fidx; // index in fword[], case-folded bad word
+ char_u ts_fidxtry; // ts_fidx at which bytes may be changed
+ char_u ts_twordlen; // valid length of tword[]
+ char_u ts_prefixdepth; // stack depth for end of prefix or
+ // PFD_PREFIXTREE or PFD_NOPREFIX
+ char_u ts_flags; // TSF_ flags
+ char_u ts_tcharlen; // number of bytes in tword character
+ char_u ts_tcharidx; // current byte index in tword character
+ char_u ts_isdiff; // DIFF_ values
+ char_u ts_fcharstart; // index in fword where badword char started
+ char_u ts_prewordlen; // length of word in "preword[]"
+ char_u ts_splitoff; // index in "tword" after last split
+ char_u ts_splitfidx; // "ts_fidx" at word split
+ char_u ts_complen; // nr of compound words used
+ char_u ts_compsplit; // index for "compflags" where word was spit
+ char_u ts_save_badflags; // su_badflags saved here
+ char_u ts_delidx; // index in fword for char that was deleted,
+ // valid when "ts_flags" has TSF_DIDDEL
+} trystate_T;
+
+// Use our own character-case definitions, because the current locale may
+// differ from what the .spl file uses.
+// These must not be called with negative number!
+#include <wchar.h> // for towupper() and towlower()
+// Multi-byte implementation. For Unicode we can call utf_*(), but don't do
+// that for ASCII, because we don't want to use 'casemap' here. Otherwise use
+// the "w" library function for characters above 255.
+#define SPELL_TOFOLD(c) (enc_utf8 && (c) >= 128 ? utf_fold(c) \
+ : (c) < \
+ 256 ? (int)spelltab.st_fold[c] : (int)towlower(c))
+
+#define SPELL_TOUPPER(c) (enc_utf8 && (c) >= 128 ? mb_toupper(c) \
+ : (c) < \
+ 256 ? (int)spelltab.st_upper[c] : (int)towupper(c))
+
+#define SPELL_ISUPPER(c) (enc_utf8 && (c) >= 128 ? mb_isupper(c) \
+ : (c) < 256 ? spelltab.st_isu[c] : iswupper(c))
+
+// First language that is loaded, start of the linked list of loaded
+// languages.
+extern slang_T *first_lang;
+
+// file used for "zG" and "zW"
+extern char_u *int_wordlist;
+
+extern spelltab_T spelltab;
+extern int did_set_spelltab;
+
+extern char *e_format;
+
+#endif // NVIM_SPELL_DEFS_H
diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c
new file mode 100644
index 0000000000..1f7f616782
--- /dev/null
+++ b/src/nvim/spellfile.c
@@ -0,0 +1,5741 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+// spellfile.c: code for reading and writing spell files.
+//
+// See spell.c for information about spell checking.
+
+// Vim spell file format: <HEADER>
+// <SECTIONS>
+// <LWORDTREE>
+// <KWORDTREE>
+// <PREFIXTREE>
+//
+// <HEADER>: <fileID> <versionnr>
+//
+// <fileID> 8 bytes "VIMspell"
+// <versionnr> 1 byte VIMSPELLVERSION
+//
+//
+// Sections make it possible to add information to the .spl file without
+// making it incompatible with previous versions. There are two kinds of
+// sections:
+// 1. Not essential for correct spell checking. E.g. for making suggestions.
+// These are skipped when not supported.
+// 2. Optional information, but essential for spell checking when present.
+// E.g. conditions for affixes. When this section is present but not
+// supported an error message is given.
+//
+// <SECTIONS>: <section> ... <sectionend>
+//
+// <section>: <sectionID> <sectionflags> <sectionlen> (section contents)
+//
+// <sectionID> 1 byte number from 0 to 254 identifying the section
+//
+// <sectionflags> 1 byte SNF_REQUIRED: this section is required for correct
+// spell checking
+//
+// <sectionlen> 4 bytes length of section contents, MSB first
+//
+// <sectionend> 1 byte SN_END
+//
+//
+// sectionID == SN_INFO: <infotext>
+// <infotext> N bytes free format text with spell file info (version,
+// website, etc)
+//
+// sectionID == SN_REGION: <regionname> ...
+// <regionname> 2 bytes Up to 8 region names: ca, au, etc. Lower case.
+// First <regionname> is region 1.
+//
+// sectionID == SN_CHARFLAGS: <charflagslen> <charflags>
+// <folcharslen> <folchars>
+// <charflagslen> 1 byte Number of bytes in <charflags> (should be 128).
+// <charflags> N bytes List of flags (first one is for character 128):
+// 0x01 word character CF_WORD
+// 0x02 upper-case character CF_UPPER
+// <folcharslen> 2 bytes Number of bytes in <folchars>.
+// <folchars> N bytes Folded characters, first one is for character 128.
+//
+// sectionID == SN_MIDWORD: <midword>
+// <midword> N bytes Characters that are word characters only when used
+// in the middle of a word.
+//
+// sectionID == SN_PREFCOND: <prefcondcnt> <prefcond> ...
+// <prefcondcnt> 2 bytes Number of <prefcond> items following.
+// <prefcond> : <condlen> <condstr>
+// <condlen> 1 byte Length of <condstr>.
+// <condstr> N bytes Condition for the prefix.
+//
+// sectionID == SN_REP: <repcount> <rep> ...
+// <repcount> 2 bytes number of <rep> items, MSB first.
+// <rep> : <repfromlen> <repfrom> <reptolen> <repto>
+// <repfromlen> 1 byte length of <repfrom>
+// <repfrom> N bytes "from" part of replacement
+// <reptolen> 1 byte length of <repto>
+// <repto> N bytes "to" part of replacement
+//
+// sectionID == SN_REPSAL: <repcount> <rep> ...
+// just like SN_REP but for soundfolded words
+//
+// sectionID == SN_SAL: <salflags> <salcount> <sal> ...
+// <salflags> 1 byte flags for soundsalike conversion:
+// SAL_F0LLOWUP
+// SAL_COLLAPSE
+// SAL_REM_ACCENTS
+// <salcount> 2 bytes number of <sal> items following
+// <sal> : <salfromlen> <salfrom> <saltolen> <salto>
+// <salfromlen> 1 byte length of <salfrom>
+// <salfrom> N bytes "from" part of soundsalike
+// <saltolen> 1 byte length of <salto>
+// <salto> N bytes "to" part of soundsalike
+//
+// sectionID == SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
+// <sofofromlen> 2 bytes length of <sofofrom>
+// <sofofrom> N bytes "from" part of soundfold
+// <sofotolen> 2 bytes length of <sofoto>
+// <sofoto> N bytes "to" part of soundfold
+//
+// sectionID == SN_SUGFILE: <timestamp>
+// <timestamp> 8 bytes time in seconds that must match with .sug file
+//
+// sectionID == SN_NOSPLITSUGS: nothing
+//
+// sectionID == SN_NOCOMPOUNDSUGS: nothing
+//
+// sectionID == SN_WORDS: <word> ...
+// <word> N bytes NUL terminated common word
+//
+// sectionID == SN_MAP: <mapstr>
+// <mapstr> N bytes String with sequences of similar characters,
+// separated by slashes.
+//
+// sectionID == SN_COMPOUND: <compmax> <compminlen> <compsylmax> <compoptions>
+// <comppatcount> <comppattern> ... <compflags>
+// <compmax> 1 byte Maximum nr of words in compound word.
+// <compminlen> 1 byte Minimal word length for compounding.
+// <compsylmax> 1 byte Maximum nr of syllables in compound word.
+// <compoptions> 2 bytes COMP_ flags.
+// <comppatcount> 2 bytes number of <comppattern> following
+// <compflags> N bytes Flags from COMPOUNDRULE items, separated by
+// slashes.
+//
+// <comppattern>: <comppatlen> <comppattext>
+// <comppatlen> 1 byte length of <comppattext>
+// <comppattext> N bytes end or begin chars from CHECKCOMPOUNDPATTERN
+//
+// sectionID == SN_NOBREAK: (empty, its presence is what matters)
+//
+// sectionID == SN_SYLLABLE: <syllable>
+// <syllable> N bytes String from SYLLABLE item.
+//
+// <LWORDTREE>: <wordtree>
+//
+// <KWORDTREE>: <wordtree>
+//
+// <PREFIXTREE>: <wordtree>
+//
+//
+// <wordtree>: <nodecount> <nodedata> ...
+//
+// <nodecount> 4 bytes Number of nodes following. MSB first.
+//
+// <nodedata>: <siblingcount> <sibling> ...
+//
+// <siblingcount> 1 byte Number of siblings in this node. The siblings
+// follow in sorted order.
+//
+// <sibling>: <byte> [ <nodeidx> <xbyte>
+// | <flags> [<flags2>] [<region>] [<affixID>]
+// | [<pflags>] <affixID> <prefcondnr> ]
+//
+// <byte> 1 byte Byte value of the sibling. Special cases:
+// BY_NOFLAGS: End of word without flags and for all
+// regions.
+// For PREFIXTREE <affixID> and
+// <prefcondnr> follow.
+// BY_FLAGS: End of word, <flags> follow.
+// For PREFIXTREE <pflags>, <affixID>
+// and <prefcondnr> follow.
+// BY_FLAGS2: End of word, <flags> and <flags2>
+// follow. Not used in PREFIXTREE.
+// BY_INDEX: Child of sibling is shared, <nodeidx>
+// and <xbyte> follow.
+//
+// <nodeidx> 3 bytes Index of child for this sibling, MSB first.
+//
+// <xbyte> 1 byte Byte value of the sibling.
+//
+// <flags> 1 byte Bitmask of:
+// WF_ALLCAP word must have only capitals
+// WF_ONECAP first char of word must be capital
+// WF_KEEPCAP keep-case word
+// WF_FIXCAP keep-case word, all caps not allowed
+// WF_RARE rare word
+// WF_BANNED bad word
+// WF_REGION <region> follows
+// WF_AFX <affixID> follows
+//
+// <flags2> 1 byte Bitmask of:
+// WF_HAS_AFF >> 8 word includes affix
+// WF_NEEDCOMP >> 8 word only valid in compound
+// WF_NOSUGGEST >> 8 word not used for suggestions
+// WF_COMPROOT >> 8 word already a compound
+// WF_NOCOMPBEF >> 8 no compounding before this word
+// WF_NOCOMPAFT >> 8 no compounding after this word
+//
+// <pflags> 1 byte Bitmask of:
+// WFP_RARE rare prefix
+// WFP_NC non-combining prefix
+// WFP_UP letter after prefix made upper case
+//
+// <region> 1 byte Bitmask for regions in which word is valid. When
+// omitted it's valid in all regions.
+// Lowest bit is for region 1.
+//
+// <affixID> 1 byte ID of affix that can be used with this word. In
+// PREFIXTREE used for the required prefix ID.
+//
+// <prefcondnr> 2 bytes Prefix condition number, index in <prefcond> list
+// from HEADER.
+//
+// All text characters are in 'encoding', but stored as single bytes.
+
+// Vim .sug file format: <SUGHEADER>
+// <SUGWORDTREE>
+// <SUGTABLE>
+//
+// <SUGHEADER>: <fileID> <versionnr> <timestamp>
+//
+// <fileID> 6 bytes "VIMsug"
+// <versionnr> 1 byte VIMSUGVERSION
+// <timestamp> 8 bytes timestamp that must match with .spl file
+//
+//
+// <SUGWORDTREE>: <wordtree> (see above, no flags or region used)
+//
+//
+// <SUGTABLE>: <sugwcount> <sugline> ...
+//
+// <sugwcount> 4 bytes number of <sugline> following
+//
+// <sugline>: <sugnr> ... NUL
+//
+// <sugnr>: X bytes word number that results in this soundfolded word,
+// stored as an offset to the previous number in as
+// few bytes as possible, see offset2bytes())
+
+#include <stdio.h>
+#include <stdint.h>
+#include <wctype.h>
+#include <strings.h>
+
+#include "nvim/vim.h"
+#include "nvim/spell_defs.h"
+#include "nvim/ascii.h"
+#include "nvim/buffer.h"
+#include "nvim/charset.h"
+#include "nvim/ex_cmds2.h"
+#include "nvim/fileio.h"
+#include "nvim/memory.h"
+#include "nvim/memline.h"
+#include "nvim/misc1.h"
+#include "nvim/option.h"
+#include "nvim/os/os.h"
+#include "nvim/path.h"
+#include "nvim/regexp.h"
+#include "nvim/screen.h"
+#include "nvim/spell.h"
+#include "nvim/spellfile.h"
+#include "nvim/ui.h"
+#include "nvim/undo.h"
+
+#ifndef UNIX // it's in os/unix_defs.h for Unix
+# include <time.h> // for time_t
+#endif
+
+// Special byte values for <byte>. Some are only used in the tree for
+// postponed prefixes, some only in the other trees. This is a bit messy...
+#define BY_NOFLAGS 0 // end of word without flags or region; for
+ // postponed prefix: no <pflags>
+#define BY_INDEX 1 // child is shared, index follows
+#define BY_FLAGS 2 // end of word, <flags> byte follows; for
+ // postponed prefix: <pflags> follows
+#define BY_FLAGS2 3 // end of word, <flags> and <flags2> bytes
+ // follow; never used in prefix tree
+#define BY_SPECIAL BY_FLAGS2 // highest special byte value
+
+// Flags used in .spl file for soundsalike flags.
+#define SAL_F0LLOWUP 1
+#define SAL_COLLAPSE 2
+#define SAL_REM_ACCENTS 4
+
+#define VIMSPELLMAGIC "VIMspell" // string at start of Vim spell file
+#define VIMSPELLMAGICL (sizeof(VIMSPELLMAGIC) - 1)
+#define VIMSPELLVERSION 50
+
+// Section IDs. Only renumber them when VIMSPELLVERSION changes!
+#define SN_REGION 0 // <regionname> section
+#define SN_CHARFLAGS 1 // charflags section
+#define SN_MIDWORD 2 // <midword> section
+#define SN_PREFCOND 3 // <prefcond> section
+#define SN_REP 4 // REP items section
+#define SN_SAL 5 // SAL items section
+#define SN_SOFO 6 // soundfolding section
+#define SN_MAP 7 // MAP items section
+#define SN_COMPOUND 8 // compound words section
+#define SN_SYLLABLE 9 // syllable section
+#define SN_NOBREAK 10 // NOBREAK section
+#define SN_SUGFILE 11 // timestamp for .sug file
+#define SN_REPSAL 12 // REPSAL items section
+#define SN_WORDS 13 // common words
+#define SN_NOSPLITSUGS 14 // don't split word for suggestions
+#define SN_INFO 15 // info section
+#define SN_NOCOMPOUNDSUGS 16 // don't compound for suggestions
+#define SN_END 255 // end of sections
+
+#define SNF_REQUIRED 1 // <sectionflags>: required section
+
+#define CF_WORD 0x01
+#define CF_UPPER 0x02
+
+static char *e_spell_trunc = N_("E758: Truncated spell file");
+static char *e_afftrailing = N_("Trailing text in %s line %d: %s");
+static char *e_affname = N_("Affix name too long in %s line %d: %s");
+static char *e_affform = N_("E761: Format error in affix file FOL, LOW or UPP");
+static char *e_affrange = N_(
+ "E762: Character in FOL, LOW or UPP is out of range");
+static char *msg_compressing = N_("Compressing word tree...");
+
+#define MAXLINELEN 500 // Maximum length in bytes of a line in a .aff
+ // and .dic file.
+// Main structure to store the contents of a ".aff" file.
+typedef struct afffile_S {
+ char_u *af_enc; // "SET", normalized, alloc'ed string or NULL
+ int af_flagtype; // AFT_CHAR, AFT_LONG, AFT_NUM or AFT_CAPLONG
+ unsigned af_rare; // RARE ID for rare word
+ unsigned af_keepcase; // KEEPCASE ID for keep-case word
+ unsigned af_bad; // BAD ID for banned word
+ unsigned af_needaffix; // NEEDAFFIX ID
+ unsigned af_circumfix; // CIRCUMFIX ID
+ unsigned af_needcomp; // NEEDCOMPOUND ID
+ unsigned af_comproot; // COMPOUNDROOT ID
+ unsigned af_compforbid; // COMPOUNDFORBIDFLAG ID
+ unsigned af_comppermit; // COMPOUNDPERMITFLAG ID
+ unsigned af_nosuggest; // NOSUGGEST ID
+ int af_pfxpostpone; // postpone prefixes without chop string and
+ // without flags
+ bool af_ignoreextra; // IGNOREEXTRA present
+ hashtab_T af_pref; // hashtable for prefixes, affheader_T
+ hashtab_T af_suff; // hashtable for suffixes, affheader_T
+ hashtab_T af_comp; // hashtable for compound flags, compitem_T
+} afffile_T;
+
+#define AFT_CHAR 0 // flags are one character
+#define AFT_LONG 1 // flags are two characters
+#define AFT_CAPLONG 2 // flags are one or two characters
+#define AFT_NUM 3 // flags are numbers, comma separated
+
+typedef struct affentry_S affentry_T;
+// Affix entry from ".aff" file. Used for prefixes and suffixes.
+struct affentry_S {
+ affentry_T *ae_next; // next affix with same name/number
+ char_u *ae_chop; // text to chop off basic word (can be NULL)
+ char_u *ae_add; // text to add to basic word (can be NULL)
+ char_u *ae_flags; // flags on the affix (can be NULL)
+ char_u *ae_cond; // condition (NULL for ".")
+ regprog_T *ae_prog; // regexp program for ae_cond or NULL
+ char ae_compforbid; // COMPOUNDFORBIDFLAG found
+ char ae_comppermit; // COMPOUNDPERMITFLAG found
+};
+
+# define AH_KEY_LEN 17 // 2 x 8 bytes + NUL
+
+// Affix header from ".aff" file. Used for af_pref and af_suff.
+typedef struct affheader_S {
+ char_u ah_key[AH_KEY_LEN]; // key for hashtab == name of affix
+ unsigned ah_flag; // affix name as number, uses "af_flagtype"
+ int ah_newID; // prefix ID after renumbering; 0 if not used
+ int ah_combine; // suffix may combine with prefix
+ int ah_follows; // another affix block should be following
+ affentry_T *ah_first; // first affix entry
+} affheader_T;
+
+#define HI2AH(hi) ((affheader_T *)(hi)->hi_key)
+
+// Flag used in compound items.
+typedef struct compitem_S {
+ char_u ci_key[AH_KEY_LEN]; // key for hashtab == name of compound
+ unsigned ci_flag; // affix name as number, uses "af_flagtype"
+ int ci_newID; // affix ID after renumbering.
+} compitem_T;
+
+#define HI2CI(hi) ((compitem_T *)(hi)->hi_key)
+
+// Structure that is used to store the items in the word tree. This avoids
+// the need to keep track of each allocated thing, everything is freed all at
+// once after ":mkspell" is done.
+// Note: "sb_next" must be just before "sb_data" to make sure the alignment of
+// "sb_data" is correct for systems where pointers must be aligned on
+// pointer-size boundaries and sizeof(pointer) > sizeof(int) (e.g., Sparc).
+#define SBLOCKSIZE 16000 // size of sb_data
+typedef struct sblock_S sblock_T;
+struct sblock_S {
+ int sb_used; // nr of bytes already in use
+ sblock_T *sb_next; // next block in list
+ char_u sb_data[1]; // data, actually longer
+};
+
+// A node in the tree.
+typedef struct wordnode_S wordnode_T;
+struct wordnode_S {
+ union { // shared to save space
+ char_u hashkey[6]; // the hash key, only used while compressing
+ int index; // index in written nodes (valid after first
+ // round)
+ } wn_u1;
+ union { // shared to save space
+ wordnode_T *next; // next node with same hash key
+ wordnode_T *wnode; // parent node that will write this node
+ } wn_u2;
+ wordnode_T *wn_child; // child (next byte in word)
+ wordnode_T *wn_sibling; // next sibling (alternate byte in word,
+ // always sorted)
+ int wn_refs; // Nr. of references to this node. Only
+ // relevant for first node in a list of
+ // siblings, in following siblings it is
+ // always one.
+ char_u wn_byte; // Byte for this node. NUL for word end
+
+ // Info for when "wn_byte" is NUL.
+ // In PREFIXTREE "wn_region" is used for the prefcondnr.
+ // In the soundfolded word tree "wn_flags" has the MSW of the wordnr and
+ // "wn_region" the LSW of the wordnr.
+ char_u wn_affixID; // supported/required prefix ID or 0
+ uint16_t wn_flags; // WF_ flags
+ short wn_region; // region mask
+
+#ifdef SPELL_PRINTTREE
+ int wn_nr; // sequence nr for printing
+#endif
+};
+
+#define WN_MASK 0xffff // mask relevant bits of "wn_flags"
+
+#define HI2WN(hi) (wordnode_T *)((hi)->hi_key)
+
+// Info used while reading the spell files.
+typedef struct spellinfo_S {
+ wordnode_T *si_foldroot; // tree with case-folded words
+ long si_foldwcount; // nr of words in si_foldroot
+
+ wordnode_T *si_keeproot; // tree with keep-case words
+ long si_keepwcount; // nr of words in si_keeproot
+
+ wordnode_T *si_prefroot; // tree with postponed prefixes
+
+ long si_sugtree; // creating the soundfolding trie
+
+ sblock_T *si_blocks; // memory blocks used
+ long si_blocks_cnt; // memory blocks allocated
+ int si_did_emsg; // TRUE when ran out of memory
+
+ long si_compress_cnt; // words to add before lowering
+ // compression limit
+ wordnode_T *si_first_free; // List of nodes that have been freed during
+ // compression, linked by "wn_child" field.
+ long si_free_count; // number of nodes in si_first_free
+#ifdef SPELL_PRINTTREE
+ int si_wordnode_nr; // sequence nr for nodes
+#endif
+ buf_T *si_spellbuf; // buffer used to store soundfold word table
+
+ int si_ascii; // handling only ASCII words
+ int si_add; // addition file
+ int si_clear_chartab; // when TRUE clear char tables
+ int si_region; // region mask
+ vimconv_T si_conv; // for conversion to 'encoding'
+ int si_memtot; // runtime memory used
+ int si_verbose; // verbose messages
+ int si_msg_count; // number of words added since last message
+ char_u *si_info; // info text chars or NULL
+ int si_region_count; // number of regions supported (1 when there
+ // are no regions)
+ char_u si_region_name[17]; // region names; used only if
+ // si_region_count > 1)
+
+ garray_T si_rep; // list of fromto_T entries from REP lines
+ garray_T si_repsal; // list of fromto_T entries from REPSAL lines
+ garray_T si_sal; // list of fromto_T entries from SAL lines
+ char_u *si_sofofr; // SOFOFROM text
+ char_u *si_sofoto; // SOFOTO text
+ int si_nosugfile; // NOSUGFILE item found
+ int si_nosplitsugs; // NOSPLITSUGS item found
+ int si_nocompoundsugs; // NOCOMPOUNDSUGS item found
+ int si_followup; // soundsalike: ?
+ int si_collapse; // soundsalike: ?
+ hashtab_T si_commonwords; // hashtable for common words
+ time_t si_sugtime; // timestamp for .sug file
+ int si_rem_accents; // soundsalike: remove accents
+ garray_T si_map; // MAP info concatenated
+ char_u *si_midword; // MIDWORD chars or NULL
+ int si_compmax; // max nr of words for compounding
+ int si_compminlen; // minimal length for compounding
+ int si_compsylmax; // max nr of syllables for compounding
+ int si_compoptions; // COMP_ flags
+ garray_T si_comppat; // CHECKCOMPOUNDPATTERN items, each stored as
+ // a string
+ char_u *si_compflags; // flags used for compounding
+ char_u si_nobreak; // NOBREAK
+ char_u *si_syllable; // syllable string
+ garray_T si_prefcond; // table with conditions for postponed
+ // prefixes, each stored as a string
+ int si_newprefID; // current value for ah_newID
+ int si_newcompID; // current value for compound ID
+} spellinfo_T;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "spellfile.c.generated.h"
+#endif
+
+/// Read n bytes from fd to buf, returning on errors
+///
+/// @param[out] buf Buffer to read to, must be at least n bytes long.
+/// @param[in] n Amount of bytes to read.
+/// @param fd FILE* to read from.
+/// @param exit_code Code to run before returning.
+///
+/// @return Allows to proceed if everything is OK, returns SP_TRUNCERROR if
+/// there are not enough bytes, returns SP_OTHERERROR if reading failed.
+#define SPELL_READ_BYTES(buf, n, fd, exit_code) \
+ do { \
+ const size_t n__SPRB = (n); \
+ FILE *const fd__SPRB = (fd); \
+ char *const buf__SPRB = (buf); \
+ const size_t read_bytes__SPRB = fread(buf__SPRB, 1, n__SPRB, fd__SPRB); \
+ if (read_bytes__SPRB != n__SPRB) { \
+ exit_code; \
+ return feof(fd__SPRB) ? SP_TRUNCERROR : SP_OTHERERROR; \
+ } \
+ } while (0)
+
+/// Like #SPELL_READ_BYTES, but also error out if NUL byte was read
+///
+/// @return Allows to proceed if everything is OK, returns SP_TRUNCERROR if
+/// there are not enough bytes, returns SP_OTHERERROR if reading failed,
+/// returns SP_FORMERROR if read out a NUL byte.
+#define SPELL_READ_NONNUL_BYTES(buf, n, fd, exit_code) \
+ do { \
+ const size_t n__SPRNB = (n); \
+ FILE *const fd__SPRNB = (fd); \
+ char *const buf__SPRNB = (buf); \
+ SPELL_READ_BYTES(buf__SPRNB, n__SPRNB, fd__SPRNB, exit_code); \
+ if (memchr(buf__SPRNB, NUL, (size_t)n__SPRNB)) { \
+ exit_code; \
+ return SP_FORMERROR; \
+ } \
+ } while (0)
+
+/// Check that spell file starts with a magic string
+///
+/// Does not check for version of the file.
+///
+/// @param fd File to check.
+///
+/// @return 0 in case of success, SP_TRUNCERROR if file contains not enough
+/// bytes, SP_FORMERROR if it does not match magic string and
+/// SP_OTHERERROR if reading file failed.
+static inline int spell_check_magic_string(FILE *const fd)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
+{
+ char buf[VIMSPELLMAGICL];
+ SPELL_READ_BYTES(buf, VIMSPELLMAGICL, fd, ;);
+ if (memcmp(buf, VIMSPELLMAGIC, VIMSPELLMAGICL) != 0) {
+ return SP_FORMERROR;
+ }
+ return 0;
+}
+
+// Load one spell file and store the info into a slang_T.
+//
+// This is invoked in three ways:
+// - From spell_load_cb() to load a spell file for the first time. "lang" is
+// the language name, "old_lp" is NULL. Will allocate an slang_T.
+// - To reload a spell file that was changed. "lang" is NULL and "old_lp"
+// points to the existing slang_T.
+// - Just after writing a .spl file; it's read back to produce the .sug file.
+// "old_lp" is NULL and "lang" is NULL. Will allocate an slang_T.
+//
+// Returns the slang_T the spell file was loaded into. NULL for error.
+slang_T *
+spell_load_file (
+ char_u *fname,
+ char_u *lang,
+ slang_T *old_lp,
+ bool silent // no error if file doesn't exist
+)
+{
+ FILE *fd;
+ char_u *p;
+ int n;
+ int len;
+ char_u *save_sourcing_name = sourcing_name;
+ linenr_T save_sourcing_lnum = sourcing_lnum;
+ slang_T *lp = NULL;
+ int c = 0;
+ int res;
+
+ fd = mch_fopen((char *)fname, "r");
+ if (fd == NULL) {
+ if (!silent)
+ EMSG2(_(e_notopen), fname);
+ else if (p_verbose > 2) {
+ verbose_enter();
+ smsg((char *)e_notopen, fname);
+ verbose_leave();
+ }
+ goto endFAIL;
+ }
+ if (p_verbose > 2) {
+ verbose_enter();
+ smsg(_("Reading spell file \"%s\""), fname);
+ verbose_leave();
+ }
+
+ if (old_lp == NULL) {
+ lp = slang_alloc(lang);
+
+ // Remember the file name, used to reload the file when it's updated.
+ lp->sl_fname = vim_strsave(fname);
+
+ // Check for .add.spl.
+ lp->sl_add = strstr((char *)path_tail(fname), SPL_FNAME_ADD) != NULL;
+ } else
+ lp = old_lp;
+
+ // Set sourcing_name, so that error messages mention the file name.
+ sourcing_name = fname;
+ sourcing_lnum = 0;
+
+ // <HEADER>: <fileID>
+ const int scms_ret = spell_check_magic_string(fd);
+ switch (scms_ret) {
+ case SP_FORMERROR:
+ case SP_TRUNCERROR: {
+ emsgf(_("E757: This does not look like a spell file"));
+ goto endFAIL;
+ }
+ case SP_OTHERERROR: {
+ emsgf(_("E5042: Failed to read spell file %s: %s"),
+ fname, strerror(ferror(fd)));
+ }
+ case 0: {
+ break;
+ }
+ }
+ c = getc(fd); // <versionnr>
+ if (c < VIMSPELLVERSION) {
+ EMSG(_("E771: Old spell file, needs to be updated"));
+ goto endFAIL;
+ } else if (c > VIMSPELLVERSION) {
+ EMSG(_("E772: Spell file is for newer version of Vim"));
+ goto endFAIL;
+ }
+
+
+ // <SECTIONS>: <section> ... <sectionend>
+ // <section>: <sectionID> <sectionflags> <sectionlen> (section contents)
+ for (;; ) {
+ n = getc(fd); // <sectionID> or <sectionend>
+ if (n == SN_END)
+ break;
+ c = getc(fd); // <sectionflags>
+ len = get4c(fd); // <sectionlen>
+ if (len < 0)
+ goto truncerr;
+
+ res = 0;
+ switch (n) {
+ case SN_INFO:
+ lp->sl_info = READ_STRING(fd, len); // <infotext>
+ if (lp->sl_info == NULL)
+ goto endFAIL;
+ break;
+
+ case SN_REGION:
+ res = read_region_section(fd, lp, len);
+ break;
+
+ case SN_CHARFLAGS:
+ res = read_charflags_section(fd);
+ break;
+
+ case SN_MIDWORD:
+ lp->sl_midword = READ_STRING(fd, len); // <midword>
+ if (lp->sl_midword == NULL)
+ goto endFAIL;
+ break;
+
+ case SN_PREFCOND:
+ res = read_prefcond_section(fd, lp);
+ break;
+
+ case SN_REP:
+ res = read_rep_section(fd, &lp->sl_rep, lp->sl_rep_first);
+ break;
+
+ case SN_REPSAL:
+ res = read_rep_section(fd, &lp->sl_repsal, lp->sl_repsal_first);
+ break;
+
+ case SN_SAL:
+ res = read_sal_section(fd, lp);
+ break;
+
+ case SN_SOFO:
+ res = read_sofo_section(fd, lp);
+ break;
+
+ case SN_MAP:
+ p = READ_STRING(fd, len); // <mapstr>
+ if (p == NULL)
+ goto endFAIL;
+ set_map_str(lp, p);
+ xfree(p);
+ break;
+
+ case SN_WORDS:
+ res = read_words_section(fd, lp, len);
+ break;
+
+ case SN_SUGFILE:
+ lp->sl_sugtime = get8ctime(fd); // <timestamp>
+ break;
+
+ case SN_NOSPLITSUGS:
+ lp->sl_nosplitsugs = true;
+ break;
+
+ case SN_NOCOMPOUNDSUGS:
+ lp->sl_nocompoundsugs = true;
+ break;
+
+ case SN_COMPOUND:
+ res = read_compound(fd, lp, len);
+ break;
+
+ case SN_NOBREAK:
+ lp->sl_nobreak = true;
+ break;
+
+ case SN_SYLLABLE:
+ lp->sl_syllable = READ_STRING(fd, len); // <syllable>
+ if (lp->sl_syllable == NULL)
+ goto endFAIL;
+ if (init_syl_tab(lp) == FAIL)
+ goto endFAIL;
+ break;
+
+ default:
+ // Unsupported section. When it's required give an error
+ // message. When it's not required skip the contents.
+ if (c & SNF_REQUIRED) {
+ EMSG(_("E770: Unsupported section in spell file"));
+ goto endFAIL;
+ }
+ while (--len >= 0)
+ if (getc(fd) < 0)
+ goto truncerr;
+ break;
+ }
+someerror:
+ if (res == SP_FORMERROR) {
+ EMSG(_(e_format));
+ goto endFAIL;
+ }
+ if (res == SP_TRUNCERROR) {
+truncerr:
+ EMSG(_(e_spell_trunc));
+ goto endFAIL;
+ }
+ if (res == SP_OTHERERROR)
+ goto endFAIL;
+ }
+
+ // <LWORDTREE>
+ res = spell_read_tree(fd, &lp->sl_fbyts, &lp->sl_fidxs, false, 0);
+ if (res != 0)
+ goto someerror;
+
+ // <KWORDTREE>
+ res = spell_read_tree(fd, &lp->sl_kbyts, &lp->sl_kidxs, false, 0);
+ if (res != 0)
+ goto someerror;
+
+ // <PREFIXTREE>
+ res = spell_read_tree(fd, &lp->sl_pbyts, &lp->sl_pidxs, true,
+ lp->sl_prefixcnt);
+ if (res != 0)
+ goto someerror;
+
+ // For a new file link it in the list of spell files.
+ if (old_lp == NULL && lang != NULL) {
+ lp->sl_next = first_lang;
+ first_lang = lp;
+ }
+
+ goto endOK;
+
+endFAIL:
+ if (lang != NULL)
+ // truncating the name signals the error to spell_load_lang()
+ *lang = NUL;
+ if (lp != NULL && old_lp == NULL)
+ slang_free(lp);
+ lp = NULL;
+
+endOK:
+ if (fd != NULL)
+ fclose(fd);
+ sourcing_name = save_sourcing_name;
+ sourcing_lnum = save_sourcing_lnum;
+
+ return lp;
+}
+
+// Fill in the wordcount fields for a trie.
+// Returns the total number of words.
+static void tree_count_words(char_u *byts, idx_T *idxs)
+{
+ int depth;
+ idx_T arridx[MAXWLEN];
+ int curi[MAXWLEN];
+ int c;
+ idx_T n;
+ int wordcount[MAXWLEN];
+
+ arridx[0] = 0;
+ curi[0] = 1;
+ wordcount[0] = 0;
+ depth = 0;
+ while (depth >= 0 && !got_int) {
+ if (curi[depth] > byts[arridx[depth]]) {
+ // Done all bytes at this node, go up one level.
+ idxs[arridx[depth]] = wordcount[depth];
+ if (depth > 0)
+ wordcount[depth - 1] += wordcount[depth];
+
+ --depth;
+ fast_breakcheck();
+ } else {
+ // Do one more byte at this node.
+ n = arridx[depth] + curi[depth];
+ ++curi[depth];
+
+ c = byts[n];
+ if (c == 0) {
+ // End of word, count it.
+ ++wordcount[depth];
+
+ // Skip over any other NUL bytes (same word with different
+ // flags).
+ while (byts[n + 1] == 0) {
+ ++n;
+ ++curi[depth];
+ }
+ } else {
+ // Normal char, go one level deeper to count the words.
+ ++depth;
+ arridx[depth] = idxs[n];
+ curi[depth] = 1;
+ wordcount[depth] = 0;
+ }
+ }
+ }
+}
+
+// Load the .sug files for languages that have one and weren't loaded yet.
+void suggest_load_files(void)
+{
+ langp_T *lp;
+ slang_T *slang;
+ char_u *dotp;
+ FILE *fd;
+ char_u buf[MAXWLEN];
+ int i;
+ time_t timestamp;
+ int wcount;
+ int wordnr;
+ garray_T ga;
+ int c;
+
+ // Do this for all languages that support sound folding.
+ for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) {
+ lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
+ slang = lp->lp_slang;
+ if (slang->sl_sugtime != 0 && !slang->sl_sugloaded) {
+ // Change ".spl" to ".sug" and open the file. When the file isn't
+ // found silently skip it. Do set "sl_sugloaded" so that we
+ // don't try again and again.
+ slang->sl_sugloaded = true;
+
+ dotp = vim_strrchr(slang->sl_fname, '.');
+ if (dotp == NULL || fnamecmp(dotp, ".spl") != 0)
+ continue;
+ STRCPY(dotp, ".sug");
+ fd = mch_fopen((char *)slang->sl_fname, "r");
+ if (fd == NULL)
+ goto nextone;
+
+ // <SUGHEADER>: <fileID> <versionnr> <timestamp>
+ for (i = 0; i < VIMSUGMAGICL; ++i)
+ buf[i] = getc(fd); // <fileID>
+ if (STRNCMP(buf, VIMSUGMAGIC, VIMSUGMAGICL) != 0) {
+ EMSG2(_("E778: This does not look like a .sug file: %s"),
+ slang->sl_fname);
+ goto nextone;
+ }
+ c = getc(fd); // <versionnr>
+ if (c < VIMSUGVERSION) {
+ EMSG2(_("E779: Old .sug file, needs to be updated: %s"),
+ slang->sl_fname);
+ goto nextone;
+ } else if (c > VIMSUGVERSION) {
+ EMSG2(_("E780: .sug file is for newer version of Vim: %s"),
+ slang->sl_fname);
+ goto nextone;
+ }
+
+ // Check the timestamp, it must be exactly the same as the one in
+ // the .spl file. Otherwise the word numbers won't match.
+ timestamp = get8ctime(fd); // <timestamp>
+ if (timestamp != slang->sl_sugtime) {
+ EMSG2(_("E781: .sug file doesn't match .spl file: %s"),
+ slang->sl_fname);
+ goto nextone;
+ }
+
+ // <SUGWORDTREE>: <wordtree>
+ // Read the trie with the soundfolded words.
+ if (spell_read_tree(fd, &slang->sl_sbyts, &slang->sl_sidxs,
+ false, 0) != 0) {
+someerror:
+ EMSG2(_("E782: error while reading .sug file: %s"),
+ slang->sl_fname);
+ slang_clear_sug(slang);
+ goto nextone;
+ }
+
+ // <SUGTABLE>: <sugwcount> <sugline> ...
+ //
+ // Read the table with word numbers. We use a file buffer for
+ // this, because it's so much like a file with lines. Makes it
+ // possible to swap the info and save on memory use.
+ slang->sl_sugbuf = open_spellbuf();
+
+ // <sugwcount>
+ wcount = get4c(fd);
+ if (wcount < 0)
+ goto someerror;
+
+ // Read all the wordnr lists into the buffer, one NUL terminated
+ // list per line.
+ ga_init(&ga, 1, 100);
+ for (wordnr = 0; wordnr < wcount; ++wordnr) {
+ ga.ga_len = 0;
+ for (;; ) {
+ c = getc(fd); // <sugline>
+ if (c < 0) {
+ goto someerror;
+ }
+ GA_APPEND(char_u, &ga, c);
+ if (c == NUL)
+ break;
+ }
+ if (ml_append_buf(slang->sl_sugbuf, (linenr_T)wordnr,
+ ga.ga_data, ga.ga_len, TRUE) == FAIL)
+ goto someerror;
+ }
+ ga_clear(&ga);
+
+ // Need to put word counts in the word tries, so that we can find
+ // a word by its number.
+ tree_count_words(slang->sl_fbyts, slang->sl_fidxs);
+ tree_count_words(slang->sl_sbyts, slang->sl_sidxs);
+
+nextone:
+ if (fd != NULL)
+ fclose(fd);
+ STRCPY(dotp, ".spl");
+ }
+ }
+}
+
+
+// Read a length field from "fd" in "cnt_bytes" bytes.
+// Allocate memory, read the string into it and add a NUL at the end.
+// Returns NULL when the count is zero.
+// Sets "*cntp" to SP_*ERROR when there is an error, length of the result
+// otherwise.
+static char_u *read_cnt_string(FILE *fd, int cnt_bytes, int *cntp)
+{
+ int cnt = 0;
+ int i;
+ char_u *str;
+
+ // read the length bytes, MSB first
+ for (i = 0; i < cnt_bytes; ++i)
+ cnt = (cnt << 8) + getc(fd);
+ if (cnt < 0) {
+ *cntp = SP_TRUNCERROR;
+ return NULL;
+ }
+ *cntp = cnt;
+ if (cnt == 0)
+ return NULL; // nothing to read, return NULL
+
+ str = READ_STRING(fd, cnt);
+ if (str == NULL)
+ *cntp = SP_OTHERERROR;
+ return str;
+}
+
+// Read SN_REGION: <regionname> ...
+// Return SP_*ERROR flags.
+static int read_region_section(FILE *fd, slang_T *lp, int len)
+{
+ if (len > 16) {
+ return SP_FORMERROR;
+ }
+ SPELL_READ_NONNUL_BYTES((char *)lp->sl_regions, (size_t)len, fd, ;);
+ lp->sl_regions[len] = NUL;
+ return 0;
+}
+
+// Read SN_CHARFLAGS section: <charflagslen> <charflags>
+// <folcharslen> <folchars>
+// Return SP_*ERROR flags.
+static int read_charflags_section(FILE *fd)
+{
+ char_u *flags;
+ char_u *fol;
+ int flagslen, follen;
+
+ // <charflagslen> <charflags>
+ flags = read_cnt_string(fd, 1, &flagslen);
+ if (flagslen < 0)
+ return flagslen;
+
+ // <folcharslen> <folchars>
+ fol = read_cnt_string(fd, 2, &follen);
+ if (follen < 0) {
+ xfree(flags);
+ return follen;
+ }
+
+ // Set the word-char flags and fill SPELL_ISUPPER() table.
+ if (flags != NULL && fol != NULL)
+ set_spell_charflags(flags, flagslen, fol);
+
+ xfree(flags);
+ xfree(fol);
+
+ // When <charflagslen> is zero then <fcharlen> must also be zero.
+ if ((flags == NULL) != (fol == NULL))
+ return SP_FORMERROR;
+ return 0;
+}
+
+// Read SN_PREFCOND section.
+// Return SP_*ERROR flags.
+static int read_prefcond_section(FILE *fd, slang_T *lp)
+{
+ // <prefcondcnt> <prefcond> ...
+ const int cnt = get2c(fd); // <prefcondcnt>
+ if (cnt <= 0) {
+ return SP_FORMERROR;
+ }
+
+ lp->sl_prefprog = xcalloc(cnt, sizeof(regprog_T *));
+ lp->sl_prefixcnt = cnt;
+
+ for (int i = 0; i < cnt; i++) {
+ // <prefcond> : <condlen> <condstr>
+ const int n = getc(fd); // <condlen>
+ if (n < 0 || n >= MAXWLEN) {
+ return SP_FORMERROR;
+ }
+
+ // When <condlen> is zero we have an empty condition. Otherwise
+ // compile the regexp program used to check for the condition.
+ if (n > 0) {
+ char buf[MAXWLEN + 1];
+ buf[0] = '^'; // always match at one position only
+ SPELL_READ_NONNUL_BYTES(buf + 1, (size_t)n, fd, ;);
+ buf[n + 1] = NUL;
+ lp->sl_prefprog[i] = vim_regcomp((char_u *)buf, RE_MAGIC | RE_STRING);
+ }
+ }
+ return 0;
+}
+
+// Read REP or REPSAL items section from "fd": <repcount> <rep> ...
+// Return SP_*ERROR flags.
+static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first)
+{
+ int cnt;
+ fromto_T *ftp;
+
+ cnt = get2c(fd); // <repcount>
+ if (cnt < 0)
+ return SP_TRUNCERROR;
+
+ ga_grow(gap, cnt);
+
+ // <rep> : <repfromlen> <repfrom> <reptolen> <repto>
+ for (; gap->ga_len < cnt; ++gap->ga_len) {
+ int c;
+ ftp = &((fromto_T *)gap->ga_data)[gap->ga_len];
+ ftp->ft_from = read_cnt_string(fd, 1, &c);
+ if (c < 0)
+ return c;
+ if (c == 0)
+ return SP_FORMERROR;
+ ftp->ft_to = read_cnt_string(fd, 1, &c);
+ if (c <= 0) {
+ xfree(ftp->ft_from);
+ if (c < 0)
+ return c;
+ return SP_FORMERROR;
+ }
+ }
+
+ // Fill the first-index table.
+ for (int i = 0; i < 256; ++i) {
+ first[i] = -1;
+ }
+ for (int i = 0; i < gap->ga_len; ++i) {
+ ftp = &((fromto_T *)gap->ga_data)[i];
+ if (first[*ftp->ft_from] == -1)
+ first[*ftp->ft_from] = i;
+ }
+ return 0;
+}
+
+// Read SN_SAL section: <salflags> <salcount> <sal> ...
+// Return SP_*ERROR flags.
+static int read_sal_section(FILE *fd, slang_T *slang)
+{
+ int cnt;
+ garray_T *gap;
+ salitem_T *smp;
+ int ccnt;
+ char_u *p;
+ int c = NUL;
+
+ slang->sl_sofo = false;
+
+ const int flags = getc(fd); // <salflags>
+ if (flags & SAL_F0LLOWUP) {
+ slang->sl_followup = true;
+ }
+ if (flags & SAL_COLLAPSE) {
+ slang->sl_collapse = true;
+ }
+ if (flags & SAL_REM_ACCENTS) {
+ slang->sl_rem_accents = true;
+ }
+
+ cnt = get2c(fd); // <salcount>
+ if (cnt < 0)
+ return SP_TRUNCERROR;
+
+ gap = &slang->sl_sal;
+ ga_init(gap, sizeof(salitem_T), 10);
+ ga_grow(gap, cnt + 1);
+
+ // <sal> : <salfromlen> <salfrom> <saltolen> <salto>
+ for (; gap->ga_len < cnt; ++gap->ga_len) {
+ smp = &((salitem_T *)gap->ga_data)[gap->ga_len];
+ ccnt = getc(fd); // <salfromlen>
+ if (ccnt < 0)
+ return SP_TRUNCERROR;
+ p = xmalloc(ccnt + 2);
+ smp->sm_lead = p;
+
+ // Read up to the first special char into sm_lead.
+ int i = 0;
+ for (; i < ccnt; ++i) {
+ c = getc(fd); // <salfrom>
+ if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL)
+ break;
+ *p++ = c;
+ }
+ smp->sm_leadlen = (int)(p - smp->sm_lead);
+ *p++ = NUL;
+
+ // Put (abc) chars in sm_oneof, if any.
+ if (c == '(') {
+ smp->sm_oneof = p;
+ for (++i; i < ccnt; ++i) {
+ c = getc(fd); // <salfrom>
+ if (c == ')')
+ break;
+ *p++ = c;
+ }
+ *p++ = NUL;
+ if (++i < ccnt)
+ c = getc(fd);
+ } else
+ smp->sm_oneof = NULL;
+
+ // Any following chars go in sm_rules.
+ smp->sm_rules = p;
+ if (i < ccnt) {
+ // store the char we got while checking for end of sm_lead
+ *p++ = c;
+ }
+ i++;
+ if (i < ccnt) {
+ SPELL_READ_NONNUL_BYTES( // <salfrom>
+ (char *)p, (size_t)(ccnt - i), fd, xfree(smp->sm_lead));
+ p += (ccnt - i);
+ i = ccnt;
+ }
+ *p++ = NUL;
+
+ // <saltolen> <salto>
+ smp->sm_to = read_cnt_string(fd, 1, &ccnt);
+ if (ccnt < 0) {
+ xfree(smp->sm_lead);
+ return ccnt;
+ }
+
+ if (has_mbyte) {
+ // convert the multi-byte strings to wide char strings
+ smp->sm_lead_w = mb_str2wide(smp->sm_lead);
+ smp->sm_leadlen = mb_charlen(smp->sm_lead);
+ if (smp->sm_oneof == NULL)
+ smp->sm_oneof_w = NULL;
+ else
+ smp->sm_oneof_w = mb_str2wide(smp->sm_oneof);
+ if (smp->sm_to == NULL)
+ smp->sm_to_w = NULL;
+ else
+ smp->sm_to_w = mb_str2wide(smp->sm_to);
+ }
+ }
+
+ if (!GA_EMPTY(gap)) {
+ // Add one extra entry to mark the end with an empty sm_lead. Avoids
+ // that we need to check the index every time.
+ smp = &((salitem_T *)gap->ga_data)[gap->ga_len];
+ p = xmalloc(1);
+ p[0] = NUL;
+ smp->sm_lead = p;
+ smp->sm_leadlen = 0;
+ smp->sm_oneof = NULL;
+ smp->sm_rules = p;
+ smp->sm_to = NULL;
+ if (has_mbyte) {
+ smp->sm_lead_w = mb_str2wide(smp->sm_lead);
+ smp->sm_leadlen = 0;
+ smp->sm_oneof_w = NULL;
+ smp->sm_to_w = NULL;
+ }
+ ++gap->ga_len;
+ }
+
+ // Fill the first-index table.
+ set_sal_first(slang);
+
+ return 0;
+}
+
+// Read SN_WORDS: <word> ...
+// Return SP_*ERROR flags.
+static int read_words_section(FILE *fd, slang_T *lp, int len)
+{
+ int done = 0;
+ int i;
+ int c;
+ char_u word[MAXWLEN];
+
+ while (done < len) {
+ // Read one word at a time.
+ for (i = 0;; ++i) {
+ c = getc(fd);
+ if (c == EOF)
+ return SP_TRUNCERROR;
+ word[i] = c;
+ if (word[i] == NUL)
+ break;
+ if (i == MAXWLEN - 1)
+ return SP_FORMERROR;
+ }
+
+ // Init the count to 10.
+ count_common_word(lp, word, -1, 10);
+ done += i + 1;
+ }
+ return 0;
+}
+
+// SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
+// Return SP_*ERROR flags.
+static int read_sofo_section(FILE *fd, slang_T *slang)
+{
+ int cnt;
+ char_u *from, *to;
+ int res;
+
+ slang->sl_sofo = true;
+
+ // <sofofromlen> <sofofrom>
+ from = read_cnt_string(fd, 2, &cnt);
+ if (cnt < 0)
+ return cnt;
+
+ // <sofotolen> <sofoto>
+ to = read_cnt_string(fd, 2, &cnt);
+ if (cnt < 0) {
+ xfree(from);
+ return cnt;
+ }
+
+ // Store the info in slang->sl_sal and/or slang->sl_sal_first.
+ if (from != NULL && to != NULL)
+ res = set_sofo(slang, from, to);
+ else if (from != NULL || to != NULL)
+ res = SP_FORMERROR; // only one of two strings is an error
+ else
+ res = 0;
+
+ xfree(from);
+ xfree(to);
+ return res;
+}
+
+// Read the compound section from the .spl file:
+// <compmax> <compminlen> <compsylmax> <compoptions> <compflags>
+// Returns SP_*ERROR flags.
+static int read_compound(FILE *fd, slang_T *slang, int len)
+{
+ int todo = len;
+ int c;
+ int atstart;
+ char_u *pat;
+ char_u *pp;
+ char_u *cp;
+ char_u *ap;
+ char_u *crp;
+ int cnt;
+ garray_T *gap;
+
+ if (todo < 2)
+ return SP_FORMERROR; // need at least two bytes
+
+ --todo;
+ c = getc(fd); // <compmax>
+ if (c < 2)
+ c = MAXWLEN;
+ slang->sl_compmax = c;
+
+ --todo;
+ c = getc(fd); // <compminlen>
+ if (c < 1)
+ c = 0;
+ slang->sl_compminlen = c;
+
+ --todo;
+ c = getc(fd); // <compsylmax>
+ if (c < 1)
+ c = MAXWLEN;
+ slang->sl_compsylmax = c;
+
+ c = getc(fd); // <compoptions>
+ if (c != 0)
+ ungetc(c, fd); // be backwards compatible with Vim 7.0b
+ else {
+ --todo;
+ c = getc(fd); // only use the lower byte for now
+ --todo;
+ slang->sl_compoptions = c;
+
+ gap = &slang->sl_comppat;
+ c = get2c(fd); // <comppatcount>
+ todo -= 2;
+ ga_init(gap, sizeof(char_u *), c);
+ ga_grow(gap, c);
+ while (--c >= 0) {
+ ((char_u **)(gap->ga_data))[gap->ga_len++] =
+ read_cnt_string(fd, 1, &cnt);
+ // <comppatlen> <comppattext>
+ if (cnt < 0)
+ return cnt;
+ todo -= cnt + 1;
+ }
+ }
+ if (todo < 0)
+ return SP_FORMERROR;
+
+ // Turn the COMPOUNDRULE items into a regexp pattern:
+ // "a[bc]/a*b+" -> "^\(a[bc]\|a*b\+\)$".
+ // Inserting backslashes may double the length, "^\(\)$<Nul>" is 7 bytes.
+ // Conversion to utf-8 may double the size.
+ c = todo * 2 + 7;
+ if (enc_utf8)
+ c += todo * 2;
+ pat = xmalloc(c);
+
+ // We also need a list of all flags that can appear at the start and one
+ // for all flags.
+ cp = xmalloc(todo + 1);
+ slang->sl_compstartflags = cp;
+ *cp = NUL;
+
+ ap = xmalloc(todo + 1);
+ slang->sl_compallflags = ap;
+ *ap = NUL;
+
+ // And a list of all patterns in their original form, for checking whether
+ // compounding may work in match_compoundrule(). This is freed when we
+ // encounter a wildcard, the check doesn't work then.
+ crp = xmalloc(todo + 1);
+ slang->sl_comprules = crp;
+
+ pp = pat;
+ *pp++ = '^';
+ *pp++ = '\\';
+ *pp++ = '(';
+
+ atstart = 1;
+ while (todo-- > 0) {
+ c = getc(fd); // <compflags>
+ if (c == EOF) {
+ xfree(pat);
+ return SP_TRUNCERROR;
+ }
+
+ // Add all flags to "sl_compallflags".
+ if (vim_strchr((char_u *)"?*+[]/", c) == NULL
+ && !byte_in_str(slang->sl_compallflags, c)) {
+ *ap++ = c;
+ *ap = NUL;
+ }
+
+ if (atstart != 0) {
+ // At start of item: copy flags to "sl_compstartflags". For a
+ // [abc] item set "atstart" to 2 and copy up to the ']'.
+ if (c == '[')
+ atstart = 2;
+ else if (c == ']')
+ atstart = 0;
+ else {
+ if (!byte_in_str(slang->sl_compstartflags, c)) {
+ *cp++ = c;
+ *cp = NUL;
+ }
+ if (atstart == 1)
+ atstart = 0;
+ }
+ }
+
+ // Copy flag to "sl_comprules", unless we run into a wildcard.
+ if (crp != NULL) {
+ if (c == '?' || c == '+' || c == '*') {
+ xfree(slang->sl_comprules);
+ slang->sl_comprules = NULL;
+ crp = NULL;
+ } else
+ *crp++ = c;
+ }
+
+ if (c == '/') { // slash separates two items
+ *pp++ = '\\';
+ *pp++ = '|';
+ atstart = 1;
+ } else { // normal char, "[abc]" and '*' are copied as-is
+ if (c == '?' || c == '+' || c == '~')
+ *pp++ = '\\'; // "a?" becomes "a\?", "a+" becomes "a\+"
+ if (enc_utf8)
+ pp += mb_char2bytes(c, pp);
+ else
+ *pp++ = c;
+ }
+ }
+
+ *pp++ = '\\';
+ *pp++ = ')';
+ *pp++ = '$';
+ *pp = NUL;
+
+ if (crp != NULL)
+ *crp = NUL;
+
+ slang->sl_compprog = vim_regcomp(pat, RE_MAGIC + RE_STRING + RE_STRICT);
+ xfree(pat);
+ if (slang->sl_compprog == NULL)
+ return SP_FORMERROR;
+
+ return 0;
+}
+
+// Set the SOFOFROM and SOFOTO items in language "lp".
+// Returns SP_*ERROR flags when there is something wrong.
+static int set_sofo(slang_T *lp, char_u *from, char_u *to)
+{
+ int i;
+
+ garray_T *gap;
+ char_u *s;
+ char_u *p;
+ int c;
+ int *inp;
+
+ if (has_mbyte) {
+ // Use "sl_sal" as an array with 256 pointers to a list of wide
+ // characters. The index is the low byte of the character.
+ // The list contains from-to pairs with a terminating NUL.
+ // sl_sal_first[] is used for latin1 "from" characters.
+ gap = &lp->sl_sal;
+ ga_init(gap, sizeof(int *), 1);
+ ga_grow(gap, 256);
+ memset(gap->ga_data, 0, sizeof(int *) * 256);
+ gap->ga_len = 256;
+
+ // First count the number of items for each list. Temporarily use
+ // sl_sal_first[] for this.
+ for (p = from, s = to; *p != NUL && *s != NUL; ) {
+ c = mb_cptr2char_adv((const char_u **)&p);
+ mb_cptr_adv(s);
+ if (c >= 256)
+ ++lp->sl_sal_first[c & 0xff];
+ }
+ if (*p != NUL || *s != NUL) // lengths differ
+ return SP_FORMERROR;
+
+ // Allocate the lists.
+ for (i = 0; i < 256; ++i)
+ if (lp->sl_sal_first[i] > 0) {
+ p = xmalloc(sizeof(int) * (lp->sl_sal_first[i] * 2 + 1));
+ ((int **)gap->ga_data)[i] = (int *)p;
+ *(int *)p = 0;
+ }
+
+ // Put the characters up to 255 in sl_sal_first[] the rest in a sl_sal
+ // list.
+ memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256);
+ for (p = from, s = to; *p != NUL && *s != NUL; ) {
+ c = mb_cptr2char_adv((const char_u **)&p);
+ i = mb_cptr2char_adv((const char_u **)&s);
+ if (c >= 256) {
+ // Append the from-to chars at the end of the list with
+ // the low byte.
+ inp = ((int **)gap->ga_data)[c & 0xff];
+ while (*inp != 0)
+ ++inp;
+ *inp++ = c; // from char
+ *inp++ = i; // to char
+ *inp++ = NUL; // NUL at the end
+ } else
+ // mapping byte to char is done in sl_sal_first[]
+ lp->sl_sal_first[c] = i;
+ }
+ } else {
+ // mapping bytes to bytes is done in sl_sal_first[]
+ if (STRLEN(from) != STRLEN(to))
+ return SP_FORMERROR;
+
+ for (i = 0; to[i] != NUL; ++i)
+ lp->sl_sal_first[from[i]] = to[i];
+ lp->sl_sal.ga_len = 1; // indicates we have soundfolding
+ }
+
+ return 0;
+}
+
+// Fill the first-index table for "lp".
+static void set_sal_first(slang_T *lp)
+{
+ salfirst_T *sfirst;
+ salitem_T *smp;
+ int c;
+ garray_T *gap = &lp->sl_sal;
+
+ sfirst = lp->sl_sal_first;
+ for (int i = 0; i < 256; ++i) {
+ sfirst[i] = -1;
+ }
+ smp = (salitem_T *)gap->ga_data;
+ for (int i = 0; i < gap->ga_len; ++i) {
+ if (has_mbyte)
+ // Use the lowest byte of the first character. For latin1 it's
+ // the character, for other encodings it should differ for most
+ // characters.
+ c = *smp[i].sm_lead_w & 0xff;
+ else
+ c = *smp[i].sm_lead;
+ if (sfirst[c] == -1) {
+ sfirst[c] = i;
+ if (has_mbyte) {
+ int n;
+
+ // Make sure all entries with this byte are following each
+ // other. Move the ones that are in the wrong position. Do
+ // keep the same ordering!
+ while (i + 1 < gap->ga_len
+ && (*smp[i + 1].sm_lead_w & 0xff) == c)
+ // Skip over entry with same index byte.
+ ++i;
+
+ for (n = 1; i + n < gap->ga_len; ++n)
+ if ((*smp[i + n].sm_lead_w & 0xff) == c) {
+ salitem_T tsal;
+
+ // Move entry with same index byte after the entries
+ // we already found.
+ ++i;
+ --n;
+ tsal = smp[i + n];
+ memmove(smp + i + 1, smp + i,
+ sizeof(salitem_T) * n);
+ smp[i] = tsal;
+ }
+ }
+ }
+ }
+}
+
+// Turn a multi-byte string into a wide character string.
+// Return it in allocated memory.
+static int *mb_str2wide(char_u *s)
+{
+ int i = 0;
+
+ int *res = xmalloc((mb_charlen(s) + 1) * sizeof(int));
+ for (char_u *p = s; *p != NUL; ) {
+ res[i++] = mb_ptr2char_adv((const char_u **)&p);
+ }
+ res[i] = NUL;
+
+ return res;
+}
+
+// Reads a tree from the .spl or .sug file.
+// Allocates the memory and stores pointers in "bytsp" and "idxsp".
+// This is skipped when the tree has zero length.
+// Returns zero when OK, SP_ value for an error.
+static int
+spell_read_tree (
+ FILE *fd,
+ char_u **bytsp,
+ idx_T **idxsp,
+ bool prefixtree, // true for the prefix tree
+ int prefixcnt // when "prefixtree" is true: prefix count
+)
+{
+ int idx;
+ char_u *bp;
+ idx_T *ip;
+
+ // The tree size was computed when writing the file, so that we can
+ // allocate it as one long block. <nodecount>
+ long len = get4c(fd);
+ if (len < 0) {
+ return SP_TRUNCERROR;
+ }
+ if ((size_t)len >= SIZE_MAX / sizeof(int)) {
+ // Invalid length, multiply with sizeof(int) would overflow.
+ return SP_FORMERROR;
+ }
+ if (len > 0) {
+ // Allocate the byte array.
+ bp = xmalloc(len);
+ *bytsp = bp;
+
+ // Allocate the index array.
+ ip = xcalloc(len, sizeof(*ip));
+ *idxsp = ip;
+
+ // Recursively read the tree and store it in the array.
+ idx = read_tree_node(fd, bp, ip, len, 0, prefixtree, prefixcnt);
+ if (idx < 0)
+ return idx;
+ }
+ return 0;
+}
+
+// Read one row of siblings from the spell file and store it in the byte array
+// "byts" and index array "idxs". Recursively read the children.
+//
+// NOTE: The code here must match put_node()!
+//
+// Returns the index (>= 0) following the siblings.
+// Returns SP_TRUNCERROR if the file is shorter than expected.
+// Returns SP_FORMERROR if there is a format error.
+static idx_T
+read_tree_node (
+ FILE *fd,
+ char_u *byts,
+ idx_T *idxs,
+ int maxidx, // size of arrays
+ idx_T startidx, // current index in "byts" and "idxs"
+ bool prefixtree, // true for reading PREFIXTREE
+ int maxprefcondnr // maximum for <prefcondnr>
+)
+{
+ int len;
+ int i;
+ int n;
+ idx_T idx = startidx;
+ int c;
+ int c2;
+#define SHARED_MASK 0x8000000
+
+ len = getc(fd); // <siblingcount>
+ if (len <= 0)
+ return SP_TRUNCERROR;
+
+ if (startidx + len >= maxidx)
+ return SP_FORMERROR;
+ byts[idx++] = len;
+
+ // Read the byte values, flag/region bytes and shared indexes.
+ for (i = 1; i <= len; ++i) {
+ c = getc(fd); // <byte>
+ if (c < 0)
+ return SP_TRUNCERROR;
+ if (c <= BY_SPECIAL) {
+ if (c == BY_NOFLAGS && !prefixtree) {
+ // No flags, all regions.
+ idxs[idx] = 0;
+ c = 0;
+ } else if (c != BY_INDEX) {
+ if (prefixtree) {
+ // Read the optional pflags byte, the prefix ID and the
+ // condition nr. In idxs[] store the prefix ID in the low
+ // byte, the condition index shifted up 8 bits, the flags
+ // shifted up 24 bits.
+ if (c == BY_FLAGS)
+ c = getc(fd) << 24; // <pflags>
+ else
+ c = 0;
+
+ c |= getc(fd); // <affixID>
+
+ n = get2c(fd); // <prefcondnr>
+ if (n >= maxprefcondnr)
+ return SP_FORMERROR;
+ c |= (n << 8);
+ } else { // c must be BY_FLAGS or BY_FLAGS2
+ // Read flags and optional region and prefix ID. In
+ // idxs[] the flags go in the low two bytes, region above
+ // that and prefix ID above the region.
+ c2 = c;
+ c = getc(fd); // <flags>
+ if (c2 == BY_FLAGS2)
+ c = (getc(fd) << 8) + c; // <flags2>
+ if (c & WF_REGION)
+ c = (getc(fd) << 16) + c; // <region>
+ if (c & WF_AFX)
+ c = (getc(fd) << 24) + c; // <affixID>
+ }
+
+ idxs[idx] = c;
+ c = 0;
+ } else { // c == BY_INDEX
+ // <nodeidx>
+ n = get3c(fd);
+ if (n < 0 || n >= maxidx)
+ return SP_FORMERROR;
+ idxs[idx] = n + SHARED_MASK;
+ c = getc(fd); // <xbyte>
+ }
+ }
+ byts[idx++] = c;
+ }
+
+ // Recursively read the children for non-shared siblings.
+ // Skip the end-of-word ones (zero byte value) and the shared ones (and
+ // remove SHARED_MASK)
+ for (i = 1; i <= len; ++i)
+ if (byts[startidx + i] != 0) {
+ if (idxs[startidx + i] & SHARED_MASK)
+ idxs[startidx + i] &= ~SHARED_MASK;
+ else {
+ idxs[startidx + i] = idx;
+ idx = read_tree_node(fd, byts, idxs, maxidx, idx,
+ prefixtree, maxprefcondnr);
+ if (idx < 0)
+ break;
+ }
+ }
+
+ return idx;
+}
+
+// Reload the spell file "fname" if it's loaded.
+static void
+spell_reload_one (
+ char_u *fname,
+ bool added_word // invoked through "zg"
+)
+{
+ slang_T *slang;
+ bool didit = false;
+
+ for (slang = first_lang; slang != NULL; slang = slang->sl_next) {
+ if (path_full_compare(fname, slang->sl_fname, FALSE) == kEqualFiles) {
+ slang_clear(slang);
+ if (spell_load_file(fname, NULL, slang, false) == NULL)
+ // reloading failed, clear the language
+ slang_clear(slang);
+ redraw_all_later(SOME_VALID);
+ didit = true;
+ }
+ }
+
+ // When "zg" was used and the file wasn't loaded yet, should redo
+ // 'spelllang' to load it now.
+ if (added_word && !didit)
+ did_set_spelllang(curwin);
+}
+
+// Functions for ":mkspell".
+
+// In the postponed prefixes tree wn_flags is used to store the WFP_ flags,
+// but it must be negative to indicate the prefix tree to tree_add_word().
+// Use a negative number with the lower 8 bits zero.
+#define PFX_FLAGS -256
+
+// flags for "condit" argument of store_aff_word()
+#define CONDIT_COMB 1 // affix must combine
+#define CONDIT_CFIX 2 // affix must have CIRCUMFIX flag
+#define CONDIT_SUF 4 // add a suffix for matching flags
+#define CONDIT_AFF 8 // word already has an affix
+
+// Tunable parameters for when the tree is compressed. See 'mkspellmem'.
+static long compress_start = 30000; // memory / SBLOCKSIZE
+static long compress_inc = 100; // memory / SBLOCKSIZE
+static long compress_added = 500000; // word count
+
+// Check the 'mkspellmem' option. Return FAIL if it's wrong.
+// Sets "sps_flags".
+int spell_check_msm(void)
+{
+ char_u *p = p_msm;
+ long start = 0;
+ long incr = 0;
+ long added = 0;
+
+ if (!ascii_isdigit(*p))
+ return FAIL;
+ // block count = (value * 1024) / SBLOCKSIZE (but avoid overflow)
+ start = (getdigits_long(&p) * 10) / (SBLOCKSIZE / 102);
+ if (*p != ',')
+ return FAIL;
+ ++p;
+ if (!ascii_isdigit(*p))
+ return FAIL;
+ incr = (getdigits_long(&p) * 102) / (SBLOCKSIZE / 10);
+ if (*p != ',')
+ return FAIL;
+ ++p;
+ if (!ascii_isdigit(*p))
+ return FAIL;
+ added = getdigits_long(&p) * 1024;
+ if (*p != NUL)
+ return FAIL;
+
+ if (start == 0 || incr == 0 || added == 0 || incr > start)
+ return FAIL;
+
+ compress_start = start;
+ compress_inc = incr;
+ compress_added = added;
+ return OK;
+}
+
+#ifdef SPELL_PRINTTREE
+// For debugging the tree code: print the current tree in a (more or less)
+// readable format, so that we can see what happens when adding a word and/or
+// compressing the tree.
+// Based on code from Olaf Seibert.
+#define PRINTLINESIZE 1000
+#define PRINTWIDTH 6
+
+#define PRINTSOME(l, depth, fmt, a1, a2) vim_snprintf(l + depth * PRINTWIDTH, \
+ PRINTLINESIZE - PRINTWIDTH * depth, fmt, a1, a2)
+
+static char line1[PRINTLINESIZE];
+static char line2[PRINTLINESIZE];
+static char line3[PRINTLINESIZE];
+
+static void spell_clear_flags(wordnode_T *node)
+{
+ wordnode_T *np;
+
+ for (np = node; np != NULL; np = np->wn_sibling) {
+ np->wn_u1.index = FALSE;
+ spell_clear_flags(np->wn_child);
+ }
+}
+
+static void spell_print_node(wordnode_T *node, int depth)
+{
+ if (node->wn_u1.index) {
+ // Done this node before, print the reference.
+ PRINTSOME(line1, depth, "(%d)", node->wn_nr, 0);
+ PRINTSOME(line2, depth, " ", 0, 0);
+ PRINTSOME(line3, depth, " ", 0, 0);
+ msg((char_u *)line1);
+ msg((char_u *)line2);
+ msg((char_u *)line3);
+ } else {
+ node->wn_u1.index = TRUE;
+
+ if (node->wn_byte != NUL) {
+ if (node->wn_child != NULL)
+ PRINTSOME(line1, depth, " %c -> ", node->wn_byte, 0);
+ else
+ // Cannot happen?
+ PRINTSOME(line1, depth, " %c ???", node->wn_byte, 0);
+ } else
+ PRINTSOME(line1, depth, " $ ", 0, 0);
+
+ PRINTSOME(line2, depth, "%d/%d ", node->wn_nr, node->wn_refs);
+
+ if (node->wn_sibling != NULL)
+ PRINTSOME(line3, depth, " | ", 0, 0);
+ else
+ PRINTSOME(line3, depth, " ", 0, 0);
+
+ if (node->wn_byte == NUL) {
+ msg((char_u *)line1);
+ msg((char_u *)line2);
+ msg((char_u *)line3);
+ }
+
+ // do the children
+ if (node->wn_byte != NUL && node->wn_child != NULL)
+ spell_print_node(node->wn_child, depth + 1);
+
+ // do the siblings
+ if (node->wn_sibling != NULL) {
+ // get rid of all parent details except |
+ STRCPY(line1, line3);
+ STRCPY(line2, line3);
+ spell_print_node(node->wn_sibling, depth);
+ }
+ }
+}
+
+static void spell_print_tree(wordnode_T *root)
+{
+ if (root != NULL) {
+ // Clear the "wn_u1.index" fields, used to remember what has been
+ // done.
+ spell_clear_flags(root);
+
+ // Recursively print the tree.
+ spell_print_node(root, 0);
+ }
+}
+
+#endif // SPELL_PRINTTREE
+
+// Reads the affix file "fname".
+// Returns an afffile_T, NULL for complete failure.
+static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
+{
+ FILE *fd;
+ afffile_T *aff;
+ char_u rline[MAXLINELEN];
+ char_u *line;
+ char_u *pc = NULL;
+#define MAXITEMCNT 30
+ char_u *(items[MAXITEMCNT]);
+ int itemcnt;
+ char_u *p;
+ int lnum = 0;
+ affheader_T *cur_aff = NULL;
+ bool did_postpone_prefix = false;
+ int aff_todo = 0;
+ hashtab_T *tp;
+ char_u *low = NULL;
+ char_u *fol = NULL;
+ char_u *upp = NULL;
+ int do_rep;
+ int do_repsal;
+ int do_sal;
+ int do_mapline;
+ bool found_map = false;
+ hashitem_T *hi;
+ int l;
+ int compminlen = 0; // COMPOUNDMIN value
+ int compsylmax = 0; // COMPOUNDSYLMAX value
+ int compoptions = 0; // COMP_ flags
+ int compmax = 0; // COMPOUNDWORDMAX value
+ char_u *compflags = NULL; // COMPOUNDFLAG and COMPOUNDRULE
+ // concatenated
+ char_u *midword = NULL; // MIDWORD value
+ char_u *syllable = NULL; // SYLLABLE value
+ char_u *sofofrom = NULL; // SOFOFROM value
+ char_u *sofoto = NULL; // SOFOTO value
+
+ // Open the file.
+ fd = mch_fopen((char *)fname, "r");
+ if (fd == NULL) {
+ EMSG2(_(e_notopen), fname);
+ return NULL;
+ }
+
+ vim_snprintf((char *)IObuff, IOSIZE, _("Reading affix file %s ..."), fname);
+ spell_message(spin, IObuff);
+
+ // Only do REP lines when not done in another .aff file already.
+ do_rep = GA_EMPTY(&spin->si_rep);
+
+ // Only do REPSAL lines when not done in another .aff file already.
+ do_repsal = GA_EMPTY(&spin->si_repsal);
+
+ // Only do SAL lines when not done in another .aff file already.
+ do_sal = GA_EMPTY(&spin->si_sal);
+
+ // Only do MAP lines when not done in another .aff file already.
+ do_mapline = GA_EMPTY(&spin->si_map);
+
+ // Allocate and init the afffile_T structure.
+ aff = (afffile_T *)getroom(spin, sizeof(afffile_T), true);
+ if (aff == NULL) {
+ fclose(fd);
+ return NULL;
+ }
+ hash_init(&aff->af_pref);
+ hash_init(&aff->af_suff);
+ hash_init(&aff->af_comp);
+
+ // Read all the lines in the file one by one.
+ while (!vim_fgets(rline, MAXLINELEN, fd) && !got_int) {
+ line_breakcheck();
+ ++lnum;
+
+ // Skip comment lines.
+ if (*rline == '#')
+ continue;
+
+ // Convert from "SET" to 'encoding' when needed.
+ xfree(pc);
+ if (spin->si_conv.vc_type != CONV_NONE) {
+ pc = string_convert(&spin->si_conv, rline, NULL);
+ if (pc == NULL) {
+ smsg(_("Conversion failure for word in %s line %d: %s"),
+ fname, lnum, rline);
+ continue;
+ }
+ line = pc;
+ } else {
+ pc = NULL;
+ line = rline;
+ }
+
+ // Split the line up in white separated items. Put a NUL after each
+ // item.
+ itemcnt = 0;
+ for (p = line;; ) {
+ while (*p != NUL && *p <= ' ') // skip white space and CR/NL
+ ++p;
+ if (*p == NUL)
+ break;
+ if (itemcnt == MAXITEMCNT) // too many items
+ break;
+ items[itemcnt++] = p;
+ // A few items have arbitrary text argument, don't split them.
+ if (itemcnt == 2 && spell_info_item(items[0]))
+ while (*p >= ' ' || *p == TAB) // skip until CR/NL
+ ++p;
+ else
+ while (*p > ' ') // skip until white space or CR/NL
+ ++p;
+ if (*p == NUL)
+ break;
+ *p++ = NUL;
+ }
+
+ // Handle non-empty lines.
+ if (itemcnt > 0) {
+ if (is_aff_rule(items, itemcnt, "SET", 2) && aff->af_enc == NULL) {
+ // Setup for conversion from "ENC" to 'encoding'.
+ aff->af_enc = enc_canonize(items[1]);
+ if (!spin->si_ascii
+ && convert_setup(&spin->si_conv, aff->af_enc,
+ p_enc) == FAIL)
+ smsg(_("Conversion in %s not supported: from %s to %s"),
+ fname, aff->af_enc, p_enc);
+ spin->si_conv.vc_fail = true;
+ } else if (is_aff_rule(items, itemcnt, "FLAG", 2)
+ && aff->af_flagtype == AFT_CHAR) {
+ if (STRCMP(items[1], "long") == 0)
+ aff->af_flagtype = AFT_LONG;
+ else if (STRCMP(items[1], "num") == 0)
+ aff->af_flagtype = AFT_NUM;
+ else if (STRCMP(items[1], "caplong") == 0)
+ aff->af_flagtype = AFT_CAPLONG;
+ else
+ smsg(_("Invalid value for FLAG in %s line %d: %s"),
+ fname, lnum, items[1]);
+ if (aff->af_rare != 0
+ || aff->af_keepcase != 0
+ || aff->af_bad != 0
+ || aff->af_needaffix != 0
+ || aff->af_circumfix != 0
+ || aff->af_needcomp != 0
+ || aff->af_comproot != 0
+ || aff->af_nosuggest != 0
+ || compflags != NULL
+ || aff->af_suff.ht_used > 0
+ || aff->af_pref.ht_used > 0)
+ smsg(_("FLAG after using flags in %s line %d: %s"),
+ fname, lnum, items[1]);
+ } else if (spell_info_item(items[0]) && itemcnt > 1) {
+ p = (char_u *)getroom(spin,
+ (spin->si_info == NULL ? 0 : STRLEN(spin->si_info))
+ + STRLEN(items[0])
+ + STRLEN(items[1]) + 3, false);
+ if (p != NULL) {
+ if (spin->si_info != NULL) {
+ STRCPY(p, spin->si_info);
+ STRCAT(p, "\n");
+ }
+ STRCAT(p, items[0]);
+ STRCAT(p, " ");
+ STRCAT(p, items[1]);
+ spin->si_info = p;
+ }
+ } else if (is_aff_rule(items, itemcnt, "MIDWORD", 2)
+ && midword == NULL) {
+ midword = getroom_save(spin, items[1]);
+ } else if (is_aff_rule(items, itemcnt, "TRY", 2)) {
+ // ignored, we look in the tree for what chars may appear
+ }
+ // TODO: remove "RAR" later
+ else if ((is_aff_rule(items, itemcnt, "RAR", 2)
+ || is_aff_rule(items, itemcnt, "RARE", 2))
+ && aff->af_rare == 0) {
+ aff->af_rare = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ }
+ // TODO: remove "KEP" later
+ else if ((is_aff_rule(items, itemcnt, "KEP", 2)
+ || is_aff_rule(items, itemcnt, "KEEPCASE", 2))
+ && aff->af_keepcase == 0) {
+ aff->af_keepcase = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ } else if ((is_aff_rule(items, itemcnt, "BAD", 2)
+ || is_aff_rule(items, itemcnt, "FORBIDDENWORD", 2))
+ && aff->af_bad == 0) {
+ aff->af_bad = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ } else if (is_aff_rule(items, itemcnt, "NEEDAFFIX", 2)
+ && aff->af_needaffix == 0) {
+ aff->af_needaffix = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ } else if (is_aff_rule(items, itemcnt, "CIRCUMFIX", 2)
+ && aff->af_circumfix == 0) {
+ aff->af_circumfix = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ } else if (is_aff_rule(items, itemcnt, "NOSUGGEST", 2)
+ && aff->af_nosuggest == 0) {
+ aff->af_nosuggest = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ } else if ((is_aff_rule(items, itemcnt, "NEEDCOMPOUND", 2)
+ || is_aff_rule(items, itemcnt, "ONLYINCOMPOUND", 2))
+ && aff->af_needcomp == 0) {
+ aff->af_needcomp = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDROOT", 2)
+ && aff->af_comproot == 0) {
+ aff->af_comproot = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDFORBIDFLAG", 2)
+ && aff->af_compforbid == 0) {
+ aff->af_compforbid = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ if (aff->af_pref.ht_used > 0)
+ smsg(_("Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line %d"),
+ fname, lnum);
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDPERMITFLAG", 2)
+ && aff->af_comppermit == 0) {
+ aff->af_comppermit = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ if (aff->af_pref.ht_used > 0)
+ smsg(_("Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line %d"),
+ fname, lnum);
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDFLAG", 2)
+ && compflags == NULL) {
+ // Turn flag "c" into COMPOUNDRULE compatible string "c+",
+ // "Na" into "Na+", "1234" into "1234+".
+ p = getroom(spin, STRLEN(items[1]) + 2, false);
+ STRCPY(p, items[1]);
+ STRCAT(p, "+");
+ compflags = p;
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2)) {
+ // We don't use the count, but do check that it's a number and
+ // not COMPOUNDRULE mistyped.
+ if (atoi((char *)items[1]) == 0)
+ smsg(_("Wrong COMPOUNDRULES value in %s line %d: %s"),
+ fname, lnum, items[1]);
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2)) {
+ // Don't use the first rule if it is a number.
+ if (compflags != NULL || *skipdigits(items[1]) != NUL) {
+ // Concatenate this string to previously defined ones,
+ // using a slash to separate them.
+ l = (int)STRLEN(items[1]) + 1;
+ if (compflags != NULL)
+ l += (int)STRLEN(compflags) + 1;
+ p = getroom(spin, l, false);
+ if (compflags != NULL) {
+ STRCPY(p, compflags);
+ STRCAT(p, "/");
+ }
+ STRCAT(p, items[1]);
+ compflags = p;
+ }
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDWORDMAX", 2)
+ && compmax == 0) {
+ compmax = atoi((char *)items[1]);
+ if (compmax == 0)
+ smsg(_("Wrong COMPOUNDWORDMAX value in %s line %d: %s"),
+ fname, lnum, items[1]);
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDMIN", 2)
+ && compminlen == 0) {
+ compminlen = atoi((char *)items[1]);
+ if (compminlen == 0)
+ smsg(_("Wrong COMPOUNDMIN value in %s line %d: %s"),
+ fname, lnum, items[1]);
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDSYLMAX", 2)
+ && compsylmax == 0) {
+ compsylmax = atoi((char *)items[1]);
+ if (compsylmax == 0)
+ smsg(_("Wrong COMPOUNDSYLMAX value in %s line %d: %s"),
+ fname, lnum, items[1]);
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDDUP", 1)) {
+ compoptions |= COMP_CHECKDUP;
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDREP", 1)) {
+ compoptions |= COMP_CHECKREP;
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDCASE", 1)) {
+ compoptions |= COMP_CHECKCASE;
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDTRIPLE", 1)) {
+ compoptions |= COMP_CHECKTRIPLE;
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 2)) {
+ if (atoi((char *)items[1]) == 0)
+ smsg(_("Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"),
+ fname, lnum, items[1]);
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 3)) {
+ garray_T *gap = &spin->si_comppat;
+ int i;
+
+ // Only add the couple if it isn't already there.
+ for (i = 0; i < gap->ga_len - 1; i += 2)
+ if (STRCMP(((char_u **)(gap->ga_data))[i], items[1]) == 0
+ && STRCMP(((char_u **)(gap->ga_data))[i + 1],
+ items[2]) == 0)
+ break;
+ if (i >= gap->ga_len) {
+ ga_grow(gap, 2);
+ ((char_u **)(gap->ga_data))[gap->ga_len++]
+ = getroom_save(spin, items[1]);
+ ((char_u **)(gap->ga_data))[gap->ga_len++]
+ = getroom_save(spin, items[2]);
+ }
+ } else if (is_aff_rule(items, itemcnt, "SYLLABLE", 2)
+ && syllable == NULL) {
+ syllable = getroom_save(spin, items[1]);
+ } else if (is_aff_rule(items, itemcnt, "NOBREAK", 1)) {
+ spin->si_nobreak = true;
+ } else if (is_aff_rule(items, itemcnt, "NOSPLITSUGS", 1)) {
+ spin->si_nosplitsugs = true;
+ } else if (is_aff_rule(items, itemcnt, "NOCOMPOUNDSUGS", 1)) {
+ spin->si_nocompoundsugs = true;
+ } else if (is_aff_rule(items, itemcnt, "NOSUGFILE", 1)) {
+ spin->si_nosugfile = true;
+ } else if (is_aff_rule(items, itemcnt, "PFXPOSTPONE", 1)) {
+ aff->af_pfxpostpone = true;
+ } else if (is_aff_rule(items, itemcnt, "IGNOREEXTRA", 1)) {
+ aff->af_ignoreextra = true;
+ } else if ((STRCMP(items[0], "PFX") == 0
+ || STRCMP(items[0], "SFX") == 0)
+ && aff_todo == 0
+ && itemcnt >= 4) {
+ int lasti = 4;
+ char_u key[AH_KEY_LEN];
+
+ if (*items[0] == 'P')
+ tp = &aff->af_pref;
+ else
+ tp = &aff->af_suff;
+
+ // Myspell allows the same affix name to be used multiple
+ // times. The affix files that do this have an undocumented
+ // "S" flag on all but the last block, thus we check for that
+ // and store it in ah_follows.
+ STRLCPY(key, items[1], AH_KEY_LEN);
+ hi = hash_find(tp, key);
+ if (!HASHITEM_EMPTY(hi)) {
+ cur_aff = HI2AH(hi);
+ if (cur_aff->ah_combine != (*items[2] == 'Y'))
+ smsg(_("Different combining flag in continued affix block in %s line %d: %s"),
+ fname, lnum, items[1]);
+ if (!cur_aff->ah_follows)
+ smsg(_("Duplicate affix in %s line %d: %s"),
+ fname, lnum, items[1]);
+ } else {
+ // New affix letter.
+ cur_aff = (affheader_T *)getroom(spin,
+ sizeof(affheader_T), true);
+ if (cur_aff == NULL)
+ break;
+ cur_aff->ah_flag = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ if (cur_aff->ah_flag == 0 || STRLEN(items[1]) >= AH_KEY_LEN)
+ break;
+ if (cur_aff->ah_flag == aff->af_bad
+ || cur_aff->ah_flag == aff->af_rare
+ || cur_aff->ah_flag == aff->af_keepcase
+ || cur_aff->ah_flag == aff->af_needaffix
+ || cur_aff->ah_flag == aff->af_circumfix
+ || cur_aff->ah_flag == aff->af_nosuggest
+ || cur_aff->ah_flag == aff->af_needcomp
+ || cur_aff->ah_flag == aff->af_comproot)
+ smsg(_("Affix also used for "
+ "BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST"
+ "in %s line %d: %s"),
+ fname, lnum, items[1]);
+ STRCPY(cur_aff->ah_key, items[1]);
+ hash_add(tp, cur_aff->ah_key);
+
+ cur_aff->ah_combine = (*items[2] == 'Y');
+ }
+
+ // Check for the "S" flag, which apparently means that another
+ // block with the same affix name is following.
+ if (itemcnt > lasti && STRCMP(items[lasti], "S") == 0) {
+ ++lasti;
+ cur_aff->ah_follows = true;
+ } else
+ cur_aff->ah_follows = false;
+
+ // Myspell allows extra text after the item, but that might
+ // mean mistakes go unnoticed. Require a comment-starter,
+ // unless IGNOREEXTRA is used. Hunspell uses a "-" item.
+ if (itemcnt > lasti
+ && !aff->af_ignoreextra
+ && *items[lasti] != '#')
+ smsg(_(e_afftrailing), fname, lnum, items[lasti]);
+
+ if (STRCMP(items[2], "Y") != 0 && STRCMP(items[2], "N") != 0)
+ smsg(_("Expected Y or N in %s line %d: %s"),
+ fname, lnum, items[2]);
+
+ if (*items[0] == 'P' && aff->af_pfxpostpone) {
+ if (cur_aff->ah_newID == 0) {
+ // Use a new number in the .spl file later, to be able
+ // to handle multiple .aff files.
+ check_renumber(spin);
+ cur_aff->ah_newID = ++spin->si_newprefID;
+
+ // We only really use ah_newID if the prefix is
+ // postponed. We know that only after handling all
+ // the items.
+ did_postpone_prefix = false;
+ } else
+ // Did use the ID in a previous block.
+ did_postpone_prefix = true;
+ }
+
+ aff_todo = atoi((char *)items[3]);
+ } else if ((STRCMP(items[0], "PFX") == 0
+ || STRCMP(items[0], "SFX") == 0)
+ && aff_todo > 0
+ && STRCMP(cur_aff->ah_key, items[1]) == 0
+ && itemcnt >= 5) {
+ affentry_T *aff_entry;
+ bool upper = false;
+ int lasti = 5;
+
+ // Myspell allows extra text after the item, but that might
+ // mean mistakes go unnoticed. Require a comment-starter.
+ // Hunspell uses a "-" item.
+ if (itemcnt > lasti && *items[lasti] != '#'
+ && (STRCMP(items[lasti], "-") != 0
+ || itemcnt != lasti + 1))
+ smsg(_(e_afftrailing), fname, lnum, items[lasti]);
+
+ // New item for an affix letter.
+ --aff_todo;
+ aff_entry = (affentry_T *)getroom(spin,
+ sizeof(affentry_T), true);
+ if (aff_entry == NULL)
+ break;
+
+ if (STRCMP(items[2], "0") != 0)
+ aff_entry->ae_chop = getroom_save(spin, items[2]);
+ if (STRCMP(items[3], "0") != 0) {
+ aff_entry->ae_add = getroom_save(spin, items[3]);
+
+ // Recognize flags on the affix: abcd/XYZ
+ aff_entry->ae_flags = vim_strchr(aff_entry->ae_add, '/');
+ if (aff_entry->ae_flags != NULL) {
+ *aff_entry->ae_flags++ = NUL;
+ aff_process_flags(aff, aff_entry);
+ }
+ }
+
+ // Don't use an affix entry with non-ASCII characters when
+ // "spin->si_ascii" is true.
+ if (!spin->si_ascii || !(has_non_ascii(aff_entry->ae_chop)
+ || has_non_ascii(aff_entry->ae_add))) {
+ aff_entry->ae_next = cur_aff->ah_first;
+ cur_aff->ah_first = aff_entry;
+
+ if (STRCMP(items[4], ".") != 0) {
+ char_u buf[MAXLINELEN];
+
+ aff_entry->ae_cond = getroom_save(spin, items[4]);
+ if (*items[0] == 'P')
+ sprintf((char *)buf, "^%s", items[4]);
+ else
+ sprintf((char *)buf, "%s$", items[4]);
+ aff_entry->ae_prog = vim_regcomp(buf,
+ RE_MAGIC + RE_STRING + RE_STRICT);
+ if (aff_entry->ae_prog == NULL)
+ smsg(_("Broken condition in %s line %d: %s"),
+ fname, lnum, items[4]);
+ }
+
+ // For postponed prefixes we need an entry in si_prefcond
+ // for the condition. Use an existing one if possible.
+ // Can't be done for an affix with flags, ignoring
+ // COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG.
+ if (*items[0] == 'P' && aff->af_pfxpostpone
+ && aff_entry->ae_flags == NULL) {
+ // When the chop string is one lower-case letter and
+ // the add string ends in the upper-case letter we set
+ // the "upper" flag, clear "ae_chop" and remove the
+ // letters from "ae_add". The condition must either
+ // be empty or start with the same letter.
+ if (aff_entry->ae_chop != NULL
+ && aff_entry->ae_add != NULL
+ && aff_entry->ae_chop[(*mb_ptr2len)(
+ aff_entry->ae_chop)] == NUL
+ ) {
+ int c, c_up;
+
+ c = PTR2CHAR(aff_entry->ae_chop);
+ c_up = SPELL_TOUPPER(c);
+ if (c_up != c
+ && (aff_entry->ae_cond == NULL
+ || PTR2CHAR(aff_entry->ae_cond) == c)) {
+ p = aff_entry->ae_add
+ + STRLEN(aff_entry->ae_add);
+ mb_ptr_back(aff_entry->ae_add, p);
+ if (PTR2CHAR(p) == c_up) {
+ upper = true;
+ aff_entry->ae_chop = NULL;
+ *p = NUL;
+
+ // The condition is matched with the
+ // actual word, thus must check for the
+ // upper-case letter.
+ if (aff_entry->ae_cond != NULL) {
+ char_u buf[MAXLINELEN];
+ if (has_mbyte) {
+ onecap_copy(items[4], buf, true);
+ aff_entry->ae_cond = getroom_save(
+ spin, buf);
+ } else
+ *aff_entry->ae_cond = c_up;
+ if (aff_entry->ae_cond != NULL) {
+ sprintf((char *)buf, "^%s",
+ aff_entry->ae_cond);
+ vim_regfree(aff_entry->ae_prog);
+ aff_entry->ae_prog = vim_regcomp(
+ buf, RE_MAGIC + RE_STRING);
+ }
+ }
+ }
+ }
+ }
+
+ if (aff_entry->ae_chop == NULL) {
+ int idx;
+ char_u **pp;
+ int n;
+
+ // Find a previously used condition.
+ for (idx = spin->si_prefcond.ga_len - 1; idx >= 0;
+ --idx) {
+ p = ((char_u **)spin->si_prefcond.ga_data)[idx];
+ if (str_equal(p, aff_entry->ae_cond))
+ break;
+ }
+ if (idx < 0) {
+ // Not found, add a new condition.
+ idx = spin->si_prefcond.ga_len;
+ pp = GA_APPEND_VIA_PTR(char_u *, &spin->si_prefcond);
+ *pp = (aff_entry->ae_cond == NULL) ?
+ NULL : getroom_save(spin, aff_entry->ae_cond);
+ }
+
+ // Add the prefix to the prefix tree.
+ if (aff_entry->ae_add == NULL)
+ p = (char_u *)"";
+ else
+ p = aff_entry->ae_add;
+
+ // PFX_FLAGS is a negative number, so that
+ // tree_add_word() knows this is the prefix tree.
+ n = PFX_FLAGS;
+ if (!cur_aff->ah_combine)
+ n |= WFP_NC;
+ if (upper)
+ n |= WFP_UP;
+ if (aff_entry->ae_comppermit)
+ n |= WFP_COMPPERMIT;
+ if (aff_entry->ae_compforbid)
+ n |= WFP_COMPFORBID;
+ tree_add_word(spin, p, spin->si_prefroot, n,
+ idx, cur_aff->ah_newID);
+ did_postpone_prefix = true;
+ }
+
+ // Didn't actually use ah_newID, backup si_newprefID.
+ if (aff_todo == 0 && !did_postpone_prefix) {
+ --spin->si_newprefID;
+ cur_aff->ah_newID = 0;
+ }
+ }
+ }
+ } else if (is_aff_rule(items, itemcnt, "FOL", 2) && fol == NULL) {
+ fol = vim_strsave(items[1]);
+ } else if (is_aff_rule(items, itemcnt, "LOW", 2) && low == NULL) {
+ low = vim_strsave(items[1]);
+ } else if (is_aff_rule(items, itemcnt, "UPP", 2) && upp == NULL) {
+ upp = vim_strsave(items[1]);
+ } else if (is_aff_rule(items, itemcnt, "REP", 2)
+ || is_aff_rule(items, itemcnt, "REPSAL", 2)) {
+ /* Ignore REP/REPSAL count */;
+ if (!isdigit(*items[1]))
+ smsg(_("Expected REP(SAL) count in %s line %d"),
+ fname, lnum);
+ } else if ((STRCMP(items[0], "REP") == 0
+ || STRCMP(items[0], "REPSAL") == 0)
+ && itemcnt >= 3) {
+ // REP/REPSAL item
+ // Myspell ignores extra arguments, we require it starts with
+ // # to detect mistakes.
+ if (itemcnt > 3 && items[3][0] != '#')
+ smsg(_(e_afftrailing), fname, lnum, items[3]);
+ if (items[0][3] == 'S' ? do_repsal : do_rep) {
+ // Replace underscore with space (can't include a space
+ // directly).
+ for (p = items[1]; *p != NUL; mb_ptr_adv(p))
+ if (*p == '_')
+ *p = ' ';
+ for (p = items[2]; *p != NUL; mb_ptr_adv(p))
+ if (*p == '_')
+ *p = ' ';
+ add_fromto(spin, items[0][3] == 'S'
+ ? &spin->si_repsal
+ : &spin->si_rep, items[1], items[2]);
+ }
+ } else if (is_aff_rule(items, itemcnt, "MAP", 2)) {
+ // MAP item or count
+ if (!found_map) {
+ // First line contains the count.
+ found_map = true;
+ if (!isdigit(*items[1]))
+ smsg(_("Expected MAP count in %s line %d"),
+ fname, lnum);
+ } else if (do_mapline) {
+ int c;
+
+ // Check that every character appears only once.
+ for (p = items[1]; *p != NUL; ) {
+ c = mb_ptr2char_adv((const char_u **)&p);
+ if ((!GA_EMPTY(&spin->si_map)
+ && vim_strchr(spin->si_map.ga_data, c)
+ != NULL)
+ || vim_strchr(p, c) != NULL) {
+ smsg(_("Duplicate character in MAP in %s line %d"),
+ fname, lnum);
+ }
+ }
+
+ // We simply concatenate all the MAP strings, separated by
+ // slashes.
+ ga_concat(&spin->si_map, items[1]);
+ ga_append(&spin->si_map, '/');
+ }
+ }
+ // Accept "SAL from to" and "SAL from to #comment".
+ else if (is_aff_rule(items, itemcnt, "SAL", 3)) {
+ if (do_sal) {
+ // SAL item (sounds-a-like)
+ // Either one of the known keys or a from-to pair.
+ if (STRCMP(items[1], "followup") == 0)
+ spin->si_followup = sal_to_bool(items[2]);
+ else if (STRCMP(items[1], "collapse_result") == 0)
+ spin->si_collapse = sal_to_bool(items[2]);
+ else if (STRCMP(items[1], "remove_accents") == 0)
+ spin->si_rem_accents = sal_to_bool(items[2]);
+ else
+ // when "to" is "_" it means empty
+ add_fromto(spin, &spin->si_sal, items[1],
+ STRCMP(items[2], "_") == 0 ? (char_u *)""
+ : items[2]);
+ }
+ } else if (is_aff_rule(items, itemcnt, "SOFOFROM", 2)
+ && sofofrom == NULL) {
+ sofofrom = getroom_save(spin, items[1]);
+ } else if (is_aff_rule(items, itemcnt, "SOFOTO", 2)
+ && sofoto == NULL) {
+ sofoto = getroom_save(spin, items[1]);
+ } else if (STRCMP(items[0], "COMMON") == 0) {
+ int i;
+
+ for (i = 1; i < itemcnt; ++i) {
+ if (HASHITEM_EMPTY(hash_find(&spin->si_commonwords,
+ items[i]))) {
+ p = vim_strsave(items[i]);
+ hash_add(&spin->si_commonwords, p);
+ }
+ }
+ } else
+ smsg(_("Unrecognized or duplicate item in %s line %d: %s"),
+ fname, lnum, items[0]);
+ }
+ }
+
+ if (fol != NULL || low != NULL || upp != NULL) {
+ if (spin->si_clear_chartab) {
+ // Clear the char type tables, don't want to use any of the
+ // currently used spell properties.
+ init_spell_chartab();
+ spin->si_clear_chartab = false;
+ }
+
+ // Don't write a word table for an ASCII file, so that we don't check
+ // for conflicts with a word table that matches 'encoding'.
+ // Don't write one for utf-8 either, we use utf_*() and
+ // mb_get_class(), the list of chars in the file will be incomplete.
+ if (!spin->si_ascii
+ && !enc_utf8
+ ) {
+ if (fol == NULL || low == NULL || upp == NULL)
+ smsg(_("Missing FOL/LOW/UPP line in %s"), fname);
+ else
+ (void)set_spell_chartab(fol, low, upp);
+ }
+
+ xfree(fol);
+ xfree(low);
+ xfree(upp);
+ }
+
+ // Use compound specifications of the .aff file for the spell info.
+ if (compmax != 0) {
+ aff_check_number(spin->si_compmax, compmax, "COMPOUNDWORDMAX");
+ spin->si_compmax = compmax;
+ }
+
+ if (compminlen != 0) {
+ aff_check_number(spin->si_compminlen, compminlen, "COMPOUNDMIN");
+ spin->si_compminlen = compminlen;
+ }
+
+ if (compsylmax != 0) {
+ if (syllable == NULL)
+ smsg(_("COMPOUNDSYLMAX used without SYLLABLE"));
+ aff_check_number(spin->si_compsylmax, compsylmax, "COMPOUNDSYLMAX");
+ spin->si_compsylmax = compsylmax;
+ }
+
+ if (compoptions != 0) {
+ aff_check_number(spin->si_compoptions, compoptions, "COMPOUND options");
+ spin->si_compoptions |= compoptions;
+ }
+
+ if (compflags != NULL)
+ process_compflags(spin, aff, compflags);
+
+ // Check that we didn't use too many renumbered flags.
+ if (spin->si_newcompID < spin->si_newprefID) {
+ if (spin->si_newcompID == 127 || spin->si_newcompID == 255)
+ MSG(_("Too many postponed prefixes"));
+ else if (spin->si_newprefID == 0 || spin->si_newprefID == 127)
+ MSG(_("Too many compound flags"));
+ else
+ MSG(_("Too many postponed prefixes and/or compound flags"));
+ }
+
+ if (syllable != NULL) {
+ aff_check_string(spin->si_syllable, syllable, "SYLLABLE");
+ spin->si_syllable = syllable;
+ }
+
+ if (sofofrom != NULL || sofoto != NULL) {
+ if (sofofrom == NULL || sofoto == NULL)
+ smsg(_("Missing SOFO%s line in %s"),
+ sofofrom == NULL ? "FROM" : "TO", fname);
+ else if (!GA_EMPTY(&spin->si_sal))
+ smsg(_("Both SAL and SOFO lines in %s"), fname);
+ else {
+ aff_check_string(spin->si_sofofr, sofofrom, "SOFOFROM");
+ aff_check_string(spin->si_sofoto, sofoto, "SOFOTO");
+ spin->si_sofofr = sofofrom;
+ spin->si_sofoto = sofoto;
+ }
+ }
+
+ if (midword != NULL) {
+ aff_check_string(spin->si_midword, midword, "MIDWORD");
+ spin->si_midword = midword;
+ }
+
+ xfree(pc);
+ fclose(fd);
+ return aff;
+}
+
+// Returns true when items[0] equals "rulename", there are "mincount" items or
+// a comment is following after item "mincount".
+static bool is_aff_rule(char_u **items, int itemcnt, char *rulename, int mincount)
+{
+ return STRCMP(items[0], rulename) == 0
+ && (itemcnt == mincount
+ || (itemcnt > mincount && items[mincount][0] == '#'));
+}
+
+// For affix "entry" move COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG from
+// ae_flags to ae_comppermit and ae_compforbid.
+static void aff_process_flags(afffile_T *affile, affentry_T *entry)
+{
+ char_u *p;
+ char_u *prevp;
+ unsigned flag;
+
+ if (entry->ae_flags != NULL
+ && (affile->af_compforbid != 0 || affile->af_comppermit != 0)) {
+ for (p = entry->ae_flags; *p != NUL; ) {
+ prevp = p;
+ flag = get_affitem(affile->af_flagtype, &p);
+ if (flag == affile->af_comppermit || flag == affile->af_compforbid) {
+ STRMOVE(prevp, p);
+ p = prevp;
+ if (flag == affile->af_comppermit)
+ entry->ae_comppermit = true;
+ else
+ entry->ae_compforbid = true;
+ }
+ if (affile->af_flagtype == AFT_NUM && *p == ',')
+ ++p;
+ }
+ if (*entry->ae_flags == NUL)
+ entry->ae_flags = NULL; // nothing left
+ }
+}
+
+// Returns true if "s" is the name of an info item in the affix file.
+static bool spell_info_item(char_u *s)
+{
+ return STRCMP(s, "NAME") == 0
+ || STRCMP(s, "HOME") == 0
+ || STRCMP(s, "VERSION") == 0
+ || STRCMP(s, "AUTHOR") == 0
+ || STRCMP(s, "EMAIL") == 0
+ || STRCMP(s, "COPYRIGHT") == 0;
+}
+
+// Turn an affix flag name into a number, according to the FLAG type.
+// returns zero for failure.
+static unsigned affitem2flag(int flagtype, char_u *item, char_u *fname, int lnum)
+{
+ unsigned res;
+ char_u *p = item;
+
+ res = get_affitem(flagtype, &p);
+ if (res == 0) {
+ if (flagtype == AFT_NUM)
+ smsg(_("Flag is not a number in %s line %d: %s"),
+ fname, lnum, item);
+ else
+ smsg(_("Illegal flag in %s line %d: %s"),
+ fname, lnum, item);
+ }
+ if (*p != NUL) {
+ smsg(_(e_affname), fname, lnum, item);
+ return 0;
+ }
+
+ return res;
+}
+
+// Get one affix name from "*pp" and advance the pointer.
+// Returns zero for an error, still advances the pointer then.
+static unsigned get_affitem(int flagtype, char_u **pp)
+{
+ int res;
+
+ if (flagtype == AFT_NUM) {
+ if (!ascii_isdigit(**pp)) {
+ ++*pp; // always advance, avoid getting stuck
+ return 0;
+ }
+ res = getdigits_int(pp);
+ } else {
+ res = mb_ptr2char_adv((const char_u **)pp);
+ if (flagtype == AFT_LONG || (flagtype == AFT_CAPLONG
+ && res >= 'A' && res <= 'Z')) {
+ if (**pp == NUL)
+ return 0;
+ res = mb_ptr2char_adv((const char_u **)pp) + (res << 16);
+ }
+ }
+ return res;
+}
+
+// Process the "compflags" string used in an affix file and append it to
+// spin->si_compflags.
+// The processing involves changing the affix names to ID numbers, so that
+// they fit in one byte.
+static void process_compflags(spellinfo_T *spin, afffile_T *aff, char_u *compflags)
+{
+ char_u *p;
+ char_u *prevp;
+ unsigned flag;
+ compitem_T *ci;
+ int id;
+ int len;
+ char_u *tp;
+ char_u key[AH_KEY_LEN];
+ hashitem_T *hi;
+
+ // Make room for the old and the new compflags, concatenated with a / in
+ // between. Processing it makes it shorter, but we don't know by how
+ // much, thus allocate the maximum.
+ len = (int)STRLEN(compflags) + 1;
+ if (spin->si_compflags != NULL)
+ len += (int)STRLEN(spin->si_compflags) + 1;
+ p = getroom(spin, len, false);
+ if (spin->si_compflags != NULL) {
+ STRCPY(p, spin->si_compflags);
+ STRCAT(p, "/");
+ }
+ spin->si_compflags = p;
+ tp = p + STRLEN(p);
+
+ for (p = compflags; *p != NUL; ) {
+ if (vim_strchr((char_u *)"/?*+[]", *p) != NULL)
+ // Copy non-flag characters directly.
+ *tp++ = *p++;
+ else {
+ // First get the flag number, also checks validity.
+ prevp = p;
+ flag = get_affitem(aff->af_flagtype, &p);
+ if (flag != 0) {
+ // Find the flag in the hashtable. If it was used before, use
+ // the existing ID. Otherwise add a new entry.
+ STRLCPY(key, prevp, p - prevp + 1);
+ hi = hash_find(&aff->af_comp, key);
+ if (!HASHITEM_EMPTY(hi))
+ id = HI2CI(hi)->ci_newID;
+ else {
+ ci = (compitem_T *)getroom(spin, sizeof(compitem_T), true);
+ if (ci == NULL)
+ break;
+ STRCPY(ci->ci_key, key);
+ ci->ci_flag = flag;
+ // Avoid using a flag ID that has a special meaning in a
+ // regexp (also inside []).
+ do {
+ check_renumber(spin);
+ id = spin->si_newcompID--;
+ } while (vim_strchr((char_u *)"/?*+[]\\-^", id) != NULL);
+ ci->ci_newID = id;
+ hash_add(&aff->af_comp, ci->ci_key);
+ }
+ *tp++ = id;
+ }
+ if (aff->af_flagtype == AFT_NUM && *p == ',')
+ ++p;
+ }
+ }
+
+ *tp = NUL;
+}
+
+// Check that the new IDs for postponed affixes and compounding don't overrun
+// each other. We have almost 255 available, but start at 0-127 to avoid
+// using two bytes for utf-8. When the 0-127 range is used up go to 128-255.
+// When that is used up an error message is given.
+static void check_renumber(spellinfo_T *spin)
+{
+ if (spin->si_newprefID == spin->si_newcompID && spin->si_newcompID < 128) {
+ spin->si_newprefID = 127;
+ spin->si_newcompID = 255;
+ }
+}
+
+// Returns true if flag "flag" appears in affix list "afflist".
+static bool flag_in_afflist(int flagtype, char_u *afflist, unsigned flag)
+{
+ char_u *p;
+ unsigned n;
+
+ switch (flagtype) {
+ case AFT_CHAR:
+ return vim_strchr(afflist, flag) != NULL;
+
+ case AFT_CAPLONG:
+ case AFT_LONG:
+ for (p = afflist; *p != NUL; ) {
+ n = mb_ptr2char_adv((const char_u **)&p);
+ if ((flagtype == AFT_LONG || (n >= 'A' && n <= 'Z'))
+ && *p != NUL) {
+ n = mb_ptr2char_adv((const char_u **)&p) + (n << 16);
+ }
+ if (n == flag) {
+ return true;
+ }
+ }
+ break;
+
+ case AFT_NUM:
+ for (p = afflist; *p != NUL; ) {
+ int digits = getdigits_int(&p);
+ assert(digits >= 0);
+ n = (unsigned int)digits;
+ if (n == flag)
+ return true;
+ if (*p != NUL) // skip over comma
+ ++p;
+ }
+ break;
+ }
+ return false;
+}
+
+// Give a warning when "spinval" and "affval" numbers are set and not the same.
+static void aff_check_number(int spinval, int affval, char *name)
+{
+ if (spinval != 0 && spinval != affval)
+ smsg(_("%s value differs from what is used in another .aff file"),
+ name);
+}
+
+// Give a warning when "spinval" and "affval" strings are set and not the same.
+static void aff_check_string(char_u *spinval, char_u *affval, char *name)
+{
+ if (spinval != NULL && STRCMP(spinval, affval) != 0)
+ smsg(_("%s value differs from what is used in another .aff file"),
+ name);
+}
+
+// Returns true if strings "s1" and "s2" are equal. Also consider both being
+// NULL as equal.
+static bool str_equal(char_u *s1, char_u *s2)
+{
+ if (s1 == NULL || s2 == NULL)
+ return s1 == s2;
+ return STRCMP(s1, s2) == 0;
+}
+
+// Add a from-to item to "gap". Used for REP and SAL items.
+// They are stored case-folded.
+static void add_fromto(spellinfo_T *spin, garray_T *gap, char_u *from, char_u *to)
+{
+ char_u word[MAXWLEN];
+
+ fromto_T *ftp = GA_APPEND_VIA_PTR(fromto_T, gap);
+ (void)spell_casefold(from, (int)STRLEN(from), word, MAXWLEN);
+ ftp->ft_from = getroom_save(spin, word);
+ (void)spell_casefold(to, (int)STRLEN(to), word, MAXWLEN);
+ ftp->ft_to = getroom_save(spin, word);
+}
+
+// Converts a boolean argument in a SAL line to true or false;
+static bool sal_to_bool(char_u *s)
+{
+ return STRCMP(s, "1") == 0 || STRCMP(s, "true") == 0;
+}
+
+// Free the structure filled by spell_read_aff().
+static void spell_free_aff(afffile_T *aff)
+{
+ hashtab_T *ht;
+ hashitem_T *hi;
+ int todo;
+ affheader_T *ah;
+ affentry_T *ae;
+
+ xfree(aff->af_enc);
+
+ // All this trouble to free the "ae_prog" items...
+ for (ht = &aff->af_pref;; ht = &aff->af_suff) {
+ todo = (int)ht->ht_used;
+ for (hi = ht->ht_array; todo > 0; ++hi) {
+ if (!HASHITEM_EMPTY(hi)) {
+ --todo;
+ ah = HI2AH(hi);
+ for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next)
+ vim_regfree(ae->ae_prog);
+ }
+ }
+ if (ht == &aff->af_suff)
+ break;
+ }
+
+ hash_clear(&aff->af_pref);
+ hash_clear(&aff->af_suff);
+ hash_clear(&aff->af_comp);
+}
+
+// Read dictionary file "fname".
+// Returns OK or FAIL;
+static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile)
+{
+ hashtab_T ht;
+ char_u line[MAXLINELEN];
+ char_u *p;
+ char_u *afflist;
+ char_u store_afflist[MAXWLEN];
+ int pfxlen;
+ bool need_affix;
+ char_u *dw;
+ char_u *pc;
+ char_u *w;
+ int l;
+ hash_T hash;
+ hashitem_T *hi;
+ FILE *fd;
+ int lnum = 1;
+ int non_ascii = 0;
+ int retval = OK;
+ char_u message[MAXLINELEN + MAXWLEN];
+ int flags;
+ int duplicate = 0;
+
+ // Open the file.
+ fd = mch_fopen((char *)fname, "r");
+ if (fd == NULL) {
+ EMSG2(_(e_notopen), fname);
+ return FAIL;
+ }
+
+ // The hashtable is only used to detect duplicated words.
+ hash_init(&ht);
+
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Reading dictionary file %s ..."), fname);
+ spell_message(spin, IObuff);
+
+ // start with a message for the first line
+ spin->si_msg_count = 999999;
+
+ // Read and ignore the first line: word count.
+ (void)vim_fgets(line, MAXLINELEN, fd);
+ if (!ascii_isdigit(*skipwhite(line)))
+ EMSG2(_("E760: No word count in %s"), fname);
+
+ // Read all the lines in the file one by one.
+ // The words are converted to 'encoding' here, before being added to
+ // the hashtable.
+ while (!vim_fgets(line, MAXLINELEN, fd) && !got_int) {
+ line_breakcheck();
+ ++lnum;
+ if (line[0] == '#' || line[0] == '/')
+ continue; // comment line
+
+ // Remove CR, LF and white space from the end. White space halfway through
+ // the word is kept to allow multi-word terms like "et al.".
+ l = (int)STRLEN(line);
+ while (l > 0 && line[l - 1] <= ' ')
+ --l;
+ if (l == 0)
+ continue; // empty line
+ line[l] = NUL;
+
+ // Convert from "SET" to 'encoding' when needed.
+ if (spin->si_conv.vc_type != CONV_NONE) {
+ pc = string_convert(&spin->si_conv, line, NULL);
+ if (pc == NULL) {
+ smsg(_("Conversion failure for word in %s line %d: %s"),
+ fname, lnum, line);
+ continue;
+ }
+ w = pc;
+ } else {
+ pc = NULL;
+ w = line;
+ }
+
+ // Truncate the word at the "/", set "afflist" to what follows.
+ // Replace "\/" by "/" and "\\" by "\".
+ afflist = NULL;
+ for (p = w; *p != NUL; mb_ptr_adv(p)) {
+ if (*p == '\\' && (p[1] == '\\' || p[1] == '/'))
+ STRMOVE(p, p + 1);
+ else if (*p == '/') {
+ *p = NUL;
+ afflist = p + 1;
+ break;
+ }
+ }
+
+ // Skip non-ASCII words when "spin->si_ascii" is true.
+ if (spin->si_ascii && has_non_ascii(w)) {
+ ++non_ascii;
+ xfree(pc);
+ continue;
+ }
+
+ // This takes time, print a message every 10000 words.
+ if (spin->si_verbose && spin->si_msg_count > 10000) {
+ spin->si_msg_count = 0;
+ vim_snprintf((char *)message, sizeof(message),
+ _("line %6d, word %6d - %s"),
+ lnum, spin->si_foldwcount + spin->si_keepwcount, w);
+ msg_start();
+ msg_puts_long_attr(message, 0);
+ msg_clr_eos();
+ msg_didout = FALSE;
+ msg_col = 0;
+ ui_flush();
+ }
+
+ // Store the word in the hashtable to be able to find duplicates.
+ dw = getroom_save(spin, w);
+ if (dw == NULL) {
+ retval = FAIL;
+ xfree(pc);
+ break;
+ }
+
+ hash = hash_hash(dw);
+ hi = hash_lookup(&ht, (const char *)dw, STRLEN(dw), hash);
+ if (!HASHITEM_EMPTY(hi)) {
+ if (p_verbose > 0)
+ smsg(_("Duplicate word in %s line %d: %s"),
+ fname, lnum, dw);
+ else if (duplicate == 0)
+ smsg(_("First duplicate word in %s line %d: %s"),
+ fname, lnum, dw);
+ ++duplicate;
+ } else
+ hash_add_item(&ht, hi, dw, hash);
+
+ flags = 0;
+ store_afflist[0] = NUL;
+ pfxlen = 0;
+ need_affix = false;
+ if (afflist != NULL) {
+ // Extract flags from the affix list.
+ flags |= get_affix_flags(affile, afflist);
+
+ if (affile->af_needaffix != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_needaffix))
+ need_affix = true;
+
+ if (affile->af_pfxpostpone)
+ // Need to store the list of prefix IDs with the word.
+ pfxlen = get_pfxlist(affile, afflist, store_afflist);
+
+ if (spin->si_compflags != NULL)
+ // Need to store the list of compound flags with the word.
+ // Concatenate them to the list of prefix IDs.
+ get_compflags(affile, afflist, store_afflist + pfxlen);
+ }
+
+ // Add the word to the word tree(s).
+ if (store_word(spin, dw, flags, spin->si_region,
+ store_afflist, need_affix) == FAIL)
+ retval = FAIL;
+
+ if (afflist != NULL) {
+ // Find all matching suffixes and add the resulting words.
+ // Additionally do matching prefixes that combine.
+ if (store_aff_word(spin, dw, afflist, affile,
+ &affile->af_suff, &affile->af_pref,
+ CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL)
+ retval = FAIL;
+
+ // Find all matching prefixes and add the resulting words.
+ if (store_aff_word(spin, dw, afflist, affile,
+ &affile->af_pref, NULL,
+ CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL)
+ retval = FAIL;
+ }
+
+ xfree(pc);
+ }
+
+ if (duplicate > 0)
+ smsg(_("%d duplicate word(s) in %s"), duplicate, fname);
+ if (spin->si_ascii && non_ascii > 0)
+ smsg(_("Ignored %d word(s) with non-ASCII characters in %s"),
+ non_ascii, fname);
+ hash_clear(&ht);
+
+ fclose(fd);
+ return retval;
+}
+
+// Check for affix flags in "afflist" that are turned into word flags.
+// Return WF_ flags.
+static int get_affix_flags(afffile_T *affile, char_u *afflist)
+{
+ int flags = 0;
+
+ if (affile->af_keepcase != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_keepcase))
+ flags |= WF_KEEPCAP | WF_FIXCAP;
+ if (affile->af_rare != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_rare))
+ flags |= WF_RARE;
+ if (affile->af_bad != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_bad))
+ flags |= WF_BANNED;
+ if (affile->af_needcomp != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_needcomp))
+ flags |= WF_NEEDCOMP;
+ if (affile->af_comproot != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_comproot))
+ flags |= WF_COMPROOT;
+ if (affile->af_nosuggest != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_nosuggest))
+ flags |= WF_NOSUGGEST;
+ return flags;
+}
+
+// Get the list of prefix IDs from the affix list "afflist".
+// Used for PFXPOSTPONE.
+// Put the resulting flags in "store_afflist[MAXWLEN]" with a terminating NUL
+// and return the number of affixes.
+static int get_pfxlist(afffile_T *affile, char_u *afflist, char_u *store_afflist)
+{
+ char_u *p;
+ char_u *prevp;
+ int cnt = 0;
+ int id;
+ char_u key[AH_KEY_LEN];
+ hashitem_T *hi;
+
+ for (p = afflist; *p != NUL; ) {
+ prevp = p;
+ if (get_affitem(affile->af_flagtype, &p) != 0) {
+ // A flag is a postponed prefix flag if it appears in "af_pref"
+ // and it's ID is not zero.
+ STRLCPY(key, prevp, p - prevp + 1);
+ hi = hash_find(&affile->af_pref, key);
+ if (!HASHITEM_EMPTY(hi)) {
+ id = HI2AH(hi)->ah_newID;
+ if (id != 0)
+ store_afflist[cnt++] = id;
+ }
+ }
+ if (affile->af_flagtype == AFT_NUM && *p == ',')
+ ++p;
+ }
+
+ store_afflist[cnt] = NUL;
+ return cnt;
+}
+
+// Get the list of compound IDs from the affix list "afflist" that are used
+// for compound words.
+// Puts the flags in "store_afflist[]".
+static void get_compflags(afffile_T *affile, char_u *afflist, char_u *store_afflist)
+{
+ char_u *p;
+ char_u *prevp;
+ int cnt = 0;
+ char_u key[AH_KEY_LEN];
+ hashitem_T *hi;
+
+ for (p = afflist; *p != NUL; ) {
+ prevp = p;
+ if (get_affitem(affile->af_flagtype, &p) != 0) {
+ // A flag is a compound flag if it appears in "af_comp".
+ STRLCPY(key, prevp, p - prevp + 1);
+ hi = hash_find(&affile->af_comp, key);
+ if (!HASHITEM_EMPTY(hi))
+ store_afflist[cnt++] = HI2CI(hi)->ci_newID;
+ }
+ if (affile->af_flagtype == AFT_NUM && *p == ',')
+ ++p;
+ }
+
+ store_afflist[cnt] = NUL;
+}
+
+// Apply affixes to a word and store the resulting words.
+// "ht" is the hashtable with affentry_T that need to be applied, either
+// prefixes or suffixes.
+// "xht", when not NULL, is the prefix hashtable, to be used additionally on
+// the resulting words for combining affixes.
+//
+// Returns FAIL when out of memory.
+static int
+store_aff_word (
+ spellinfo_T *spin, // spell info
+ char_u *word, // basic word start
+ char_u *afflist, // list of names of supported affixes
+ afffile_T *affile,
+ hashtab_T *ht,
+ hashtab_T *xht,
+ int condit, // CONDIT_SUF et al.
+ int flags, // flags for the word
+ char_u *pfxlist, // list of prefix IDs
+ int pfxlen // nr of flags in "pfxlist" for prefixes, rest
+ // is compound flags
+)
+{
+ int todo;
+ hashitem_T *hi;
+ affheader_T *ah;
+ affentry_T *ae;
+ char_u newword[MAXWLEN];
+ int retval = OK;
+ int i, j;
+ char_u *p;
+ int use_flags;
+ char_u *use_pfxlist;
+ int use_pfxlen;
+ bool need_affix;
+ char_u store_afflist[MAXWLEN];
+ char_u pfx_pfxlist[MAXWLEN];
+ size_t wordlen = STRLEN(word);
+ int use_condit;
+
+ todo = (int)ht->ht_used;
+ for (hi = ht->ht_array; todo > 0 && retval == OK; ++hi) {
+ if (!HASHITEM_EMPTY(hi)) {
+ --todo;
+ ah = HI2AH(hi);
+
+ // Check that the affix combines, if required, and that the word
+ // supports this affix.
+ if (((condit & CONDIT_COMB) == 0 || ah->ah_combine)
+ && flag_in_afflist(affile->af_flagtype, afflist,
+ ah->ah_flag)) {
+ // Loop over all affix entries with this name.
+ for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next) {
+ // Check the condition. It's not logical to match case
+ // here, but it is required for compatibility with
+ // Myspell.
+ // Another requirement from Myspell is that the chop
+ // string is shorter than the word itself.
+ // For prefixes, when "PFXPOSTPONE" was used, only do
+ // prefixes with a chop string and/or flags.
+ // When a previously added affix had CIRCUMFIX this one
+ // must have it too, if it had not then this one must not
+ // have one either.
+ if ((xht != NULL || !affile->af_pfxpostpone
+ || ae->ae_chop != NULL
+ || ae->ae_flags != NULL)
+ && (ae->ae_chop == NULL
+ || STRLEN(ae->ae_chop) < wordlen)
+ && (ae->ae_prog == NULL
+ || vim_regexec_prog(&ae->ae_prog, false, word, (colnr_T)0))
+ && (((condit & CONDIT_CFIX) == 0)
+ == ((condit & CONDIT_AFF) == 0
+ || ae->ae_flags == NULL
+ || !flag_in_afflist(affile->af_flagtype,
+ ae->ae_flags, affile->af_circumfix)))) {
+ // Match. Remove the chop and add the affix.
+ if (xht == NULL) {
+ // prefix: chop/add at the start of the word
+ if (ae->ae_add == NULL)
+ *newword = NUL;
+ else
+ STRLCPY(newword, ae->ae_add, MAXWLEN);
+ p = word;
+ if (ae->ae_chop != NULL) {
+ // Skip chop string.
+ if (has_mbyte) {
+ i = mb_charlen(ae->ae_chop);
+ for (; i > 0; --i)
+ mb_ptr_adv(p);
+ } else
+ p += STRLEN(ae->ae_chop);
+ }
+ STRCAT(newword, p);
+ } else {
+ // suffix: chop/add at the end of the word
+ STRLCPY(newword, word, MAXWLEN);
+ if (ae->ae_chop != NULL) {
+ // Remove chop string.
+ p = newword + STRLEN(newword);
+ i = (int)MB_CHARLEN(ae->ae_chop);
+ for (; i > 0; --i)
+ mb_ptr_back(newword, p);
+ *p = NUL;
+ }
+ if (ae->ae_add != NULL)
+ STRCAT(newword, ae->ae_add);
+ }
+
+ use_flags = flags;
+ use_pfxlist = pfxlist;
+ use_pfxlen = pfxlen;
+ need_affix = false;
+ use_condit = condit | CONDIT_COMB | CONDIT_AFF;
+ if (ae->ae_flags != NULL) {
+ // Extract flags from the affix list.
+ use_flags |= get_affix_flags(affile, ae->ae_flags);
+
+ if (affile->af_needaffix != 0 && flag_in_afflist(
+ affile->af_flagtype, ae->ae_flags,
+ affile->af_needaffix))
+ need_affix = true;
+
+ // When there is a CIRCUMFIX flag the other affix
+ // must also have it and we don't add the word
+ // with one affix.
+ if (affile->af_circumfix != 0 && flag_in_afflist(
+ affile->af_flagtype, ae->ae_flags,
+ affile->af_circumfix)) {
+ use_condit |= CONDIT_CFIX;
+ if ((condit & CONDIT_CFIX) == 0)
+ need_affix = true;
+ }
+
+ if (affile->af_pfxpostpone
+ || spin->si_compflags != NULL) {
+ if (affile->af_pfxpostpone)
+ // Get prefix IDS from the affix list.
+ use_pfxlen = get_pfxlist(affile,
+ ae->ae_flags, store_afflist);
+ else
+ use_pfxlen = 0;
+ use_pfxlist = store_afflist;
+
+ // Combine the prefix IDs. Avoid adding the
+ // same ID twice.
+ for (i = 0; i < pfxlen; ++i) {
+ for (j = 0; j < use_pfxlen; ++j)
+ if (pfxlist[i] == use_pfxlist[j])
+ break;
+ if (j == use_pfxlen)
+ use_pfxlist[use_pfxlen++] = pfxlist[i];
+ }
+
+ if (spin->si_compflags != NULL)
+ // Get compound IDS from the affix list.
+ get_compflags(affile, ae->ae_flags,
+ use_pfxlist + use_pfxlen);
+ else
+ use_pfxlist[use_pfxlen] = NUL;
+
+ // Combine the list of compound flags.
+ // Concatenate them to the prefix IDs list.
+ // Avoid adding the same ID twice.
+ for (i = pfxlen; pfxlist[i] != NUL; ++i) {
+ for (j = use_pfxlen;
+ use_pfxlist[j] != NUL; ++j)
+ if (pfxlist[i] == use_pfxlist[j])
+ break;
+ if (use_pfxlist[j] == NUL) {
+ use_pfxlist[j++] = pfxlist[i];
+ use_pfxlist[j] = NUL;
+ }
+ }
+ }
+ }
+
+ // Obey a "COMPOUNDFORBIDFLAG" of the affix: don't
+ // use the compound flags.
+ if (use_pfxlist != NULL && ae->ae_compforbid) {
+ STRLCPY(pfx_pfxlist, use_pfxlist, use_pfxlen + 1);
+ use_pfxlist = pfx_pfxlist;
+ }
+
+ // When there are postponed prefixes...
+ if (spin->si_prefroot != NULL
+ && spin->si_prefroot->wn_sibling != NULL) {
+ // ... add a flag to indicate an affix was used.
+ use_flags |= WF_HAS_AFF;
+
+ // ... don't use a prefix list if combining
+ // affixes is not allowed. But do use the
+ // compound flags after them.
+ if (!ah->ah_combine && use_pfxlist != NULL)
+ use_pfxlist += use_pfxlen;
+ }
+
+ // When compounding is supported and there is no
+ // "COMPOUNDPERMITFLAG" then forbid compounding on the
+ // side where the affix is applied.
+ if (spin->si_compflags != NULL && !ae->ae_comppermit) {
+ if (xht != NULL)
+ use_flags |= WF_NOCOMPAFT;
+ else
+ use_flags |= WF_NOCOMPBEF;
+ }
+
+ // Store the modified word.
+ if (store_word(spin, newword, use_flags,
+ spin->si_region, use_pfxlist,
+ need_affix) == FAIL)
+ retval = FAIL;
+
+ // When added a prefix or a first suffix and the affix
+ // has flags may add a(nother) suffix. RECURSIVE!
+ if ((condit & CONDIT_SUF) && ae->ae_flags != NULL)
+ if (store_aff_word(spin, newword, ae->ae_flags,
+ affile, &affile->af_suff, xht,
+ use_condit & (xht == NULL
+ ? ~0 : ~CONDIT_SUF),
+ use_flags, use_pfxlist, pfxlen) == FAIL)
+ retval = FAIL;
+
+ // When added a suffix and combining is allowed also
+ // try adding a prefix additionally. Both for the
+ // word flags and for the affix flags. RECURSIVE!
+ if (xht != NULL && ah->ah_combine) {
+ if (store_aff_word(spin, newword,
+ afflist, affile,
+ xht, NULL, use_condit,
+ use_flags, use_pfxlist,
+ pfxlen) == FAIL
+ || (ae->ae_flags != NULL
+ && store_aff_word(spin, newword,
+ ae->ae_flags, affile,
+ xht, NULL, use_condit,
+ use_flags, use_pfxlist,
+ pfxlen) == FAIL))
+ retval = FAIL;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return retval;
+}
+
+// Read a file with a list of words.
+static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
+{
+ FILE *fd;
+ long lnum = 0;
+ char_u rline[MAXLINELEN];
+ char_u *line;
+ char_u *pc = NULL;
+ char_u *p;
+ int l;
+ int retval = OK;
+ bool did_word = false;
+ int non_ascii = 0;
+ int flags;
+ int regionmask;
+
+ // Open the file.
+ fd = mch_fopen((char *)fname, "r");
+ if (fd == NULL) {
+ EMSG2(_(e_notopen), fname);
+ return FAIL;
+ }
+
+ vim_snprintf((char *)IObuff, IOSIZE, _("Reading word file %s ..."), fname);
+ spell_message(spin, IObuff);
+
+ // Read all the lines in the file one by one.
+ while (!vim_fgets(rline, MAXLINELEN, fd) && !got_int) {
+ line_breakcheck();
+ ++lnum;
+
+ // Skip comment lines.
+ if (*rline == '#')
+ continue;
+
+ // Remove CR, LF and white space from the end.
+ l = (int)STRLEN(rline);
+ while (l > 0 && rline[l - 1] <= ' ')
+ --l;
+ if (l == 0)
+ continue; // empty or blank line
+ rline[l] = NUL;
+
+ // Convert from "/encoding={encoding}" to 'encoding' when needed.
+ xfree(pc);
+ if (spin->si_conv.vc_type != CONV_NONE) {
+ pc = string_convert(&spin->si_conv, rline, NULL);
+ if (pc == NULL) {
+ smsg(_("Conversion failure for word in %s line %d: %s"),
+ fname, lnum, rline);
+ continue;
+ }
+ line = pc;
+ } else {
+ pc = NULL;
+ line = rline;
+ }
+
+ if (*line == '/') {
+ ++line;
+ if (STRNCMP(line, "encoding=", 9) == 0) {
+ if (spin->si_conv.vc_type != CONV_NONE)
+ smsg(_("Duplicate /encoding= line ignored in %s line %d: %s"),
+ fname, lnum, line - 1);
+ else if (did_word)
+ smsg(_("/encoding= line after word ignored in %s line %d: %s"),
+ fname, lnum, line - 1);
+ else {
+ char_u *enc;
+
+ // Setup for conversion to 'encoding'.
+ line += 9;
+ enc = enc_canonize(line);
+ if (!spin->si_ascii
+ && convert_setup(&spin->si_conv, enc,
+ p_enc) == FAIL)
+ smsg(_("Conversion in %s not supported: from %s to %s"),
+ fname, line, p_enc);
+ xfree(enc);
+ spin->si_conv.vc_fail = true;
+ }
+ continue;
+ }
+
+ if (STRNCMP(line, "regions=", 8) == 0) {
+ if (spin->si_region_count > 1)
+ smsg(_("Duplicate /regions= line ignored in %s line %d: %s"),
+ fname, lnum, line);
+ else {
+ line += 8;
+ if (STRLEN(line) > 16)
+ smsg(_("Too many regions in %s line %d: %s"),
+ fname, lnum, line);
+ else {
+ spin->si_region_count = (int)STRLEN(line) / 2;
+ STRCPY(spin->si_region_name, line);
+
+ // Adjust the mask for a word valid in all regions.
+ spin->si_region = (1 << spin->si_region_count) - 1;
+ }
+ }
+ continue;
+ }
+
+ smsg(_("/ line ignored in %s line %d: %s"),
+ fname, lnum, line - 1);
+ continue;
+ }
+
+ flags = 0;
+ regionmask = spin->si_region;
+
+ // Check for flags and region after a slash.
+ p = vim_strchr(line, '/');
+ if (p != NULL) {
+ *p++ = NUL;
+ while (*p != NUL) {
+ if (*p == '=') // keep-case word
+ flags |= WF_KEEPCAP | WF_FIXCAP;
+ else if (*p == '!') // Bad, bad, wicked word.
+ flags |= WF_BANNED;
+ else if (*p == '?') // Rare word.
+ flags |= WF_RARE;
+ else if (ascii_isdigit(*p)) { // region number(s)
+ if ((flags & WF_REGION) == 0) // first one
+ regionmask = 0;
+ flags |= WF_REGION;
+
+ l = *p - '0';
+ if (l > spin->si_region_count) {
+ smsg(_("Invalid region nr in %s line %d: %s"),
+ fname, lnum, p);
+ break;
+ }
+ regionmask |= 1 << (l - 1);
+ } else {
+ smsg(_("Unrecognized flags in %s line %d: %s"),
+ fname, lnum, p);
+ break;
+ }
+ ++p;
+ }
+ }
+
+ // Skip non-ASCII words when "spin->si_ascii" is true.
+ if (spin->si_ascii && has_non_ascii(line)) {
+ ++non_ascii;
+ continue;
+ }
+
+ // Normal word: store it.
+ if (store_word(spin, line, flags, regionmask, NULL, false) == FAIL) {
+ retval = FAIL;
+ break;
+ }
+ did_word = true;
+ }
+
+ xfree(pc);
+ fclose(fd);
+
+ if (spin->si_ascii && non_ascii > 0) {
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Ignored %d words with non-ASCII characters"), non_ascii);
+ spell_message(spin, IObuff);
+ }
+
+ return retval;
+}
+
+/// Get part of an sblock_T, "len" bytes long.
+/// This avoids calling free() for every little struct we use (and keeping
+/// track of them).
+/// The memory is cleared to all zeros.
+///
+/// @param len Length needed (<= SBLOCKSIZE).
+/// @param align Align for pointer.
+/// @return Pointer into block data.
+static void *getroom(spellinfo_T *spin, size_t len, bool align)
+ FUNC_ATTR_NONNULL_RET
+{
+ char_u *p;
+ sblock_T *bl = spin->si_blocks;
+
+ assert(len <= SBLOCKSIZE);
+
+ if (align && bl != NULL)
+ // Round size up for alignment. On some systems structures need to be
+ // aligned to the size of a pointer (e.g., SPARC).
+ bl->sb_used = (bl->sb_used + sizeof(char *) - 1)
+ & ~(sizeof(char *) - 1);
+
+ if (bl == NULL || bl->sb_used + len > SBLOCKSIZE) {
+ // Allocate a block of memory. It is not freed until much later.
+ bl = xcalloc(1, (sizeof(sblock_T) + SBLOCKSIZE));
+ bl->sb_next = spin->si_blocks;
+ spin->si_blocks = bl;
+ bl->sb_used = 0;
+ ++spin->si_blocks_cnt;
+ }
+
+ p = bl->sb_data + bl->sb_used;
+ bl->sb_used += (int)len;
+
+ return p;
+}
+
+// Make a copy of a string into memory allocated with getroom().
+// Returns NULL when out of memory.
+static char_u *getroom_save(spellinfo_T *spin, char_u *s)
+{
+ char_u *sc;
+
+ sc = (char_u *)getroom(spin, STRLEN(s) + 1, false);
+ if (sc != NULL)
+ STRCPY(sc, s);
+ return sc;
+}
+
+
+// Free the list of allocated sblock_T.
+static void free_blocks(sblock_T *bl)
+{
+ sblock_T *next;
+
+ while (bl != NULL) {
+ next = bl->sb_next;
+ xfree(bl);
+ bl = next;
+ }
+}
+
+// Allocate the root of a word tree.
+// Returns NULL when out of memory.
+static wordnode_T *wordtree_alloc(spellinfo_T *spin)
+{
+ return (wordnode_T *)getroom(spin, sizeof(wordnode_T), true);
+}
+
+// Store a word in the tree(s).
+// Always store it in the case-folded tree. For a keep-case word this is
+// useful when the word can also be used with all caps (no WF_FIXCAP flag) and
+// used to find suggestions.
+// For a keep-case word also store it in the keep-case tree.
+// When "pfxlist" is not NULL store the word for each postponed prefix ID and
+// compound flag.
+static int
+store_word (
+ spellinfo_T *spin,
+ char_u *word,
+ int flags, // extra flags, WF_BANNED
+ int region, // supported region(s)
+ char_u *pfxlist, // list of prefix IDs or NULL
+ bool need_affix // only store word with affix ID
+)
+{
+ int len = (int)STRLEN(word);
+ int ct = captype(word, word + len);
+ char_u foldword[MAXWLEN];
+ int res = OK;
+ char_u *p;
+
+ (void)spell_casefold(word, len, foldword, MAXWLEN);
+ for (p = pfxlist; res == OK; ++p) {
+ if (!need_affix || (p != NULL && *p != NUL))
+ res = tree_add_word(spin, foldword, spin->si_foldroot, ct | flags,
+ region, p == NULL ? 0 : *p);
+ if (p == NULL || *p == NUL)
+ break;
+ }
+ ++spin->si_foldwcount;
+
+ if (res == OK && (ct == WF_KEEPCAP || (flags & WF_KEEPCAP))) {
+ for (p = pfxlist; res == OK; ++p) {
+ if (!need_affix || (p != NULL && *p != NUL))
+ res = tree_add_word(spin, word, spin->si_keeproot, flags,
+ region, p == NULL ? 0 : *p);
+ if (p == NULL || *p == NUL)
+ break;
+ }
+ ++spin->si_keepwcount;
+ }
+ return res;
+}
+
+// Add word "word" to a word tree at "root".
+// When "flags" < 0 we are adding to the prefix tree where "flags" is used for
+// "rare" and "region" is the condition nr.
+// Returns FAIL when out of memory.
+static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int flags, int region, int affixID)
+{
+ wordnode_T *node = root;
+ wordnode_T *np;
+ wordnode_T *copyp, **copyprev;
+ wordnode_T **prev = NULL;
+ int i;
+
+ // Add each byte of the word to the tree, including the NUL at the end.
+ for (i = 0;; ++i) {
+ // When there is more than one reference to this node we need to make
+ // a copy, so that we can modify it. Copy the whole list of siblings
+ // (we don't optimize for a partly shared list of siblings).
+ if (node != NULL && node->wn_refs > 1) {
+ --node->wn_refs;
+ copyprev = prev;
+ for (copyp = node; copyp != NULL; copyp = copyp->wn_sibling) {
+ // Allocate a new node and copy the info.
+ np = get_wordnode(spin);
+ if (np == NULL)
+ return FAIL;
+ np->wn_child = copyp->wn_child;
+ if (np->wn_child != NULL)
+ ++np->wn_child->wn_refs; // child gets extra ref
+ np->wn_byte = copyp->wn_byte;
+ if (np->wn_byte == NUL) {
+ np->wn_flags = copyp->wn_flags;
+ np->wn_region = copyp->wn_region;
+ np->wn_affixID = copyp->wn_affixID;
+ }
+
+ // Link the new node in the list, there will be one ref.
+ np->wn_refs = 1;
+ if (copyprev != NULL)
+ *copyprev = np;
+ copyprev = &np->wn_sibling;
+
+ // Let "node" point to the head of the copied list.
+ if (copyp == node)
+ node = np;
+ }
+ }
+
+ // Look for the sibling that has the same character. They are sorted
+ // on byte value, thus stop searching when a sibling is found with a
+ // higher byte value. For zero bytes (end of word) the sorting is
+ // done on flags and then on affixID.
+ while (node != NULL
+ && (node->wn_byte < word[i]
+ || (node->wn_byte == NUL
+ && (flags < 0
+ ? node->wn_affixID < (unsigned)affixID
+ : (node->wn_flags < (unsigned)(flags & WN_MASK)
+ || (node->wn_flags == (flags & WN_MASK)
+ && (spin->si_sugtree
+ ? (node->wn_region & 0xffff) < region
+ : node->wn_affixID
+ < (unsigned)affixID))))))) {
+ prev = &node->wn_sibling;
+ node = *prev;
+ }
+ if (node == NULL
+ || node->wn_byte != word[i]
+ || (word[i] == NUL
+ && (flags < 0
+ || spin->si_sugtree
+ || node->wn_flags != (flags & WN_MASK)
+ || node->wn_affixID != affixID))) {
+ // Allocate a new node.
+ np = get_wordnode(spin);
+ if (np == NULL)
+ return FAIL;
+ np->wn_byte = word[i];
+
+ // If "node" is NULL this is a new child or the end of the sibling
+ // list: ref count is one. Otherwise use ref count of sibling and
+ // make ref count of sibling one (matters when inserting in front
+ // of the list of siblings).
+ if (node == NULL)
+ np->wn_refs = 1;
+ else {
+ np->wn_refs = node->wn_refs;
+ node->wn_refs = 1;
+ }
+ if (prev != NULL)
+ *prev = np;
+ np->wn_sibling = node;
+ node = np;
+ }
+
+ if (word[i] == NUL) {
+ node->wn_flags = flags;
+ node->wn_region |= region;
+ node->wn_affixID = affixID;
+ break;
+ }
+ prev = &node->wn_child;
+ node = *prev;
+ }
+#ifdef SPELL_PRINTTREE
+ smsg((char_u *)"Added \"%s\"", word);
+ spell_print_tree(root->wn_sibling);
+#endif
+
+ // count nr of words added since last message
+ ++spin->si_msg_count;
+
+ if (spin->si_compress_cnt > 1) {
+ if (--spin->si_compress_cnt == 1)
+ // Did enough words to lower the block count limit.
+ spin->si_blocks_cnt += compress_inc;
+ }
+
+ // When we have allocated lots of memory we need to compress the word tree
+ // to free up some room. But compression is slow, and we might actually
+ // need that room, thus only compress in the following situations:
+ // 1. When not compressed before (si_compress_cnt == 0): when using
+ // "compress_start" blocks.
+ // 2. When compressed before and used "compress_inc" blocks before
+ // adding "compress_added" words (si_compress_cnt > 1).
+ // 3. When compressed before, added "compress_added" words
+ // (si_compress_cnt == 1) and the number of free nodes drops below the
+ // maximum word length.
+#ifndef SPELL_COMPRESS_ALLWAYS
+ if (spin->si_compress_cnt == 1 // NOLINT(readability/braces)
+ ? spin->si_free_count < MAXWLEN
+ : spin->si_blocks_cnt >= compress_start)
+#endif
+ {
+ // Decrement the block counter. The effect is that we compress again
+ // when the freed up room has been used and another "compress_inc"
+ // blocks have been allocated. Unless "compress_added" words have
+ // been added, then the limit is put back again.
+ spin->si_blocks_cnt -= compress_inc;
+ spin->si_compress_cnt = compress_added;
+
+ if (spin->si_verbose) {
+ msg_start();
+ msg_puts(_(msg_compressing));
+ msg_clr_eos();
+ msg_didout = FALSE;
+ msg_col = 0;
+ ui_flush();
+ }
+
+ // Compress both trees. Either they both have many nodes, which makes
+ // compression useful, or one of them is small, which means
+ // compression goes fast. But when filling the soundfold word tree
+ // there is no keep-case tree.
+ wordtree_compress(spin, spin->si_foldroot);
+ if (affixID >= 0)
+ wordtree_compress(spin, spin->si_keeproot);
+ }
+
+ return OK;
+}
+
+// Get a wordnode_T, either from the list of previously freed nodes or
+// allocate a new one.
+// Returns NULL when out of memory.
+static wordnode_T *get_wordnode(spellinfo_T *spin)
+{
+ wordnode_T *n;
+
+ if (spin->si_first_free == NULL)
+ n = (wordnode_T *)getroom(spin, sizeof(wordnode_T), true);
+ else {
+ n = spin->si_first_free;
+ spin->si_first_free = n->wn_child;
+ memset(n, 0, sizeof(wordnode_T));
+ --spin->si_free_count;
+ }
+#ifdef SPELL_PRINTTREE
+ if (n != NULL)
+ n->wn_nr = ++spin->si_wordnode_nr;
+#endif
+ return n;
+}
+
+// Decrement the reference count on a node (which is the head of a list of
+// siblings). If the reference count becomes zero free the node and its
+// siblings.
+// Returns the number of nodes actually freed.
+static int deref_wordnode(spellinfo_T *spin, wordnode_T *node)
+{
+ wordnode_T *np;
+ int cnt = 0;
+
+ if (--node->wn_refs == 0) {
+ for (np = node; np != NULL; np = np->wn_sibling) {
+ if (np->wn_child != NULL)
+ cnt += deref_wordnode(spin, np->wn_child);
+ free_wordnode(spin, np);
+ ++cnt;
+ }
+ ++cnt; // length field
+ }
+ return cnt;
+}
+
+// Free a wordnode_T for re-use later.
+// Only the "wn_child" field becomes invalid.
+static void free_wordnode(spellinfo_T *spin, wordnode_T *n)
+{
+ n->wn_child = spin->si_first_free;
+ spin->si_first_free = n;
+ ++spin->si_free_count;
+}
+
+// Compress a tree: find tails that are identical and can be shared.
+static void wordtree_compress(spellinfo_T *spin, wordnode_T *root)
+{
+ hashtab_T ht;
+ int n;
+ int tot = 0;
+ int perc;
+
+ // Skip the root itself, it's not actually used. The first sibling is the
+ // start of the tree.
+ if (root->wn_sibling != NULL) {
+ hash_init(&ht);
+ n = node_compress(spin, root->wn_sibling, &ht, &tot);
+
+#ifndef SPELL_PRINTTREE
+ if (spin->si_verbose || p_verbose > 2)
+#endif
+ {
+ if (tot > 1000000)
+ perc = (tot - n) / (tot / 100);
+ else if (tot == 0)
+ perc = 0;
+ else
+ perc = (tot - n) * 100 / tot;
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Compressed %d of %d nodes; %d (%d%%) remaining"),
+ n, tot, tot - n, perc);
+ spell_message(spin, IObuff);
+ }
+#ifdef SPELL_PRINTTREE
+ spell_print_tree(root->wn_sibling);
+#endif
+ hash_clear(&ht);
+ }
+}
+
+// Compress a node, its siblings and its children, depth first.
+// Returns the number of compressed nodes.
+static int
+node_compress (
+ spellinfo_T *spin,
+ wordnode_T *node,
+ hashtab_T *ht,
+ int *tot // total count of nodes before compressing,
+ // incremented while going through the tree
+)
+{
+ wordnode_T *np;
+ wordnode_T *tp;
+ wordnode_T *child;
+ hash_T hash;
+ hashitem_T *hi;
+ int len = 0;
+ unsigned nr, n;
+ int compressed = 0;
+
+ // Go through the list of siblings. Compress each child and then try
+ // finding an identical child to replace it.
+ // Note that with "child" we mean not just the node that is pointed to,
+ // but the whole list of siblings of which the child node is the first.
+ for (np = node; np != NULL && !got_int; np = np->wn_sibling) {
+ ++len;
+ if ((child = np->wn_child) != NULL) {
+ // Compress the child first. This fills hashkey.
+ compressed += node_compress(spin, child, ht, tot);
+
+ // Try to find an identical child.
+ hash = hash_hash(child->wn_u1.hashkey);
+ hi = hash_lookup(ht, (const char *)child->wn_u1.hashkey,
+ STRLEN(child->wn_u1.hashkey), hash);
+ if (!HASHITEM_EMPTY(hi)) {
+ // There are children we encountered before with a hash value
+ // identical to the current child. Now check if there is one
+ // that is really identical.
+ for (tp = HI2WN(hi); tp != NULL; tp = tp->wn_u2.next)
+ if (node_equal(child, tp)) {
+ // Found one! Now use that child in place of the
+ // current one. This means the current child and all
+ // its siblings is unlinked from the tree.
+ ++tp->wn_refs;
+ compressed += deref_wordnode(spin, child);
+ np->wn_child = tp;
+ break;
+ }
+ if (tp == NULL) {
+ // No other child with this hash value equals the child of
+ // the node, add it to the linked list after the first
+ // item.
+ tp = HI2WN(hi);
+ child->wn_u2.next = tp->wn_u2.next;
+ tp->wn_u2.next = child;
+ }
+ } else
+ // No other child has this hash value, add it to the
+ // hashtable.
+ hash_add_item(ht, hi, child->wn_u1.hashkey, hash);
+ }
+ }
+ *tot += len + 1; // add one for the node that stores the length
+
+ // Make a hash key for the node and its siblings, so that we can quickly
+ // find a lookalike node. This must be done after compressing the sibling
+ // list, otherwise the hash key would become invalid by the compression.
+ node->wn_u1.hashkey[0] = len;
+ nr = 0;
+ for (np = node; np != NULL; np = np->wn_sibling) {
+ if (np->wn_byte == NUL)
+ // end node: use wn_flags, wn_region and wn_affixID
+ n = np->wn_flags + (np->wn_region << 8) + (np->wn_affixID << 16);
+ else
+ // byte node: use the byte value and the child pointer
+ n = (unsigned)(np->wn_byte + ((uintptr_t)np->wn_child << 8));
+ nr = nr * 101 + n;
+ }
+
+ // Avoid NUL bytes, it terminates the hash key.
+ n = nr & 0xff;
+ node->wn_u1.hashkey[1] = n == 0 ? 1 : n;
+ n = (nr >> 8) & 0xff;
+ node->wn_u1.hashkey[2] = n == 0 ? 1 : n;
+ n = (nr >> 16) & 0xff;
+ node->wn_u1.hashkey[3] = n == 0 ? 1 : n;
+ n = (nr >> 24) & 0xff;
+ node->wn_u1.hashkey[4] = n == 0 ? 1 : n;
+ node->wn_u1.hashkey[5] = NUL;
+
+ // Check for CTRL-C pressed now and then.
+ fast_breakcheck();
+
+ return compressed;
+}
+
+// Returns true when two nodes have identical siblings and children.
+static bool node_equal(wordnode_T *n1, wordnode_T *n2)
+{
+ wordnode_T *p1;
+ wordnode_T *p2;
+
+ for (p1 = n1, p2 = n2; p1 != NULL && p2 != NULL;
+ p1 = p1->wn_sibling, p2 = p2->wn_sibling)
+ if (p1->wn_byte != p2->wn_byte
+ || (p1->wn_byte == NUL
+ ? (p1->wn_flags != p2->wn_flags
+ || p1->wn_region != p2->wn_region
+ || p1->wn_affixID != p2->wn_affixID)
+ : (p1->wn_child != p2->wn_child)))
+ break;
+
+ return p1 == NULL && p2 == NULL;
+}
+
+
+// Function given to qsort() to sort the REP items on "from" string.
+static int rep_compare(const void *s1, const void *s2)
+{
+ fromto_T *p1 = (fromto_T *)s1;
+ fromto_T *p2 = (fromto_T *)s2;
+
+ return STRCMP(p1->ft_from, p2->ft_from);
+}
+
+// Write the Vim .spl file "fname".
+// Return OK/FAIL.
+static int write_vim_spell(spellinfo_T *spin, char_u *fname)
+{
+ int retval = OK;
+ int regionmask;
+
+ FILE *fd = mch_fopen((char *)fname, "w");
+ if (fd == NULL) {
+ EMSG2(_(e_notopen), fname);
+ return FAIL;
+ }
+
+ // <HEADER>: <fileID> <versionnr>
+ // <fileID>
+ size_t fwv = fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, 1, fd);
+ if (fwv != (size_t)1)
+ // Catch first write error, don't try writing more.
+ goto theend;
+
+ putc(VIMSPELLVERSION, fd); // <versionnr>
+
+ // <SECTIONS>: <section> ... <sectionend>
+
+ // SN_INFO: <infotext>
+ if (spin->si_info != NULL) {
+ putc(SN_INFO, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+ size_t i = STRLEN(spin->si_info);
+ put_bytes(fd, i, 4); // <sectionlen>
+ fwv &= fwrite(spin->si_info, i, 1, fd); // <infotext>
+ }
+
+ // SN_REGION: <regionname> ...
+ // Write the region names only if there is more than one.
+ if (spin->si_region_count > 1) {
+ putc(SN_REGION, fd); // <sectionID>
+ putc(SNF_REQUIRED, fd); // <sectionflags>
+ size_t l = (size_t)spin->si_region_count * 2;
+ put_bytes(fd, l, 4); // <sectionlen>
+ fwv &= fwrite(spin->si_region_name, l, 1, fd);
+ // <regionname> ...
+ regionmask = (1 << spin->si_region_count) - 1;
+ } else
+ regionmask = 0;
+
+ // SN_CHARFLAGS: <charflagslen> <charflags> <folcharslen> <folchars>
+ //
+ // The table with character flags and the table for case folding.
+ // This makes sure the same characters are recognized as word characters
+ // when generating an when using a spell file.
+ // Skip this for ASCII, the table may conflict with the one used for
+ // 'encoding'.
+ // Also skip this for an .add.spl file, the main spell file must contain
+ // the table (avoids that it conflicts). File is shorter too.
+ if (!spin->si_ascii && !spin->si_add) {
+ char_u folchars[128 * 8];
+ int flags;
+
+ putc(SN_CHARFLAGS, fd); // <sectionID>
+ putc(SNF_REQUIRED, fd); // <sectionflags>
+
+ // Form the <folchars> string first, we need to know its length.
+ size_t l = 0;
+ for (size_t i = 128; i < 256; ++i) {
+ if (has_mbyte)
+ l += (size_t)mb_char2bytes(spelltab.st_fold[i], folchars + l);
+ else
+ folchars[l++] = spelltab.st_fold[i];
+ }
+ put_bytes(fd, 1 + 128 + 2 + l, 4); // <sectionlen>
+
+ fputc(128, fd); // <charflagslen>
+ for (size_t i = 128; i < 256; ++i) {
+ flags = 0;
+ if (spelltab.st_isw[i])
+ flags |= CF_WORD;
+ if (spelltab.st_isu[i])
+ flags |= CF_UPPER;
+ fputc(flags, fd); // <charflags>
+ }
+
+ put_bytes(fd, l, 2); // <folcharslen>
+ fwv &= fwrite(folchars, l, 1, fd); // <folchars>
+ }
+
+ // SN_MIDWORD: <midword>
+ if (spin->si_midword != NULL) {
+ putc(SN_MIDWORD, fd); // <sectionID>
+ putc(SNF_REQUIRED, fd); // <sectionflags>
+
+ size_t i = STRLEN(spin->si_midword);
+ put_bytes(fd, i, 4); // <sectionlen>
+ fwv &= fwrite(spin->si_midword, i, 1, fd);
+ // <midword>
+ }
+
+ // SN_PREFCOND: <prefcondcnt> <prefcond> ...
+ if (!GA_EMPTY(&spin->si_prefcond)) {
+ putc(SN_PREFCOND, fd); // <sectionID>
+ putc(SNF_REQUIRED, fd); // <sectionflags>
+
+ size_t l = (size_t)write_spell_prefcond(NULL, &spin->si_prefcond);
+ put_bytes(fd, l, 4); // <sectionlen>
+
+ write_spell_prefcond(fd, &spin->si_prefcond);
+ }
+
+ // SN_REP: <repcount> <rep> ...
+ // SN_SAL: <salflags> <salcount> <sal> ...
+ // SN_REPSAL: <repcount> <rep> ...
+
+ // round 1: SN_REP section
+ // round 2: SN_SAL section (unless SN_SOFO is used)
+ // round 3: SN_REPSAL section
+ for (unsigned int round = 1; round <= 3; ++round) {
+ garray_T *gap;
+ if (round == 1)
+ gap = &spin->si_rep;
+ else if (round == 2) {
+ // Don't write SN_SAL when using a SN_SOFO section
+ if (spin->si_sofofr != NULL && spin->si_sofoto != NULL)
+ continue;
+ gap = &spin->si_sal;
+ } else
+ gap = &spin->si_repsal;
+
+ // Don't write the section if there are no items.
+ if (GA_EMPTY(gap))
+ continue;
+
+ // Sort the REP/REPSAL items.
+ if (round != 2)
+ qsort(gap->ga_data, (size_t)gap->ga_len,
+ sizeof(fromto_T), rep_compare);
+
+ int i = round == 1 ? SN_REP : (round == 2 ? SN_SAL : SN_REPSAL);
+ putc(i, fd); // <sectionID>
+
+ // This is for making suggestions, section is not required.
+ putc(0, fd); // <sectionflags>
+
+ // Compute the length of what follows.
+ size_t l = 2; // count <repcount> or <salcount>
+ assert(gap->ga_len >= 0);
+ for (size_t i = 0; i < (size_t)gap->ga_len; ++i) {
+ fromto_T *ftp = &((fromto_T *)gap->ga_data)[i];
+ l += 1 + STRLEN(ftp->ft_from); // count <*fromlen> and <*from>
+ l += 1 + STRLEN(ftp->ft_to); // count <*tolen> and <*to>
+ }
+ if (round == 2)
+ ++l; // count <salflags>
+ put_bytes(fd, l, 4); // <sectionlen>
+
+ if (round == 2) {
+ int i = 0;
+ if (spin->si_followup)
+ i |= SAL_F0LLOWUP;
+ if (spin->si_collapse)
+ i |= SAL_COLLAPSE;
+ if (spin->si_rem_accents)
+ i |= SAL_REM_ACCENTS;
+ putc(i, fd); // <salflags>
+ }
+
+ put_bytes(fd, (uintmax_t)gap->ga_len, 2); // <repcount> or <salcount>
+ for (size_t i = 0; i < (size_t)gap->ga_len; ++i) {
+ // <rep> : <repfromlen> <repfrom> <reptolen> <repto>
+ // <sal> : <salfromlen> <salfrom> <saltolen> <salto>
+ fromto_T *ftp = &((fromto_T *)gap->ga_data)[i];
+ for (unsigned int rr = 1; rr <= 2; ++rr) {
+ char_u *p = rr == 1 ? ftp->ft_from : ftp->ft_to;
+ l = STRLEN(p);
+ assert(l < INT_MAX);
+ putc((int)l, fd);
+ if (l > 0)
+ fwv &= fwrite(p, l, 1, fd);
+ }
+ }
+
+ }
+
+ // SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
+ // This is for making suggestions, section is not required.
+ if (spin->si_sofofr != NULL && spin->si_sofoto != NULL) {
+ putc(SN_SOFO, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+
+ size_t l = STRLEN(spin->si_sofofr);
+ put_bytes(fd, l + STRLEN(spin->si_sofoto) + 4, 4); // <sectionlen>
+
+ put_bytes(fd, l, 2); // <sofofromlen>
+ fwv &= fwrite(spin->si_sofofr, l, 1, fd); // <sofofrom>
+
+ l = STRLEN(spin->si_sofoto);
+ put_bytes(fd, l, 2); // <sofotolen>
+ fwv &= fwrite(spin->si_sofoto, l, 1, fd); // <sofoto>
+ }
+
+ // SN_WORDS: <word> ...
+ // This is for making suggestions, section is not required.
+ if (spin->si_commonwords.ht_used > 0) {
+ putc(SN_WORDS, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+
+ // round 1: count the bytes
+ // round 2: write the bytes
+ for (unsigned int round = 1; round <= 2; ++round) {
+ size_t todo;
+ size_t len = 0;
+ hashitem_T *hi;
+
+ todo = spin->si_commonwords.ht_used;
+ for (hi = spin->si_commonwords.ht_array; todo > 0; ++hi)
+ if (!HASHITEM_EMPTY(hi)) {
+ size_t l = STRLEN(hi->hi_key) + 1;
+ len += l;
+ if (round == 2) // <word>
+ fwv &= fwrite(hi->hi_key, l, 1, fd);
+ --todo;
+ }
+ if (round == 1)
+ put_bytes(fd, len, 4); // <sectionlen>
+ }
+ }
+
+ // SN_MAP: <mapstr>
+ // This is for making suggestions, section is not required.
+ if (!GA_EMPTY(&spin->si_map)) {
+ putc(SN_MAP, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+ size_t l = (size_t)spin->si_map.ga_len;
+ put_bytes(fd, l, 4); // <sectionlen>
+ fwv &= fwrite(spin->si_map.ga_data, l, 1, fd); // <mapstr>
+ }
+
+ // SN_SUGFILE: <timestamp>
+ // This is used to notify that a .sug file may be available and at the
+ // same time allows for checking that a .sug file that is found matches
+ // with this .spl file. That's because the word numbers must be exactly
+ // right.
+ if (!spin->si_nosugfile
+ && (!GA_EMPTY(&spin->si_sal)
+ || (spin->si_sofofr != NULL && spin->si_sofoto != NULL))) {
+ putc(SN_SUGFILE, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+ put_bytes(fd, 8, 4); // <sectionlen>
+
+ // Set si_sugtime and write it to the file.
+ spin->si_sugtime = time(NULL);
+ put_time(fd, spin->si_sugtime); // <timestamp>
+ }
+
+ // SN_NOSPLITSUGS: nothing
+ // This is used to notify that no suggestions with word splits are to be
+ // made.
+ if (spin->si_nosplitsugs) {
+ putc(SN_NOSPLITSUGS, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+ put_bytes(fd, 0, 4); // <sectionlen>
+ }
+
+ // SN_NOCOMPUNDSUGS: nothing
+ // This is used to notify that no suggestions with compounds are to be
+ // made.
+ if (spin->si_nocompoundsugs) {
+ putc(SN_NOCOMPOUNDSUGS, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+ put_bytes(fd, 0, 4); // <sectionlen>
+ }
+
+ // SN_COMPOUND: compound info.
+ // We don't mark it required, when not supported all compound words will
+ // be bad words.
+ if (spin->si_compflags != NULL) {
+ putc(SN_COMPOUND, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+
+ size_t l = STRLEN(spin->si_compflags);
+ assert(spin->si_comppat.ga_len >= 0);
+ for (size_t i = 0; i < (size_t)spin->si_comppat.ga_len; ++i) {
+ l += STRLEN(((char_u **)(spin->si_comppat.ga_data))[i]) + 1;
+ }
+ put_bytes(fd, l + 7, 4); // <sectionlen>
+
+ putc(spin->si_compmax, fd); // <compmax>
+ putc(spin->si_compminlen, fd); // <compminlen>
+ putc(spin->si_compsylmax, fd); // <compsylmax>
+ putc(0, fd); // for Vim 7.0b compatibility
+ putc(spin->si_compoptions, fd); // <compoptions>
+ put_bytes(fd, (uintmax_t)spin->si_comppat.ga_len, 2); // <comppatcount>
+ for (size_t i = 0; i < (size_t)spin->si_comppat.ga_len; ++i) {
+ char_u *p = ((char_u **)(spin->si_comppat.ga_data))[i];
+ assert(STRLEN(p) < INT_MAX);
+ putc((int)STRLEN(p), fd); // <comppatlen>
+ fwv &= fwrite(p, STRLEN(p), 1, fd); // <comppattext>
+ }
+ // <compflags>
+ fwv &= fwrite(spin->si_compflags, STRLEN(spin->si_compflags), 1, fd);
+ }
+
+ // SN_NOBREAK: NOBREAK flag
+ if (spin->si_nobreak) {
+ putc(SN_NOBREAK, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+
+ // It's empty, the presence of the section flags the feature.
+ put_bytes(fd, 0, 4); // <sectionlen>
+ }
+
+ // SN_SYLLABLE: syllable info.
+ // We don't mark it required, when not supported syllables will not be
+ // counted.
+ if (spin->si_syllable != NULL) {
+ putc(SN_SYLLABLE, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+
+ size_t l = STRLEN(spin->si_syllable);
+ put_bytes(fd, l, 4); // <sectionlen>
+ fwv &= fwrite(spin->si_syllable, l, 1, fd); // <syllable>
+ }
+
+ // end of <SECTIONS>
+ putc(SN_END, fd); // <sectionend>
+
+
+ // <LWORDTREE> <KWORDTREE> <PREFIXTREE>
+ spin->si_memtot = 0;
+ for (unsigned int round = 1; round <= 3; ++round) {
+ wordnode_T *tree;
+ if (round == 1)
+ tree = spin->si_foldroot->wn_sibling;
+ else if (round == 2)
+ tree = spin->si_keeproot->wn_sibling;
+ else
+ tree = spin->si_prefroot->wn_sibling;
+
+ // Clear the index and wnode fields in the tree.
+ clear_node(tree);
+
+ // Count the number of nodes. Needed to be able to allocate the
+ // memory when reading the nodes. Also fills in index for shared
+ // nodes.
+ size_t nodecount = (size_t)put_node(NULL, tree, 0, regionmask, round == 3);
+
+ // number of nodes in 4 bytes
+ put_bytes(fd, nodecount, 4); // <nodecount>
+ assert(nodecount + nodecount * sizeof(int) < INT_MAX);
+ spin->si_memtot += (int)(nodecount + nodecount * sizeof(int));
+
+ // Write the nodes.
+ (void)put_node(fd, tree, 0, regionmask, round == 3);
+ }
+
+ // Write another byte to check for errors (file system full).
+ if (putc(0, fd) == EOF)
+ retval = FAIL;
+theend:
+ if (fclose(fd) == EOF)
+ retval = FAIL;
+
+ if (fwv != (size_t)1)
+ retval = FAIL;
+ if (retval == FAIL)
+ EMSG(_(e_write));
+
+ return retval;
+}
+
+// Clear the index and wnode fields of "node", it siblings and its
+// children. This is needed because they are a union with other items to save
+// space.
+static void clear_node(wordnode_T *node)
+{
+ wordnode_T *np;
+
+ if (node != NULL)
+ for (np = node; np != NULL; np = np->wn_sibling) {
+ np->wn_u1.index = 0;
+ np->wn_u2.wnode = NULL;
+
+ if (np->wn_byte != NUL)
+ clear_node(np->wn_child);
+ }
+}
+
+
+// Dump a word tree at node "node".
+//
+// This first writes the list of possible bytes (siblings). Then for each
+// byte recursively write the children.
+//
+// NOTE: The code here must match the code in read_tree_node(), since
+// assumptions are made about the indexes (so that we don't have to write them
+// in the file).
+//
+// Returns the number of nodes used.
+static int
+put_node (
+ FILE *fd, // NULL when only counting
+ wordnode_T *node,
+ int idx,
+ int regionmask,
+ bool prefixtree // true for PREFIXTREE
+)
+{
+ // If "node" is zero the tree is empty.
+ if (node == NULL)
+ return 0;
+
+ // Store the index where this node is written.
+ node->wn_u1.index = idx;
+
+ // Count the number of siblings.
+ int siblingcount = 0;
+ for (wordnode_T *np = node; np != NULL; np = np->wn_sibling)
+ ++siblingcount;
+
+ // Write the sibling count.
+ if (fd != NULL)
+ putc(siblingcount, fd); // <siblingcount>
+
+ // Write each sibling byte and optionally extra info.
+ for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) {
+ if (np->wn_byte == 0) {
+ if (fd != NULL) {
+ // For a NUL byte (end of word) write the flags etc.
+ if (prefixtree) {
+ // In PREFIXTREE write the required affixID and the
+ // associated condition nr (stored in wn_region). The
+ // byte value is misused to store the "rare" and "not
+ // combining" flags
+ if (np->wn_flags == (uint16_t)PFX_FLAGS)
+ putc(BY_NOFLAGS, fd); // <byte>
+ else {
+ putc(BY_FLAGS, fd); // <byte>
+ putc(np->wn_flags, fd); // <pflags>
+ }
+ putc(np->wn_affixID, fd); // <affixID>
+ put_bytes(fd, (uintmax_t)np->wn_region, 2); // <prefcondnr>
+ } else {
+ // For word trees we write the flag/region items.
+ int flags = np->wn_flags;
+ if (regionmask != 0 && np->wn_region != regionmask)
+ flags |= WF_REGION;
+ if (np->wn_affixID != 0)
+ flags |= WF_AFX;
+ if (flags == 0) {
+ // word without flags or region
+ putc(BY_NOFLAGS, fd); // <byte>
+ } else {
+ if (np->wn_flags >= 0x100) {
+ putc(BY_FLAGS2, fd); // <byte>
+ putc(flags, fd); // <flags>
+ putc((int)((unsigned)flags >> 8), fd); // <flags2>
+ } else {
+ putc(BY_FLAGS, fd); // <byte>
+ putc(flags, fd); // <flags>
+ }
+ if (flags & WF_REGION)
+ putc(np->wn_region, fd); // <region>
+ if (flags & WF_AFX)
+ putc(np->wn_affixID, fd); // <affixID>
+ }
+ }
+ }
+ } else {
+ if (np->wn_child->wn_u1.index != 0
+ && np->wn_child->wn_u2.wnode != node) {
+ // The child is written elsewhere, write the reference.
+ if (fd != NULL) {
+ putc(BY_INDEX, fd); // <byte>
+ put_bytes(fd, (uintmax_t)np->wn_child->wn_u1.index, 3); // <nodeidx>
+ }
+ } else if (np->wn_child->wn_u2.wnode == NULL)
+ // We will write the child below and give it an index.
+ np->wn_child->wn_u2.wnode = node;
+
+ if (fd != NULL)
+ if (putc(np->wn_byte, fd) == EOF) { // <byte> or <xbyte>
+ EMSG(_(e_write));
+ return 0;
+ }
+ }
+ }
+
+ // Space used in the array when reading: one for each sibling and one for
+ // the count.
+ int newindex = idx + siblingcount + 1;
+
+ // Recursively dump the children of each sibling.
+ for (wordnode_T *np = node; np != NULL; np = np->wn_sibling)
+ if (np->wn_byte != 0 && np->wn_child->wn_u2.wnode == node)
+ newindex = put_node(fd, np->wn_child, newindex, regionmask,
+ prefixtree);
+
+ return newindex;
+}
+
+
+// ":mkspell [-ascii] outfile infile ..."
+// ":mkspell [-ascii] addfile"
+void ex_mkspell(exarg_T *eap)
+{
+ int fcount;
+ char_u **fnames;
+ char_u *arg = eap->arg;
+ bool ascii = false;
+
+ if (STRNCMP(arg, "-ascii", 6) == 0) {
+ ascii = true;
+ arg = skipwhite(arg + 6);
+ }
+
+ // Expand all the remaining arguments (e.g., $VIMRUNTIME).
+ if (get_arglist_exp(arg, &fcount, &fnames, false) == OK) {
+ mkspell(fcount, fnames, ascii, eap->forceit, false);
+ FreeWild(fcount, fnames);
+ }
+}
+
+// Create the .sug file.
+// Uses the soundfold info in "spin".
+// Writes the file with the name "wfname", with ".spl" changed to ".sug".
+static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname)
+{
+ char_u *fname = NULL;
+ int len;
+ slang_T *slang;
+ bool free_slang = false;
+
+ // Read back the .spl file that was written. This fills the required
+ // info for soundfolding. This also uses less memory than the
+ // pointer-linked version of the trie. And it avoids having two versions
+ // of the code for the soundfolding stuff.
+ // It might have been done already by spell_reload_one().
+ for (slang = first_lang; slang != NULL; slang = slang->sl_next)
+ if (path_full_compare(wfname, slang->sl_fname, FALSE) == kEqualFiles)
+ break;
+ if (slang == NULL) {
+ spell_message(spin, (char_u *)_("Reading back spell file..."));
+ slang = spell_load_file(wfname, NULL, NULL, false);
+ if (slang == NULL)
+ return;
+ free_slang = true;
+ }
+
+ // Clear the info in "spin" that is used.
+ spin->si_blocks = NULL;
+ spin->si_blocks_cnt = 0;
+ spin->si_compress_cnt = 0; // will stay at 0 all the time
+ spin->si_free_count = 0;
+ spin->si_first_free = NULL;
+ spin->si_foldwcount = 0;
+
+ // Go through the trie of good words, soundfold each word and add it to
+ // the soundfold trie.
+ spell_message(spin, (char_u *)_("Performing soundfolding..."));
+ if (sug_filltree(spin, slang) == FAIL)
+ goto theend;
+
+ // Create the table which links each soundfold word with a list of the
+ // good words it may come from. Creates buffer "spin->si_spellbuf".
+ // This also removes the wordnr from the NUL byte entries to make
+ // compression possible.
+ if (sug_maketable(spin) == FAIL)
+ goto theend;
+
+ smsg(_("Number of words after soundfolding: %" PRId64),
+ (int64_t)spin->si_spellbuf->b_ml.ml_line_count);
+
+ // Compress the soundfold trie.
+ spell_message(spin, (char_u *)_(msg_compressing));
+ wordtree_compress(spin, spin->si_foldroot);
+
+ // Write the .sug file.
+ // Make the file name by changing ".spl" to ".sug".
+ fname = xmalloc(MAXPATHL);
+ STRLCPY(fname, wfname, MAXPATHL);
+ len = (int)STRLEN(fname);
+ fname[len - 2] = 'u';
+ fname[len - 1] = 'g';
+ sug_write(spin, fname);
+
+theend:
+ xfree(fname);
+ if (free_slang)
+ slang_free(slang);
+ free_blocks(spin->si_blocks);
+ close_spellbuf(spin->si_spellbuf);
+}
+
+// Build the soundfold trie for language "slang".
+static int sug_filltree(spellinfo_T *spin, slang_T *slang)
+{
+ char_u *byts;
+ idx_T *idxs;
+ int depth;
+ idx_T arridx[MAXWLEN];
+ int curi[MAXWLEN];
+ char_u tword[MAXWLEN];
+ char_u tsalword[MAXWLEN];
+ int c;
+ idx_T n;
+ unsigned words_done = 0;
+ int wordcount[MAXWLEN];
+
+ // We use si_foldroot for the soundfolded trie.
+ spin->si_foldroot = wordtree_alloc(spin);
+ if (spin->si_foldroot == NULL)
+ return FAIL;
+
+ // Let tree_add_word() know we're adding to the soundfolded tree
+ spin->si_sugtree = true;
+
+ // Go through the whole case-folded tree, soundfold each word and put it
+ // in the trie.
+ byts = slang->sl_fbyts;
+ idxs = slang->sl_fidxs;
+
+ arridx[0] = 0;
+ curi[0] = 1;
+ wordcount[0] = 0;
+
+ depth = 0;
+ while (depth >= 0 && !got_int) {
+ if (curi[depth] > byts[arridx[depth]]) {
+ // Done all bytes at this node, go up one level.
+ idxs[arridx[depth]] = wordcount[depth];
+ if (depth > 0)
+ wordcount[depth - 1] += wordcount[depth];
+
+ --depth;
+ line_breakcheck();
+ } else {
+
+ // Do one more byte at this node.
+ n = arridx[depth] + curi[depth];
+ ++curi[depth];
+
+ c = byts[n];
+ if (c == 0) {
+ // Sound-fold the word.
+ tword[depth] = NUL;
+ spell_soundfold(slang, tword, true, tsalword);
+
+ // We use the "flags" field for the MSB of the wordnr,
+ // "region" for the LSB of the wordnr.
+ if (tree_add_word(spin, tsalword, spin->si_foldroot,
+ words_done >> 16, words_done & 0xffff,
+ 0) == FAIL)
+ return FAIL;
+
+ ++words_done;
+ ++wordcount[depth];
+
+ // Reset the block count each time to avoid compression
+ // kicking in.
+ spin->si_blocks_cnt = 0;
+
+ // Skip over any other NUL bytes (same word with different
+ // flags).
+ while (byts[n + 1] == 0) {
+ ++n;
+ ++curi[depth];
+ }
+ } else {
+ // Normal char, go one level deeper.
+ tword[depth++] = c;
+ arridx[depth] = idxs[n];
+ curi[depth] = 1;
+ wordcount[depth] = 0;
+ }
+ }
+ }
+
+ smsg(_("Total number of words: %d"), words_done);
+
+ return OK;
+}
+
+// Make the table that links each word in the soundfold trie to the words it
+// can be produced from.
+// This is not unlike lines in a file, thus use a memfile to be able to access
+// the table efficiently.
+// Returns FAIL when out of memory.
+static int sug_maketable(spellinfo_T *spin)
+{
+ garray_T ga;
+ int res = OK;
+
+ // Allocate a buffer, open a memline for it and create the swap file
+ // (uses a temp file, not a .swp file).
+ spin->si_spellbuf = open_spellbuf();
+
+ // Use a buffer to store the line info, avoids allocating many small
+ // pieces of memory.
+ ga_init(&ga, 1, 100);
+
+ // recursively go through the tree
+ if (sug_filltable(spin, spin->si_foldroot->wn_sibling, 0, &ga) == -1)
+ res = FAIL;
+
+ ga_clear(&ga);
+ return res;
+}
+
+// Fill the table for one node and its children.
+// Returns the wordnr at the start of the node.
+// Returns -1 when out of memory.
+static int
+sug_filltable (
+ spellinfo_T *spin,
+ wordnode_T *node,
+ int startwordnr,
+ garray_T *gap // place to store line of numbers
+)
+{
+ wordnode_T *p, *np;
+ int wordnr = startwordnr;
+ int nr;
+ int prev_nr;
+
+ for (p = node; p != NULL; p = p->wn_sibling) {
+ if (p->wn_byte == NUL) {
+ gap->ga_len = 0;
+ prev_nr = 0;
+ for (np = p; np != NULL && np->wn_byte == NUL; np = np->wn_sibling) {
+ ga_grow(gap, 10);
+
+ nr = (np->wn_flags << 16) + (np->wn_region & 0xffff);
+ // Compute the offset from the previous nr and store the
+ // offset in a way that it takes a minimum number of bytes.
+ // It's a bit like utf-8, but without the need to mark
+ // following bytes.
+ nr -= prev_nr;
+ prev_nr += nr;
+ gap->ga_len += offset2bytes(nr,
+ (char_u *)gap->ga_data + gap->ga_len);
+ }
+
+ // add the NUL byte
+ ((char_u *)gap->ga_data)[gap->ga_len++] = NUL;
+
+ if (ml_append_buf(spin->si_spellbuf, (linenr_T)wordnr,
+ gap->ga_data, gap->ga_len, TRUE) == FAIL)
+ return -1;
+ ++wordnr;
+
+ // Remove extra NUL entries, we no longer need them. We don't
+ // bother freeing the nodes, the won't be reused anyway.
+ while (p->wn_sibling != NULL && p->wn_sibling->wn_byte == NUL)
+ p->wn_sibling = p->wn_sibling->wn_sibling;
+
+ // Clear the flags on the remaining NUL node, so that compression
+ // works a lot better.
+ p->wn_flags = 0;
+ p->wn_region = 0;
+ } else {
+ wordnr = sug_filltable(spin, p->wn_child, wordnr, gap);
+ if (wordnr == -1)
+ return -1;
+ }
+ }
+ return wordnr;
+}
+
+// Convert an offset into a minimal number of bytes.
+// Similar to utf_char2byters, but use 8 bits in followup bytes and avoid NUL
+// bytes.
+static int offset2bytes(int nr, char_u *buf)
+{
+ int rem;
+ int b1, b2, b3, b4;
+
+ // Split the number in parts of base 255. We need to avoid NUL bytes.
+ b1 = nr % 255 + 1;
+ rem = nr / 255;
+ b2 = rem % 255 + 1;
+ rem = rem / 255;
+ b3 = rem % 255 + 1;
+ b4 = rem / 255 + 1;
+
+ if (b4 > 1 || b3 > 0x1f) { // 4 bytes
+ buf[0] = 0xe0 + b4;
+ buf[1] = b3;
+ buf[2] = b2;
+ buf[3] = b1;
+ return 4;
+ }
+ if (b3 > 1 || b2 > 0x3f ) { // 3 bytes
+ buf[0] = 0xc0 + b3;
+ buf[1] = b2;
+ buf[2] = b1;
+ return 3;
+ }
+ if (b2 > 1 || b1 > 0x7f ) { // 2 bytes
+ buf[0] = 0x80 + b2;
+ buf[1] = b1;
+ return 2;
+ }
+ // 1 byte
+ buf[0] = b1;
+ return 1;
+}
+
+// Write the .sug file in "fname".
+static void sug_write(spellinfo_T *spin, char_u *fname)
+{
+ // Create the file. Note that an existing file is silently overwritten!
+ FILE *fd = mch_fopen((char *)fname, "w");
+ if (fd == NULL) {
+ EMSG2(_(e_notopen), fname);
+ return;
+ }
+
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Writing suggestion file %s ..."), fname);
+ spell_message(spin, IObuff);
+
+ // <SUGHEADER>: <fileID> <versionnr> <timestamp>
+ if (fwrite(VIMSUGMAGIC, VIMSUGMAGICL, (size_t)1, fd) != 1) { // <fileID>
+ EMSG(_(e_write));
+ goto theend;
+ }
+ putc(VIMSUGVERSION, fd); // <versionnr>
+
+ // Write si_sugtime to the file.
+ put_time(fd, spin->si_sugtime); // <timestamp>
+
+ // <SUGWORDTREE>
+ spin->si_memtot = 0;
+ wordnode_T *tree = spin->si_foldroot->wn_sibling;
+
+ // Clear the index and wnode fields in the tree.
+ clear_node(tree);
+
+ // Count the number of nodes. Needed to be able to allocate the
+ // memory when reading the nodes. Also fills in index for shared
+ // nodes.
+ size_t nodecount = (size_t)put_node(NULL, tree, 0, 0, false);
+
+ // number of nodes in 4 bytes
+ put_bytes(fd, nodecount, 4); // <nodecount>
+ assert(nodecount + nodecount * sizeof(int) < INT_MAX);
+ spin->si_memtot += (int)(nodecount + nodecount * sizeof(int));
+
+ // Write the nodes.
+ (void)put_node(fd, tree, 0, 0, false);
+
+ // <SUGTABLE>: <sugwcount> <sugline> ...
+ linenr_T wcount = spin->si_spellbuf->b_ml.ml_line_count;
+ assert(wcount >= 0);
+ put_bytes(fd, (uintmax_t)wcount, 4); // <sugwcount>
+
+ for (linenr_T lnum = 1; lnum <= wcount; ++lnum) {
+ // <sugline>: <sugnr> ... NUL
+ char_u *line = ml_get_buf(spin->si_spellbuf, lnum, FALSE);
+ size_t len = STRLEN(line) + 1;
+ if (fwrite(line, len, 1, fd) == 0) {
+ EMSG(_(e_write));
+ goto theend;
+ }
+ assert((size_t)spin->si_memtot + len <= INT_MAX);
+ spin->si_memtot += (int)len;
+ }
+
+ // Write another byte to check for errors.
+ if (putc(0, fd) == EOF)
+ EMSG(_(e_write));
+
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Estimated runtime memory use: %d bytes"), spin->si_memtot);
+ spell_message(spin, IObuff);
+
+theend:
+ // close the file
+ fclose(fd);
+}
+
+
+// Create a Vim spell file from one or more word lists.
+// "fnames[0]" is the output file name.
+// "fnames[fcount - 1]" is the last input file name.
+// Exception: when "fnames[0]" ends in ".add" it's used as the input file name
+// and ".spl" is appended to make the output file name.
+static void
+mkspell (
+ int fcount,
+ char_u **fnames,
+ bool ascii, // -ascii argument given
+ bool over_write, // overwrite existing output file
+ bool added_word // invoked through "zg"
+)
+{
+ char_u *fname = NULL;
+ char_u *wfname;
+ char_u **innames;
+ int incount;
+ afffile_T *(afile[8]);
+ int i;
+ int len;
+ bool error = false;
+ spellinfo_T spin;
+
+ memset(&spin, 0, sizeof(spin));
+ spin.si_verbose = !added_word;
+ spin.si_ascii = ascii;
+ spin.si_followup = true;
+ spin.si_rem_accents = true;
+ ga_init(&spin.si_rep, (int)sizeof(fromto_T), 20);
+ ga_init(&spin.si_repsal, (int)sizeof(fromto_T), 20);
+ ga_init(&spin.si_sal, (int)sizeof(fromto_T), 20);
+ ga_init(&spin.si_map, (int)sizeof(char_u), 100);
+ ga_init(&spin.si_comppat, (int)sizeof(char_u *), 20);
+ ga_init(&spin.si_prefcond, (int)sizeof(char_u *), 50);
+ hash_init(&spin.si_commonwords);
+ spin.si_newcompID = 127; // start compound ID at first maximum
+
+ // default: fnames[0] is output file, following are input files
+ innames = &fnames[1];
+ incount = fcount - 1;
+
+ wfname = xmalloc(MAXPATHL);
+
+ if (fcount >= 1) {
+ len = (int)STRLEN(fnames[0]);
+ if (fcount == 1 && len > 4 && STRCMP(fnames[0] + len - 4, ".add") == 0) {
+ // For ":mkspell path/en.latin1.add" output file is
+ // "path/en.latin1.add.spl".
+ innames = &fnames[0];
+ incount = 1;
+ vim_snprintf((char *)wfname, MAXPATHL, "%s.spl", fnames[0]);
+ } else if (fcount == 1) {
+ // For ":mkspell path/vim" output file is "path/vim.latin1.spl".
+ innames = &fnames[0];
+ incount = 1;
+ vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL,
+ fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc());
+ } else if (len > 4 && STRCMP(fnames[0] + len - 4, ".spl") == 0) {
+ // Name ends in ".spl", use as the file name.
+ STRLCPY(wfname, fnames[0], MAXPATHL);
+ } else
+ // Name should be language, make the file name from it.
+ vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL,
+ fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc());
+
+ // Check for .ascii.spl.
+ if (strstr((char *)path_tail(wfname), SPL_FNAME_ASCII) != NULL)
+ spin.si_ascii = true;
+
+ // Check for .add.spl.
+ if (strstr((char *)path_tail(wfname), SPL_FNAME_ADD) != NULL)
+ spin.si_add = true;
+ }
+
+ if (incount <= 0)
+ EMSG(_(e_invarg)); // need at least output and input names
+ else if (vim_strchr(path_tail(wfname), '_') != NULL)
+ EMSG(_("E751: Output file name must not have region name"));
+ else if (incount > 8)
+ EMSG(_("E754: Only up to 8 regions supported"));
+ else {
+ // Check for overwriting before doing things that may take a lot of
+ // time.
+ if (!over_write && os_path_exists(wfname)) {
+ EMSG(_(e_exists));
+ goto theend;
+ }
+ if (os_isdir(wfname)) {
+ EMSG2(_(e_isadir2), wfname);
+ goto theend;
+ }
+
+ fname = xmalloc(MAXPATHL);
+
+ // Init the aff and dic pointers.
+ // Get the region names if there are more than 2 arguments.
+ for (i = 0; i < incount; ++i) {
+ afile[i] = NULL;
+
+ if (incount > 1) {
+ len = (int)STRLEN(innames[i]);
+ if (STRLEN(path_tail(innames[i])) < 5
+ || innames[i][len - 3] != '_') {
+ EMSG2(_("E755: Invalid region in %s"), innames[i]);
+ goto theend;
+ }
+ spin.si_region_name[i * 2] = TOLOWER_ASC(innames[i][len - 2]);
+ spin.si_region_name[i * 2 + 1] =
+ TOLOWER_ASC(innames[i][len - 1]);
+ }
+ }
+ spin.si_region_count = incount;
+
+ spin.si_foldroot = wordtree_alloc(&spin);
+ spin.si_keeproot = wordtree_alloc(&spin);
+ spin.si_prefroot = wordtree_alloc(&spin);
+ if (spin.si_foldroot == NULL
+ || spin.si_keeproot == NULL
+ || spin.si_prefroot == NULL) {
+ free_blocks(spin.si_blocks);
+ goto theend;
+ }
+
+ // When not producing a .add.spl file clear the character table when
+ // we encounter one in the .aff file. This means we dump the current
+ // one in the .spl file if the .aff file doesn't define one. That's
+ // better than guessing the contents, the table will match a
+ // previously loaded spell file.
+ if (!spin.si_add)
+ spin.si_clear_chartab = true;
+
+ // Read all the .aff and .dic files.
+ // Text is converted to 'encoding'.
+ // Words are stored in the case-folded and keep-case trees.
+ for (i = 0; i < incount && !error; ++i) {
+ spin.si_conv.vc_type = CONV_NONE;
+ spin.si_region = 1 << i;
+
+ vim_snprintf((char *)fname, MAXPATHL, "%s.aff", innames[i]);
+ if (os_path_exists(fname)) {
+ // Read the .aff file. Will init "spin->si_conv" based on the
+ // "SET" line.
+ afile[i] = spell_read_aff(&spin, fname);
+ if (afile[i] == NULL)
+ error = true;
+ else {
+ // Read the .dic file and store the words in the trees.
+ vim_snprintf((char *)fname, MAXPATHL, "%s.dic",
+ innames[i]);
+ if (spell_read_dic(&spin, fname, afile[i]) == FAIL)
+ error = true;
+ }
+ } else {
+ // No .aff file, try reading the file as a word list. Store
+ // the words in the trees.
+ if (spell_read_wordfile(&spin, innames[i]) == FAIL)
+ error = true;
+ }
+
+ // Free any conversion stuff.
+ convert_setup(&spin.si_conv, NULL, NULL);
+ }
+
+ if (spin.si_compflags != NULL && spin.si_nobreak)
+ MSG(_("Warning: both compounding and NOBREAK specified"));
+
+ if (!error && !got_int) {
+ // Combine tails in the tree.
+ spell_message(&spin, (char_u *)_(msg_compressing));
+ wordtree_compress(&spin, spin.si_foldroot);
+ wordtree_compress(&spin, spin.si_keeproot);
+ wordtree_compress(&spin, spin.si_prefroot);
+ }
+
+ if (!error && !got_int) {
+ // Write the info in the spell file.
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Writing spell file %s ..."), wfname);
+ spell_message(&spin, IObuff);
+
+ error = write_vim_spell(&spin, wfname) == FAIL;
+
+ spell_message(&spin, (char_u *)_("Done!"));
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Estimated runtime memory use: %d bytes"), spin.si_memtot);
+ spell_message(&spin, IObuff);
+
+ // If the file is loaded need to reload it.
+ if (!error)
+ spell_reload_one(wfname, added_word);
+ }
+
+ // Free the allocated memory.
+ ga_clear(&spin.si_rep);
+ ga_clear(&spin.si_repsal);
+ ga_clear(&spin.si_sal);
+ ga_clear(&spin.si_map);
+ ga_clear(&spin.si_comppat);
+ ga_clear(&spin.si_prefcond);
+ hash_clear_all(&spin.si_commonwords, 0);
+
+ // Free the .aff file structures.
+ for (i = 0; i < incount; ++i)
+ if (afile[i] != NULL)
+ spell_free_aff(afile[i]);
+
+ // Free all the bits and pieces at once.
+ free_blocks(spin.si_blocks);
+
+ // If there is soundfolding info and no NOSUGFILE item create the
+ // .sug file with the soundfolded word trie.
+ if (spin.si_sugtime != 0 && !error && !got_int)
+ spell_make_sugfile(&spin, wfname);
+
+ }
+
+theend:
+ xfree(fname);
+ xfree(wfname);
+}
+
+// Display a message for spell file processing when 'verbose' is set or using
+// ":mkspell". "str" can be IObuff.
+static void spell_message(spellinfo_T *spin, char_u *str)
+{
+ if (spin->si_verbose || p_verbose > 2) {
+ if (!spin->si_verbose)
+ verbose_enter();
+ MSG(str);
+ ui_flush();
+ if (!spin->si_verbose)
+ verbose_leave();
+ }
+}
+
+// ":[count]spellgood {word}"
+// ":[count]spellwrong {word}"
+// ":[count]spellundo {word}"
+void ex_spell(exarg_T *eap)
+{
+ spell_add_word(eap->arg, (int)STRLEN(eap->arg), eap->cmdidx == CMD_spellwrong,
+ eap->forceit ? 0 : (int)eap->line2,
+ eap->cmdidx == CMD_spellundo);
+}
+
+// Add "word[len]" to 'spellfile' as a good or bad word.
+void
+spell_add_word (
+ char_u *word,
+ int len,
+ int bad,
+ int idx, // "zG" and "zW": zero, otherwise index in
+ // 'spellfile'
+ bool undo // true for "zug", "zuG", "zuw" and "zuW"
+)
+{
+ FILE *fd = NULL;
+ buf_T *buf = NULL;
+ bool new_spf = false;
+ char_u *fname;
+ char_u *fnamebuf = NULL;
+ char_u line[MAXWLEN * 2];
+ long fpos, fpos_next = 0;
+ int i;
+ char_u *spf;
+
+ if (idx == 0) { // use internal wordlist
+ if (int_wordlist == NULL) {
+ int_wordlist = vim_tempname();
+ if (int_wordlist == NULL)
+ return;
+ }
+ fname = int_wordlist;
+ } else {
+ // If 'spellfile' isn't set figure out a good default value.
+ if (*curwin->w_s->b_p_spf == NUL) {
+ init_spellfile();
+ new_spf = true;
+ }
+
+ if (*curwin->w_s->b_p_spf == NUL) {
+ EMSG2(_(e_notset), "spellfile");
+ return;
+ }
+ fnamebuf = xmalloc(MAXPATHL);
+
+ for (spf = curwin->w_s->b_p_spf, i = 1; *spf != NUL; ++i) {
+ copy_option_part(&spf, fnamebuf, MAXPATHL, ",");
+ if (i == idx)
+ break;
+ if (*spf == NUL) {
+ EMSGN(_("E765: 'spellfile' does not have %" PRId64 " entries"), idx);
+ xfree(fnamebuf);
+ return;
+ }
+ }
+
+ // Check that the user isn't editing the .add file somewhere.
+ buf = buflist_findname_exp(fnamebuf);
+ if (buf != NULL && buf->b_ml.ml_mfp == NULL)
+ buf = NULL;
+ if (buf != NULL && bufIsChanged(buf)) {
+ EMSG(_(e_bufloaded));
+ xfree(fnamebuf);
+ return;
+ }
+
+ fname = fnamebuf;
+ }
+
+ if (bad || undo) {
+ // When the word appears as good word we need to remove that one,
+ // since its flags sort before the one with WF_BANNED.
+ fd = mch_fopen((char *)fname, "r");
+ if (fd != NULL) {
+ while (!vim_fgets(line, MAXWLEN * 2, fd)) {
+ fpos = fpos_next;
+ fpos_next = ftell(fd);
+ if (STRNCMP(word, line, len) == 0
+ && (line[len] == '/' || line[len] < ' ')) {
+ // Found duplicate word. Remove it by writing a '#' at
+ // the start of the line. Mixing reading and writing
+ // doesn't work for all systems, close the file first.
+ fclose(fd);
+ fd = mch_fopen((char *)fname, "r+");
+ if (fd == NULL)
+ break;
+ if (fseek(fd, fpos, SEEK_SET) == 0) {
+ fputc('#', fd);
+ if (undo) {
+ home_replace(NULL, fname, NameBuff, MAXPATHL, TRUE);
+ smsg(_("Word '%.*s' removed from %s"),
+ len, word, NameBuff);
+ }
+ }
+ fseek(fd, fpos_next, SEEK_SET);
+ }
+ }
+ if (fd != NULL)
+ fclose(fd);
+ }
+ }
+
+ if (!undo) {
+ fd = mch_fopen((char *)fname, "a");
+ if (fd == NULL && new_spf) {
+ char_u *p;
+
+ // We just initialized the 'spellfile' option and can't open the
+ // file. We may need to create the "spell" directory first. We
+ // already checked the runtime directory is writable in
+ // init_spellfile().
+ if (!dir_of_file_exists(fname) && (p = path_tail_with_sep(fname)) != fname) {
+ int c = *p;
+
+ // The directory doesn't exist. Try creating it and opening
+ // the file again.
+ *p = NUL;
+ os_mkdir((char *)fname, 0755);
+ *p = c;
+ fd = mch_fopen((char *)fname, "a");
+ }
+ }
+
+ if (fd == NULL)
+ EMSG2(_(e_notopen), fname);
+ else {
+ if (bad)
+ fprintf(fd, "%.*s/!\n", len, word);
+ else
+ fprintf(fd, "%.*s\n", len, word);
+ fclose(fd);
+
+ home_replace(NULL, fname, NameBuff, MAXPATHL, TRUE);
+ smsg(_("Word '%.*s' added to %s"), len, word, NameBuff);
+ }
+ }
+
+ if (fd != NULL) {
+ // Update the .add.spl file.
+ mkspell(1, &fname, false, true, true);
+
+ // If the .add file is edited somewhere, reload it.
+ if (buf != NULL)
+ buf_reload(buf, buf->b_orig_mode);
+
+ redraw_all_later(SOME_VALID);
+ }
+ xfree(fnamebuf);
+}
+
+// Initialize 'spellfile' for the current buffer.
+static void init_spellfile(void)
+{
+ char_u *buf;
+ int l;
+ char_u *fname;
+ char_u *rtp;
+ char_u *lend;
+ bool aspath = false;
+ char_u *lstart = curbuf->b_s.b_p_spl;
+
+ if (*curwin->w_s->b_p_spl != NUL && !GA_EMPTY(&curwin->w_s->b_langp)) {
+ buf = xmalloc(MAXPATHL);
+
+ // Find the end of the language name. Exclude the region. If there
+ // is a path separator remember the start of the tail.
+ for (lend = curwin->w_s->b_p_spl; *lend != NUL
+ && vim_strchr((char_u *)",._", *lend) == NULL; ++lend)
+ if (vim_ispathsep(*lend)) {
+ aspath = true;
+ lstart = lend + 1;
+ }
+
+ // Loop over all entries in 'runtimepath'. Use the first one where we
+ // are allowed to write.
+ rtp = p_rtp;
+ while (*rtp != NUL) {
+ if (aspath)
+ // Use directory of an entry with path, e.g., for
+ // "/dir/lg.utf-8.spl" use "/dir".
+ STRLCPY(buf, curbuf->b_s.b_p_spl,
+ lstart - curbuf->b_s.b_p_spl);
+ else
+ // Copy the path from 'runtimepath' to buf[].
+ copy_option_part(&rtp, buf, MAXPATHL, ",");
+ if (os_file_is_writable((char *)buf) == 2) {
+ // Use the first language name from 'spelllang' and the
+ // encoding used in the first loaded .spl file.
+ if (aspath)
+ STRLCPY(buf, curbuf->b_s.b_p_spl,
+ lend - curbuf->b_s.b_p_spl + 1);
+ else {
+ // Create the "spell" directory if it doesn't exist yet.
+ l = (int)STRLEN(buf);
+ vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell");
+ if (os_file_is_writable((char *)buf) != 2) {
+ os_mkdir((char *)buf, 0755);
+ }
+
+ l = (int)STRLEN(buf);
+ vim_snprintf((char *)buf + l, MAXPATHL - l,
+ "/%.*s", (int)(lend - lstart), lstart);
+ }
+ l = (int)STRLEN(buf);
+ fname = LANGP_ENTRY(curwin->w_s->b_langp, 0)
+ ->lp_slang->sl_fname;
+ vim_snprintf((char *)buf + l, MAXPATHL - l, ".%s.add",
+ ((fname != NULL
+ && strstr((char *)path_tail(fname), ".ascii.") != NULL)
+ ? "ascii"
+ : (const char *)spell_enc()));
+ set_option_value("spellfile", 0L, (const char *)buf, OPT_LOCAL);
+ break;
+ }
+ aspath = false;
+ }
+
+ xfree(buf);
+ }
+}
+
+// Set the spell character tables from strings in the affix file.
+static int set_spell_chartab(char_u *fol, char_u *low, char_u *upp)
+{
+ // We build the new tables here first, so that we can compare with the
+ // previous one.
+ spelltab_T new_st;
+ char_u *pf = fol, *pl = low, *pu = upp;
+ int f, l, u;
+
+ clear_spell_chartab(&new_st);
+
+ while (*pf != NUL) {
+ if (*pl == NUL || *pu == NUL) {
+ EMSG(_(e_affform));
+ return FAIL;
+ }
+ f = mb_ptr2char_adv((const char_u **)&pf);
+ l = mb_ptr2char_adv((const char_u **)&pl);
+ u = mb_ptr2char_adv((const char_u **)&pu);
+ // Every character that appears is a word character.
+ if (f < 256)
+ new_st.st_isw[f] = true;
+ if (l < 256)
+ new_st.st_isw[l] = true;
+ if (u < 256)
+ new_st.st_isw[u] = true;
+
+ // if "LOW" and "FOL" are not the same the "LOW" char needs
+ // case-folding
+ if (l < 256 && l != f) {
+ if (f >= 256) {
+ EMSG(_(e_affrange));
+ return FAIL;
+ }
+ new_st.st_fold[l] = f;
+ }
+
+ // if "UPP" and "FOL" are not the same the "UPP" char needs
+ // case-folding, it's upper case and the "UPP" is the upper case of
+ // "FOL" .
+ if (u < 256 && u != f) {
+ if (f >= 256) {
+ EMSG(_(e_affrange));
+ return FAIL;
+ }
+ new_st.st_fold[u] = f;
+ new_st.st_isu[u] = true;
+ new_st.st_upper[f] = u;
+ }
+ }
+
+ if (*pl != NUL || *pu != NUL) {
+ EMSG(_(e_affform));
+ return FAIL;
+ }
+
+ return set_spell_finish(&new_st);
+}
+
+// Set the spell character tables from strings in the .spl file.
+static void
+set_spell_charflags (
+ char_u *flags,
+ int cnt, // length of "flags"
+ char_u *fol
+)
+{
+ // We build the new tables here first, so that we can compare with the
+ // previous one.
+ spelltab_T new_st;
+ int i;
+ char_u *p = fol;
+ int c;
+
+ clear_spell_chartab(&new_st);
+
+ for (i = 0; i < 128; ++i) {
+ if (i < cnt) {
+ new_st.st_isw[i + 128] = (flags[i] & CF_WORD) != 0;
+ new_st.st_isu[i + 128] = (flags[i] & CF_UPPER) != 0;
+ }
+
+ if (*p != NUL) {
+ c = mb_ptr2char_adv((const char_u **)&p);
+ new_st.st_fold[i + 128] = c;
+ if (i + 128 != c && new_st.st_isu[i + 128] && c < 256)
+ new_st.st_upper[c] = i + 128;
+ }
+ }
+
+ (void)set_spell_finish(&new_st);
+}
+
+static int set_spell_finish(spelltab_T *new_st)
+{
+ int i;
+
+ if (did_set_spelltab) {
+ // check that it's the same table
+ for (i = 0; i < 256; ++i) {
+ if (spelltab.st_isw[i] != new_st->st_isw[i]
+ || spelltab.st_isu[i] != new_st->st_isu[i]
+ || spelltab.st_fold[i] != new_st->st_fold[i]
+ || spelltab.st_upper[i] != new_st->st_upper[i]) {
+ EMSG(_("E763: Word characters differ between spell files"));
+ return FAIL;
+ }
+ }
+ } else {
+ // copy the new spelltab into the one being used
+ spelltab = *new_st;
+ did_set_spelltab = true;
+ }
+
+ return OK;
+}
+
+// Write the table with prefix conditions to the .spl file.
+// When "fd" is NULL only count the length of what is written.
+static int write_spell_prefcond(FILE *fd, garray_T *gap)
+{
+ assert(gap->ga_len >= 0);
+
+ if (fd != NULL)
+ put_bytes(fd, (uintmax_t)gap->ga_len, 2); // <prefcondcnt>
+
+ size_t totlen = 2 + (size_t)gap->ga_len; // <prefcondcnt> and <condlen> bytes
+ size_t x = 1; // collect return value of fwrite()
+ for (int i = 0; i < gap->ga_len; ++i) {
+ // <prefcond> : <condlen> <condstr>
+ char_u *p = ((char_u **)gap->ga_data)[i];
+ if (p != NULL) {
+ size_t len = STRLEN(p);
+ if (fd != NULL) {
+ assert(len <= INT_MAX);
+ fputc((int)len, fd);
+ x &= fwrite(p, len, 1, fd);
+ }
+ totlen += len;
+ } else if (fd != NULL)
+ fputc(0, fd);
+ }
+
+ assert(totlen <= INT_MAX);
+ return (int)totlen;
+}
+
+// Use map string "map" for languages "lp".
+static void set_map_str(slang_T *lp, char_u *map)
+{
+ char_u *p;
+ int headc = 0;
+ int c;
+ int i;
+
+ if (*map == NUL) {
+ lp->sl_has_map = false;
+ return;
+ }
+ lp->sl_has_map = true;
+
+ // Init the array and hash tables empty.
+ for (i = 0; i < 256; ++i)
+ lp->sl_map_array[i] = 0;
+ hash_init(&lp->sl_map_hash);
+
+ // The similar characters are stored separated with slashes:
+ // "aaa/bbb/ccc/". Fill sl_map_array[c] with the character before c and
+ // before the same slash. For characters above 255 sl_map_hash is used.
+ for (p = map; *p != NUL; ) {
+ c = mb_cptr2char_adv((const char_u **)&p);
+ if (c == '/') {
+ headc = 0;
+ } else {
+ if (headc == 0) {
+ headc = c;
+ }
+
+ // Characters above 255 don't fit in sl_map_array[], put them in
+ // the hash table. Each entry is the char, a NUL the headchar and
+ // a NUL.
+ if (c >= 256) {
+ int cl = mb_char2len(c);
+ int headcl = mb_char2len(headc);
+ char_u *b;
+ hash_T hash;
+ hashitem_T *hi;
+
+ b = xmalloc(cl + headcl + 2);
+ 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, (const char *)b, STRLEN(b), hash);
+ if (HASHITEM_EMPTY(hi)) {
+ hash_add_item(&lp->sl_map_hash, hi, b, hash);
+ } else {
+ // This should have been checked when generating the .spl
+ // file.
+ EMSG(_("E783: duplicate char in MAP entry"));
+ xfree(b);
+ }
+ } else
+ lp->sl_map_array[c] = headc;
+ }
+ }
+}
+
diff --git a/src/nvim/spellfile.h b/src/nvim/spellfile.h
new file mode 100644
index 0000000000..633ee014a7
--- /dev/null
+++ b/src/nvim/spellfile.h
@@ -0,0 +1,13 @@
+#ifndef NVIM_SPELLFILE_H
+#define NVIM_SPELLFILE_H
+
+#include <stdbool.h>
+
+#include "nvim/spell_defs.h"
+#include "nvim/types.h"
+#include "nvim/ex_cmds_defs.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "spellfile.h.generated.h"
+#endif
+#endif // NVIM_SPELLFILE_H
diff --git a/src/nvim/state.c b/src/nvim/state.c
index 44c6441e40..eb0b590a9b 100644
--- a/src/nvim/state.c
+++ b/src/nvim/state.c
@@ -1,8 +1,12 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include "nvim/lib/kvec.h"
#include "nvim/ascii.h"
+#include "nvim/log.h"
#include "nvim/state.h"
#include "nvim/vim.h"
#include "nvim/main.h"
@@ -95,3 +99,52 @@ int get_real_state(void)
return State;
}
+/// @returns[allocated] mode string
+char *get_mode(void)
+{
+ char *buf = xcalloc(3, sizeof(char));
+
+ if (VIsual_active) {
+ if (VIsual_select) {
+ buf[0] = (char)(VIsual_mode + 's' - 'v');
+ } else {
+ buf[0] = (char)VIsual_mode;
+ }
+ } else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE
+ || State == CONFIRM) {
+ buf[0] = 'r';
+ if (State == ASKMORE) {
+ buf[1] = 'm';
+ } else if (State == CONFIRM) {
+ buf[1] = '?';
+ }
+ } else if (State == EXTERNCMD) {
+ buf[0] = '!';
+ } else if (State & INSERT) {
+ if (State & VREPLACE_FLAG) {
+ buf[0] = 'R';
+ buf[1] = 'v';
+ } else if (State & REPLACE_FLAG) {
+ buf[0] = 'R';
+ } else {
+ buf[0] = 'i';
+ }
+ } else if (State & CMDLINE) {
+ buf[0] = 'c';
+ if (exmode_active) {
+ buf[1] = 'v';
+ }
+ } else if (exmode_active) {
+ buf[0] = 'c';
+ buf[1] = 'e';
+ } else if (State & TERM_FOCUS) {
+ buf[0] = 't';
+ } else {
+ buf[0] = 'n';
+ if (finish_op) {
+ buf[1] = 'o';
+ }
+ }
+
+ return buf;
+}
diff --git a/src/nvim/strings.c b/src/nvim/strings.c
index c1800a0639..687f734742 100644
--- a/src/nvim/strings.c
+++ b/src/nvim/strings.c
@@ -1,7 +1,14 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <inttypes.h>
+#include <stdarg.h>
#include <stdbool.h>
#include <string.h>
+#include <math.h>
+#include <assert.h>
+#include "nvim/assert.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/strings.h"
@@ -41,6 +48,7 @@
#include "nvim/window.h"
#include "nvim/os/os.h"
#include "nvim/os/shell.h"
+#include "nvim/eval/encode.h"
/*
* Copy "string" into newly allocated memory.
@@ -51,15 +59,14 @@ char_u *vim_strsave(const char_u *string)
return (char_u *)xstrdup((char *)string);
}
-/*
- * Copy up to "len" bytes of "string" into newly allocated memory and
- * terminate with a NUL.
- * The allocated memory always has size "len + 1", also when "string" is
- * shorter.
- */
+/// Copy up to `len` bytes of `string` into newly allocated memory and
+/// terminate with a NUL. The allocated memory always has size `len + 1`, even
+/// when `string` is shorter.
char_u *vim_strnsave(const char_u *string, size_t len)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
+ // strncpy is intentional: some parts of Vim use `string` shorter than `len`
+ // and expect the remainder to be zeroed out.
return (char_u *)strncpy(xmallocz(len), (char *)string, len);
}
@@ -194,8 +201,16 @@ char_u *vim_strsave_shellescape(const char_u *string,
/* First count the number of extra bytes required. */
size_t length = STRLEN(string) + 3; // two quotes and a trailing NUL
for (const char_u *p = string; *p != NUL; mb_ptr_adv(p)) {
- if (*p == '\'')
- length += 3; /* ' => '\'' */
+#ifdef WIN32
+ if (!p_ssl) {
+ if (*p == '"') {
+ length++; // " -> ""
+ }
+ } else
+#endif
+ if (*p == '\'') {
+ length += 3; // ' => '\''
+ }
if ((*p == '\n' && (csh_like || do_newline))
|| (*p == '!' && (csh_like || do_special))) {
++length; /* insert backslash */
@@ -212,10 +227,25 @@ char_u *vim_strsave_shellescape(const char_u *string,
escaped_string = xmalloc(length);
d = escaped_string;
- /* add opening quote */
+ // add opening quote
+#ifdef WIN32
+ if (!p_ssl) {
+ *d++ = '"';
+ } else
+#endif
*d++ = '\'';
for (const char_u *p = string; *p != NUL; ) {
+#ifdef WIN32
+ if (!p_ssl) {
+ if (*p == '"') {
+ *d++ = '"';
+ *d++ = '"';
+ p++;
+ continue;
+ }
+ } else
+#endif
if (*p == '\'') {
*d++ = '\'';
*d++ = '\\';
@@ -242,7 +272,12 @@ char_u *vim_strsave_shellescape(const char_u *string,
MB_COPY_CHAR(p, d);
}
- /* add terminating quote and finish with a NUL */
+ // add terminating quote and finish with a NUL
+# ifdef WIN32
+ if (!p_ssl) {
+ *d++ = '"';
+ } else
+# endif
*d++ = '\'';
*d = NUL;
@@ -287,45 +322,42 @@ void vim_strup(char_u *p)
}
}
-/*
- * Make string "s" all upper-case and return it in allocated memory.
- * Handles multi-byte characters as well as possible.
- */
-char_u *strup_save(const char_u *orig)
+/// Make given string all upper-case or all lower-case
+///
+/// Handles multi-byte characters as good as possible.
+///
+/// @param[in] orig Input string.
+/// @param[in] upper If true make uppercase, otherwise lowercase
+///
+/// @return [allocated] upper-cased string.
+char *strcase_save(const char *const orig, bool upper)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
- char_u *res = vim_strsave(orig);
+ char *res = xstrdup(orig);
- char_u *p = res;
+ char *p = res;
while (*p != NUL) {
int l;
- if (enc_utf8) {
- int c = utf_ptr2char(p);
- int uc = utf_toupper(c);
-
- /* Reallocate string when byte count changes. This is rare,
- * thus it's OK to do another malloc()/free(). */
- l = utf_ptr2len(p);
- int newl = utf_char2len(uc);
- if (newl != l) {
- // TODO(philix): use xrealloc() in strup_save()
- char_u *s = xmalloc(STRLEN(res) + (size_t)(1 + newl - l));
- memcpy(s, res, (size_t)(p - res));
- STRCPY(s + (p - res) + newl, p + l);
- p = s + (p - res);
- xfree(res);
- res = s;
- }
+ int c = utf_ptr2char((const char_u *)p);
+ int uc = upper ? mb_toupper(c) : mb_tolower(c);
- utf_char2bytes(uc, p);
- p += newl;
- } else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
- p += l; /* skip multi-byte character */
- else {
- *p = (char_u) TOUPPER_LOC(*p); // note that toupper() can be a macro
- p++;
+ // Reallocate string when byte count changes. This is rare,
+ // thus it's OK to do another malloc()/free().
+ l = utf_ptr2len((const char_u *)p);
+ int newl = utf_char2len(uc);
+ if (newl != l) {
+ // TODO(philix): use xrealloc() in strup_save()
+ char *s = xmalloc(STRLEN(res) + (size_t)(1 + newl - l));
+ memcpy(s, res, (size_t)(p - res));
+ STRCPY(s + (p - res) + newl, p + l);
+ p = s + (p - res);
+ xfree(res);
+ res = s;
}
+
+ utf_char2bytes(uc, (char_u *)p);
+ p += newl;
}
return res;
@@ -344,24 +376,6 @@ void del_trailing_spaces(char_u *ptr)
*q = NUL;
}
-/*
- * Like strcat(), but make sure the result fits in "tosize" bytes and is
- * always NUL terminated.
- */
-void vim_strcat(char_u *restrict to, const char_u *restrict from,
- size_t tosize)
- FUNC_ATTR_NONNULL_ALL
-{
- size_t tolen = STRLEN(to);
- size_t fromlen = STRLEN(from);
-
- if (tolen + fromlen + 1 > tosize) {
- memcpy(to + tolen, from, tosize - tolen - 1);
- to[tosize - 1] = NUL;
- } else
- STRCPY(to + tolen, from);
-}
-
#if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP))
/*
* Compare two strings, ignoring case, using current locale.
@@ -411,72 +425,27 @@ int vim_strnicmp(const char *s1, const char *s2, size_t len)
}
#endif
-/*
- * Version of strchr() and strrchr() that handle unsigned char strings
- * with characters from 128 to 255 correctly. It also doesn't return a
- * pointer to the NUL at the end of the string.
- */
-char_u *vim_strchr(const char_u *string, int c)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
+/// strchr() version which handles multibyte strings
+///
+/// @param[in] string String to search in.
+/// @param[in] c Character to search for.
+///
+/// @return Pointer to the first byte of the found character in string or NULL
+/// if it was not found or character is invalid. NUL character is never
+/// found, use `strlen()` instead.
+char_u *vim_strchr(const char_u *const string, const int c)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- int b;
-
- const char_u *p = string;
- if (enc_utf8 && c >= 0x80) {
- while (*p != NUL) {
- int l = (*mb_ptr2len)(p);
-
- // Avoid matching an illegal byte here.
- if (l > 1 && utf_ptr2char(p) == c) {
- return (char_u *) p;
- }
- p += l;
- }
+ if (c <= 0) {
return NULL;
+ } else if (c < 0x80) {
+ return (char_u *)strchr((const char *)string, c);
+ } else {
+ char u8char[MB_MAXBYTES + 1];
+ const int len = utf_char2bytes(c, (char_u *)u8char);
+ u8char[len] = NUL;
+ return (char_u *)strstr((const char *)string, u8char);
}
- if (enc_dbcs != 0 && c > 255) {
- int n2 = c & 0xff;
-
- c = ((unsigned)c >> 8) & 0xff;
- while ((b = *p) != NUL) {
- if (b == c && p[1] == n2)
- return (char_u *) p;
- p += (*mb_ptr2len)(p);
- }
- return NULL;
- }
- if (has_mbyte) {
- while ((b = *p) != NUL) {
- if (b == c)
- return (char_u *) p;
- p += (*mb_ptr2len)(p);
- }
- return NULL;
- }
- while ((b = *p) != NUL) {
- if (b == c)
- return (char_u *) p;
- ++p;
- }
- return NULL;
-}
-
-/*
- * Version of strchr() that only works for bytes and handles unsigned char
- * strings with characters above 128 correctly. It also doesn't return a
- * pointer to the NUL at the end of the string.
- */
-char_u *vim_strbyte(const char_u *string, int c)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
-{
- const char_u *p = string;
-
- while (*p != NUL) {
- if (*p == c)
- return (char_u *) p;
- ++p;
- }
- return NULL;
}
/*
@@ -560,3 +529,905 @@ char_u *concat_str(const char_u *restrict str1, const char_u *restrict str2)
return dest;
}
+
+static const char *const e_printf =
+ N_("E766: Insufficient arguments for printf()");
+
+/// Get number argument from idxp entry in tvs
+///
+/// Will give an error message for VimL entry with invalid type or for
+/// insufficient entries.
+///
+/// @param[in] tvs List of VimL values. List is terminated by VAR_UNKNOWN
+/// value.
+/// @param[in,out] idxp Index in a list. Will be incremented. Indexing starts
+/// at 1.
+///
+/// @return Number value or 0 in case of error.
+static varnumber_T tv_nr(typval_T *tvs, int *idxp)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ int idx = *idxp - 1;
+ varnumber_T n = 0;
+
+ if (tvs[idx].v_type == VAR_UNKNOWN) {
+ EMSG(_(e_printf));
+ } else {
+ (*idxp)++;
+ bool err = false;
+ n = tv_get_number_chk(&tvs[idx], &err);
+ if (err) {
+ n = 0;
+ }
+ }
+ return n;
+}
+
+/// Get string argument from idxp entry in tvs
+///
+/// Will give an error message for VimL entry with invalid type or for
+/// insufficient entries.
+///
+/// @param[in] tvs List of VimL values. List is terminated by VAR_UNKNOWN
+/// value.
+/// @param[in,out] idxp Index in a list. Will be incremented.
+/// @param[out] tofree If the idxp entry in tvs is not a String or a Number,
+/// it will be converted to String in the same format
+/// as ":echo" and stored in "*tofree". The caller must
+/// free "*tofree".
+///
+/// @return String value or NULL in case of error.
+static const char *tv_str(typval_T *tvs, int *idxp, char **const tofree)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ int idx = *idxp - 1;
+ const char *s = NULL;
+
+ if (tvs[idx].v_type == VAR_UNKNOWN) {
+ EMSG(_(e_printf));
+ } else {
+ (*idxp)++;
+ if (tvs[idx].v_type == VAR_STRING || tvs[idx].v_type == VAR_NUMBER) {
+ s = tv_get_string_chk(&tvs[idx]);
+ *tofree = NULL;
+ } else {
+ s = *tofree = encode_tv2echo(&tvs[idx], NULL);
+ }
+ }
+ return s;
+}
+
+/// Get pointer argument from the next entry in tvs
+///
+/// Will give an error message for VimL entry with invalid type or for
+/// insufficient entries.
+///
+/// @param[in] tvs List of typval_T values.
+/// @param[in,out] idxp Pointer to the index of the current value.
+///
+/// @return Pointer stored in typval_T or NULL.
+static const void *tv_ptr(const typval_T *const tvs, int *const idxp)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+#define OFF(attr) offsetof(union typval_vval_union, attr)
+ STATIC_ASSERT(
+ OFF(v_string) == OFF(v_list)
+ && OFF(v_string) == OFF(v_dict)
+ && OFF(v_string) == OFF(v_partial)
+ && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_list)
+ && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_dict)
+ && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_partial),
+ "Strings, dictionaries, lists and partials are expected to be pointers, "
+ "so that all three of them can be accessed via v_string");
+#undef OFF
+ const int idx = *idxp - 1;
+ if (tvs[idx].v_type == VAR_UNKNOWN) {
+ EMSG(_(e_printf));
+ return NULL;
+ } else {
+ (*idxp)++;
+ return tvs[idx].vval.v_string;
+ }
+}
+
+/// Get float argument from idxp entry in tvs
+///
+/// Will give an error message for VimL entry with invalid type or for
+/// insufficient entries.
+///
+/// @param[in] tvs List of VimL values. List is terminated by VAR_UNKNOWN
+/// value.
+/// @param[in,out] idxp Index in a list. Will be incremented.
+///
+/// @return Floating-point value or zero in case of error.
+static float_T tv_float(typval_T *const tvs, int *const idxp)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ int idx = *idxp - 1;
+ float_T f = 0;
+
+ if (tvs[idx].v_type == VAR_UNKNOWN) {
+ EMSG(_(e_printf));
+ } else {
+ (*idxp)++;
+ if (tvs[idx].v_type == VAR_FLOAT) {
+ f = tvs[idx].vval.v_float;
+ } else if (tvs[idx].v_type == VAR_NUMBER) {
+ f = (float_T)tvs[idx].vval.v_number;
+ } else {
+ EMSG(_("E807: Expected Float argument for printf()"));
+ }
+ }
+ return f;
+}
+
+// This code was included to provide a portable vsnprintf() and snprintf().
+// Some systems may provide their own, but we always use this one for
+// consistency.
+//
+// This code is based on snprintf.c - a portable implementation of snprintf
+// by Mark Martinec <mark.martinec@ijs.si>, Version 2.2, 2000-10-06.
+// Included with permission. It was heavily modified to fit in Vim.
+// The original code, including useful comments, can be found here:
+//
+// http://www.ijs.si/software/snprintf/
+//
+// This snprintf() only supports the following conversion specifiers:
+// s, c, b, B, d, u, o, x, X, p (and synonyms: i, D, U, O - see below)
+// with flags: '-', '+', ' ', '0' and '#'.
+// An asterisk is supported for field width as well as precision.
+//
+// Limited support for floating point was added: 'f', 'e', 'E', 'g', 'G'.
+//
+// Length modifiers 'h' (short int), 'l' (long int) and "ll" (long long int) are
+// supported.
+//
+// The locale is not used, the string is used as a byte string. This is only
+// relevant for double-byte encodings where the second byte may be '%'.
+//
+// It is permitted for "str_m" to be zero, and it is permitted to specify NULL
+// pointer for resulting string argument if "str_m" is zero (as per ISO C99).
+//
+// The return value is the number of characters which would be generated
+// for the given input, excluding the trailing NUL. If this value
+// is greater or equal to "str_m", not all characters from the result
+// have been stored in str, output bytes beyond the ("str_m"-1) -th character
+// are discarded. If "str_m" is greater than zero it is guaranteed
+// the resulting string will be NUL-terminated.
+
+// vim_vsnprintf() can be invoked with either "va_list" or a list of
+// "typval_T". When the latter is not used it must be NULL.
+
+/// Append a formatted value to the string
+///
+/// @see vim_vsnprintf().
+int vim_snprintf_add(char *str, size_t str_m, char *fmt, ...)
+{
+ const size_t len = strlen(str);
+ size_t space;
+
+ if (str_m <= len) {
+ space = 0;
+ } else {
+ space = str_m - len;
+ }
+ va_list ap;
+ va_start(ap, fmt);
+ const int str_l = vim_vsnprintf(str + len, space, fmt, ap, NULL);
+ va_end(ap);
+ return str_l;
+}
+
+/// Write formatted value to the string
+///
+/// @param[out] str String to write to.
+/// @param[in] str_m String length.
+/// @param[in] fmt String format.
+///
+/// @return Number of bytes excluding NUL byte that would be written to the
+/// string if str_m was greater or equal to the return value.
+int vim_snprintf(char *str, size_t str_m, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ const int str_l = vim_vsnprintf(str, str_m, fmt, ap, NULL);
+ va_end(ap);
+ return str_l;
+}
+
+// Return the representation of infinity for printf() function:
+// "-inf", "inf", "+inf", " inf", "-INF", "INF", "+INF" or " INF".
+static const char *infinity_str(bool positive, char fmt_spec,
+ int force_sign, int space_for_positive)
+{
+ static const char *table[] = {
+ "-inf", "inf", "+inf", " inf",
+ "-INF", "INF", "+INF", " INF"
+ };
+ int idx = positive * (1 + force_sign + force_sign * space_for_positive);
+ if (ASCII_ISUPPER(fmt_spec)) {
+ idx += 4;
+ }
+ return table[idx];
+}
+
+
+/// Write formatted value to the string
+///
+/// @param[out] str String to write to.
+/// @param[in] str_m String length.
+/// @param[in] fmt String format.
+/// @param[in] ap Values that should be formatted. Ignored if tvs is not NULL.
+/// @param[in] tvs Values that should be formatted, for printf() VimL
+/// function. Must be NULL in other cases.
+///
+/// @return Number of bytes excluding NUL byte that would be written to the
+/// string if str_m was greater or equal to the return value.
+int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap,
+ typval_T *const tvs)
+{
+ size_t str_l = 0;
+ bool str_avail = str_l < str_m;
+ const char *p = fmt;
+ int arg_idx = 1;
+
+ if (!p) {
+ p = "";
+ }
+ while (*p) {
+ if (*p != '%') {
+ // copy up to the next '%' or NUL without any changes
+ size_t n = (size_t)(xstrchrnul(p + 1, '%') - p);
+ if (str_avail) {
+ size_t avail = str_m - str_l;
+ memmove(str + str_l, p, MIN(n, avail));
+ str_avail = n < avail;
+ }
+ p += n;
+ assert(n <= SIZE_MAX - str_l);
+ str_l += n;
+ } else {
+ size_t min_field_width = 0, precision = 0;
+ int zero_padding = 0, precision_specified = 0, justify_left = 0;
+ int alternate_form = 0, force_sign = 0;
+
+ // if both ' ' and '+' flags appear, ' ' flag should be ignored
+ int space_for_positive = 1;
+
+ // allowed values: \0, h, l, 2 (for ll), z, L
+ char length_modifier = '\0';
+
+ // temporary buffer for simple numeric->string conversion
+# define TMP_LEN 350 // 1e308 seems reasonable as the maximum printable
+ char tmp[TMP_LEN];
+
+ // string address in case of string argument
+ const char *str_arg = NULL;
+
+ // natural field width of arg without padding and sign
+ size_t str_arg_l;
+
+ // unsigned char argument value (only defined for c conversion);
+ // standard explicitly states the char argument for the c
+ // conversion is unsigned
+ unsigned char uchar_arg;
+
+ // number of zeros to be inserted for numeric conversions as
+ // required by the precision or minimal field width
+ size_t number_of_zeros_to_pad = 0;
+
+ // index into tmp where zero padding is to be inserted
+ size_t zero_padding_insertion_ind = 0;
+
+ // current conversion specifier character
+ char fmt_spec = '\0';
+
+ // buffer for 's' and 'S' specs
+ char *tofree = NULL;
+
+ p++; // skip '%'
+
+ // parse flags
+ while (true) {
+ switch (*p) {
+ case '0': zero_padding = 1; p++; continue;
+ case '-': justify_left = 1; p++; continue;
+ // if both '0' and '-' flags appear, '0' should be ignored
+ case '+': force_sign = 1; space_for_positive = 0; p++; continue;
+ case ' ': force_sign = 1; p++; continue;
+ // if both ' ' and '+' flags appear, ' ' should be ignored
+ case '#': alternate_form = 1; p++; continue;
+ case '\'': p++; continue;
+ default: break;
+ }
+ break;
+ }
+
+ // parse field width
+ if (*p == '*') {
+ p++;
+ const int j = tvs ? (int)tv_nr(tvs, &arg_idx) : va_arg(ap, int);
+ if (j >= 0) {
+ min_field_width = (size_t)j;
+ } else {
+ min_field_width = (size_t)-j;
+ justify_left = 1;
+ }
+ } else if (ascii_isdigit((int)(*p))) {
+ // size_t could be wider than unsigned int; make sure we treat
+ // argument like common implementations do
+ unsigned int uj = (unsigned)(*p++ - '0');
+
+ while (ascii_isdigit((int)(*p))) {
+ uj = 10 * uj + (unsigned int)(*p++ - '0');
+ }
+ min_field_width = uj;
+ }
+
+ // parse precision
+ if (*p == '.') {
+ p++;
+ precision_specified = 1;
+ if (*p == '*') {
+ const int j = tvs ? (int)tv_nr(tvs, &arg_idx) : va_arg(ap, int);
+ p++;
+ if (j >= 0) {
+ precision = (size_t)j;
+ } else {
+ precision_specified = 0;
+ precision = 0;
+ }
+ } else if (ascii_isdigit((int)(*p))) {
+ // size_t could be wider than unsigned int; make sure we
+ // treat argument like common implementations do
+ unsigned int uj = (unsigned)(*p++ - '0');
+
+ while (ascii_isdigit((int)(*p))) {
+ uj = 10 * uj + (unsigned int)(*p++ - '0');
+ }
+ precision = uj;
+ }
+ }
+
+ // parse 'h', 'l', 'll' and 'z' length modifiers
+ if (*p == 'h' || *p == 'l' || *p == 'z') {
+ length_modifier = *p;
+ p++;
+ if (length_modifier == 'l' && *p == 'l') { // ll, encoded as 2
+ length_modifier = '2';
+ p++;
+ }
+ }
+
+ fmt_spec = *p;
+
+ // common synonyms
+ switch (fmt_spec) {
+ case 'i': fmt_spec = 'd'; break;
+ case 'D': fmt_spec = 'd'; length_modifier = 'l'; break;
+ case 'U': fmt_spec = 'u'; length_modifier = 'l'; break;
+ case 'O': fmt_spec = 'o'; length_modifier = 'l'; break;
+ default: break;
+ }
+
+ switch (fmt_spec) {
+ case 'd': case 'u': case 'o': case 'x': case 'X':
+ if (tvs && length_modifier == '\0') {
+ length_modifier = '2';
+ }
+ }
+
+ // get parameter value, do initial processing
+ switch (fmt_spec) {
+ // '%' and 'c' behave similar to 's' regarding flags and field widths
+ case '%': case 'c': case 's': case 'S':
+ str_arg_l = 1;
+ switch (fmt_spec) {
+ case '%':
+ str_arg = p;
+ break;
+
+ case 'c': {
+ const int j = tvs ? (int)tv_nr(tvs, &arg_idx) : va_arg(ap, int);
+ // standard demands unsigned char
+ uchar_arg = (unsigned char)j;
+ str_arg = (char *)&uchar_arg;
+ break;
+ }
+
+ case 's':
+ case 'S':
+ str_arg = tvs ? tv_str(tvs, &arg_idx, &tofree)
+ : va_arg(ap, const char *);
+ if (!str_arg) {
+ str_arg = "[NULL]";
+ str_arg_l = 6;
+ } else if (!precision_specified) {
+ // make sure not to address string beyond the specified
+ // precision
+ str_arg_l = strlen(str_arg);
+ } else if (precision == 0) {
+ // truncate string if necessary as requested by precision
+ str_arg_l = 0;
+ } else {
+ // memchr on HP does not like n > 2^31
+ // TODO(elmart): check if this still holds / is relevant
+ str_arg_l = (size_t)((char *)xmemscan(str_arg,
+ NUL,
+ MIN(precision,
+ 0x7fffffff))
+ - str_arg);
+ }
+ if (fmt_spec == 'S') {
+ if (min_field_width != 0) {
+ min_field_width += (strlen(str_arg)
+ - mb_string2cells((char_u *)str_arg));
+ }
+ if (precision) {
+ const char *p1 = str_arg;
+ for (size_t i = 0; i < precision && *p1; i++) {
+ p1 += mb_ptr2len((const char_u *)p1);
+ }
+ str_arg_l = precision = (size_t)(p1 - str_arg);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case 'd':
+ case 'u':
+ case 'b': case 'B':
+ case 'o':
+ case 'x': case 'X':
+ case 'p': {
+ // u, b, B, o, x, X and p conversion specifiers imply
+ // the value is unsigned; d implies a signed value
+
+ // 0 if numeric argument is zero (or if pointer is NULL for 'p'),
+ // +1 if greater than zero (or non NULL for 'p'),
+ // -1 if negative (unsigned argument is never negative)
+ int arg_sign = 0;
+
+ intmax_t arg = 0;
+ uintmax_t uarg = 0;
+
+ // only defined for p conversion
+ const void *ptr_arg = NULL;
+
+ if (fmt_spec == 'p') {
+ ptr_arg = tvs ? tv_ptr(tvs, &arg_idx) : va_arg(ap, void *);
+ if (ptr_arg) {
+ arg_sign = 1;
+ }
+ } else if (fmt_spec == 'd') {
+ // signed
+ switch (length_modifier) {
+ case '\0':
+ case 'h': {
+ // char and short arguments are passed as int
+ arg = (tvs ? (int)tv_nr(tvs, &arg_idx) : va_arg(ap, int));
+ break;
+ }
+ case 'l': {
+ arg = (tvs ? (long)tv_nr(tvs, &arg_idx) : va_arg(ap, long));
+ break;
+ }
+ case '2': {
+ arg = (
+ tvs
+ ? (long long)tv_nr(tvs, &arg_idx) // NOLINT (runtime/int)
+ : va_arg(ap, long long)); // NOLINT (runtime/int)
+ break;
+ }
+ case 'z': {
+ arg = (tvs
+ ? (ptrdiff_t)tv_nr(tvs, &arg_idx)
+ : va_arg(ap, ptrdiff_t));
+ break;
+ }
+ }
+ if (arg > 0) {
+ arg_sign = 1;
+ } else if (arg < 0) {
+ arg_sign = -1;
+ }
+ } else {
+ // unsigned
+ switch (length_modifier) {
+ case '\0':
+ case 'h': {
+ uarg = (tvs
+ ? (unsigned)tv_nr(tvs, &arg_idx)
+ : va_arg(ap, unsigned));
+ break;
+ }
+ case 'l': {
+ uarg = (tvs
+ ? (unsigned long)tv_nr(tvs, &arg_idx)
+ : va_arg(ap, unsigned long));
+ break;
+ }
+ case '2': {
+ uarg = (uintmax_t)(unsigned long long)( // NOLINT (runtime/int)
+ tvs
+ ? ((unsigned long long) // NOLINT (runtime/int)
+ tv_nr(tvs, &arg_idx))
+ : va_arg(ap, unsigned long long)); // NOLINT (runtime/int)
+ break;
+ }
+ case 'z': {
+ uarg = (tvs
+ ? (size_t)tv_nr(tvs, &arg_idx)
+ : va_arg(ap, size_t));
+ break;
+ }
+ }
+ arg_sign = (uarg != 0);
+ }
+
+ str_arg = tmp;
+ str_arg_l = 0;
+
+ // For d, i, u, o, x, and X conversions, if precision is specified,
+ // '0' flag should be ignored. This is so with Solaris 2.6, Digital
+ // UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl.
+ if (precision_specified) {
+ zero_padding = 0;
+ }
+
+ if (fmt_spec == 'd') {
+ if (force_sign && arg_sign >= 0) {
+ tmp[str_arg_l++] = space_for_positive ? ' ' : '+';
+ }
+ // leave negative numbers for snprintf to handle, to
+ // avoid handling tricky cases like (short int)-32768
+ } else if (alternate_form) {
+ if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X'
+ || fmt_spec == 'b' || fmt_spec == 'B')) {
+ tmp[str_arg_l++] = '0';
+ tmp[str_arg_l++] = fmt_spec;
+ }
+ // alternate form should have no effect for p * conversion, but ...
+ }
+
+ zero_padding_insertion_ind = str_arg_l;
+ if (!precision_specified) {
+ precision = 1; // default precision is 1
+ }
+ if (precision == 0 && arg_sign == 0) {
+ // when zero value is formatted with an explicit precision 0,
+ // resulting formatted string is empty (d, i, u, b, B, o, x, X, p)
+ } else {
+ switch (fmt_spec) {
+ case 'p': { // pointer
+ str_arg_l += (size_t)snprintf(tmp + str_arg_l,
+ sizeof(tmp) - str_arg_l,
+ "%p", ptr_arg);
+ break;
+ }
+ case 'd': { // signed
+ str_arg_l += (size_t)snprintf(tmp + str_arg_l,
+ sizeof(tmp) - str_arg_l,
+ "%" PRIdMAX, arg);
+ break;
+ }
+ case 'b': case 'B': { // binary
+ size_t bits = 0;
+ for (bits = sizeof(uintmax_t) * 8; bits > 0; bits--) {
+ if ((uarg >> (bits - 1)) & 0x1) {
+ break;
+ }
+ }
+
+ while (bits > 0) {
+ tmp[str_arg_l++] = ((uarg >> --bits) & 0x1) ? '1' : '0';
+ }
+ break;
+ }
+ default: { // unsigned
+ // construct a simple format string for snprintf
+ char f[] = "%" PRIuMAX;
+ f[sizeof("%" PRIuMAX) - 1 - 1] = fmt_spec;
+ assert(PRIuMAX[sizeof(PRIuMAX) - 1 - 1] == 'u');
+ str_arg_l += (size_t)snprintf(tmp + str_arg_l,
+ sizeof(tmp) - str_arg_l,
+ f, uarg);
+ break;
+ }
+ assert(str_arg_l < sizeof(tmp));
+ }
+
+ // include the optional minus sign and possible "0x" in the region
+ // before the zero padding insertion point
+ if (zero_padding_insertion_ind < str_arg_l
+ && tmp[zero_padding_insertion_ind] == '-') {
+ zero_padding_insertion_ind++;
+ }
+ if (zero_padding_insertion_ind + 1 < str_arg_l
+ && tmp[zero_padding_insertion_ind] == '0'
+ && (tmp[zero_padding_insertion_ind + 1] == 'x'
+ || tmp[zero_padding_insertion_ind + 1] == 'X'
+ || tmp[zero_padding_insertion_ind + 1] == 'b'
+ || tmp[zero_padding_insertion_ind + 1] == 'B')) {
+ zero_padding_insertion_ind += 2;
+ }
+ }
+
+ {
+ size_t num_of_digits = str_arg_l - zero_padding_insertion_ind;
+
+ if (alternate_form && fmt_spec == 'o'
+ // unless zero is already the first character
+ && !(zero_padding_insertion_ind < str_arg_l
+ && tmp[zero_padding_insertion_ind] == '0')) {
+ // assure leading zero for alternate-form octal numbers
+ if (!precision_specified
+ || precision < num_of_digits + 1) {
+ // precision is increased to force the first character to be
+ // zero, except if a zero value is formatted with an explicit
+ // precision of zero
+ precision = num_of_digits + 1;
+ }
+ }
+ // zero padding to specified precision?
+ if (num_of_digits < precision) {
+ number_of_zeros_to_pad = precision - num_of_digits;
+ }
+ }
+ // zero padding to specified minimal field width?
+ if (!justify_left && zero_padding) {
+ const int n = (int)(min_field_width - (str_arg_l
+ + number_of_zeros_to_pad));
+ if (n > 0) {
+ number_of_zeros_to_pad += (size_t)n;
+ }
+ }
+ break;
+ }
+
+ case 'f':
+ case 'F':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ {
+ // floating point
+ char format[40];
+ int remove_trailing_zeroes = false;
+
+ double f = tvs ? tv_float(tvs, &arg_idx) : va_arg(ap, double);
+ double abs_f = f < 0 ? -f : f;
+
+ if (fmt_spec == 'g' || fmt_spec == 'G') {
+ // can't use %g directly, cause it prints "1.0" as "1"
+ if ((abs_f >= 0.001 && abs_f < 10000000.0) || abs_f == 0.0) {
+ fmt_spec = ASCII_ISUPPER(fmt_spec) ? 'F' : 'f';
+ } else {
+ fmt_spec = fmt_spec == 'g' ? 'e' : 'E';
+ }
+ remove_trailing_zeroes = true;
+ }
+
+ if (isinf(f)
+ || (strchr("fF", fmt_spec) != NULL && abs_f > 1.0e307)) {
+ xstrlcpy(tmp, infinity_str(f > 0.0, fmt_spec,
+ force_sign, space_for_positive),
+ sizeof(tmp));
+ str_arg_l = strlen(tmp);
+ zero_padding = 0;
+ } else if (isnan(f)) {
+ // Not a number: nan or NAN
+ memmove(tmp, ASCII_ISUPPER(fmt_spec) ? "NAN" : "nan", 4);
+ str_arg_l = 3;
+ zero_padding = 0;
+ } else {
+ format[0] = '%';
+ size_t l = 1;
+ if (force_sign) {
+ format[l++] = space_for_positive ? ' ' : '+';
+ }
+ if (precision_specified) {
+ size_t max_prec = TMP_LEN - 10;
+
+ // make sure we don't get more digits than we have room for
+ if ((fmt_spec == 'f' || fmt_spec == 'F') && abs_f > 1.0) {
+ max_prec -= (size_t)log10(abs_f);
+ }
+ if (precision > max_prec) {
+ precision = max_prec;
+ }
+ l += (size_t)snprintf(format + l, sizeof(format) - l, ".%d",
+ (int)precision);
+ }
+
+ // Cast to char to avoid a conversion warning on Ubuntu 12.04.
+ format[l] = (char)(fmt_spec == 'F' ? 'f' : fmt_spec);
+ format[l + 1] = NUL;
+
+ // Regular float number
+ assert(l + 1 < sizeof(format));
+ str_arg_l = (size_t)snprintf(tmp, sizeof(tmp), format, f);
+ assert(str_arg_l < sizeof(tmp));
+
+ if (remove_trailing_zeroes) {
+ int i;
+ char *tp;
+
+ // using %g or %G: remove superfluous zeroes
+ if (fmt_spec == 'f' || fmt_spec == 'F') {
+ tp = tmp + str_arg_l - 1;
+ } else {
+ tp = (char *)vim_strchr((char_u *)tmp,
+ fmt_spec == 'e' ? 'e' : 'E');
+ if (tp) {
+ // remove superfluous '+' and leading zeroes from exponent
+ if (tp[1] == '+') {
+ // change "1.0e+07" to "1.0e07"
+ STRMOVE(tp + 1, tp + 2);
+ str_arg_l--;
+ }
+ i = (tp[1] == '-') ? 2 : 1;
+ while (tp[i] == '0') {
+ // change "1.0e07" to "1.0e7"
+ STRMOVE(tp + i, tp + i + 1);
+ str_arg_l--;
+ }
+ tp--;
+ }
+ }
+
+ if (tp != NULL && !precision_specified) {
+ // remove trailing zeroes, but keep the one just after a dot
+ while (tp > tmp + 2 && *tp == '0' && tp[-1] != '.') {
+ STRMOVE(tp, tp + 1);
+ tp--;
+ str_arg_l--;
+ }
+ }
+ } else {
+ // Be consistent: some printf("%e") use 1.0e+12 and some
+ // 1.0e+012; remove one zero in the last case.
+ char *tp = (char *)vim_strchr((char_u *)tmp,
+ fmt_spec == 'e' ? 'e' : 'E');
+ if (tp && (tp[1] == '+' || tp[1] == '-') && tp[2] == '0'
+ && ascii_isdigit(tp[3]) && ascii_isdigit(tp[4])) {
+ STRMOVE(tp + 2, tp + 3);
+ str_arg_l--;
+ }
+ }
+ }
+ if (zero_padding && min_field_width > str_arg_l
+ && (tmp[0] == '-' || force_sign)) {
+ // Padding 0's should be inserted after the sign.
+ number_of_zeros_to_pad = min_field_width - str_arg_l;
+ zero_padding_insertion_ind = 1;
+ }
+ str_arg = tmp;
+ break;
+ }
+
+ default:
+ // unrecognized conversion specifier, keep format string as-is
+ zero_padding = 0; // turn zero padding off for non-numeric conversion
+ justify_left = 1;
+ min_field_width = 0; // reset flags
+
+ // discard the unrecognized conversion, just keep
+ // the unrecognized conversion character
+ str_arg = p;
+ str_arg_l = 0;
+ if (*p) {
+ str_arg_l++; // include invalid conversion specifier
+ }
+ // unchanged if not at end-of-string
+ break;
+ }
+
+ if (*p) {
+ p++; // step over the just processed conversion specifier
+ }
+
+ // insert padding to the left as requested by min_field_width;
+ // this does not include the zero padding in case of numerical conversions
+ if (!justify_left) {
+ assert(str_arg_l <= SIZE_MAX - number_of_zeros_to_pad);
+ if (min_field_width > str_arg_l + number_of_zeros_to_pad) {
+ // left padding with blank or zero
+ size_t pn = min_field_width - (str_arg_l + number_of_zeros_to_pad);
+ if (str_avail) {
+ size_t avail = str_m - str_l;
+ memset(str + str_l, zero_padding ? '0' : ' ', MIN(pn, avail));
+ str_avail = pn < avail;
+ }
+ assert(pn <= SIZE_MAX - str_l);
+ str_l += pn;
+ }
+ }
+
+ // zero padding as requested by the precision or by the minimal
+ // field width for numeric conversions required?
+ if (number_of_zeros_to_pad == 0) {
+ // will not copy first part of numeric right now,
+ // force it to be copied later in its entirety
+ zero_padding_insertion_ind = 0;
+ } else {
+ // insert first part of numerics (sign or '0x') before zero padding
+ if (zero_padding_insertion_ind > 0) {
+ size_t zn = zero_padding_insertion_ind;
+ if (str_avail) {
+ size_t avail = str_m - str_l;
+ memmove(str + str_l, str_arg, MIN(zn, avail));
+ str_avail = zn < avail;
+ }
+ assert(zn <= SIZE_MAX - str_l);
+ str_l += zn;
+ }
+
+ // insert zero padding as requested by precision or min field width
+ if (number_of_zeros_to_pad > 0) {
+ size_t zn = number_of_zeros_to_pad;
+ if (str_avail) {
+ size_t avail = str_m - str_l;
+ memset(str + str_l, '0', MIN(zn, avail));
+ str_avail = zn < avail;
+ }
+ assert(zn <= SIZE_MAX - str_l);
+ str_l += zn;
+ }
+ }
+
+ // insert formatted string
+ // (or as-is conversion specifier for unknown conversions)
+ if (str_arg_l > zero_padding_insertion_ind) {
+ size_t sn = str_arg_l - zero_padding_insertion_ind;
+ if (str_avail) {
+ size_t avail = str_m - str_l;
+ memmove(str + str_l,
+ str_arg + zero_padding_insertion_ind,
+ MIN(sn, avail));
+ str_avail = sn < avail;
+ }
+ assert(sn <= SIZE_MAX - str_l);
+ str_l += sn;
+ }
+
+ // insert right padding
+ if (justify_left) {
+ assert(str_arg_l <= SIZE_MAX - number_of_zeros_to_pad);
+ if (min_field_width > str_arg_l + number_of_zeros_to_pad) {
+ // right blank padding to the field width
+ size_t pn = min_field_width - (str_arg_l + number_of_zeros_to_pad);
+ if (str_avail) {
+ size_t avail = str_m - str_l;
+ memset(str + str_l, ' ', MIN(pn, avail));
+ str_avail = pn < avail;
+ }
+ assert(pn <= SIZE_MAX - str_l);
+ str_l += pn;
+ }
+ }
+
+ xfree(tofree);
+ }
+ }
+
+ if (str_m > 0) {
+ // make sure the string is nul-terminated even at the expense of
+ // overwriting the last character (shouldn't happen, but just in case)
+ str[str_l <= str_m - 1 ? str_l : str_m - 1] = '\0';
+ }
+
+ if (tvs && tvs[arg_idx - 1].v_type != VAR_UNKNOWN) {
+ EMSG(_("E767: Too many arguments to printf()"));
+ }
+
+ // return the number of characters formatted (excluding trailing nul
+ // character); that is, the number of characters that would have been
+ // written to the buffer if it were large enough.
+ return (int)str_l;
+}
diff --git a/src/nvim/strings.h b/src/nvim/strings.h
index 3f0f0c8d6a..59b8701a3f 100644
--- a/src/nvim/strings.h
+++ b/src/nvim/strings.h
@@ -2,6 +2,10 @@
#define NVIM_STRINGS_H
#include <stdbool.h>
+#include <stdarg.h>
+
+#include "nvim/types.h"
+#include "nvim/eval/typval.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "strings.h.generated.h"
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index aded08faee..65c0e2464a 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* syntax.c: code for syntax highlighting
*/
@@ -42,39 +45,46 @@
static bool did_syntax_onoff = false;
-// Structure that stores information about a highlight group.
-// The ID of a highlight group is also called group ID. It is the index in
-// the highlight_ga array PLUS ONE.
+/// Structure that stores information about a highlight group.
+/// The ID of a highlight group is also called group ID. It is the index in
+/// the highlight_ga array PLUS ONE.
struct hl_group {
- char_u *sg_name; // highlight group name
- char_u *sg_name_u; // uppercase of sg_name
- int sg_attr; // Screen attr
- int sg_link; // link to this highlight group ID
- int sg_set; // combination of SG_* flags
- scid_T sg_scriptID; // script in which the group was last set
+ char_u *sg_name; ///< highlight group name
+ char_u *sg_name_u; ///< uppercase of sg_name
+ int sg_attr; ///< Screen attr @see ATTR_ENTRY
+ int sg_link; ///< link to this highlight group ID
+ int sg_set; ///< combination of flags in \ref SG_SET
+ scid_T sg_scriptID; ///< script in which the group was last set
// for terminal UIs
- int sg_cterm; // "cterm=" highlighting attr
- int sg_cterm_fg; // terminal fg color number + 1
- int sg_cterm_bg; // terminal bg color number + 1
- int sg_cterm_bold; // bold attr was set for light color
+ int sg_cterm; ///< "cterm=" highlighting attr
+ int sg_cterm_fg; ///< terminal fg color number + 1
+ int sg_cterm_bg; ///< terminal bg color number + 1
+ int sg_cterm_bold; ///< bold attr was set for light color
// for RGB UIs
- int sg_gui; // "gui=" highlighting attributes
- RgbValue sg_rgb_fg; // RGB foreground color
- RgbValue sg_rgb_bg; // RGB background color
- RgbValue sg_rgb_sp; // RGB special color
- uint8_t *sg_rgb_fg_name; // RGB foreground color name
- uint8_t *sg_rgb_bg_name; // RGB background color name
- uint8_t *sg_rgb_sp_name; // RGB special color name
+ int sg_gui; ///< "gui=" highlighting attributes
+ ///< (combination of \ref HL_ATTRIBUTES)
+ RgbValue sg_rgb_fg; ///< RGB foreground color
+ RgbValue sg_rgb_bg; ///< RGB background color
+ RgbValue sg_rgb_sp; ///< RGB special color
+ uint8_t *sg_rgb_fg_name; ///< RGB foreground color name
+ uint8_t *sg_rgb_bg_name; ///< RGB background color name
+ uint8_t *sg_rgb_sp_name; ///< RGB special color name
};
+/// \addtogroup SG_SET
+/// @{
#define SG_CTERM 2 // cterm has been set
#define SG_GUI 4 // gui has been set
#define SG_LINK 8 // link has been set
+/// @}
// highlight groups for 'highlight' option
static garray_T highlight_ga = GA_EMPTY_INIT_VALUE;
-#define HL_TABLE() ((struct hl_group *)((highlight_ga.ga_data)))
+static inline struct hl_group * HL_TABLE(void)
+{
+ return ((struct hl_group *)((highlight_ga.ga_data)));
+}
#define MAX_HL_ID 20000 /* maximum value for a highlight ID. */
@@ -93,10 +103,8 @@ static int include_none = 0; /* when 1 include "nvim/None" */
static int include_default = 0; /* when 1 include "nvim/default" */
static int include_link = 0; /* when 2 include "nvim/link" and "clear" */
-/*
- * The "term", "cterm" and "gui" arguments can be any combination of the
- * following names, separated by commas (but no spaces!).
- */
+/// The "term", "cterm" and "gui" arguments can be any combination of the
+/// following names, separated by commas (but no spaces!).
static char *(hl_name_table[]) =
{"bold", "standout", "underline", "undercurl",
"italic", "reverse", "inverse", "NONE"};
@@ -302,6 +310,8 @@ static keyentry_T dumkey;
#define HIKEY2KE(p) ((keyentry_T *)((p) - (dumkey.keyword - (char_u *)&dumkey)))
#define HI2KE(hi) HIKEY2KE((hi)->hi_key)
+// -V:HI2KE:782
+
/*
* To reduce the time spent in keepend(), remember at which level in the state
* stack the first item with "keepend" is present. When "-1", there is no
@@ -1406,14 +1416,14 @@ static int syn_stack_equal(synstate_T *sp)
/* If the pointer is different it can still be the
* same text. Compare the strings, ignore case when
* the start item has the sp_ic flag set. */
- if (bsx->matches[j] == NULL
- || six->matches[j] == NULL)
+ if (bsx->matches[j] == NULL || six->matches[j] == NULL) {
break;
- if ((SYN_ITEMS(syn_block)[CUR_STATE(i).si_idx]).sp_ic
- ? mb_stricmp(bsx->matches[j],
- six->matches[j]) != 0
- : STRCMP(bsx->matches[j], six->matches[j]) != 0)
+ }
+ if (mb_strcmp_ic((SYN_ITEMS(syn_block)[CUR_STATE(i).si_idx]).sp_ic,
+ (const char *)bsx->matches[j],
+ (const char *)six->matches[j]) != 0) {
break;
+ }
}
}
if (j != NSUBEXP)
@@ -1657,8 +1667,9 @@ syn_current_attr (
* If we found a match after the last column, use it.
*/
if (next_match_idx >= 0 && next_match_col >= (int)current_col
- && next_match_col != MAXCOL)
- (void)push_next_match(NULL);
+ && next_match_col != MAXCOL) {
+ (void)push_next_match();
+ }
current_finished = TRUE;
current_state_stored = FALSE;
@@ -1765,8 +1776,9 @@ syn_current_attr (
cur_si->si_trans_id = CUR_STATE(
current_state.ga_len - 2).si_trans_id;
}
- } else
+ } else {
cur_si->si_attr = syn_id2attr(syn_id);
+ }
cur_si->si_cont_list = NULL;
cur_si->si_next_list = next_list;
check_keepend();
@@ -1976,9 +1988,10 @@ syn_current_attr (
* endless loop). */
GA_APPEND(int, &zero_width_next_ga, next_match_idx);
next_match_idx = -1;
- } else
- cur_si = push_next_match(cur_si);
- found_match = TRUE;
+ } else {
+ cur_si = push_next_match();
+ }
+ found_match = true;
}
}
}
@@ -2158,9 +2171,10 @@ static int did_match_already(int idx, garray_T *gap)
/*
* Push the next match onto the stack.
*/
-static stateitem_T *push_next_match(stateitem_T *cur_si)
+static stateitem_T *push_next_match(void)
{
- synpat_T *spp;
+ stateitem_T *cur_si;
+ synpat_T *spp;
int save_flags;
spp = &(SYN_ITEMS(syn_block)[next_match_idx]);
@@ -3259,9 +3273,10 @@ static void syn_cmd_clear(exarg_T *eap, int syncing)
syntax_sync_clear();
else {
syntax_clear(curwin->w_s);
- if (curwin->w_s == &curwin->w_buffer->b_s)
- do_unlet((char_u *)"b:current_syntax", TRUE);
- do_unlet((char_u *)"w:current_syntax", TRUE);
+ if (curwin->w_s == &curwin->w_buffer->b_s) {
+ do_unlet(S_LEN("b:current_syntax"), true);
+ }
+ do_unlet(S_LEN("w:current_syntax"), true);
}
} else {
/*
@@ -3337,7 +3352,7 @@ static void syn_cmd_enable(exarg_T *eap, int syncing)
{
set_internal_string_var((char_u *)"syntax_cmd", (char_u *)"enable");
syn_cmd_onoff(eap, "syntax");
- do_unlet((char_u *)"g:syntax_cmd", TRUE);
+ do_unlet(S_LEN("g:syntax_cmd"), true);
}
/*
@@ -3350,7 +3365,7 @@ static void syn_cmd_reset(exarg_T *eap, int syncing)
if (!eap->skip) {
set_internal_string_var((char_u *)"syntax_cmd", (char_u *)"reset");
do_cmdline_cmd("runtime! syntax/syncolor.vim");
- do_unlet((char_u *)"g:syntax_cmd", TRUE);
+ do_unlet(S_LEN("g:syntax_cmd"), true);
}
}
@@ -3377,7 +3392,7 @@ static void syn_cmd_onoff(exarg_T *eap, char *name)
eap->nextcmd = check_nextcmd(eap->arg);
if (!eap->skip) {
char buf[100];
- strncpy(buf, "so ", 4);
+ memcpy(buf, "so ", 4);
vim_snprintf(buf + 3, sizeof(buf) - 3, SYNTAX_FNAME, name);
do_cmdline_cmd(buf);
}
@@ -3576,22 +3591,24 @@ syn_list_one (
}
syn_list_flags(namelist1, spp->sp_flags, attr);
- if (spp->sp_cont_list != NULL)
- put_id_list((char_u *)"contains", spp->sp_cont_list, attr);
+ if (spp->sp_cont_list != NULL) {
+ put_id_list("contains", spp->sp_cont_list, attr);
+ }
- if (spp->sp_syn.cont_in_list != NULL)
- put_id_list((char_u *)"containedin",
- spp->sp_syn.cont_in_list, attr);
+ if (spp->sp_syn.cont_in_list != NULL) {
+ put_id_list("containedin", spp->sp_syn.cont_in_list, attr);
+ }
if (spp->sp_next_list != NULL) {
- put_id_list((char_u *)"nextgroup", spp->sp_next_list, attr);
+ put_id_list("nextgroup", spp->sp_next_list, attr);
syn_list_flags(namelist2, spp->sp_flags, attr);
}
if (spp->sp_flags & (HL_SYNC_HERE|HL_SYNC_THERE)) {
- if (spp->sp_flags & HL_SYNC_HERE)
- msg_puts_attr((char_u *)"grouphere", attr);
- else
- msg_puts_attr((char_u *)"groupthere", attr);
+ if (spp->sp_flags & HL_SYNC_HERE) {
+ msg_puts_attr("grouphere", attr);
+ } else {
+ msg_puts_attr("groupthere", attr);
+ }
msg_putchar(' ');
if (spp->sp_sync_idx >= 0)
msg_outtrans(HL_TABLE()[SYN_ITEMS(curwin->w_s)
@@ -3605,7 +3622,7 @@ syn_list_one (
/* list the link, if there is one */
if (HL_TABLE()[id - 1].sg_link && (did_header || link_only) && !got_int) {
(void)syn_list_header(did_header, 999, id);
- msg_puts_attr((char_u *)"links to", attr);
+ msg_puts_attr("links to", attr);
msg_putchar(' ');
msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name);
}
@@ -3617,7 +3634,7 @@ static void syn_list_flags(struct name_list *nlist, int flags, int attr)
for (i = 0; nlist[i].flag != 0; ++i)
if (flags & nlist[i].flag) {
- msg_puts_attr((char_u *)nlist[i].name, attr);
+ msg_puts_attr(nlist[i].name, attr);
msg_putchar(' ');
}
}
@@ -3640,15 +3657,16 @@ static void syn_list_cluster(int id)
msg_advance(endcol);
if (SYN_CLSTR(curwin->w_s)[id].scl_list != NULL) {
- put_id_list((char_u *)"cluster", SYN_CLSTR(curwin->w_s)[id].scl_list,
- hl_attr(HLF_D));
+ put_id_list("cluster", SYN_CLSTR(curwin->w_s)[id].scl_list, hl_attr(HLF_D));
} else {
- msg_puts_attr((char_u *)"cluster", hl_attr(HLF_D));
- msg_puts((char_u *)"=NONE");
+ msg_puts_attr("cluster", hl_attr(HLF_D));
+ msg_puts("=NONE");
}
}
-static void put_id_list(char_u *name, short *list, int attr)
+static void put_id_list(const char *name,
+ short *list, // NOLINT(runtime/int)
+ int attr)
{
short *p;
@@ -3656,14 +3674,15 @@ static void put_id_list(char_u *name, short *list, int 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");
+ if (p[1]) {
+ msg_puts("ALLBUT");
+ } else {
+ msg_puts("ALL");
+ }
} else if (*p >= SYNID_TOP && *p < SYNID_CONTAINED) {
- MSG_PUTS("TOP");
+ msg_puts("TOP");
} else if (*p >= SYNID_CONTAINED && *p < SYNID_CLUSTER) {
- MSG_PUTS("CONTAINED");
+ msg_puts("CONTAINED");
} else if (*p >= SYNID_CLUSTER) {
short scl_id = *p - SYNID_CLUSTER;
@@ -3688,7 +3707,7 @@ static void put_pattern(char *s, int c, synpat_T *spp, int attr)
/* May have to write "matchgroup=group" */
if (last_matchgroup != spp->sp_syn_match_id) {
last_matchgroup = spp->sp_syn_match_id;
- msg_puts_attr((char_u *)"matchgroup", attr);
+ msg_puts_attr("matchgroup", attr);
msg_putchar('=');
if (last_matchgroup == 0)
msg_outtrans((char_u *)"NONE");
@@ -3697,8 +3716,8 @@ static void put_pattern(char *s, int c, synpat_T *spp, int attr)
msg_putchar(' ');
}
- /* output the name of the pattern and an '=' or ' ' */
- msg_puts_attr((char_u *)s, attr);
+ // Output the name of the pattern and an '=' or ' '.
+ msg_puts_attr(s, attr);
msg_putchar(c);
/* output the pattern, in between a char that is not in the pattern */
@@ -3718,9 +3737,10 @@ static void put_pattern(char *s, int c, synpat_T *spp, int attr)
if (!(spp->sp_off_flags & (mask + (mask << SPO_COUNT)))) {
continue;
}
- if (!first)
- msg_putchar(','); /* separate with commas */
- msg_puts((char_u *)spo_name_tab[i]);
+ if (!first) {
+ msg_putchar(','); // Separate with commas.
+ }
+ msg_puts(spo_name_tab[i]);
n = spp->sp_offsets[i];
if (i != SPO_LC_OFF) {
if (spp->sp_off_flags & mask)
@@ -3792,32 +3812,31 @@ syn_list_keywords (
}
did_header = TRUE;
if (prev_contained != (kp->flags & HL_CONTAINED)) {
- msg_puts_attr((char_u *)"contained", attr);
+ msg_puts_attr("contained", attr);
msg_putchar(' ');
prev_contained = (kp->flags & HL_CONTAINED);
}
if (kp->k_syn.cont_in_list != prev_cont_in_list) {
- put_id_list((char_u *)"containedin",
- kp->k_syn.cont_in_list, attr);
+ put_id_list("containedin", kp->k_syn.cont_in_list, attr);
msg_putchar(' ');
prev_cont_in_list = kp->k_syn.cont_in_list;
}
if (kp->next_list != prev_next_list) {
- put_id_list((char_u *)"nextgroup", kp->next_list, attr);
+ put_id_list("nextgroup", kp->next_list, attr);
msg_putchar(' ');
prev_next_list = kp->next_list;
if (kp->flags & HL_SKIPNL) {
- msg_puts_attr((char_u *)"skipnl", attr);
+ msg_puts_attr("skipnl", attr);
msg_putchar(' ');
prev_skipnl = (kp->flags & HL_SKIPNL);
}
if (kp->flags & HL_SKIPWHITE) {
- msg_puts_attr((char_u *)"skipwhite", attr);
+ msg_puts_attr("skipwhite", attr);
msg_putchar(' ');
prev_skipwhite = (kp->flags & HL_SKIPWHITE);
}
if (kp->flags & HL_SKIPEMPTY) {
- msg_puts_attr((char_u *)"skipempty", attr);
+ msg_puts_attr("skipempty", attr);
msg_putchar(' ');
prev_skipempty = (kp->flags & HL_SKIPEMPTY);
}
@@ -3929,7 +3948,8 @@ static void add_keyword(char_u *name,
hash_T hash = hash_hash(kp->keyword);
hashtab_T *ht = (curwin->w_s->b_syn_ic) ? &curwin->w_s->b_keywtab_ic
: &curwin->w_s->b_keywtab;
- hashitem_T *hi = hash_lookup(ht, kp->keyword, hash);
+ hashitem_T *hi = hash_lookup(ht, (const char *)kp->keyword,
+ STRLEN(kp->keyword), hash);
// even though it looks like only the kp->keyword member is
// being used here, vim uses some pointer trickery to get the orignal
@@ -4236,83 +4256,81 @@ static void syn_cmd_keyword(exarg_T *eap, int syncing)
if (rest != NULL) {
syn_id = syn_check_group(arg, (int)(group_name_end - arg));
- if (syn_id != 0)
- /* allocate a buffer, for removing backslashes in the keyword */
+ if (syn_id != 0) {
+ // Allocate a buffer, for removing backslashes in the keyword.
keyword_copy = xmalloc(STRLEN(rest) + 1);
- syn_opt_arg.flags = 0;
- syn_opt_arg.keyword = TRUE;
- syn_opt_arg.sync_idx = NULL;
- syn_opt_arg.has_cont_list = FALSE;
- syn_opt_arg.cont_in_list = NULL;
- syn_opt_arg.next_list = NULL;
-
- /*
- * The options given apply to ALL keywords, so all options must be
- * found before keywords can be created.
- * 1: collect the options and copy the keywords to keyword_copy.
- */
- cnt = 0;
- p = keyword_copy;
- for (; rest != NULL && !ends_excmd(*rest); rest = skipwhite(rest)) {
- rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
- if (rest == NULL || ends_excmd(*rest))
- break;
- /* Copy the keyword, removing backslashes, and add a NUL. */
- while (*rest != NUL && !ascii_iswhite(*rest)) {
- if (*rest == '\\' && rest[1] != NUL)
- ++rest;
- *p++ = *rest++;
- }
- *p++ = NUL;
- ++cnt;
}
+ if (keyword_copy != NULL) {
+ syn_opt_arg.flags = 0;
+ syn_opt_arg.keyword = true;
+ syn_opt_arg.sync_idx = NULL;
+ syn_opt_arg.has_cont_list = false;
+ syn_opt_arg.cont_in_list = NULL;
+ syn_opt_arg.next_list = NULL;
+
+ // The options given apply to ALL keywords, so all options must be
+ // found before keywords can be created.
+ // 1: collect the options and copy the keywords to keyword_copy.
+ cnt = 0;
+ p = keyword_copy;
+ for (; rest != NULL && !ends_excmd(*rest); rest = skipwhite(rest)) {
+ rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
+ if (rest == NULL || ends_excmd(*rest)) {
+ break;
+ }
+ // Copy the keyword, removing backslashes, and add a NUL.
+ while (*rest != NUL && !ascii_iswhite(*rest)) {
+ if (*rest == '\\' && rest[1] != NUL) {
+ rest++;
+ }
+ *p++ = *rest++;
+ }
+ *p++ = NUL;
+ cnt++;
+ }
- if (!eap->skip) {
- /* Adjust flags for use of ":syn include". */
- syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
+ if (!eap->skip) {
+ // Adjust flags for use of ":syn include".
+ syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
- /*
- * 2: Add an entry for each keyword.
- */
- for (kw = keyword_copy; --cnt >= 0; kw += STRLEN(kw) + 1) {
- for (p = vim_strchr(kw, '[');; ) {
- if (p != NULL)
- *p = NUL;
- add_keyword(kw, syn_id, syn_opt_arg.flags,
- syn_opt_arg.cont_in_list,
- syn_opt_arg.next_list, conceal_char);
- if (p == NULL)
- break;
- if (p[1] == NUL) {
- EMSG2(_("E789: Missing ']': %s"), kw);
- goto error;
- }
- if (p[1] == ']') {
- if (p[2] != NUL) {
- EMSG3(_("E890: trailing char after ']': %s]%s"),
- kw, &p[2]);
+ // 2: Add an entry for each keyword.
+ for (kw = keyword_copy; --cnt >= 0; kw += STRLEN(kw) + 1) {
+ for (p = vim_strchr(kw, '[');; ) {
+ if (p != NULL) {
+ *p = NUL;
+ }
+ add_keyword(kw, syn_id, syn_opt_arg.flags,
+ syn_opt_arg.cont_in_list,
+ syn_opt_arg.next_list, conceal_char);
+ if (p == NULL) {
+ break;
+ }
+ if (p[1] == NUL) {
+ emsgf(_("E789: Missing ']': %s"), kw);
goto error;
}
- kw = p + 1;
- break; // skip over the "]"
- }
- if (has_mbyte) {
- int l = (*mb_ptr2len)(p + 1);
+ if (p[1] == ']') {
+ if (p[2] != NUL) {
+ emsgf(_("E890: trailing char after ']': %s]%s"),
+ kw, &p[2]);
+ goto error;
+ }
+ kw = p + 1;
+ break; // skip over the "]"
+ }
+ const int l = (*mb_ptr2len)(p + 1);
memmove(p, p + 1, l);
p += l;
- } else {
- p[0] = p[1];
- ++p;
}
}
}
- }
error:
- xfree(keyword_copy);
- xfree(syn_opt_arg.cont_in_list);
- xfree(syn_opt_arg.next_list);
+ xfree(keyword_copy);
+ xfree(syn_opt_arg.cont_in_list);
+ xfree(syn_opt_arg.next_list);
+ }
}
if (rest != NULL)
@@ -5236,12 +5254,10 @@ get_id_list (
/*
* Handle full group name.
*/
- if (vim_strpbrk(name + 1, (char_u *)"\\.*^$~[") == NULL)
+ if (vim_strpbrk(name + 1, (char_u *)"\\.*^$~[") == NULL) {
id = syn_check_group(name + 1, (int)(end - p));
- else {
- /*
- * Handle match of regexp with group names.
- */
+ } else {
+ // Handle match of regexp with group names.
*name = '^';
STRCAT(name, "$");
regmatch.regprog = vim_regcomp(name, RE_MAGIC);
@@ -5516,24 +5532,26 @@ void ex_ownsyntax(exarg_T *eap)
clear_string_option(&curwin->w_s->b_syn_isk);
}
- /* save value of b:current_syntax */
- old_value = get_var_value((char_u *)"b:current_syntax");
- if (old_value != NULL)
+ // Save value of b:current_syntax.
+ old_value = get_var_value("b:current_syntax");
+ if (old_value != NULL) {
old_value = vim_strsave(old_value);
+ }
/* Apply the "syntax" autocommand event, this finds and loads the syntax
* file. */
apply_autocmds(EVENT_SYNTAX, eap->arg, curbuf->b_fname, TRUE, curbuf);
- /* move value of b:current_syntax to w:current_syntax */
- new_value = get_var_value((char_u *)"b:current_syntax");
- if (new_value != NULL)
+ // Move value of b:current_syntax to w:current_syntax.
+ new_value = get_var_value("b:current_syntax");
+ if (new_value != NULL) {
set_internal_string_var((char_u *)"w:current_syntax", new_value);
+ }
- /* restore value of b:current_syntax */
- if (old_value == NULL)
- do_unlet((char_u *)"b:current_syntax", TRUE);
- else {
+ // Restore value of b:current_syntax.
+ if (old_value == NULL) {
+ do_unlet(S_LEN("b:current_syntax"), true);
+ } else {
set_internal_string_var((char_u *)"b:current_syntax", old_value);
xfree(old_value);
}
@@ -5566,43 +5584,42 @@ void reset_expand_highlight(void)
* Handle command line completion for :match and :echohl command: Add "None"
* as highlight group.
*/
-void set_context_in_echohl_cmd(expand_T *xp, char_u *arg)
+void set_context_in_echohl_cmd(expand_T *xp, const char *arg)
{
xp->xp_context = EXPAND_HIGHLIGHT;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
include_none = 1;
}
/*
* Handle command line completion for :syntax command.
*/
-void set_context_in_syntax_cmd(expand_T *xp, char_u *arg)
+void set_context_in_syntax_cmd(expand_T *xp, const char *arg)
{
- char_u *p;
-
- /* Default: expand subcommands */
+ // Default: expand subcommands.
xp->xp_context = EXPAND_SYNTAX;
expand_what = EXP_SUBCMD;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
include_link = 0;
include_default = 0;
/* (part of) subcommand already typed */
if (*arg != NUL) {
- p = skiptowhite(arg);
- if (*p != NUL) { /* past first word */
- xp->xp_pattern = skipwhite(p);
- if (*skiptowhite(xp->xp_pattern) != NUL)
+ const char *p = (const char *)skiptowhite((const char_u *)arg);
+ if (*p != NUL) { // Past first word.
+ xp->xp_pattern = skipwhite((const char_u *)p);
+ if (*skiptowhite(xp->xp_pattern) != NUL) {
xp->xp_context = EXPAND_NOTHING;
- else if (STRNICMP(arg, "case", p - arg) == 0)
+ } else if (STRNICMP(arg, "case", p - arg) == 0) {
expand_what = EXP_CASE;
- else if ( STRNICMP(arg, "keyword", p - arg) == 0
+ } else if (STRNICMP(arg, "keyword", p - arg) == 0
|| STRNICMP(arg, "region", p - arg) == 0
|| STRNICMP(arg, "match", p - arg) == 0
- || STRNICMP(arg, "list", p - arg) == 0)
+ || STRNICMP(arg, "list", p - arg) == 0) {
xp->xp_context = EXPAND_HIGHLIGHT;
- else
+ } else {
xp->xp_context = EXPAND_NOTHING;
+ }
}
}
}
@@ -5889,6 +5906,8 @@ static void syntime_report(void)
static char *highlight_init_both[] =
{
"Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey",
+ "Cursor guibg=fg guifg=bg",
+ "lCursor guibg=fg guifg=bg",
"DiffText cterm=bold ctermbg=Red gui=bold guibg=Red",
"ErrorMsg ctermbg=DarkRed ctermfg=White guibg=Red guifg=White",
"IncSearch cterm=reverse gui=reverse",
@@ -5905,6 +5924,7 @@ static char *highlight_init_both[] =
"default link EndOfBuffer NonText",
"default link QuickFixLine Search",
"default link Substitute Search",
+ "default link Whitespace NonText",
NULL
};
@@ -5938,6 +5958,7 @@ static char *highlight_init_light[] =
"Title ctermfg=DarkMagenta gui=bold guifg=Magenta",
"Visual guibg=LightGrey",
"WarningMsg ctermfg=DarkRed guifg=Red",
+ "Normal gui=NONE",
NULL
};
@@ -5971,24 +5992,26 @@ static char *highlight_init_dark[] =
"Title ctermfg=LightMagenta gui=bold guifg=Magenta",
"Visual guibg=DarkGrey",
"WarningMsg ctermfg=LightRed guifg=Red",
+ "Normal gui=NONE",
NULL
};
-void
-init_highlight (
- int both, /* include groups where 'bg' doesn't matter */
- int reset /* clear group first */
-)
+
+/// Load colors from a file if "g:colors_name" is set, otherwise load builtin
+/// colors
+///
+/// @param both include groups where 'bg' doesn't matter
+/// @param reset clear groups first
+void
+init_highlight(int both, int reset)
{
int i;
char **pp;
static int had_both = FALSE;
- /*
- * Try finding the color scheme file. Used when a color file was loaded
- * and 'background' or 't_Co' is changed.
- */
- char_u *p = get_var_value((char_u *)"g:colors_name");
+ // Try finding the color scheme file. Used when a color file was loaded
+ // and 'background' or 't_Co' is changed.
+ char_u *p = get_var_value("g:colors_name");
if (p != NULL) {
// Value of g:colors_name could be freed in load_colors() and make
// p invalid, so copy it.
@@ -6006,33 +6029,34 @@ init_highlight (
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. */
+ 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);
+ pp = (*p_bg == 'l') ? highlight_init_light : 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)
+ if (t_colors > 8) {
do_highlight(
(char_u *)(*p_bg == 'l'
? "Visual cterm=NONE ctermbg=LightGrey"
- : "Visual cterm=NONE ctermbg=DarkGrey"), FALSE,
- TRUE);
- else {
+ : "Visual cterm=NONE ctermbg=DarkGrey"), false,
+ true);
+ } else {
do_highlight((char_u *)"Visual cterm=reverse ctermbg=NONE",
FALSE, TRUE);
if (*p_bg == 'l')
@@ -6042,7 +6066,7 @@ init_highlight (
/*
* If syntax highlighting is enabled load the highlighting for it.
*/
- if (get_var_value((char_u *)"g:syntax_on") != NULL) {
+ if (get_var_value("g:syntax_on") != NULL) {
static int recursive = 0;
if (recursive >= 5) {
@@ -6086,18 +6110,13 @@ int load_colors(char_u *name)
return retval;
}
-/*
- * Handle the ":highlight .." command.
- * When using ":hi clear" this is called recursively for each group with
- * "forceit" and "init" both TRUE.
- */
-void
-do_highlight (
- char_u *line,
- int forceit,
- int init /* TRUE when called for initializing */
-)
-{
+
+/// Handle the ":highlight .." command.
+/// When using ":hi clear" this is called recursively for each group with
+/// "forceit" and "init" both TRUE.
+/// @param init TRUE when called for initializing
+void
+do_highlight(char_u *line, int forceit, int init) {
char_u *name_end;
char_u *linep;
char_u *key_start;
@@ -6114,15 +6133,16 @@ do_highlight (
int dolink = FALSE;
int error = FALSE;
int color;
- int is_normal_group = FALSE; /* "Normal" group */
+ bool is_normal_group = false; // "Normal" group
/*
* If no argument, list current highlighting.
*/
if (ends_excmd(*line)) {
- for (int i = 1; i <= highlight_ga.ga_len && !got_int; ++i)
- /* TODO: only call when the group has attributes set */
+ for (int i = 1; i <= highlight_ga.ga_len && !got_int; i++) {
+ // todo(vim): only call when the group has attributes set
highlight_list_one(i);
+ }
return;
}
@@ -6224,7 +6244,7 @@ do_highlight (
*/
line = linep;
if (ends_excmd(*line)) {
- do_unlet((char_u *)"colors_name", TRUE);
+ do_unlet(S_LEN("colors_name"), true);
restore_cterm_colors();
/*
@@ -6250,12 +6270,12 @@ do_highlight (
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 "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;
+ is_normal_group = (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0);
/* Clear the highlighting for ":hi clear {group}" and ":hi clear". */
if (doclear || (forceit && init)) {
@@ -6264,7 +6284,7 @@ do_highlight (
HL_TABLE()[idx].sg_set = 0;
}
- if (!doclear)
+ if (!doclear) {
while (!ends_excmd(*linep)) {
key_start = linep;
if (*linep == '=') {
@@ -6370,12 +6390,12 @@ do_highlight (
}
}
} else if (STRCMP(key, "FONT") == 0) {
- /* in non-GUI fonts are simply ignored */
- } else if (STRCMP(key,
- "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0) {
+ // in non-GUI fonts are simply ignored
+ } else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0) {
if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) {
- if (!init)
+ if (!init) {
HL_TABLE()[idx].sg_set |= SG_CTERM;
+ }
/* When setting the foreground color, and previously the "bold"
* flag was set for a light color, reset it now */
@@ -6469,9 +6489,10 @@ do_highlight (
* 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_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) {
@@ -6503,16 +6524,16 @@ do_highlight (
if (!ui_rgb_attached()) {
must_redraw = CLEAR;
if (color >= 0) {
- if (t_colors < 16)
+ if (t_colors < 16) {
i = (color == 0 || color == 4);
- else
+ } 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);
+ }
+ // Set the 'background' option if the value is
+ // wrong.
+ if (i != (*p_bg == 'd')) {
+ set_option_value("bg", 0L, (i ? "dark" : "light"), 0);
+ }
}
}
}
@@ -6583,21 +6604,23 @@ do_highlight (
/*
* When highlighting has been given for a group, don't link it.
*/
- if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK))
+ 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)
+ if (error && idx == highlight_ga.ga_len) {
syn_unadd_group();
- else {
+ } else {
if (is_normal_group) {
HL_TABLE()[idx].sg_attr = 0;
// Need to update all groups, because they might be using "bg" and/or
@@ -6605,16 +6628,17 @@ do_highlight (
highlight_attr_set_all();
// If the normal group has changed, it is simpler to refresh every UI
ui_refresh();
- } else
+ } else {
set_hl_attr(idx);
+ }
HL_TABLE()[idx].sg_scriptID = current_SID;
redraw_all_later(NOT_VALID);
}
xfree(key);
xfree(arg);
- /* Only call highlight_changed() once, after sourcing a syntax file */
- need_highlight_changed = TRUE;
+ // Only call highlight_changed() once, after sourcing a syntax file
+ need_highlight_changed = true;
}
#if defined(EXITFREE)
@@ -6687,22 +6711,21 @@ static void highlight_clear(int idx)
}
-/*
- * Table with the specifications for an attribute number.
- * Note that this table is used by ALL buffers. This is required because the
- * GUI can redraw at any time for any buffer.
- */
+/// Table with the specifications for an attribute number.
+/// Note that this table is used by ALL buffers. This is required because the
+/// GUI can redraw at any time for any buffer.
static garray_T attr_table = GA_EMPTY_INIT_VALUE;
-#define ATTR_ENTRY(idx) ((attrentry_T *)attr_table.ga_data)[idx]
+static inline attrentry_T * ATTR_ENTRY(int idx)
+{
+ return &((attrentry_T *)attr_table.ga_data)[idx];
+}
-/*
- * Return the attr number for a set of colors and font.
- * Add a new entry to the term_attr_table, attr_table or gui_attr_table
- * if the combination is new.
- * Return 0 for error.
- */
+/// Return the attr number for a set of colors and font.
+/// Add a new entry to the term_attr_table, attr_table or gui_attr_table
+/// if the combination is new.
+/// @return 0 for error.
int get_attr_entry(attrentry_T *aep)
{
garray_T *table = &attr_table;
@@ -6786,7 +6809,7 @@ int hl_combine_attr(int char_attr, int prim_attr)
{
attrentry_T *char_aep = NULL;
attrentry_T *spell_aep;
- attrentry_T new_en;
+ attrentry_T new_en = ATTRENTRY_INIT;
if (char_attr == 0) {
return prim_attr;
@@ -6834,17 +6857,24 @@ int hl_combine_attr(int char_attr, int prim_attr)
return get_attr_entry(&new_en);
}
+/// \note this function does not apply exclusively to cterm attr contrary
+/// to what its name implies
attrentry_T *syn_cterm_attr2entry(int attr)
{
attr -= ATTR_OFF;
- if (attr >= attr_table.ga_len) /* did ":syntax clear" */
+ if (attr >= attr_table.ga_len) {
+ // did ":syntax clear"
return NULL;
- return &(ATTR_ENTRY(attr));
+ }
+ return ATTR_ENTRY(attr);
}
+/// \addtogroup LIST_XXX
+/// @{
#define LIST_ATTR 1
#define LIST_STRING 2
#define LIST_INT 3
+/// @}
static void highlight_list_one(int id)
{
@@ -6871,8 +6901,8 @@ static void highlight_list_one(int id)
if (sgp->sg_link && !got_int) {
(void)syn_list_header(didh, 9999, id);
- didh = TRUE;
- msg_puts_attr((char_u *)"links to", hl_attr(HLF_D));
+ didh = true;
+ msg_puts_attr("links to", hl_attr(HLF_D));
msg_putchar(' ');
msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name);
}
@@ -6883,7 +6913,13 @@ static void highlight_list_one(int id)
last_set_msg(sgp->sg_scriptID);
}
-static int highlight_list_arg(int id, int didh, int type, int iarg, char_u *sarg, char *name)
+/// Outputs a highlight when doing ":hi MyHighlight"
+///
+/// @param type one of \ref LIST_XXX
+/// @param iarg integer argument used if \p type == LIST_INT
+/// @param sarg string used if \p type == LIST_STRING
+static int highlight_list_arg(int id, int didh, int type, int iarg,
+ char_u *sarg, const char *name)
{
char_u buf[100];
char_u *ts;
@@ -6902,8 +6938,8 @@ static int highlight_list_arg(int id, int didh, int type, int iarg, char_u *sarg
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);
+ xstrlcat((char *)buf, ",", 100);
+ xstrlcat((char *)buf, hl_name_table[i], 100);
iarg &= ~hl_attr_table[i]; /* don't want "inverse" */
}
}
@@ -6923,21 +6959,21 @@ static int highlight_list_arg(int id, int didh, int type, int iarg, char_u *sarg
return didh;
}
-/*
- * Return "1" if highlight group "id" has attribute "flag".
- * Return NULL otherwise.
- */
-char_u *
-highlight_has_attr (
- int id,
- int flag,
- int modec // 'g' for GUI, 'c' for cterm
-)
+/// Check whether highlight group has attribute
+///
+/// @param[in] id Highlight group to check.
+/// @param[in] flag Attribute to check.
+/// @param[in] modec 'g' for GUI, 'c' for term.
+///
+/// @return "1" if highlight group has attribute, NULL otherwise.
+const char *highlight_has_attr(const int id, const int flag, const int modec)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
{
int attr;
- if (id <= 0 || id > highlight_ga.ga_len)
+ if (id <= 0 || id > highlight_ga.ga_len) {
return NULL;
+ }
if (modec == 'g') {
attr = HL_TABLE()[id - 1].sg_gui;
@@ -6945,39 +6981,42 @@ highlight_has_attr (
attr = HL_TABLE()[id - 1].sg_cterm;
}
- if (attr & flag)
- return (char_u *)"1";
- return NULL;
+ return (attr & flag) ? "1" : NULL;
}
-/*
- * Return color name of highlight group "id".
- */
-char_u *
-highlight_color (
- int id,
- char_u *what, /* "font", "fg", "bg", "sp", "fg#", "bg#" or "sp#" */
- int modec /* 'g' for GUI, 'c' for cterm, 't' for term */
-)
+/// Return color name of the given highlight group
+///
+/// @param[in] id Highlight group to work with.
+/// @param[in] what What to return: one of "font", "fg", "bg", "sp", "fg#",
+/// "bg#" or "sp#".
+/// @param[in] modec 'g' for GUI, 'c' for cterm and 't' for term.
+///
+/// @return color name, possibly in a static buffer. Buffer will be overwritten
+/// on next highlight_color() call. May return NULL.
+const char *highlight_color(const int id, const char *const what,
+ const int modec)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- static char_u name[20];
+ static char name[20];
int n;
- int fg = FALSE;
- int sp = FALSE;
- int font = FALSE;
+ bool fg = false;
+ bool sp = false;
+ bool font = false;
- if (id <= 0 || id > highlight_ga.ga_len)
+ if (id <= 0 || id > highlight_ga.ga_len) {
return NULL;
+ }
- if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'g')
- fg = TRUE;
- else if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'o'
- && TOLOWER_ASC(what[2]) == 'n' && TOLOWER_ASC(what[3]) == 't')
- font = TRUE;
- else if (TOLOWER_ASC(what[0]) == 's' && TOLOWER_ASC(what[1]) == 'p')
- sp = TRUE;
- else if (!(TOLOWER_ASC(what[0]) == 'b' && TOLOWER_ASC(what[1]) == 'g'))
+ if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'g') {
+ fg = true;
+ } else if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'o'
+ && TOLOWER_ASC(what[2]) == 'n' && TOLOWER_ASC(what[3]) == 't') {
+ font = true;
+ } else if (TOLOWER_ASC(what[0]) == 's' && TOLOWER_ASC(what[1]) == 'p') {
+ sp = true;
+ } else if (!(TOLOWER_ASC(what[0]) == 'b' && TOLOWER_ASC(what[1]) == 'g')) {
return NULL;
+ }
if (modec == 'g') {
if (what[2] == '#' && ui_rgb_attached()) {
if (fg) {
@@ -6990,19 +7029,20 @@ highlight_color (
if (n < 0 || n > 0xffffff) {
return NULL;
}
- snprintf((char *)name, sizeof(name), "#%06x", n);
+ snprintf(name, sizeof(name), "#%06x", n);
return name;
}
if (fg) {
- return HL_TABLE()[id - 1].sg_rgb_fg_name;
+ return (const char *)HL_TABLE()[id - 1].sg_rgb_fg_name;
}
if (sp) {
- return HL_TABLE()[id - 1].sg_rgb_sp_name;
+ return (const char *)HL_TABLE()[id - 1].sg_rgb_sp_name;
}
- return HL_TABLE()[id - 1].sg_rgb_bg_name;
+ return (const char *)HL_TABLE()[id - 1].sg_rgb_bg_name;
}
- if (font || sp)
+ if (font || sp) {
return NULL;
+ }
if (modec == 'c') {
if (fg) {
n = HL_TABLE()[id - 1].sg_cterm_fg - 1;
@@ -7012,31 +7052,30 @@ highlight_color (
if (n < 0) {
return NULL;
}
- snprintf((char *)name, sizeof(name), "%d", n);
+ snprintf(name, sizeof(name), "%d", n);
return name;
}
- /* term doesn't have color */
+ // term doesn't have color.
return NULL;
}
-/*
- * Output the syntax list header.
- * Return TRUE when started a new line.
- */
-static int
-syn_list_header (
- int did_header, /* did header already */
- int outlen, /* length of string that comes */
- int id /* highlight group id */
-)
+/// Output the syntax list header.
+///
+/// @param did_header did header already
+/// @param outlen length of string that comes
+/// @param id highlight group id
+/// @return true when started a new line.
+static int
+syn_list_header(int did_header, int outlen, int id)
{
int endcol = 19;
int newline = TRUE;
if (!did_header) {
msg_putchar('\n');
- if (got_int)
- return TRUE;
+ if (got_int) {
+ return true;
+ }
msg_outtrans(HL_TABLE()[id - 1].sg_name);
endcol = 15;
} else if (msg_col + outlen + 1 >= Columns) {
@@ -7057,7 +7096,7 @@ syn_list_header (
/* Show "xxx" with the attributes. */
if (!did_header) {
- msg_puts_attr((char_u *)"xxx", syn_id2attr(id));
+ msg_puts_attr("xxx", syn_id2attr(id));
msg_putchar(' ');
}
@@ -7073,12 +7112,13 @@ set_hl_attr (
int idx /* index in array */
)
{
- attrentry_T at_en;
+ attrentry_T at_en = ATTRENTRY_INIT;
struct hl_group *sgp = HL_TABLE() + idx;
- /* The "Normal" group doesn't need an attribute number */
- if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0)
+ // The "Normal" group doesn't need an attribute number
+ if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0) {
return;
+ }
at_en.cterm_ae_attr = sgp->sg_cterm;
at_en.cterm_fg_color = sgp->sg_cterm_fg;
@@ -7102,11 +7142,11 @@ set_hl_attr (
}
}
-/*
- * Lookup a highlight group name and return it's ID.
- * If it is not found, 0 is returned.
- */
-int syn_name2id(char_u *name)
+/// Lookup a highlight group name and return its ID.
+///
+/// @param highlight name e.g. 'Cursor', 'Normal'
+/// @return the highlight id, else 0 if \p name does not exist
+int syn_name2id(const char_u *name)
{
int i;
char_u name_u[200];
@@ -7126,7 +7166,7 @@ int syn_name2id(char_u *name)
/*
* Return TRUE if highlight group "name" exists.
*/
-int highlight_exists(char_u *name)
+int highlight_exists(const char_u *name)
{
return syn_name2id(name) > 0;
}
@@ -7154,12 +7194,13 @@ int syn_namen2id(char_u *linep, int len)
return id;
}
-/*
- * Find highlight group name in the table and return it's ID.
- * The argument is a pointer to the name and the length of the name.
- * If it doesn't exist yet, a new entry is created.
- * Return 0 for failure.
- */
+/// Find highlight group name in the table and return its ID.
+/// If it doesn't exist yet, a new entry is created.
+///
+/// @param pp Highlight group name
+/// @param len length of \p pp
+///
+/// @return 0 for failure else the id of the group
int syn_check_group(char_u *pp, int len)
{
char_u *name = vim_strnsave(pp, len);
@@ -7172,11 +7213,11 @@ int syn_check_group(char_u *pp, int len)
return id;
}
-/*
- * Add new highlight group and return it's ID.
- * "name" must be an allocated string, it will be consumed.
- * Return 0 for failure.
- */
+/// Add new highlight group and return it's ID.
+///
+/// @param name must be an allocated string, it will be consumed.
+/// @return 0 for failure, else the allocated group id
+/// @see syn_check_group syn_unadd_group
static int syn_add_group(char_u *name)
{
char_u *p;
@@ -7214,25 +7255,26 @@ static int syn_add_group(char_u *name)
struct hl_group* hlgp = GA_APPEND_VIA_PTR(struct hl_group, &highlight_ga);
memset(hlgp, 0, sizeof(*hlgp));
hlgp->sg_name = name;
+ hlgp->sg_rgb_bg = -1;
+ hlgp->sg_rgb_fg = -1;
+ hlgp->sg_rgb_sp = -1;
hlgp->sg_name_u = vim_strsave_up(name);
return highlight_ga.ga_len; /* ID is index plus one */
}
-/*
- * When, just after calling syn_add_group(), an error is discovered, this
- * function deletes the new name.
- */
+/// When, just after calling syn_add_group(), an error is discovered, this
+/// function deletes the new name.
static void syn_unadd_group(void)
{
- --highlight_ga.ga_len;
+ highlight_ga.ga_len--;
xfree(HL_TABLE()[highlight_ga.ga_len].sg_name);
xfree(HL_TABLE()[highlight_ga.ga_len].sg_name_u);
}
-/*
- * Translate a group ID to highlight attributes.
- */
+
+/// Translate a group ID to highlight attributes.
+/// @see syn_cterm_attr2entry
int syn_id2attr(int hl_id)
{
struct hl_group *sgp;
@@ -7286,110 +7328,34 @@ static void highlight_attr_set_all(void)
}
}
-/*
- * Translate the 'highlight' option into attributes in highlight_attr[] and
- * set up the user highlights User1..9. A set of
- * corresponding highlights to use on top of HLF_SNC is computed.
- * Called only when the 'highlight' option has been changed and upon first
- * screen redraw after any :highlight command.
- * Return FAIL when an invalid flag is found in 'highlight'. OK otherwise.
- */
-int highlight_changed(void)
+/// Tranlate highlight groups into attributes in highlight_attr[] and set up
+/// the user highlights User1..9. A set of corresponding highlights to use on
+/// top of HLF_SNC is computed. Called only when nvim starts and upon first
+/// screen redraw after any :highlight command.
+void highlight_changed(void)
{
- int hlf;
- int i;
- char_u *p;
int attr;
- char_u *end;
int id;
char_u userhl[10];
int id_SNC = -1;
int id_S = -1;
int hlcnt;
- static int hl_flags[HLF_COUNT] = HL_FLAGS;
need_highlight_changed = FALSE;
- /*
- * Clear all attributes.
- */
- for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf)
- highlight_attr[hlf] = 0;
-
- /*
- * First set all attributes to their default value.
- * Then use the attributes from the 'highlight' option.
- */
- for (i = 0; i < 2; ++i) {
- if (i)
- p = p_hl;
- else
- p = get_highlight_default();
- if (p == NULL) /* just in case */
- continue;
-
- while (*p) {
- for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf)
- if (hl_flags[hlf] == *p)
- break;
- ++p;
- if (hlf == (int)HLF_COUNT || *p == NUL)
- return FAIL;
-
- /*
- * Allow several hl_flags to be combined, like "bu" for
- * bold-underlined.
- */
- attr = 0;
- bool colon = false;
- for (; *p && *p != ','; ++p) { // parse upto comma
- if (ascii_iswhite(*p)) { // ignore white space
- continue;
- }
-
- if (colon) /* Combination with ':' is not allowed. */
- return FAIL;
-
- switch (*p) {
- case 'b': attr |= HL_BOLD;
- break;
- case 'i': attr |= HL_ITALIC;
- break;
- case '-':
- case 'n': /* no highlighting */
- break;
- case 'r': attr |= HL_INVERSE;
- break;
- case 's': attr |= HL_STANDOUT;
- break;
- case 'u': attr |= HL_UNDERLINE;
- break;
- case 'c': attr |= HL_UNDERCURL;
- break;
- case ':': ++p; /* highlight group name */
- if (attr || *p == NUL) /* no combinations */
- return FAIL;
- colon = true;
- end = vim_strchr(p, ',');
- if (end == NULL)
- end = p + STRLEN(p);
- id = syn_check_group(p, (int)(end - p));
- if (id == 0)
- return FAIL;
- attr = syn_id2attr(id);
- p = end - 1;
- if (hlf == (int)HLF_SNC)
- id_SNC = syn_get_final_id(id);
- else if (hlf == (int)HLF_S)
- id_S = syn_get_final_id(id);
- break;
- default: return FAIL;
- }
- }
- highlight_attr[hlf] = attr;
-
- p = skip_to_option_part(p); /* skip comma and spaces */
+ /// Translate builtin highlight groups into attributes for quick lookup.
+ for (int hlf = 0; hlf < (int)HLF_COUNT; hlf++) {
+ id = syn_check_group((char_u *)hlf_names[hlf], STRLEN(hlf_names[hlf]));
+ if (id == 0) {
+ abort();
+ }
+ attr = syn_id2attr(id);
+ 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);
}
+ highlight_attr[hlf] = attr;
}
/* Setup the user highlights
@@ -7454,49 +7420,47 @@ int highlight_changed(void)
}
}
highlight_ga.ga_len = hlcnt;
-
- return OK;
}
/*
* Handle command line completion for :highlight command.
*/
-void set_context_in_highlight_cmd(expand_T *xp, char_u *arg)
+void set_context_in_highlight_cmd(expand_T *xp, const char *arg)
{
- char_u *p;
-
- /* Default: expand group names */
+ // Default: expand group names.
xp->xp_context = EXPAND_HIGHLIGHT;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
include_link = 2;
include_default = 1;
/* (part of) subcommand already typed */
if (*arg != NUL) {
- p = skiptowhite(arg);
- if (*p != NUL) { /* past "default" or group name */
+ const char *p = (const char *)skiptowhite((const char_u *)arg);
+ if (*p != NUL) { // Past "default" or group name.
include_default = 0;
- if (STRNCMP("default", arg, p - arg) == 0) {
- arg = skipwhite(p);
- xp->xp_pattern = arg;
- p = skiptowhite(arg);
+ if (strncmp("default", arg, p - arg) == 0) {
+ arg = (const char *)skipwhite((const char_u *)p);
+ xp->xp_pattern = (char_u *)arg;
+ p = (const char *)skiptowhite((const char_u *)arg);
}
if (*p != NUL) { /* past group name */
include_link = 0;
- if (arg[1] == 'i' && arg[0] == 'N')
+ if (arg[1] == 'i' && arg[0] == 'N') {
highlight_list();
- if (STRNCMP("link", arg, p - arg) == 0
- || STRNCMP("clear", arg, p - arg) == 0) {
- xp->xp_pattern = skipwhite(p);
- p = skiptowhite(xp->xp_pattern);
- if (*p != NUL) { /* past first group name */
- xp->xp_pattern = skipwhite(p);
- p = skiptowhite(xp->xp_pattern);
+ }
+ if (strncmp("link", arg, p - arg) == 0
+ || strncmp("clear", arg, p - arg) == 0) {
+ xp->xp_pattern = skipwhite((const char_u *)p);
+ p = (const char *)skiptowhite(xp->xp_pattern);
+ if (*p != NUL) { // Past first group name.
+ xp->xp_pattern = skipwhite((const char_u *)p);
+ p = (const char *)skiptowhite(xp->xp_pattern);
}
}
- if (*p != NUL) /* past group name(s) */
+ if (*p != NUL) { // Past group name(s).
xp->xp_context = EXPAND_NOTHING;
+ }
}
}
}
@@ -7517,7 +7481,7 @@ static void highlight_list(void)
static void highlight_list_two(int cnt, int attr)
{
- msg_puts_attr((char_u *)&("N \bI \b! \b"[cnt / 11]), attr);
+ msg_puts_attr(&("N \bI \b! \b"[cnt / 11]), attr);
msg_clr_eos();
ui_flush();
os_delay(cnt == 99 ? 40L : (long)cnt * 50L, false);
@@ -7528,22 +7492,25 @@ static void highlight_list_two(int cnt, int attr)
* Function given to ExpandGeneric() to obtain the list of group names.
* Also used for synIDattr() function.
*/
-char_u *get_highlight_name(expand_T *xp, int idx)
-{
- //TODO: 'xp' is unused
- if (idx == highlight_ga.ga_len && include_none != 0)
- return (char_u *)"none";
- if (idx == highlight_ga.ga_len + include_none && include_default != 0)
- return (char_u *)"default";
- if (idx == highlight_ga.ga_len + include_none + include_default
- && include_link != 0)
- return (char_u *)"link";
- if (idx == highlight_ga.ga_len + include_none + include_default + 1
- && include_link != 0)
- return (char_u *)"clear";
- if (idx < 0 || idx >= highlight_ga.ga_len)
+const char *get_highlight_name(expand_T *const xp, const int idx)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ // TODO(justinmk): 'xp' is unused
+ if (idx == highlight_ga.ga_len && include_none != 0) {
+ return "none";
+ } else if (idx == highlight_ga.ga_len + include_none
+ && include_default != 0) {
+ return "default";
+ } else if (idx == highlight_ga.ga_len + include_none + include_default
+ && include_link != 0) {
+ return "link";
+ } else if (idx == highlight_ga.ga_len + include_none + include_default + 1
+ && include_link != 0) {
+ return "clear";
+ } else if (idx < 0 || idx >= highlight_ga.ga_len) {
return NULL;
- return HL_TABLE()[idx].sg_name;
+ }
+ return (const char *)HL_TABLE()[idx].sg_name;
}
color_name_table_T color_name_table[] = {
@@ -8230,7 +8197,14 @@ color_name_table_T color_name_table[] = {
{ NULL, 0 },
};
-RgbValue name_to_color(uint8_t *name)
+
+/// Translate to RgbValue if \p name is an hex value (e.g. #XXXXXX),
+/// else look into color_name_table to translate a color name to its
+/// hex value
+///
+/// @param[in] name string value to convert to RGB
+/// return the hex value or -1 if could not find a correct value
+RgbValue name_to_color(const uint8_t *name)
{
if (name[0] == '#' && isxdigit(name[1]) && isxdigit(name[2])
diff --git a/src/nvim/syntax.h b/src/nvim/syntax.h
index af2ac719c6..bb733ead30 100644
--- a/src/nvim/syntax.h
+++ b/src/nvim/syntax.h
@@ -4,11 +4,12 @@
#include <stdbool.h>
#include "nvim/buffer_defs.h"
+#include "nvim/ex_cmds_defs.h"
-/*
- * Terminal highlighting attribute bits.
- * Attributes above HL_ALL are used for syntax highlighting.
- */
+/// Terminal highlighting attribute bits.
+/// Attributes above HL_ALL are used for syntax highlighting.
+/// \addtogroup HL_ATTRIBUTES
+/// @{
#define HL_NORMAL 0x00
#define HL_INVERSE 0x01
#define HL_BOLD 0x02
@@ -16,6 +17,7 @@
#define HL_UNDERLINE 0x08
#define HL_UNDERCURL 0x10
#define HL_STANDOUT 0x20
+/// @}
#define HL_CONTAINED 0x01 /* not used on toplevel */
#define HL_TRANSP 0x02 /* has no highlighting */
diff --git a/src/nvim/syntax_defs.h b/src/nvim/syntax_defs.h
index 8d207e6286..56fadbe7f6 100644
--- a/src/nvim/syntax_defs.h
+++ b/src/nvim/syntax_defs.h
@@ -1,10 +1,9 @@
#ifndef NVIM_SYNTAX_DEFS_H
#define NVIM_SYNTAX_DEFS_H
+#include "nvim/highlight_defs.h"
#include "nvim/regexp_defs.h"
-typedef int32_t RgbValue;
-
# 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[]. */
@@ -74,4 +73,14 @@ typedef struct attr_entry {
int cterm_fg_color, cterm_bg_color;
} attrentry_T;
+#define ATTRENTRY_INIT { \
+ .rgb_ae_attr = 0, \
+ .cterm_ae_attr = 0, \
+ .rgb_fg_color = -1, \
+ .rgb_bg_color = -1, \
+ .rgb_sp_color = -1, \
+ .cterm_fg_color = 0, \
+ .cterm_bg_color = 0, \
+}
+
#endif // NVIM_SYNTAX_DEFS_H
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index 0b76e36a6b..be9d621c7d 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* Code to handle tags and the tag stack
*/
@@ -72,23 +75,18 @@ typedef struct {
regmatch_T regmatch; /* regexp program, may be NULL */
} pat_T;
-/*
- * The matching tags are first stored in ga_match[]. In which one depends on
- * the priority of the match.
- * At the end, the matches from ga_match[] are concatenated, to make a list
- * sorted on priority.
- */
-#define MT_ST_CUR 0 /* static match in current file */
-#define MT_GL_CUR 1 /* global match in current file */
-#define MT_GL_OTH 2 /* global match in other file */
-#define MT_ST_OTH 3 /* static match in other file */
-#define MT_IC_ST_CUR 4 /* icase static match in current file */
-#define MT_IC_GL_CUR 5 /* icase global match in current file */
-#define MT_IC_GL_OTH 6 /* icase global match in other file */
-#define MT_IC_ST_OTH 7 /* icase static match in other file */
-#define MT_IC_OFF 4 /* add for icase match */
-#define MT_RE_OFF 8 /* add for regexp match */
-#define MT_MASK 7 /* mask for printing priority */
+// The matching tags are first stored in one of the hash tables. In
+// which one depends on the priority of the match.
+// ht_match[] is used to find duplicates, ga_match[] to keep them in sequence.
+// At the end, the matches from ga_match[] are concatenated, to make a list
+// sorted on priority.
+#define MT_ST_CUR 0 // static match in current file
+#define MT_GL_CUR 1 // global match in current file
+#define MT_GL_OTH 2 // global match in other file
+#define MT_ST_OTH 3 // static match in other file
+#define MT_IC_OFF 4 // add for icase match
+#define MT_RE_OFF 8 // add for regexp match
+#define MT_MASK 7 // mask for printing priority
#define MT_COUNT 16
static char *mt_names[MT_COUNT/2] =
@@ -108,15 +106,6 @@ static char_u *topmsg = (char_u *)N_("E556: at top of tag stack");
static char_u *tagmatchname = NULL; /* name of last used tag */
/*
- * We use ftello() here, if available. It returns off_t instead of long,
- * which helps if long is 32 bit and off_t is 64 bit.
- * We assume that when fseeko() is available then ftello() is too.
- */
-#ifdef HAVE_FSEEKO
-# define ftell ftello
-#endif
-
-/*
* Tag for preview window is remembered separately, to avoid messing up the
* normal tagstack.
*/
@@ -210,10 +199,9 @@ do_tag (
clearpos(&saved_fmark.mark); /* shutup gcc 4.0 */
saved_fmark.fnum = 0;
- /*
- * Don't add a tag to the tagstack if 'tagstack' has been reset.
- */
- if (!p_tgst && *tag != NUL) {
+ // Don't add a tag to the tagstack if 'tagstack' has been reset.
+ assert(tag != NULL);
+ if (!p_tgst && *tag != NUL) { // -V522
use_tagstack = false;
new_tag = true;
if (g_do_tagpreview != 0) {
@@ -540,10 +528,11 @@ do_tag (
}
vim_snprintf((char *)IObuff + 1, IOSIZE - 1, "%2d %s ", i + 1,
mt_names[matches[i][0] & MT_MASK]);
- msg_puts(IObuff);
- if (tagp.tagkind != NULL)
+ msg_puts((const char *)IObuff);
+ if (tagp.tagkind != NULL) {
msg_outtrans_len(tagp.tagkind,
- (int)(tagp.tagkind_end - tagp.tagkind));
+ (int)(tagp.tagkind_end - tagp.tagkind));
+ }
msg_advance(13);
msg_outtrans_len_attr(tagp.tagname,
(int)(tagp.tagname_end - tagp.tagname),
@@ -595,7 +584,7 @@ do_tag (
}
p = msg_outtrans_one(p, attr);
if (*p == TAB) {
- msg_puts_attr((char_u *)" ", attr);
+ msg_puts_attr(" ", attr);
break;
}
if (*p == ':')
@@ -678,7 +667,7 @@ do_tag (
fname = xmalloc(MAXPATHL + 1);
cmd = xmalloc(CMDBUFFSIZE + 1);
- list = list_alloc();
+ list = tv_list_alloc();
for (i = 0; i < num_matches; ++i) {
int len, cmd_len;
@@ -777,20 +766,21 @@ do_tag (
cmd[len] = NUL;
}
- dict = dict_alloc();
- list_append_dict(list, dict);
+ dict = tv_dict_alloc();
+ tv_list_append_dict(list, dict);
- dict_add_nr_str(dict, "text", 0L, tag_name);
- dict_add_nr_str(dict, "filename", 0L, fname);
- dict_add_nr_str(dict, "lnum", lnum, NULL);
- if (lnum == 0)
- dict_add_nr_str(dict, "pattern", 0L, cmd);
+ tv_dict_add_str(dict, S_LEN("text"), (const char *)tag_name);
+ tv_dict_add_str(dict, S_LEN("filename"), (const char *)fname);
+ tv_dict_add_nr(dict, S_LEN("lnum"), lnum);
+ if (lnum == 0) {
+ tv_dict_add_str(dict, S_LEN("pattern"), (const char *)cmd);
+ }
}
vim_snprintf((char *)IObuff, IOSIZE, "ltag %s", tag);
- set_errorlist(curwin, list, ' ', IObuff);
+ set_errorlist(curwin, list, ' ', IObuff, NULL);
- list_free(list);
+ tv_list_free(list);
xfree(fname);
xfree(cmd);
@@ -858,13 +848,15 @@ do_tag (
STRCAT(IObuff, _(" Using tag with different case!"));
if ((num_matches > prev_num_matches || new_tag)
&& num_matches > 1) {
- if (ic)
- msg_attr(IObuff, hl_attr(HLF_W));
- else
+ if (ic) {
+ msg_attr((const char *)IObuff, hl_attr(HLF_W));
+ } else {
msg(IObuff);
- msg_scroll = TRUE; /* don't overwrite this message */
- } else
+ }
+ msg_scroll = true; // Don't overwrite this message.
+ } else {
give_warning(IObuff, ic);
+ }
if (ic && !msg_scrolled && msg_silent == 0) {
ui_flush();
os_delay(1000L, true);
@@ -916,7 +908,8 @@ end_do_tag:
/* Only store the new index when using the tagstack and it's valid. */
if (use_tagstack && tagstackidx <= curwin->w_tagstacklen)
curwin->w_tagstackidx = tagstackidx;
- postponed_split = 0; /* don't split next time */
+ postponed_split = 0; // don't split next time
+ g_do_tagpreview = 0; // don't do tag preview next time
return jumped_to_tag;
}
@@ -1057,6 +1050,7 @@ static void prepare_pats(pat_T *pats, int has_re)
* TAG_REGEXP use "pat" as a regexp
* TAG_NOIC don't always ignore case
* TAG_KEEP_LANG keep language
+ * TAG_CSCOPE use cscope results for tags
*/
int
find_tags (
@@ -1085,22 +1079,21 @@ find_tags (
char_u *p;
char_u *s;
int i;
- int tag_file_sorted = NUL; /* !_TAG_FILE_SORTED value */
- struct tag_search_info /* Binary search file offsets */
- {
- off_t low_offset; /* offset for first char of first line that
- could match */
- off_t high_offset; /* offset of char after last line that could
- match */
- off_t curr_offset; /* Current file offset in search range */
- off_t curr_offset_used; /* curr_offset used when skipping back */
- off_t match_offset; /* Where the binary search found a tag */
- int low_char; /* first char at low_offset */
- int high_char; /* first char at high_offset */
+ int tag_file_sorted = NUL; // !_TAG_FILE_SORTED value
+ struct tag_search_info { // Binary search file offsets
+ off_T low_offset; // offset for first char of first line that
+ // could match
+ off_T high_offset; // offset of char after last line that could
+ // match
+ off_T curr_offset; // Current file offset in search range
+ off_T curr_offset_used; // curr_offset used when skipping back
+ off_T match_offset; // Where the binary search found a tag
+ int low_char; // first char at low_offset
+ int high_char; // first char at high_offset
} search_info;
- off_t filesize;
+ off_T filesize;
int tagcmp;
- off_t offset;
+ off_T offset;
int round;
enum {
TS_START, /* at start of file */
@@ -1118,19 +1111,19 @@ find_tags (
int save_emsg_off;
- struct match_found {
- int len; /* nr of chars of match[] to be compared */
- char_u match[1]; /* actually longer */
- } *mfp, *mfp2;
- garray_T ga_match[MT_COUNT];
- int match_count = 0; /* number of matches found */
+ char_u *mfp;
+ garray_T ga_match[MT_COUNT]; // stores matches in sequence
+ hashtab_T ht_match[MT_COUNT]; // stores matches by key
+ hash_T hash = 0;
+ int match_count = 0; // number of matches found
char_u **matches;
int mtt;
int help_save;
int help_pri = 0;
- char_u *help_lang_find = NULL; /* lang to be found */
- char_u help_lang[3]; /* lang of current tags file */
- char_u *saved_pat = NULL; /* copy of pat[] */
+ char_u *help_lang_find = NULL; // lang to be found
+ char_u help_lang[3]; // lang of current tags file
+ char_u *saved_pat = NULL; // copy of pat[]
+ bool is_txt = false;
pat_T orgpat; /* holds unconverted pattern info */
vimconv_T vimconv;
@@ -1161,6 +1154,12 @@ find_tags (
case TC_MATCH:
p_ic = false;
break;
+ case TC_FOLLOWSCS:
+ p_ic = ignorecase(pat);
+ break;
+ case TC_SMART:
+ p_ic = ignorecase_opt(pat, true, true);
+ break;
default:
assert(false);
}
@@ -1174,16 +1173,23 @@ find_tags (
*/
lbuf = xmalloc(lbuf_size);
tag_fname = xmalloc(MAXPATHL + 1);
- for (mtt = 0; mtt < MT_COUNT; ++mtt)
- ga_init(&ga_match[mtt], (int)sizeof(struct match_found *), 100);
+ for (mtt = 0; mtt < MT_COUNT; mtt++) {
+ ga_init(&ga_match[mtt], sizeof(char_u *), 100);
+ hash_init(&ht_match[mtt]);
+ }
STRCPY(tag_fname, "from cscope"); /* for error messages */
/*
* Initialize a few variables
*/
- if (help_only) /* want tags from help file */
- curbuf->b_help = true; /* will be restored later */
+ if (help_only) { // want tags from help file
+ curbuf->b_help = true; // will be restored later
+ } else if (use_cscope) {
+ // Make sure we don't mix help and cscope, confuses Coverity.
+ help_only = false;
+ curbuf->b_help = false;
+ }
orgpat.len = (int)STRLEN(pat);
if (curbuf->b_help) {
@@ -1208,9 +1214,9 @@ find_tags (
if (has_re && orgpat.regmatch.regprog == NULL)
goto findtag_end;
- /* This is only to avoid a compiler warning for using search_info
- * uninitialised. */
- memset(&search_info, 0, (size_t)1);
+ // This is only to avoid a compiler warning for using search_info
+ // uninitialised.
+ memset(&search_info, 0, 1); // -V512
/*
* When finding a specified number of matches, first try with matching
@@ -1222,6 +1228,14 @@ find_tags (
* When the tag file is case-fold sorted, it is either one or the other.
* Only ignore case when TAG_NOIC not used or 'ignorecase' set.
*/
+ // Set a flag if the file extension is .txt
+ if ((flags & TAG_KEEP_LANG)
+ && help_lang_find == NULL
+ && curbuf->b_fname != NULL
+ && (i = (int)STRLEN(curbuf->b_fname)) > 4
+ && STRICMP(curbuf->b_fname + i - 4, ".txt") == 0) {
+ is_txt = true;
+ }
orgpat.regmatch.rm_ic = ((p_ic || !noic)
&& (findall || orgpat.headlen == 0 || !p_tbs));
for (round = 1; round <= 2; ++round) {
@@ -1237,13 +1251,19 @@ find_tags (
fp = NULL; // avoid GCC warning
} else {
if (curbuf->b_help) {
- /* Prefer help tags according to 'helplang'. Put the
- * two-letter language name in help_lang[]. */
- i = (int)STRLEN(tag_fname);
- if (i > 3 && tag_fname[i - 3] == '-')
- STRCPY(help_lang, tag_fname + i - 2);
- else
+ // Keep en if the file extension is .txt
+ if (is_txt) {
STRCPY(help_lang, "en");
+ } else {
+ // Prefer help tags according to 'helplang'. Put the
+ // two-letter language name in help_lang[].
+ i = (int)STRLEN(tag_fname);
+ if (i > 3 && tag_fname[i - 3] == '-') {
+ STRCPY(help_lang, tag_fname + i - 2);
+ } else {
+ STRCPY(help_lang, "en");
+ }
+ }
/* When searching for a specific language skip tags files
* for other languages. */
@@ -1348,36 +1368,28 @@ find_tags (
if (state == TS_BINARY || state == TS_SKIP_BACK) {
/* Adjust the search file offset to the correct position */
search_info.curr_offset_used = search_info.curr_offset;
-#ifdef HAVE_FSEEKO
- fseeko(fp, search_info.curr_offset, SEEK_SET);
-#else
- fseek(fp, (long)search_info.curr_offset, SEEK_SET);
-#endif
+ vim_fseek(fp, search_info.curr_offset, SEEK_SET);
eof = vim_fgets(lbuf, LSIZE, fp);
if (!eof && search_info.curr_offset != 0) {
/* The explicit cast is to work around a bug in gcc 3.4.2
* (repeated below). */
- search_info.curr_offset = ftell(fp);
+ search_info.curr_offset = vim_ftell(fp);
if (search_info.curr_offset == search_info.high_offset) {
- /* oops, gone a bit too far; try from low offset */
-#ifdef HAVE_FSEEKO
- fseeko(fp, search_info.low_offset, SEEK_SET);
-#else
- fseek(fp, (long)search_info.low_offset, SEEK_SET);
-#endif
+ // oops, gone a bit too far; try from low offset
+ vim_fseek(fp, search_info.low_offset, SEEK_SET);
search_info.curr_offset = search_info.low_offset;
}
eof = vim_fgets(lbuf, LSIZE, fp);
}
/* skip empty and blank lines */
while (!eof && vim_isblankline(lbuf)) {
- search_info.curr_offset = ftell(fp);
+ search_info.curr_offset = vim_ftell(fp);
eof = vim_fgets(lbuf, LSIZE, fp);
}
if (eof) {
/* Hit end of file. Skip backwards. */
state = TS_SKIP_BACK;
- search_info.match_offset = ftell(fp);
+ search_info.match_offset = vim_ftell(fp);
search_info.curr_offset = search_info.curr_offset_used;
continue;
}
@@ -1493,10 +1505,10 @@ line_read_in:
*/
if (state == TS_BINARY) {
// Get the tag file size.
- if ((filesize = lseek(fileno(fp), (off_t)0L, SEEK_END)) <= 0) {
+ if ((filesize = vim_lseek(fileno(fp), (off_T)0L, SEEK_END)) <= 0) {
state = TS_LINEAR;
} else {
- lseek(fileno(fp), (off_t)0L, SEEK_SET);
+ vim_lseek(fileno(fp), (off_T)0L, SEEK_SET);
/* Calculate the first read offset in the file. Start
* the search in the middle of the file. */
@@ -1534,11 +1546,7 @@ parse_line:
/* Avoid getting stuck. */
linear = TRUE;
state = TS_LINEAR;
-# ifdef HAVE_FSEEKO
- fseeko(fp, search_info.low_offset, SEEK_SET);
-# else
- fseek(fp, (long)search_info.low_offset, SEEK_SET);
-# endif
+ vim_fseek(fp, search_info.low_offset, SEEK_SET);
}
continue;
}
@@ -1617,7 +1625,7 @@ parse_line:
continue;
}
if (tagcmp < 0) {
- search_info.curr_offset = ftell(fp);
+ search_info.curr_offset = vim_ftell(fp);
if (search_info.curr_offset < search_info.high_offset) {
search_info.low_offset = search_info.curr_offset;
if (sortic)
@@ -1653,10 +1661,11 @@ parse_line:
} else if (state == TS_STEP_FORWARD) {
assert(cmplen >= 0);
if (mb_strnicmp(tagp.tagname, orgpat.head, (size_t)cmplen) != 0) {
- if ((off_t)ftell(fp) > search_info.match_offset)
- break; /* past last match */
- else
- continue; /* before first match */
+ if ((off_T)vim_ftell(fp) > search_info.match_offset) {
+ break; // past last match
+ } else {
+ continue; // before first match
+ }
}
} else
/* skip this match if it can't match */
@@ -1727,10 +1736,10 @@ parse_line:
match_re = TRUE;
}
- /*
- * If a match is found, add it to ga_match[].
- */
+ // If a match is found, add it to ht_match[] and ga_match[].
if (match) {
+ int len = 0;
+
if (use_cscope) {
/* Don't change the ordering, always use the same table. */
mtt = MT_GL_OTH;
@@ -1765,116 +1774,109 @@ parse_line:
mtt += MT_RE_OFF;
}
- /*
- * Add the found match in ga_match[mtt], avoiding duplicates.
- * Store the info we need later, which depends on the kind of
- * tags we are dealing with.
- */
- ga_grow(&ga_match[mtt], 1);
- {
- int len;
-
- if (help_only) {
+ // Add the found match in ht_match[mtt] and ga_match[mtt].
+ // Store the info we need later, which depends on the kind of
+ // tags we are dealing with.
+ if (help_only) {
# define ML_EXTRA 3
- /*
- * Append the help-heuristic number after the
- * tagname, for sorting it later.
- */
- *tagp.tagname_end = NUL;
- len = (int)(tagp.tagname_end - tagp.tagname);
- mfp = xmalloc(sizeof(struct match_found) + len + 10 + ML_EXTRA);
- /* "len" includes the language and the NUL, but
- * not the priority. */
- mfp->len = len + ML_EXTRA + 1;
-#define ML_HELP_LEN 6
- p = mfp->match;
- STRCPY(p, tagp.tagname);
- p[len] = '@';
- STRCPY(p + len + 1, help_lang);
- sprintf((char *)p + len + 1 + ML_EXTRA, "%06d",
- help_heuristic(tagp.tagname,
- match_re ? matchoff : 0, !match_no_ic)
- + help_pri
- );
-
- *tagp.tagname_end = TAB;
- } else if (name_only) {
- if (get_it_again) {
- char_u *temp_end = tagp.command;
-
- if (*temp_end == '/')
- while (*temp_end && *temp_end != '\r'
- && *temp_end != '\n'
- && *temp_end != '$')
- temp_end++;
-
- if (tagp.command + 2 < temp_end) {
- len = (int)(temp_end - tagp.command - 2);
- mfp = xmalloc(sizeof(struct match_found) + len);
- mfp->len = len + 1; /* include the NUL */
- p = mfp->match;
- STRLCPY(p, tagp.command + 2, len + 1);
- } else
- mfp = NULL;
- get_it_again = FALSE;
+ // Append the help-heuristic number after the tagname, for
+ // sorting it later. The heuristic is ignored for
+ // detecting duplicates.
+ // The format is {tagname}@{lang}NUL{heuristic}NUL
+ *tagp.tagname_end = NUL;
+ len = (int)(tagp.tagname_end - tagp.tagname);
+ mfp = xmalloc(sizeof(char_u) + len + 10 + ML_EXTRA + 1);
+
+ p = mfp;
+ STRCPY(p, tagp.tagname);
+ p[len] = '@';
+ STRCPY(p + len + 1, help_lang);
+ snprintf((char *)p + len + 1 + ML_EXTRA, 10, "%06d",
+ help_heuristic(tagp.tagname,
+ match_re ? matchoff : 0, !match_no_ic)
+ + help_pri);
+
+ *tagp.tagname_end = TAB;
+ } else if (name_only) {
+ if (get_it_again) {
+ char_u *temp_end = tagp.command;
+
+ if (*temp_end == '/') {
+ while (*temp_end && *temp_end != '\r'
+ && *temp_end != '\n'
+ && *temp_end != '$') {
+ temp_end++;
+ }
+ }
+
+ if (tagp.command + 2 < temp_end) {
+ len = (int)(temp_end - tagp.command - 2);
+ mfp = xmalloc(len + 2);
+ STRLCPY(mfp, tagp.command + 2, len + 1);
} else {
- len = (int)(tagp.tagname_end - tagp.tagname);
- mfp = xmalloc(sizeof(struct match_found) + len);
- mfp->len = len + 1; /* include the NUL */
- p = mfp->match;
- STRLCPY(p, tagp.tagname, len + 1);
-
- /* if wanted, re-read line to get long form too */
- if (State & INSERT)
- get_it_again = p_sft;
+ mfp = NULL;
}
+ get_it_again = false;
} else {
- /* Save the tag in a buffer.
- * Emacs tag: <mtt><tag_fname><NUL><ebuf><NUL><lbuf>
- * other tag: <mtt><tag_fname><NUL><NUL><lbuf>
- * without Emacs tags: <mtt><tag_fname><NUL><lbuf>
- */
- len = (int)STRLEN(tag_fname)
- + (int)STRLEN(lbuf) + 3;
- mfp = xmalloc(sizeof(struct match_found) + len);
- mfp->len = len;
- p = mfp->match;
- p[0] = mtt;
- STRCPY(p + 1, tag_fname);
+ len = (int)(tagp.tagname_end - tagp.tagname);
+ mfp = xmalloc(sizeof(char_u) + len + 1);
+ STRLCPY(mfp, tagp.tagname, len + 1);
+
+ // if wanted, re-read line to get long form too
+ if (State & INSERT) {
+ get_it_again = p_sft;
+ }
+ }
+ } else {
+#define TAG_SEP 0x02
+ size_t tag_fname_len = STRLEN(tag_fname);
+ // Save the tag in a buffer.
+ // Use 0x02 to separate fields (Can't use NUL, because the
+ // hash key is terminated by NUL).
+ // Emacs tag: <mtt><tag_fname><0x02><ebuf><0x02><lbuf><NUL>
+ // other tag: <mtt><tag_fname><0x02><0x02><lbuf><NUL>
+ // without Emacs tags: <mtt><tag_fname><0x02><lbuf><NUL>
+ // Here <mtt> is the "mtt" value plus 1 to avoid NUL.
+ len = (int)tag_fname_len + (int)STRLEN(lbuf) + 3;
+ mfp = xmalloc(sizeof(char_u) + len + 1);
+ p = mfp;
+ p[0] = mtt + 1;
+ STRCPY(p + 1, tag_fname);
#ifdef BACKSLASH_IN_FILENAME
- /* Ignore differences in slashes, avoid adding
- * both path/file and path\file. */
- slash_adjust(p + 1);
+ // Ignore differences in slashes, avoid adding
+ // both path/file and path\file.
+ slash_adjust(p + 1);
#endif
- s = p + 1 + STRLEN(tag_fname) + 1;
- STRCPY(s, lbuf);
- }
+ p[tag_fname_len + 1] = TAG_SEP;
+ s = p + 1 + tag_fname_len + 1;
+ STRCPY(s, lbuf);
+ }
- if (mfp != NULL) {
- /*
- * Don't add identical matches.
- * This can take a lot of time when finding many
- * matches, check for CTRL-C now and then.
- * Add all cscope tags, because they are all listed.
- */
- if (use_cscope)
- i = -1;
- else
- for (i = ga_match[mtt].ga_len; --i >= 0 && !got_int; ) {
- mfp2 = ((struct match_found **)
- (ga_match[mtt].ga_data))[i];
- if (mfp2->len == mfp->len
- && memcmp(mfp2->match, mfp->match,
- (size_t)mfp->len) == 0)
- break;
- fast_breakcheck();
- }
- if (i < 0) {
- ((struct match_found **)(ga_match[mtt].ga_data))
+ if (mfp != NULL) {
+ hashitem_T *hi;
+
+ // Don't add identical matches.
+ // Add all cscope tags, because they are all listed.
+ // "mfp" is used as a hash key, there is a NUL byte to end
+ // the part matters for comparing, more bytes may follow
+ // after it. E.g. help tags store the priority after the
+ // NUL.
+ if (use_cscope) {
+ hash++;
+ } else {
+ hash = hash_hash(mfp);
+ }
+ hi = hash_lookup(&ht_match[mtt], (const char *)mfp,
+ STRLEN(mfp), hash);
+ if (HASHITEM_EMPTY(hi)) {
+ hash_add_item(&ht_match[mtt], hi, mfp, hash);
+ ga_grow(&ga_match[mtt], 1);
+ ((char_u **)(ga_match[mtt].ga_data))
[ga_match[mtt].ga_len++] = mfp;
- ++match_count;
- } else
- xfree(mfp);
+ match_count++;
+ } else {
+ // duplicate tag, drop it
+ xfree(mfp);
}
}
}
@@ -1884,10 +1886,11 @@ parse_line:
if (line_error) {
EMSG2(_("E431: Format error in tags file \"%s\""), tag_fname);
- if (!use_cscope)
- EMSGN(_("Before byte %" PRId64), ftell(fp));
- stop_searching = TRUE;
- line_error = FALSE;
+ if (!use_cscope) {
+ EMSGN(_("Before byte %" PRId64), vim_ftell(fp));
+ }
+ stop_searching = true;
+ line_error = false;
}
if (!use_cscope)
@@ -1949,21 +1952,29 @@ findtag_end:
else
matches = NULL;
match_count = 0;
- for (mtt = 0; mtt < MT_COUNT; ++mtt) {
- for (int i = 0; i < ga_match[mtt].ga_len; ++i) {
- mfp = ((struct match_found **)(ga_match[mtt].ga_data))[i];
- if (matches == NULL)
+ for (mtt = 0; mtt < MT_COUNT; mtt++) {
+ for (i = 0; i < ga_match[mtt].ga_len; i++) {
+ mfp = ((char_u **)(ga_match[mtt].ga_data))[i];
+ if (matches == NULL) {
xfree(mfp);
- else {
- /* To avoid allocating memory again we turn the struct
- * match_found into a string. For help the priority was not
- * included in the length. */
- memmove(mfp, mfp->match,
- (size_t)(mfp->len + (help_only ? ML_HELP_LEN : 0)));
+ } else {
+ if (!name_only) {
+ // Change mtt back to zero-based.
+ *mfp = *mfp - 1;
+
+ // change the TAG_SEP back to NUL
+ for (p = mfp + 1; *p != NUL; p++) {
+ if (*p == TAG_SEP) {
+ *p = NUL;
+ }
+ }
+ }
matches[match_count++] = (char_u *)mfp;
}
}
+
ga_clear(&ga_match[mtt]);
+ hash_clear(&ht_match[mtt]);
}
*matchesp = matches;
@@ -2175,7 +2186,7 @@ parse_tag_line (
* Return TRUE if it is a static tag and adjust *tagname to the real tag.
* Return FALSE if it is not a static tag.
*/
-static int test_for_static(tagptrs_T *tagp)
+static bool test_for_static(tagptrs_T *tagp)
{
char_u *p;
@@ -2505,7 +2516,7 @@ jumpto_tag (
}
}
p_ws = save_p_ws;
- p_ic = save_p_ic;
+ p_ic = save_p_ic; // -V519
p_scs = save_p_scs;
/* A search command may have positioned the cursor beyond the end
@@ -2740,8 +2751,8 @@ add_tag_field (
int len = 0;
int retval;
- /* check that the field name doesn't exist yet */
- if (dict_find(dict, (char_u *)field_name, -1) != NULL) {
+ // Check that the field name doesn't exist yet.
+ if (tv_dict_find(dict, field_name, -1) != NULL) {
if (p_verbose > 0) {
verbose_enter();
smsg(_("Duplicate field name: %s"), field_name);
@@ -2762,26 +2773,25 @@ add_tag_field (
STRLCPY(buf, start, len + 1);
}
buf[len] = NUL;
- retval = dict_add_nr_str(dict, field_name, 0L, buf);
+ retval = tv_dict_add_str(dict, field_name, STRLEN(field_name),
+ (const char *)buf);
xfree(buf);
return retval;
}
-/*
- * Add the tags matching the specified pattern to the list "list"
- * as a dictionary
- */
-int get_tags(list_T *list, char_u *pat)
+/// Add the tags matching the specified pattern "pat" to the list "list"
+/// as a dictionary. Use "buf_fname" for priority, unless NULL.
+int get_tags(list_T *list, char_u *pat, char_u *buf_fname)
{
int num_matches, i, ret;
char_u **matches, *p;
char_u *full_fname;
dict_T *dict;
tagptrs_T tp;
- long is_static;
+ bool is_static;
ret = find_tags(pat, &num_matches, &matches,
- TAG_REGEXP | TAG_NOIC, (int)MAXCOL, NULL);
+ TAG_REGEXP | TAG_NOIC, (int)MAXCOL, buf_fname);
if (ret == OK && num_matches > 0) {
for (i = 0; i < num_matches; ++i) {
int parse_result = parse_match(matches[i], &tp);
@@ -2796,19 +2806,18 @@ int get_tags(list_T *list, char_u *pat)
if (STRNCMP(tp.tagname, "!_TAG_", 6) == 0)
continue;
- dict = dict_alloc();
- list_append_dict(list, dict);
+ dict = tv_dict_alloc();
+ tv_list_append_dict(list, dict);
full_fname = tag_full_fname(&tp);
if (add_tag_field(dict, "name", tp.tagname, tp.tagname_end) == FAIL
- || add_tag_field(dict, "filename", full_fname,
- NULL) == FAIL
- || add_tag_field(dict, "cmd", tp.command,
- tp.command_end) == FAIL
+ || add_tag_field(dict, "filename", full_fname, NULL) == FAIL
+ || add_tag_field(dict, "cmd", tp.command, tp.command_end) == FAIL
|| add_tag_field(dict, "kind", tp.tagkind,
- tp.tagkind ? tp.tagkind_end : NULL) == FAIL
- || dict_add_nr_str(dict, "static", is_static, NULL) == FAIL)
+ tp.tagkind ? tp.tagkind_end : NULL) == FAIL
+ || tv_dict_add_nr(dict, S_LEN("static"), is_static) == FAIL) {
ret = FAIL;
+ }
xfree(full_fname);
diff --git a/src/nvim/tag.h b/src/nvim/tag.h
index 5d4bcddf94..a8fddd05da 100644
--- a/src/nvim/tag.h
+++ b/src/nvim/tag.h
@@ -1,6 +1,9 @@
#ifndef NVIM_TAG_H
#define NVIM_TAG_H
+#include "nvim/types.h"
+#include "nvim/ex_cmds_defs.h"
+
/*
* Values for do_tag().
*/
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index 30556a3835..3b278dc666 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -1,18 +1,20 @@
-// VT220/xterm-like terminal emulator implementation for nvim. Powered by
-// libvterm (http://www.leonerd.org.uk/code/libvterm/).
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+// VT220/xterm-like terminal emulator.
+// Powered by libvterm http://www.leonerd.org.uk/code/libvterm
//
// libvterm is a pure C99 terminal emulation library with abstract input and
// display. This means that the library needs to read data from the master fd
// and feed VTerm instances, which will invoke user callbacks with screen
// update instructions that must be mirrored to the real display.
//
-// Keys are pressed in VTerm instances by calling
+// Keys are sent to VTerm instances by calling
// vterm_keyboard_key/vterm_keyboard_unichar, which generates byte streams that
// must be fed back to the master fd.
//
-// This implementation uses nvim buffers as the display mechanism for both
-// the visible screen and the scrollback buffer. When focused, the window
-// "pins" to the bottom of the buffer and mirrors libvterm screen state.
+// Nvim buffers are used as the display mechanism for both the visible screen
+// and the scrollback buffer.
//
// When a line becomes invisible due to a decrease in screen height or because
// a line was pushed up during normal terminal output, we store the line
@@ -23,18 +25,17 @@
// scrollback buffer, which is mirrored in the nvim buffer displaying lines
// that were previously invisible.
//
-// The vterm->nvim synchronization is performed in intervals of 10
-// milliseconds. This is done to minimize screen updates when receiving large
-// bursts of data.
+// The vterm->nvim synchronization is performed in intervals of 10 milliseconds,
+// to minimize screen updates when receiving large bursts of data.
//
// This module is decoupled from the processes that normally feed it data, so
// it's possible to use it as a general purpose console buffer (possibly as a
// log/display mechanism for nvim in the future)
//
-// Inspired by vimshell (http://www.wana.at/vimshell/) and
-// Conque (https://code.google.com/p/conque/). Libvterm usage instructions (plus
-// some extra code) were taken from
-// pangoterm (http://www.leonerd.org.uk/code/pangoterm/)
+// Inspired by: vimshell http://www.wana.at/vimshell
+// Conque https://code.google.com/p/conque
+// Some code from pangoterm http://www.leonerd.org.uk/code/pangoterm
+
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
@@ -42,6 +43,7 @@
#include <vterm.h>
+#include "nvim/log.h"
#include "nvim/vim.h"
#include "nvim/terminal.h"
#include "nvim/message.h"
@@ -80,17 +82,15 @@ typedef struct terminal_state {
Terminal *term;
int save_rd; // saved value of RedrawingDisabled
bool close;
- bool got_bs; // if the last input was <C-\>
+ bool got_bsl; // if the last input was <C-\>
} TerminalState;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "terminal.c.generated.h"
#endif
-#define SCROLLBACK_BUFFER_DEFAULT_SIZE 1000
// Delay for refreshing the terminal buffer after receiving updates from
-// libvterm. This is greatly improves performance when receiving large bursts
-// of data.
+// libvterm. Improves performance when receiving large bursts of data.
#define REFRESH_DELAY 10
static TimeWatcher refresh_timer;
@@ -102,27 +102,23 @@ typedef struct {
} ScrollbackLine;
struct terminal {
- // options passed to terminal_open
- TerminalOptions opts;
- // libvterm structures
+ TerminalOptions opts; // options passed to terminal_open
VTerm *vt;
VTermScreen *vts;
// buffer used to:
// - convert VTermScreen cell arrays into utf8 strings
// - receive data from libvterm as a result of key presses.
char textbuf[0x1fff];
- // Scrollback buffer storage for libvterm.
- // TODO(tarruda): Use a doubly-linked list
- ScrollbackLine **sb_buffer;
- // number of rows pushed to sb_buffer
- size_t sb_current;
- // sb_buffer size;
- size_t sb_size;
+
+ ScrollbackLine **sb_buffer; // Scrollback buffer storage for libvterm
+ size_t sb_current; // number of rows pushed to sb_buffer
+ size_t sb_size; // sb_buffer size
// "virtual index" that points to the first sb_buffer row that we need to
// push to the terminal buffer when refreshing the scrollback. When negative,
// it actually points to entries that are no longer in sb_buffer (because the
// window height has increased) and must be deleted from the terminal buffer
int sb_pending;
+
// buf_T instance that acts as a "drawing surface" for libvterm
// we can't store a direct reference to the buffer because the
// refresh_timer_cb may be called after the buffer was freed, and there's
@@ -130,20 +126,18 @@ struct terminal {
handle_T buf_handle;
// program exited
bool closed, destroy;
+
// some vterm properties
bool forward_mouse;
- // invalid rows libvterm screen
- int invalid_start, invalid_end;
+ int invalid_start, invalid_end; // invalid rows in libvterm screen
struct {
int row, col;
bool visible;
} cursor;
- // which mouse button is pressed
- int pressed_button;
- // pending width/height
- bool pending_resize;
- // With a reference count of 0 the terminal can be freed.
- size_t refcount;
+ int pressed_button; // which mouse button is pressed
+ bool pending_resize; // pending width/height
+
+ size_t refcount; // reference count
};
static VTermScreenCallbacks vterm_screen_callbacks = {
@@ -174,7 +168,7 @@ void terminal_init(void)
VTerm *vt = vterm_new(24, 80);
VTermState *state = vterm_obtain_state(vt);
- for (int color_index = 0; color_index < 256; color_index++) {
+ for (int color_index = 255; color_index >= 0; color_index--) {
VTermColor color;
// Some of the default 16 colors has the same color as the later
// 240 colors. To avoid collisions, we will use the custom colors
@@ -236,26 +230,26 @@ Terminal *terminal_open(TerminalOptions opts)
rv->invalid_start = 0;
rv->invalid_end = opts.height;
refresh_screen(rv, curbuf);
- set_option_value((uint8_t *)"buftype", 0, (uint8_t *)"terminal", OPT_LOCAL);
- // some sane settings for terminal buffers
- set_option_value((uint8_t *)"wrap", false, NULL, OPT_LOCAL);
- set_option_value((uint8_t *)"number", false, NULL, OPT_LOCAL);
- set_option_value((uint8_t *)"relativenumber", false, NULL, OPT_LOCAL);
+ set_option_value("buftype", 0, "terminal", OPT_LOCAL); // -V666
+
+ // Default settings for terminal buffers
+ curbuf->b_p_ma = false; // 'nomodifiable'
+ curbuf->b_p_ul = -1; // 'undolevels'
+ curbuf->b_p_scbk = p_scbk; // 'scrollback'
+ curbuf->b_p_tw = 0; // 'textwidth'
+ set_option_value("wrap", false, NULL, OPT_LOCAL);
+ set_option_value("list", false, NULL, OPT_LOCAL);
buf_set_term_title(curbuf, (char *)curbuf->b_ffname);
RESET_BINDING(curwin);
- // Apply TermOpen autocmds so the user can configure the terminal
+ // Reset cursor in current window.
+ curwin->w_cursor = (pos_T){ .lnum = 1, .col = 0, .coladd = 0 };
+
+ // Apply TermOpen autocmds _before_ configuring the scrollback buffer.
apply_autocmds(EVENT_TERMOPEN, NULL, NULL, false, curbuf);
- // Configure the scrollback buffer. Try to get the size from:
- //
- // - b:terminal_scrollback_buffer_size
- // - g:terminal_scrollback_buffer_size
- // - SCROLLBACK_BUFFER_DEFAULT_SIZE
- //
- // but limit to 100k.
- int size = get_config_int("terminal_scrollback_buffer_size");
- rv->sb_size = size > 0 ? (size_t)size : SCROLLBACK_BUFFER_DEFAULT_SIZE;
- rv->sb_size = MIN(rv->sb_size, 100000);
+ // Configure the scrollback buffer.
+ rv->sb_size = curbuf->b_p_scbk < 0
+ ? SB_MAX : (size_t)MAX(1, curbuf->b_p_scbk);
rv->sb_buffer = xmalloc(sizeof(ScrollbackLine *) * rv->sb_size);
if (!true_color) {
@@ -307,8 +301,16 @@ void terminal_close(Terminal *term, char *msg)
}
term->forward_mouse = false;
- term->closed = true;
+
+ // flush any pending changes to the buffer
+ if (!exiting) {
+ block_autocmds();
+ refresh_terminal(term);
+ unblock_autocmds();
+ }
+
buf_T *buf = handle_get_buffer(term->buf_handle);
+ term->closed = true;
if (!msg || exiting) {
// If no msg was given, this was called by close_buffer(buffer.c). Or if
@@ -334,22 +336,22 @@ void terminal_close(Terminal *term, char *msg)
void terminal_resize(Terminal *term, uint16_t width, uint16_t height)
{
if (term->closed) {
- // will be called after exited if two windows display the same terminal and
- // one of the is closed as a consequence of pressing a key.
+ // If two windows display the same terminal and one is closed by keypress.
return;
}
+ bool force = width == UINT16_MAX || height == UINT16_MAX;
int curwidth, curheight;
vterm_get_size(term->vt, &curheight, &curwidth);
- if (!width) {
+ if (force || !width) {
width = (uint16_t)curwidth;
}
- if (!height) {
+ if (force || !height) {
height = (uint16_t)curheight;
}
- if (curheight == height && curwidth == width) {
+ if (!force && curheight == height && curwidth == width) {
return;
}
@@ -381,8 +383,18 @@ void terminal_enter(void)
State = TERM_FOCUS;
mapped_ctrl_c |= TERM_FOCUS; // Always map CTRL-C to avoid interrupt.
RedrawingDisabled = false;
- // go to the bottom when the terminal is focused
- adjust_topline(s->term, buf, false);
+
+ // Disable these options in terminal-mode. They are nonsense because cursor is
+ // placed at end of buffer to "follow" output.
+ win_T *save_curwin = curwin;
+ int save_w_p_cul = curwin->w_p_cul;
+ int save_w_p_cuc = curwin->w_p_cuc;
+ int save_w_p_rnu = curwin->w_p_rnu;
+ curwin->w_p_cul = false;
+ curwin->w_p_cuc = false;
+ curwin->w_p_rnu = false;
+
+ adjust_topline(s->term, buf, 0); // scroll to end
// erase the unfocused cursor
invalidate_terminal(s->term, s->term->cursor.row, s->term->cursor.row + 1);
showmode();
@@ -395,6 +407,12 @@ void terminal_enter(void)
restart_edit = 0;
State = save_state;
RedrawingDisabled = s->save_rd;
+ if (save_curwin == curwin) { // save_curwin may be invalid (window closed)!
+ curwin->w_p_cul = save_w_p_cul;
+ curwin->w_p_cuc = save_w_p_cuc;
+ curwin->w_p_rnu = save_w_p_rnu;
+ }
+
// draw the unfocused cursor
invalidate_terminal(s->term, s->term->cursor.row, s->term->cursor.row + 1);
unshowmode(true);
@@ -454,14 +472,14 @@ static int terminal_execute(VimState *state, int key)
break;
case Ctrl_N:
- if (s->got_bs) {
+ if (s->got_bsl) {
return 0;
}
// FALLTHROUGH
default:
- if (key == Ctrl_BSL && !s->got_bs) {
- s->got_bs = true;
+ if (key == Ctrl_BSL && !s->got_bsl) {
+ s->got_bsl = true;
break;
}
if (s->term->closed) {
@@ -469,7 +487,7 @@ static int terminal_execute(VimState *state, int key)
return 0;
}
- s->got_bs = false;
+ s->got_bsl = false;
terminal_send_key(s->term, key);
}
@@ -590,8 +608,10 @@ void terminal_get_line_attributes(Terminal *term, win_T *wp, int linenr,
if (term->cursor.visible && term->cursor.row == row
&& term->cursor.col == col) {
- attr_id = hl_combine_attr(attr_id, is_focused(term) && wp == curwin ?
- hl_attr(HLF_TERM) : hl_attr(HLF_TERMNC));
+ attr_id = hl_combine_attr(attr_id,
+ is_focused(term) && wp == curwin
+ ? win_hl_attr(wp, HLF_TERM)
+ : win_hl_attr(wp, HLF_TERMNC));
}
term_attrs[col] = attr_id;
@@ -626,15 +646,16 @@ static int term_movecursor(VTermPos new, VTermPos old, int visible,
}
static void buf_set_term_title(buf_T *buf, char *title)
- FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_ALL
{
- Error err;
- dict_set_value(buf->b_vars,
- cstr_as_string("term_title"),
- STRING_OBJ(cstr_as_string(title)),
- false,
- false,
- &err);
+ Error err = ERROR_INIT;
+ dict_set_var(buf->b_vars,
+ STATIC_CSTR_AS_STRING("term_title"),
+ STRING_OBJ(cstr_as_string(title)),
+ false,
+ false,
+ &err);
+ api_clear_error(&err);
}
static int term_settermprop(VTermProp prop, VTermValue *val, void *data)
@@ -669,14 +690,19 @@ static int term_settermprop(VTermProp prop, VTermValue *val, void *data)
static int term_bell(void *data)
{
- ui_putc('\x07');
+ ui_call_bell();
return 1;
}
-// the scrollback push/pop handlers were copied almost verbatim from pangoterm
+// Scrollback push handler (from pangoterm).
static int term_sb_push(int cols, const VTermScreenCell *cells, void *data)
{
Terminal *term = data;
+
+ if (!term->sb_size) {
+ return 0;
+ }
+
// copy vterm cells into sb_buffer
size_t c = (size_t)cols;
ScrollbackLine *sbrow = NULL;
@@ -688,10 +714,12 @@ static int term_sb_push(int cols, const VTermScreenCell *cells, void *data)
xfree(term->sb_buffer[term->sb_current - 1]);
}
+ // Make room at the start by shifting to the right.
memmove(term->sb_buffer + 1, term->sb_buffer,
sizeof(term->sb_buffer[0]) * (term->sb_current - 1));
} else if (term->sb_current > 0) {
+ // Make room at the start by shifting to the right.
memmove(term->sb_buffer + 1, term->sb_buffer,
sizeof(term->sb_buffer[0]) * term->sb_current);
}
@@ -701,6 +729,7 @@ static int term_sb_push(int cols, const VTermScreenCell *cells, void *data)
sbrow->cols = c;
}
+ // New row is added at the start of the storage buffer.
term->sb_buffer[0] = sbrow;
if (term->sb_current < term->sb_size) {
term->sb_current++;
@@ -716,6 +745,11 @@ static int term_sb_push(int cols, const VTermScreenCell *cells, void *data)
return 1;
}
+/// Scrollback pop handler (from pangoterm).
+///
+/// @param cols
+/// @param cells VTerm state to update.
+/// @param data Terminal
static int term_sb_pop(int cols, VTermScreenCell *cells, void *data)
{
Terminal *term = data;
@@ -728,24 +762,24 @@ static int term_sb_pop(int cols, VTermScreenCell *cells, void *data)
term->sb_pending--;
}
- // restore vterm state
- size_t c = (size_t)cols;
ScrollbackLine *sbrow = term->sb_buffer[0];
term->sb_current--;
+ // Forget the "popped" row by shifting the rest onto it.
memmove(term->sb_buffer, term->sb_buffer + 1,
sizeof(term->sb_buffer[0]) * (term->sb_current));
- size_t cols_to_copy = c;
+ size_t cols_to_copy = (size_t)cols;
if (cols_to_copy > sbrow->cols) {
cols_to_copy = sbrow->cols;
}
// copy to vterm state
memcpy(cells, sbrow->cells, sizeof(cells[0]) * cols_to_copy);
- for (size_t col = cols_to_copy; col < c; col++) {
+ for (size_t col = cols_to_copy; col < (size_t)cols; col++) {
cells[col].chars[0] = 0;
cells[col].width = 1;
}
+
xfree(sbrow);
pmap_put(ptr_t)(invalidated_terminals, term, NULL);
@@ -976,7 +1010,7 @@ static bool send_mouse_event(Terminal *term, int c)
// terminal buffer refresh & misc {{{
-void fetch_row(Terminal *term, int row, int end_col)
+static void fetch_row(Terminal *term, int row, int end_col)
{
int col = 0;
size_t line_len = 0;
@@ -1049,28 +1083,29 @@ static void refresh_terminal(Terminal *term)
buf_T *buf = handle_get_buffer(term->buf_handle);
bool valid = true;
if (!buf || !(valid = buf_valid(buf))) {
- // destroyed by `close_buffer`. Dont do anything else
+ // Destroyed by `close_buffer`. Do not do anything else.
if (!valid) {
term->buf_handle = 0;
}
return;
}
- bool pending_resize = term->pending_resize;
+ long ml_before = buf->b_ml.ml_line_count;
WITH_BUFFER(buf, {
refresh_size(term, buf);
refresh_scrollback(term, buf);
refresh_screen(term, buf);
redraw_buf_later(buf, NOT_VALID);
});
- adjust_topline(term, buf, pending_resize);
+ long ml_added = buf->b_ml.ml_line_count - ml_before;
+ adjust_topline(term, buf, ml_added);
}
-// libuv timer callback. This will enqueue on_refresh to be processed as an
-// event.
+// Calls refresh_terminal() on all invalidated_terminals.
static void refresh_timer_cb(TimeWatcher *watcher, void *data)
{
- if (exiting) {
- // bad things can happen if we redraw when exiting, and there's no need to
- // update the buffer.
+ if (exiting // Cannot redraw (requires event loop) during teardown/exit.
+ // WM_LIST (^D) is not redrawn, unlike the normal wildmenu. So we must
+ // skip redraws to keep it visible.
+ || wild_menu_showing == WM_LIST) {
goto end;
}
Terminal *term;
@@ -1080,9 +1115,12 @@ static void refresh_timer_cb(TimeWatcher *watcher, void *data)
map_foreach(invalidated_terminals, term, stub, {
refresh_terminal(term);
});
+ bool any_visible = is_term_visible();
pmap_clear(ptr_t)(invalidated_terminals);
unblock_autocmds();
- redraw(true);
+ if (any_visible) {
+ redraw(true);
+ }
end:
refresh_pending = false;
}
@@ -1101,7 +1139,37 @@ static void refresh_size(Terminal *term, buf_T *buf)
term->opts.resize_cb((uint16_t)width, (uint16_t)height, term->opts.data);
}
-// Refresh the scrollback of a invalidated terminal
+/// Adjusts scrollback storage after 'scrollback' option changed.
+static void on_scrollback_option_changed(Terminal *term, buf_T *buf)
+{
+ const size_t scbk = curbuf->b_p_scbk < 0
+ ? SB_MAX : (size_t)MAX(1, curbuf->b_p_scbk);
+ assert(term->sb_current < SIZE_MAX);
+ if (term->sb_pending > 0) { // Pending rows must be processed first.
+ abort();
+ }
+
+ // Delete lines exceeding the new 'scrollback' limit.
+ if (scbk < term->sb_current) {
+ size_t diff = term->sb_current - scbk;
+ for (size_t i = 0; i < diff; i++) {
+ ml_delete(1, false);
+ term->sb_current--;
+ xfree(term->sb_buffer[term->sb_current]);
+ }
+ deleted_lines(1, (long)diff);
+ }
+
+ // Resize the scrollback storage.
+ size_t sb_region = sizeof(ScrollbackLine *) * scbk;
+ if (scbk != term->sb_size) {
+ term->sb_buffer = xrealloc(term->sb_buffer, sb_region);
+ }
+
+ term->sb_size = scbk;
+}
+
+// Refresh the scrollback of an invalidated terminal.
static void refresh_scrollback(Terminal *term, buf_T *buf)
{
int width, height;
@@ -1130,9 +1198,11 @@ static void refresh_scrollback(Terminal *term, buf_T *buf)
ml_delete(buf->b_ml.ml_line_count, false);
deleted_lines(buf->b_ml.ml_line_count, 1);
}
+
+ on_scrollback_option_changed(term, buf);
}
-// Refresh the screen(visible part of the buffer when the terminal is
+// Refresh the screen (visible part of the buffer when the terminal is
// focused) of a invalidated terminal
static void refresh_screen(Terminal *term, buf_T *buf)
{
@@ -1141,8 +1211,7 @@ static void refresh_screen(Terminal *term, buf_T *buf)
int height;
int width;
vterm_get_size(term->vt, &height, &width);
- // It's possible that the terminal height decreased and `term->invalid_end`
- // doesn't reflect it yet
+ // Terminal height may have decreased before `invalid_end` reflects it.
term->invalid_end = MIN(term->invalid_end, height);
for (int r = term->invalid_start, linenr = row_to_linenr(term, r);
@@ -1165,6 +1234,18 @@ static void refresh_screen(Terminal *term, buf_T *buf)
term->invalid_end = -1;
}
+/// @return true if any invalidated terminal buffer is visible to the user
+static bool is_term_visible(void)
+{
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ if (wp->w_buffer->terminal
+ && pmap_has(ptr_t)(invalidated_terminals, wp->w_buffer->terminal)) {
+ return true;
+ }
+ }
+ return false;
+}
+
static void redraw(bool restore_cursor)
{
Terminal *term = curbuf->terminal;
@@ -1181,55 +1262,47 @@ static void redraw(bool restore_cursor)
save_col = ui_current_col();
}
block_autocmds();
- validate_cursor();
if (must_redraw) {
update_screen(0);
}
- redraw_statuslines();
-
- if (need_maketitle) {
- maketitle();
- }
-
- showruler(false);
-
- if (term && is_focused(term)) {
- curwin->w_wrow = term->cursor.row;
- curwin->w_wcol = term->cursor.col + win_col_off(curwin);
- setcursor();
- } else if (restore_cursor) {
+ if (restore_cursor) {
ui_cursor_goto(save_row, save_col);
} else if (term) {
- // exiting terminal focus, put the window cursor in a valid position
- int height, width;
- vterm_get_size(term->vt, &height, &width);
- curwin->w_wrow = height - 1;
- curwin->w_wcol = 0;
- setcursor();
+ curwin->w_wrow = term->cursor.row;
+ curwin->w_wcol = term->cursor.col + win_col_off(curwin);
+ curwin->w_cursor.lnum = MIN(curbuf->b_ml.ml_line_count,
+ row_to_linenr(term, term->cursor.row));
+ // Nudge cursor when returning to normal-mode.
+ int off = is_focused(term) ? 0 : (curwin->w_p_rl ? 1 : -1);
+ curwin->w_cursor.col = MAX(0, term->cursor.col + win_col_off(curwin) + off);
+ curwin->w_cursor.coladd = 0;
+ mb_check_adjust_col(curwin);
}
unblock_autocmds();
ui_flush();
}
-static void adjust_topline(Terminal *term, buf_T *buf, bool force)
+static void adjust_topline(Terminal *term, buf_T *buf, long added)
{
int height, width;
vterm_get_size(term->vt, &height, &width);
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_buffer == buf) {
- // for every window that displays a terminal, ensure the cursor is in a
- // valid line
- wp->w_cursor.lnum = MIN(wp->w_cursor.lnum, buf->b_ml.ml_line_count);
- if (force || curbuf != buf || is_focused(term)) {
- // if the terminal is not in the current window or if it's focused,
- // adjust topline/cursor so the window will "follow" the terminal
- // output
- wp->w_cursor.lnum = buf->b_ml.ml_line_count;
+ linenr_T ml_end = buf->b_ml.ml_line_count;
+ bool following = ml_end == wp->w_cursor.lnum + added; // cursor at end?
+
+ if (following || (wp == curwin && is_focused(term))) {
+ // "Follow" the terminal output
+ wp->w_cursor.lnum = ml_end;
set_topline(wp, MAX(wp->w_cursor.lnum - height + 1, 1));
+ } else {
+ // Ensure valid cursor for each window displaying this terminal.
+ wp->w_cursor.lnum = MIN(wp->w_cursor.lnum, ml_end);
}
+ mb_check_adjust_col(wp);
}
}
}
@@ -1251,12 +1324,14 @@ static bool is_focused(Terminal *term)
#define GET_CONFIG_VALUE(k, o) \
do { \
- Error err; \
+ Error err = ERROR_INIT; \
/* Only called from terminal_open where curbuf->terminal is the */ \
/* context */ \
o = dict_get_value(curbuf->b_vars, cstr_as_string(k), &err); \
+ api_clear_error(&err); \
if (o.type == kObjectTypeNil) { \
o = dict_get_value(&globvardict, cstr_as_string(k), &err); \
+ api_clear_error(&err); \
} \
} while (0)
@@ -1271,17 +1346,6 @@ static char *get_config_string(char *key)
return NULL;
}
-static int get_config_int(char *key)
-{
- Object obj;
- GET_CONFIG_VALUE(key, obj);
- if (obj.type == kObjectTypeInteger) {
- return (int)obj.data.integer;
- }
- api_free_object(obj);
- return 0;
-}
-
// }}}
// vim: foldmethod=marker
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile
index 814c0bc3cb..96de7224c5 100644
--- a/src/nvim/testdir/Makefile
+++ b/src/nvim/testdir/Makefile
@@ -1,14 +1,16 @@
-#
+# vim: noet ts=8
# Makefile to run all tests for Vim
#
-export SHELL := sh
-
-VIMPROG := ../../../build/bin/nvim
+NVIM_PRG ?= ../../../build/bin/nvim
+TMPDIR ?= Xtest-tmpdir
SCRIPTSOURCE := ../../../runtime
-SCRIPTS := \
- test8.out \
+export SHELL := sh
+export NVIM_PRG := $(NVIM_PRG)
+export TMPDIR
+
+SCRIPTS ?= \
test13.out \
test14.out \
test17.out \
@@ -22,33 +24,60 @@ SCRIPTS := \
test52.out \
test53.out \
test64.out \
- test69.out \
test73.out \
test79.out \
- test_marks.out \
-# Tests using runtest.vim.vim.
+# Tests using runtest.vim.
# Keep test_alot*.res as the last one, sort the others.
-NEW_TESTS = \
+NEW_TESTS ?= \
+ test_autocmd.res \
test_bufwintabinfo.res \
+ test_charsearch.res \
test_cmdline.res \
+ test_command_count.res \
test_cscope.res \
+ test_digraph.res \
test_diffmode.res \
+ test_farsi.res \
+ test_filter_map.res \
+ test_fnameescape.res \
+ test_fold.res \
+ test_glob2regpat.res \
+ test_gf.res \
test_gn.res \
test_hardcopy.res \
test_help_tagjump.res \
+ test_hide.res \
test_history.res \
+ test_hlsearch.res \
+ test_increment.res \
+ test_increment_dbcs.res \
+ test_lambda.res \
test_langmap.res \
+ test_marks.res \
test_match.res \
test_matchadd_conceal.res \
+ test_matchadd_conceal_utf8.res \
+ test_nested_function.res \
+ test_normal.res \
test_quickfix.res \
+ test_search.res \
test_signs.res \
+ test_smartindent.res \
+ test_stat.res \
+ test_startup.res \
+ test_startup_utf8.res \
+ test_substitute.res \
test_syntax.res \
+ test_tabpage.res \
+ test_textobjects.res \
test_timers.res \
+ test_undo.res \
test_usercommands.res \
- test_viml.res \
+ test_vimscript.res \
test_visual.res \
test_window_id.res \
+ test_writefile.res \
test_alot.res
SCRIPTS_GUI := test16.out
@@ -100,13 +129,13 @@ report:
echo ALL DONE; \
fi"
-test1.out: $(VIMPROG)
+test1.out: $(NVIM_PRG)
-$(SCRIPTS) $(SCRIPTS_GUI): $(VIMPROG) test1.out
+$(SCRIPTS) $(SCRIPTS_GUI): $(NVIM_PRG) test1.out
RM_ON_RUN := test.out X* viminfo
RM_ON_START := test.ok
-RUN_VIM := VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(TOOL) $(VIMPROG) -u unix.vim -U NONE -i viminfo --noplugin -s dotest.in
+RUN_VIM := VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(TOOL) $(NVIM_PRG) -u unix.vim -U NONE -i viminfo --headless --noplugin -s dotest.in
clean:
-rm -rf *.out \
@@ -122,10 +151,12 @@ clean:
.*.swp \
.*.swo \
.gdbinit \
+ $(TMPDIR) \
del
test1.out: .gdbinit test1.in
-rm -rf $*.failed $(RM_ON_RUN) $(RM_ON_START) wrongtermsize
+ mkdir -p $(TMPDIR)
$(RUN_VIM) $*.in
@/bin/sh -c "if test -e wrongtermsize; then \
echo; \
@@ -143,6 +174,7 @@ test1.out: .gdbinit test1.in
%.out: %.in .gdbinit
-rm -rf $*.failed test.ok $(RM_ON_RUN)
+ mkdir -p $(TMPDIR)
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
@@ -175,7 +207,7 @@ nolog:
# New style of tests uses Vim script with assert calls. These are easier
# to write and a lot easier to read and debug.
# Limitation: Only works with the +eval feature.
-RUN_VIMTEST = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(VIMPROG) -u unix.vim -U NONE --noplugin
+RUN_VIMTEST = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(TOOL) $(NVIM_PRG) -u unix.vim -U NONE --headless --noplugin
newtests: newtestssilent
@/bin/sh -c "if test -f messages && grep -q 'FAILED' messages; then \
@@ -185,4 +217,5 @@ newtests: newtestssilent
newtestssilent: $(NEW_TESTS)
%.res: %.vim .gdbinit
+ mkdir -p $(TMPDIR)
$(RUN_VIMTEST) -u NONE -S runtest.vim $*.vim
diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim
index 20863bbaf3..39ffabc024 100644
--- a/src/nvim/testdir/runtest.vim
+++ b/src/nvim/testdir/runtest.vim
@@ -39,6 +39,9 @@ if &lines < 24 || &columns < 80
cquit
endif
+" Common with all tests on all systems.
+source setup.vim
+
" This also enables use of line continuation.
set viminfo+=nviminfo
@@ -62,14 +65,25 @@ set shellslash
" Make sure $HOME does not get read or written.
let $HOME = '/does/not/exist'
-" Align with vim defaults.
+" Prepare for calling garbagecollect_for_testing().
+let v:testing = 1
+
+" Align Nvim defaults to Vim.
set directory^=.
-set nohidden
+set backspace=
+set nohidden smarttab noautoindent noautoread complete-=i noruler noshowcmd
+set listchars=eol:$
+" Prevent Nvim log from writing to stderr.
+let $NVIM_LOG_FILE = exists($NVIM_LOG_FILE) ? $NVIM_LOG_FILE : 'Xnvim.log'
-function RunTheTest(test)
+func RunTheTest(test)
echo 'Executing ' . a:test
if exists("*SetUp")
- call SetUp()
+ try
+ call SetUp()
+ catch
+ call add(v:errors, 'Caught exception in SetUp() before ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
+ endtry
endif
call add(s:messages, 'Executing ' . a:test)
@@ -84,16 +98,83 @@ function RunTheTest(test)
endtry
if exists("*TearDown")
- call TearDown()
+ try
+ call TearDown()
+ catch
+ call add(v:errors, 'Caught exception in TearDown() after ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
+ endtry
endif
" Close any extra windows and make the current one not modified.
- while winnr('$') > 1
+ while 1
+ let wincount = winnr('$')
+ if wincount == 1
+ break
+ endif
bwipe!
+ if wincount == winnr('$')
+ " Did not manage to close a window.
+ only!
+ break
+ endif
endwhile
set nomodified
endfunc
+func AfterTheTest()
+ if len(v:errors) > 0
+ let s:fail += 1
+ call add(s:errors, 'Found errors in ' . s:test . ':')
+ call extend(s:errors, v:errors)
+ let v:errors = []
+ endif
+endfunc
+
+" This function can be called by a test if it wants to abort testing.
+func FinishTesting()
+ call AfterTheTest()
+
+ " Don't write viminfo on exit.
+ set viminfo=
+
+ if s:fail == 0
+ " Success, create the .res file so that make knows it's done.
+ exe 'split ' . fnamemodify(g:testname, ':r') . '.res'
+ write
+ endif
+
+ if len(s:errors) > 0
+ " Append errors to test.log
+ split test.log
+ call append(line('$'), '')
+ call append(line('$'), 'From ' . g:testname . ':')
+ call append(line('$'), s:errors)
+ write
+ endif
+
+ let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test')
+ echo message
+ call add(s:messages, message)
+ if s:fail > 0
+ let message = s:fail . ' FAILED:'
+ echo message
+ call add(s:messages, message)
+ call extend(s:messages, s:errors)
+ endif
+
+ " Add SKIPPED messages
+ call extend(s:messages, s:skipped)
+
+ " Append messages to the file "messages"
+ split messages
+ call append(line('$'), '')
+ call append(line('$'), 'From ' . g:testname . ':')
+ call append(line('$'), s:messages)
+ write
+
+ qall!
+endfunc
+
" Source the test script. First grab the file name, in case the script
" navigates away. g:testname can be used by the tests.
let g:testname = expand('%')
@@ -102,7 +183,7 @@ let s:fail = 0
let s:errors = []
let s:messages = []
let s:skipped = []
-if expand('%') =~ 'test_viml.vim'
+if expand('%') =~ 'test_vimscript.vim'
" this test has intentional s:errors, don't use try/catch.
source %
else
@@ -115,7 +196,11 @@ else
endif
" Names of flaky tests.
-let s:flaky = []
+let s:flaky = [
+ \ 'Test_with_partial_callback()',
+ \ 'Test_oneshot()',
+ \ 'Test_lambda_with_timer()',
+ \ ]
" Locate Test_ functions and execute them.
set nomore
@@ -134,56 +219,14 @@ for s:test in sort(s:tests)
call RunTheTest(s:test)
if len(v:errors) > 0 && index(s:flaky, s:test) >= 0
- call add(s:messages, 'Flaky test failed, running it again')
- let v:errors = []
- call RunTheTest(s:test)
- endif
-
- if len(v:errors) > 0
- let s:fail += 1
- call add(s:errors, 'Found errors in ' . s:test . ':')
- call extend(s:errors, v:errors)
+ call add(s:messages, 'Flaky test failed, running it again')
let v:errors = []
+ call RunTheTest(s:test)
endif
+ call AfterTheTest()
endfor
-" Don't write viminfo on exit.
-set viminfo=
-
-if s:fail == 0
- " Success, create the .res file so that make knows it's done.
- exe 'split ' . fnamemodify(g:testname, ':r') . '.res'
- write
-endif
-
-if len(s:errors) > 0
- " Append errors to test.log
- split test.log
- call append(line('$'), '')
- call append(line('$'), 'From ' . g:testname . ':')
- call append(line('$'), s:errors)
- write
-endif
-
-let message = 'Executed ' . s:done . (s:done > 1 ? ' tests': ' test')
-echo message
-call add(s:messages, message)
-if s:fail > 0
- let message = s:fail . ' FAILED'
- echo message
- call add(s:messages, message)
- call extend(s:messages, s:errors)
-endif
-
-" Add SKIPPED messages
-call extend(s:messages, s:skipped)
-
-" Append messages to the file "messages"
-split messages
-call append(line('$'), '')
-call append(line('$'), 'From ' . g:testname . ':')
-call append(line('$'), s:messages)
-write
+call FinishTesting()
-qall!
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/samples/memfile_test.c b/src/nvim/testdir/samples/memfile_test.c
new file mode 100644
index 0000000000..3c8f108255
--- /dev/null
+++ b/src/nvim/testdir/samples/memfile_test.c
@@ -0,0 +1,146 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+/* vi:set ts=8 sts=4 sw=4 noet:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+ * Do ":help uganda" in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * memfile_test.c: Unittests for memfile.c
+ * Mostly by Ivan Krasilnikov.
+ */
+
+#undef NDEBUG
+#include <assert.h>
+
+/* Must include main.c because it contains much more than just main() */
+#define NO_VIM_MAIN
+#include "main.c"
+
+/* This file has to be included because the tested functions are static */
+#include "memfile.c"
+
+#define index_to_key(i) ((i) ^ 15167)
+#define TEST_COUNT 50000
+
+/*
+ * Test mf_hash_*() functions.
+ */
+ static void
+test_mf_hash(void)
+{
+ mf_hashtab_T ht;
+ mf_hashitem_T *item;
+ blocknr_T key;
+ long_u i;
+ long_u num_buckets;
+
+ mf_hash_init(&ht);
+
+ /* insert some items and check invariants */
+ for (i = 0; i < TEST_COUNT; i++)
+ {
+ assert(ht.mht_count == i);
+
+ /* check that number of buckets is a power of 2 */
+ num_buckets = ht.mht_mask + 1;
+ assert(num_buckets > 0 && (num_buckets & (num_buckets - 1)) == 0);
+
+ /* check load factor */
+ assert(ht.mht_count <= (num_buckets << MHT_LOG_LOAD_FACTOR));
+
+ if (i < (MHT_INIT_SIZE << MHT_LOG_LOAD_FACTOR))
+ {
+ /* first expansion shouldn't have occurred yet */
+ assert(num_buckets == MHT_INIT_SIZE);
+ assert(ht.mht_buckets == ht.mht_small_buckets);
+ }
+ else
+ {
+ assert(num_buckets > MHT_INIT_SIZE);
+ assert(ht.mht_buckets != ht.mht_small_buckets);
+ }
+
+ key = index_to_key(i);
+ assert(mf_hash_find(&ht, key) == NULL);
+
+ /* allocate and add new item */
+ item = (mf_hashitem_T *)lalloc_clear(sizeof(mf_hashtab_T), FALSE);
+ assert(item != NULL);
+ item->mhi_key = key;
+ mf_hash_add_item(&ht, item);
+
+ assert(mf_hash_find(&ht, key) == item);
+
+ if (ht.mht_mask + 1 != num_buckets)
+ {
+ /* hash table was expanded */
+ assert(ht.mht_mask + 1 == num_buckets * MHT_GROWTH_FACTOR);
+ assert(i + 1 == (num_buckets << MHT_LOG_LOAD_FACTOR));
+ }
+ }
+
+ /* check presence of inserted items */
+ for (i = 0; i < TEST_COUNT; i++)
+ {
+ key = index_to_key(i);
+ item = mf_hash_find(&ht, key);
+ assert(item != NULL);
+ assert(item->mhi_key == key);
+ }
+
+ /* delete some items */
+ for (i = 0; i < TEST_COUNT; i++)
+ {
+ if (i % 100 < 70)
+ {
+ key = index_to_key(i);
+ item = mf_hash_find(&ht, key);
+ assert(item != NULL);
+ assert(item->mhi_key == key);
+
+ mf_hash_rem_item(&ht, item);
+ assert(mf_hash_find(&ht, key) == NULL);
+
+ mf_hash_add_item(&ht, item);
+ assert(mf_hash_find(&ht, key) == item);
+
+ mf_hash_rem_item(&ht, item);
+ assert(mf_hash_find(&ht, key) == NULL);
+
+ vim_free(item);
+ }
+ }
+
+ /* check again */
+ for (i = 0; i < TEST_COUNT; i++)
+ {
+ key = index_to_key(i);
+ item = mf_hash_find(&ht, key);
+
+ if (i % 100 < 70)
+ {
+ assert(item == NULL);
+ }
+ else
+ {
+ assert(item != NULL);
+ assert(item->mhi_key == key);
+ }
+ }
+
+ /* free hash table and all remaining items */
+ mf_hash_free_all(&ht);
+}
+
+ int
+main(void)
+{
+ test_mf_hash();
+ return 0;
+}
diff --git a/src/nvim/testdir/setup.vim b/src/nvim/testdir/setup.vim
new file mode 100644
index 0000000000..06f2199214
--- /dev/null
+++ b/src/nvim/testdir/setup.vim
@@ -0,0 +1,12 @@
+" Common preparations for running tests.
+
+set noruler
+set noshowcmd
+set belloff=
+
+" Make sure 'runtimepath' and 'packpath' does not include $HOME.
+set rtp=$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after
+let &packpath = &rtp
+
+" Make sure $HOME does not get read or written.
+let $HOME = '/does/not/exist'
diff --git a/src/nvim/testdir/shared.vim b/src/nvim/testdir/shared.vim
new file mode 100644
index 0000000000..72cfea96c6
--- /dev/null
+++ b/src/nvim/testdir/shared.vim
@@ -0,0 +1,214 @@
+" Functions shared by several tests.
+
+" Get the name of the Python executable.
+" Also keeps it in s:python.
+func PythonProg()
+ " This test requires the Python command to run the test server.
+ " This most likely only works on Unix and Windows.
+ if has('unix')
+ " We also need the job feature or the pkill command to make sure the server
+ " can be stopped.
+ if !(executable('python') && (has('job') || executable('pkill')))
+ return ''
+ endif
+ let s:python = 'python'
+ elseif has('win32')
+ " Use Python Launcher for Windows (py.exe) if available.
+ if executable('py.exe')
+ let s:python = 'py.exe'
+ elseif executable('python.exe')
+ let s:python = 'python.exe'
+ else
+ return ''
+ endif
+ else
+ return ''
+ endif
+ return s:python
+endfunc
+
+" Run "cmd". Returns the job if using a job.
+func RunCommand(cmd)
+ let job = 0
+ if has('job')
+ let job = job_start(a:cmd, {"stoponexit": "hup"})
+ call job_setoptions(job, {"stoponexit": "kill"})
+ elseif has('win32')
+ exe 'silent !start cmd /c start "test_channel" ' . a:cmd
+ else
+ exe 'silent !' . a:cmd . '&'
+ endif
+ return job
+endfunc
+
+" Read the port number from the Xportnr file.
+func GetPort()
+ let l = []
+ for i in range(200)
+ try
+ let l = readfile("Xportnr")
+ catch
+ endtry
+ if len(l) >= 1
+ break
+ endif
+ sleep 10m
+ endfor
+ call delete("Xportnr")
+
+ if len(l) == 0
+ " Can't make the connection, give up.
+ return 0
+ endif
+ return l[0]
+endfunc
+
+" Run a Python server for "cmd" and call "testfunc".
+" Always kills the server before returning.
+func RunServer(cmd, testfunc, args)
+ " The Python program writes the port number in Xportnr.
+ call delete("Xportnr")
+
+ if len(a:args) == 1
+ let arg = ' ' . a:args[0]
+ else
+ let arg = ''
+ endif
+ let pycmd = s:python . " " . a:cmd . arg
+
+ try
+ let g:currentJob = RunCommand(pycmd)
+
+ " Wait for up to 2 seconds for the port number to be there.
+ let port = GetPort()
+ if port == 0
+ call assert_false(1, "Can't start " . a:cmd)
+ return
+ endif
+
+ call call(function(a:testfunc), [port])
+ catch
+ call assert_false(1, 'Caught exception: "' . v:exception . '" in ' . v:throwpoint)
+ finally
+ call s:kill_server(a:cmd)
+ endtry
+endfunc
+
+func s:kill_server(cmd)
+ if has('job')
+ if exists('g:currentJob')
+ call job_stop(g:currentJob)
+ unlet g:currentJob
+ endif
+ elseif has('win32')
+ let cmd = substitute(a:cmd, ".py", '', '')
+ call system('taskkill /IM ' . s:python . ' /T /F /FI "WINDOWTITLE eq ' . cmd . '"')
+ else
+ call system("pkill -f " . a:cmd)
+ endif
+endfunc
+
+" Wait for up to a second for "expr" to become true.
+" Return time slept in milliseconds. With the +reltime feature this can be
+" more than the actual waiting time. Without +reltime it can also be less.
+func WaitFor(expr)
+ " using reltime() is more accurate, but not always available
+ if has('reltime')
+ let start = reltime()
+ else
+ let slept = 0
+ endif
+ for i in range(100)
+ try
+ if eval(a:expr)
+ if has('reltime')
+ return float2nr(reltimefloat(reltime(start)) * 1000)
+ endif
+ return slept
+ endif
+ catch
+ endtry
+ if !has('reltime')
+ let slept += 10
+ endif
+ sleep 10m
+ endfor
+ return 1000
+endfunc
+
+" Wait for up to a given milliseconds.
+" With the +timers feature this waits for key-input by getchar(), Resume()
+" feeds key-input and resumes process. Return time waited in milliseconds.
+" Without +timers it uses simply :sleep.
+func Standby(msec)
+ if has('timers')
+ let start = reltime()
+ let g:_standby_timer = timer_start(a:msec, function('s:feedkeys'))
+ call getchar()
+ return float2nr(reltimefloat(reltime(start)) * 1000)
+ else
+ execute 'sleep ' a:msec . 'm'
+ return a:msec
+ endif
+endfunc
+
+func Resume()
+ if exists('g:_standby_timer')
+ call timer_stop(g:_standby_timer)
+ call s:feedkeys(0)
+ unlet g:_standby_timer
+ endif
+endfunc
+
+func s:feedkeys(timer)
+ call feedkeys('x', 'nt')
+endfunc
+
+" Get the command to run Vim, with -u NONE and --headless arguments.
+" Returns an empty string on error.
+func GetVimCommand()
+ let cmd = v:progpath
+ let cmd = substitute(cmd, '-u \f\+', '-u NONE', '')
+ if cmd !~ '-u NONE'
+ let cmd = cmd . ' -u NONE'
+ endif
+ let cmd .= ' --headless -i NONE'
+ let cmd = substitute(cmd, 'VIMRUNTIME=.*VIMRUNTIME;', '', '')
+ return cmd
+endfunc
+
+" Run Vim, using the "vimcmd" file and "-u NORC".
+" "before" is a list of Vim commands to be executed before loading plugins.
+" "after" is a list of Vim commands to be executed after loading plugins.
+" Plugins are not loaded, unless 'loadplugins' is set in "before".
+" Return 1 if Vim could be executed.
+func RunVim(before, after, arguments)
+ return RunVimPiped(a:before, a:after, a:arguments, '')
+endfunc
+
+func RunVimPiped(before, after, arguments, pipecmd)
+ let $NVIM_LOG_FILE = exists($NVIM_LOG_FILE) ? $NVIM_LOG_FILE : 'Xnvim.log'
+ let cmd = GetVimCommand()
+ if cmd == ''
+ return 0
+ endif
+ let args = ''
+ if len(a:before) > 0
+ call writefile(a:before, 'Xbefore.vim')
+ let args .= ' --cmd "so Xbefore.vim"'
+ endif
+ if len(a:after) > 0
+ call writefile(a:after, 'Xafter.vim')
+ let args .= ' -S Xafter.vim'
+ endif
+
+ exe "silent !" . a:pipecmd . cmd . args . ' ' . a:arguments
+
+ if len(a:before) > 0
+ call delete('Xbefore.vim')
+ endif
+ if len(a:after) > 0
+ call delete('Xafter.vim')
+ endif
+ return 1
+endfunc
diff --git a/src/nvim/testdir/test13.in b/src/nvim/testdir/test13.in
deleted file mode 100644
index fa9ba312b7..0000000000
--- a/src/nvim/testdir/test13.in
+++ /dev/null
@@ -1,63 +0,0 @@
-Tests for autocommands on :close command
-
-Write three files and open them, each in a window.
-Then go to next window, with autocommand that deletes the previous one.
-Do this twice, writing the file.
-
-Also test deleting the buffer on a Unload event. If this goes wrong there
-will be the ATTENTION prompt.
-
-Also test changing buffers in a BufDel autocommand. If this goes wrong there
-are ml_line errors and/or a Crash.
-
-STARTTEST
-:/^start of testfile/,/^end of testfile/w! Xtestje1
-:/^start of testfile/,/^end of testfile/w! Xtestje2
-:/^start of testfile/,/^end of testfile/w! Xtestje3
-:e Xtestje1
-otestje1
-:w
-:sp Xtestje2
-otestje2
-:w
-:sp Xtestje3
-otestje3
-:w
-
-:au WinLeave Xtestje2 bwipe
-
-:w! test.out
-:au WinLeave Xtestje1 bwipe Xtestje3
-:close
-:w >>test.out
-:e Xtestje1
-:bwipe Xtestje2 Xtestje3 test.out
-:au!
-:au! BufUnload Xtestje1 bwipe
-:e Xtestje3
-:w >>test.out
-:e Xtestje2
-:sp Xtestje1
-:e
-:w >>test.out
-:au!
-:only
-:e Xtestje1
-:bwipe Xtestje2 Xtestje3 test.out test13.in
-:au BufWipeout Xtestje1 buf Xtestje1
-:bwipe
-:w >>test.out
-:only
-:new|set buftype=help
-:wincmd w
-:1quit
-:$put ='Final line'
-:$w >>test.out
-:qa!
-ENDTEST
-
-start of testfile
- contents
- contents
- contents
-end of testfile
diff --git a/src/nvim/testdir/test13.ok b/src/nvim/testdir/test13.ok
deleted file mode 100644
index 66ebce63f7..0000000000
--- a/src/nvim/testdir/test13.ok
+++ /dev/null
@@ -1,31 +0,0 @@
-start of testfile
-testje1
- contents
- contents
- contents
-end of testfile
-start of testfile
-testje1
- contents
- contents
- contents
-end of testfile
-start of testfile
-testje3
- contents
- contents
- contents
-end of testfile
-start of testfile
-testje2
- contents
- contents
- contents
-end of testfile
-start of testfile
-testje1
- contents
- contents
- contents
-end of testfile
-Final line
diff --git a/src/nvim/testdir/test17.in b/src/nvim/testdir/test17.in
index 83abe17770..1a4ac6b6d1 100644
--- a/src/nvim/testdir/test17.in
+++ b/src/nvim/testdir/test17.in
@@ -4,13 +4,7 @@ Tests for:
STARTTEST
:set isfname=@,48-57,/,.,-,_,+,,,$,:,~,{,}
-:function! DeleteDirectory(dir)
-: if has("win16") || has("win32") || has("win64") || has("dos16") || has("dos32")
-: exec "silent !rmdir /Q /S " . a:dir
-: else
-: exec "silent !rm -rf " . a:dir
-: endif
-:endfun
+:"
:if has("unix")
:let $CDIR = "."
/CDIR
@@ -36,7 +30,7 @@ STARTTEST
:" check for 'include' without \zs or \ze
:lang C
:call delete("./Xbase.a")
-:call DeleteDirectory("Xdir1")
+:call delete("Xdir1", "rf")
:!mkdir Xdir1
:!mkdir "Xdir1/dir2"
:e! Xdir1/dir2/foo.a
@@ -61,7 +55,7 @@ ENDTEST
STARTTEST
:" check for 'include' with \zs and \ze
:call delete("./Xbase.b")
-:call DeleteDirectory("Xdir1")
+:call delete("Xdir1", "rf")
:!mkdir Xdir1
:!mkdir "Xdir1/dir2"
:let &include='^\s*%inc\s*/\zs[^/]\+\ze'
@@ -91,7 +85,7 @@ ENDTEST
STARTTEST
:" check for 'include' with \zs and no \ze
:call delete("./Xbase.c")
-:call DeleteDirectory("Xdir1")
+:call delete("Xdir1", "rf")
:!mkdir Xdir1
:!mkdir "Xdir1/dir2"
:let &include='^\s*%inc\s*\%([[:upper:]][^[:space:]]*\s\+\)\?\zs\S\+\ze'
diff --git a/src/nvim/testdir/test49.vim b/src/nvim/testdir/test49.vim
index edd49a2b63..467abcd9b9 100644
--- a/src/nvim/testdir/test49.vim
+++ b/src/nvim/testdir/test49.vim
@@ -456,7 +456,7 @@ function! ExtraVim(...)
" messing up the user's viminfo file.
let redirect = a:0 ?
\ " -c 'au VimLeave * redir END' -c 'redir\\! >" . a:1 . "'" : ""
- exec "!echo '" . debug_quits . "q' | ../../../build/bin/nvim -u NONE -N -es" . redirect .
+ exec "!echo '" . debug_quits . "q' | $NVIM_PRG -u NONE -N -es" . redirect .
\ " -c 'debuggreedy|set viminfo+=nviminfo'" .
\ " -c 'let ExtraVimBegin = " . extra_begin . "'" .
\ " -c 'let ExtraVimResult = \"" . resultfile . "\"'" . breakpoints .
@@ -608,7 +608,7 @@ com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
" END_OF_TEST_ENVIRONMENT - do not change or remove this line.
-" Tests 1 to 15 were moved to test_viml.vim
+" Tests 1 to 15 were moved to test_vimscript.vim
let Xtest = 16
"-------------------------------------------------------------------------------
diff --git a/src/nvim/testdir/test69.in b/src/nvim/testdir/test69.in
deleted file mode 100644
index 39b360fc81..0000000000
--- a/src/nvim/testdir/test69.in
+++ /dev/null
@@ -1,191 +0,0 @@
-Test for multi-byte text formatting.
-Also test, that 'mps' with multibyte chars works.
-And test "ra" on multi-byte characters.
-Also test byteidx() and byteidxcomp()
-
-STARTTEST
-:
-ENDTEST
-
-Results of test69:
-
-STARTTEST
-/^{/+1
-:set tw=2 fo=t
-gqgqjgqgqo
-XYZ
-abc XYZ
-ENDTEST
-
-{
-XYZ
-abc XYZ
-}
-
-STARTTEST
-/^{/+1
-:set tw=1 fo=tm
-gqgqjgqgqjgqgqjgqgqjgqgqo
-X
-Xa
-X a
-XY
-X Y
-ENDTEST
-
-{
-X
-Xa
-X a
-XY
-X Y
-}
-
-STARTTEST
-/^{/+1
-:set tw=2 fo=tm
-gqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqo
-X
-Xa
-X a
-XY
-X Y
-aX
-abX
-abcX
-abX c
-abXY
-ENDTEST
-
-{
-X
-Xa
-X a
-XY
-X Y
-aX
-abX
-abcX
-abX c
-abXY
-}
-
-STARTTEST
-/^{/+1
-:set ai tw=2 fo=tm
-gqgqjgqgqo
-X
-Xa
-ENDTEST
-
-{
- X
- Xa
-}
-
-STARTTEST
-/^{/+1
-:set noai tw=2 fo=tm
-gqgqjgqgqo
- X
- Xa
-ENDTEST
-
-{
- X
- Xa
-}
-
-STARTTEST
-/^{/+1
-:set tw=2 fo=cqm comments=n:X
-gqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqo
-X
-Xa
-XaY
-XY
-XYZ
-X Y
-X YZ
-XX
-XXa
-XXY
-ENDTEST
-
-{
-X
-Xa
-XaY
-XY
-XYZ
-X Y
-X YZ
-XX
-XXa
-XXY
-}
-
-STARTTEST
-/^{/+1
-:set tw=2 fo=tm
-RXa
-ENDTEST
-
-{
-
-}
-
-STARTTEST
-/^{/+1
-:set mps+=u2018:u2019
-d%
-ENDTEST
-
-{
-‘ two three ’ four
-}
-STARTTEST
-/^ra test
-jVjra
-ENDTEST
-
-ra test
-ï½bbï½
-ï½ï½b
-
-STARTTEST
-:set whichwrap+=h
-/^x
-dh
-:set whichwrap-=h
-ENDTEST
-
-á
-x
-
-STARTTEST
-:let a = '.é.' " one char of two bytes
-:let b = '.eÌ.' " normal e with composing char
-/^byteidx
-:put =string([byteidx(a, 0), byteidx(a, 1), byteidx(a, 2), byteidx(a, 3), byteidx(a, 4)])
-:put =string([byteidx(b, 0), byteidx(b, 1), byteidx(b, 2), byteidx(b, 3), byteidx(b, 4)])
-/^byteidxcomp
-:put =string([byteidxcomp(a, 0), byteidxcomp(a, 1), byteidxcomp(a, 2), byteidxcomp(a, 3), byteidxcomp(a, 4)])
-:let b = '.eÌ.'
-:put =string([byteidxcomp(b, 0), byteidxcomp(b, 1), byteidxcomp(b, 2), byteidxcomp(b, 3), byteidxcomp(b, 4), byteidxcomp(b, 5)])
-ENDTEST
-
-byteidx
-byteidxcomp
-
-STARTTEST
-/^substitute
-:let y = substitute('123', '\zs', 'a', 'g') | put =y
-ENDTEST
-
-substitute
-
-STARTTEST
-:g/^STARTTEST/.,/^ENDTEST/d
-:1;/^Results/,$wq! test.out
-ENDTEST
diff --git a/src/nvim/testdir/test69.ok b/src/nvim/testdir/test69.ok
deleted file mode 100644
index af8befb0c7..0000000000
--- a/src/nvim/testdir/test69.ok
+++ /dev/null
@@ -1,166 +0,0 @@
-Results of test69:
-
-
-{
-XYZ
-abc
-XYZ
-
-XYZ
-abc
-XYZ
-}
-
-
-{
-X
-X
-a
-X
-a
-X
-ï¼¹
-X
-ï¼¹
-
-X
-X
-a
-X
-a
-X
-ï¼¹
-X
-ï¼¹
-}
-
-
-{
-X
-X
-a
-X
-a
-X
-ï¼¹
-X
-ï¼¹
-a
-X
-ab
-X
-abc
-X
-ab
-X
-c
-ab
-X
-ï¼¹
-
-X
-X
-a
-X
-a
-X
-ï¼¹
-X
-ï¼¹
-a
-X
-ab
-X
-abc
-X
-ab
-X
-c
-ab
-X
-ï¼¹
-}
-
-
-{
- X
- X
- a
-
- X
- X
- a
-}
-
-
-{
- X
- X
-a
-
- X
- X
-a
-}
-
-
-{
-X
-Xa
-Xa
-XY
-XY
-XY
-XZ
-X Y
-X Y
-X Z
-XX
-XXa
-XXY
-
-X
-Xa
-Xa
-XY
-XY
-XY
-XZ
-X Y
-X Y
-X Z
-XX
-XXa
-XXY
-}
-
-
-{
-X
-a
-}
-
-
-{
- four
-}
-
-ra test
-aaaa
-aaa
-
-
-áx
-
-
-byteidx
-[0, 1, 3, 4, -1]
-[0, 1, 4, 5, -1]
-byteidxcomp
-[0, 1, 3, 4, -1]
-[0, 1, 2, 4, 5, -1]
-
-
-substitute
-a1a2a3a
-
diff --git a/src/nvim/testdir/test73.in b/src/nvim/testdir/test73.in
index 7d6c7287a5..9d50f7a789 100644
--- a/src/nvim/testdir/test73.in
+++ b/src/nvim/testdir/test73.in
@@ -8,16 +8,9 @@ STARTTEST
:" This will cause a few errors, do it silently.
:set visualbell
:"
-:function! DeleteDirectory(dir)
-: if has("win16") || has("win32") || has("win64") || has("dos16") || has("dos32")
-: exec "silent !rmdir /Q /S " . a:dir
-: else
-: exec "silent !rm -rf " . a:dir
-: endif
-:endfun
:" On windows a stale "Xfind" directory may exist, remove it so that
:" we start from a clean state.
-:call DeleteDirectory("Xfind")
+:call delete("Xfind", "rf")
:new
:let cwd=getcwd()
:let test_out = cwd . '/test.out'
@@ -169,7 +162,7 @@ SVoyager 2:w
:exec "w >>" . test_out
:q
:exec "cd " . cwd
-:call DeleteDirectory("Xfind")
+:call delete("Xfind", "rf")
:qa!
ENDTEST
diff --git a/src/nvim/testdir/test8.in b/src/nvim/testdir/test8.in
deleted file mode 100644
index a5e6034782..0000000000
--- a/src/nvim/testdir/test8.in
+++ /dev/null
@@ -1,43 +0,0 @@
-Test for BufWritePre autocommand that deletes or unloads the buffer.
-Test for BufUnload autocommand that unloads all other buffers.
-
-STARTTEST
-:au BufWritePre Xxx1 bunload
-:au BufWritePre Xxx2 bwipe
-/^start of
-A1:.,/end of/w! Xxx1 " write test file Xxx1
-$r2:.,/end of/w! Xxx2 " write test file Xxx2
-:e! Xxx2 " edit Xxx2
-:bdel test8.in " delete this file from the buffer list
-:e Xxx1 " edit Xxx1
-:w " write it, will unload it and give an error msg
-:w! test.out " Write contents of this file
-:e! Xxx2 " start editing Xxx2
-:bwipe test.out " remove test.out from the buffer list
-:w " write it, will delete the buffer and give an error msg
-:w >>test.out " Append contents of this file
-:au! BufWritePre
-:func CloseAll()
- let i = 0
- while i <= bufnr('$')
- if i != bufnr('%') && bufloaded(i)
- exe i . "bunload"
- endif
- let i += 1
- endwhile
-endfunc
-:func WriteToOut()
- edit! test.out
- $put ='VimLeave done'
- write
-endfunc
-:set shada='100
-:au BufUnload * call CloseAll()
-:au VimLeave * call WriteToOut()
-:q
-:qa!
-ENDTEST
-
-start of Xxx
- test
-end of Xxx
diff --git a/src/nvim/testdir/test8.ok b/src/nvim/testdir/test8.ok
deleted file mode 100644
index adecb2f4be..0000000000
--- a/src/nvim/testdir/test8.ok
+++ /dev/null
@@ -1,7 +0,0 @@
-start of Xxx2
- test
-end of Xxx
-start of Xxx1
- test
-end of Xxx
-VimLeave done
diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim
index 60248bf430..d55170c27c 100644
--- a/src/nvim/testdir/test_alot.vim
+++ b/src/nvim/testdir/test_alot.vim
@@ -2,27 +2,36 @@
" This makes testing go faster, since Vim doesn't need to restart.
source test_assign.vim
-source test_autocmd.vim
source test_cursor_func.vim
source test_execute_func.vim
source test_ex_undo.vim
source test_expr.vim
source test_expr_utf8.vim
source test_feedkeys.vim
+source test_filter_cmd.vim
+source test_filter_map.vim
+source test_float_func.vim
+source test_functions.vim
source test_goto.vim
source test_jumps.vim
-source test_match.vim
-source test_matchadd_conceal_utf8.vim
+source test_fileformat.vim
+source test_lambda.vim
source test_menu.vim
+source test_mapping.vim
source test_messages.vim
source test_options.vim
source test_partial.vim
source test_popup.vim
source test_regexp_utf8.vim
+source test_source_utf8.vim
source test_statusline.vim
source test_syn_attr.vim
source test_tabline.vim
-source test_tabpage.vim
+" source test_tabpage.vim
+source test_tagcase.vim
source test_tagjump.vim
+source test_taglist.vim
+source test_true_false.vim
source test_unlet.vim
+source test_utf8.vim
source test_window_cmd.vim
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index 5675697dc4..835df42a10 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -1,5 +1,15 @@
" Tests for autocommands
+set belloff=all
+
+function! s:cleanup_buffers() abort
+ for bnr in range(1, bufnr('$'))
+ if bufloaded(bnr) && bufnr('%') != bnr
+ execute 'bd! ' . bnr
+ endif
+ endfor
+endfunction
+
func Test_vim_did_enter()
call assert_false(v:vim_did_enter)
@@ -13,6 +23,9 @@ if has('timers')
endfunc
func Test_cursorhold_insert()
+ " Need to move the cursor.
+ call feedkeys("ggG", "xt")
+
let g:triggered = 0
au CursorHoldI * let g:triggered += 1
set updatetime=20
@@ -20,6 +33,7 @@ if has('timers')
call feedkeys('a', 'x!')
call assert_equal(1, g:triggered)
au! CursorHoldI
+ set updatetime&
endfunc
func Test_cursorhold_insert_ctrl_x()
@@ -31,6 +45,7 @@ if has('timers')
call feedkeys("a\<C-X>", 'x!')
call assert_equal(0, g:triggered)
au! CursorHoldI
+ set updatetime&
endfunc
endif
@@ -64,6 +79,115 @@ function Test_bufunload()
augroup! test_bufunload_group
endfunc
+" SEGV occurs in older versions. (At least 7.4.2005 or older)
+function Test_autocmd_bufunload_with_tabnext()
+ tabedit
+ tabfirst
+
+ augroup test_autocmd_bufunload_with_tabnext_group
+ autocmd!
+ autocmd BufUnload <buffer> tabnext
+ augroup END
+
+ quit
+ call assert_equal(2, tabpagenr('$'))
+
+ autocmd! test_autocmd_bufunload_with_tabnext_group
+ augroup! test_autocmd_bufunload_with_tabnext_group
+ tablast
+ quit
+endfunc
+
+function Test_autocmd_bufwinleave_with_tabfirst()
+ tabedit
+ augroup sample
+ autocmd!
+ autocmd BufWinLeave <buffer> tabfirst
+ augroup END
+ call setline(1, ['a', 'b', 'c'])
+ edit! a.txt
+ tabclose
+endfunc
+
+" SEGV occurs in older versions. (At least 7.4.2321 or older)
+function Test_autocmd_bufunload_avoiding_SEGV_01()
+ split aa.txt
+ let lastbuf = bufnr('$')
+
+ augroup test_autocmd_bufunload
+ autocmd!
+ exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!'
+ augroup END
+
+ call assert_fails('edit bb.txt', 'E937:')
+
+ autocmd! test_autocmd_bufunload
+ augroup! test_autocmd_bufunload
+ bwipe! aa.txt
+ bwipe! bb.txt
+endfunc
+
+" SEGV occurs in older versions. (At least 7.4.2321 or older)
+function Test_autocmd_bufunload_avoiding_SEGV_02()
+ setlocal buftype=nowrite
+ let lastbuf = bufnr('$')
+
+ augroup test_autocmd_bufunload
+ autocmd!
+ exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!'
+ augroup END
+
+ normal! i1
+ call assert_fails('edit a.txt', 'E517:')
+ call feedkeys("\<CR>")
+
+ autocmd! test_autocmd_bufunload
+ augroup! test_autocmd_bufunload
+ bwipe! a.txt
+endfunc
+
+func Test_win_tab_autocmd()
+ let g:record = []
+
+ augroup testing
+ au WinNew * call add(g:record, 'WinNew')
+ au WinEnter * call add(g:record, 'WinEnter')
+ au WinLeave * call add(g:record, 'WinLeave')
+ au TabNew * call add(g:record, 'TabNew')
+ au TabClosed * call add(g:record, 'TabClosed')
+ au TabEnter * call add(g:record, 'TabEnter')
+ au TabLeave * call add(g:record, 'TabLeave')
+ augroup END
+
+ split
+ tabnew
+ close
+ close
+
+ call assert_equal([
+ \ 'WinLeave', 'WinNew', 'WinEnter',
+ \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
+ \ 'WinLeave', 'TabLeave', 'TabClosed', 'WinEnter', 'TabEnter',
+ \ 'WinLeave', 'WinEnter'
+ \ ], g:record)
+
+ let g:record = []
+ tabnew somefile
+ tabnext
+ bwipe somefile
+
+ call assert_equal([
+ \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
+ \ 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter',
+ \ 'TabClosed'
+ \ ], g:record)
+
+ augroup testing
+ au!
+ augroup END
+ unlet g:record
+endfunc
+
func s:AddAnAutocmd()
augroup vimBarTest
au BufReadCmd * echo 'hello'
@@ -91,3 +215,208 @@ func Test_early_bar()
au! vimBarTest|echo 'hello'
call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
endfunc
+
+func RemoveGroup()
+ autocmd! StartOK
+ augroup! StartOK
+endfunc
+
+func Test_augroup_warning()
+ augroup TheWarning
+ au VimEnter * echo 'entering'
+ augroup END
+ call assert_true(match(execute('au VimEnter'), "TheWarning.*VimEnter") >= 0)
+ redir => res
+ augroup! TheWarning
+ redir END
+ call assert_true(match(res, "W19:") >= 0)
+ call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0)
+
+ " check "Another" does not take the pace of the deleted entry
+ augroup Another
+ augroup END
+ call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0)
+ augroup! Another
+
+ " no warning for postpone aucmd delete
+ augroup StartOK
+ au VimEnter * call RemoveGroup()
+ augroup END
+ call assert_true(match(execute('au VimEnter'), "StartOK.*VimEnter") >= 0)
+ redir => res
+ doautocmd VimEnter
+ redir END
+ call assert_true(match(res, "W19:") < 0)
+ au! VimEnter
+endfunc
+
+func Test_augroup_deleted()
+ " This caused a crash before E936 was introduced
+ augroup x
+ call assert_fails('augroup! x', 'E936:')
+ au VimEnter * echo
+ augroup end
+ augroup! x
+ call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0)
+ au! VimEnter
+endfunc
+
+" Tests for autocommands on :close command.
+" This used to be in test13.
+func Test_three_windows()
+ " Clean up buffers, because in some cases this function fails.
+ call s:cleanup_buffers()
+
+ " Write three files and open them, each in a window.
+ " Then go to next window, with autocommand that deletes the previous one.
+ " Do this twice, writing the file.
+ e! Xtestje1
+ call setline(1, 'testje1')
+ w
+ sp Xtestje2
+ call setline(1, 'testje2')
+ w
+ sp Xtestje3
+ call setline(1, 'testje3')
+ w
+ wincmd w
+ au WinLeave Xtestje2 bwipe
+ wincmd w
+ call assert_equal('Xtestje1', expand('%'))
+
+ au WinLeave Xtestje1 bwipe Xtestje3
+ close
+ call assert_equal('Xtestje1', expand('%'))
+
+ " Test deleting the buffer on a Unload event. If this goes wrong there
+ " will be the ATTENTION prompt.
+ e Xtestje1
+ au!
+ au! BufUnload Xtestje1 bwipe
+ call assert_fails('e Xtestje3', 'E937:')
+ call assert_equal('Xtestje3', expand('%'))
+
+ e Xtestje2
+ sp Xtestje1
+ call assert_fails('e', 'E937:')
+ call assert_equal('Xtestje2', expand('%'))
+
+ " Test changing buffers in a BufWipeout autocommand. If this goes wrong
+ " there are ml_line errors and/or a Crash.
+ au!
+ only
+ e Xanother
+ e Xtestje1
+ bwipe Xtestje2
+ bwipe Xtestje3
+ au BufWipeout Xtestje1 buf Xtestje1
+ bwipe
+ call assert_equal('Xanother', expand('%'))
+
+ only
+
+ helptags ALL
+ help
+ wincmd w
+ 1quit
+ call assert_equal('Xanother', expand('%'))
+
+ au!
+ enew
+ bwipe! Xtestje1
+ call delete('Xtestje1')
+ call delete('Xtestje2')
+ call delete('Xtestje3')
+endfunc
+
+func Test_BufEnter()
+ au! BufEnter
+ au Bufenter * let val = val . '+'
+ let g:val = ''
+ split NewFile
+ call assert_equal('+', g:val)
+ bwipe!
+ call assert_equal('++', g:val)
+
+ " Also get BufEnter when editing a directory
+ call mkdir('Xdir')
+ split Xdir
+ call assert_equal('+++', g:val)
+
+ " On MS-Windows we can't edit the directory, make sure we wipe the right
+ " buffer.
+ bwipe! Xdir
+
+ call delete('Xdir', 'd')
+ au! BufEnter
+endfunc
+
+" Closing a window might cause an endless loop
+" E814 for older Vims
+function Test_autocmd_bufwipe_in_SessLoadPost()
+ tabnew
+ set noswapfile
+ mksession!
+
+ let content = ['set nocp noswapfile',
+ \ 'let v:swapchoice="e"',
+ \ 'augroup test_autocmd_sessionload',
+ \ 'autocmd!',
+ \ 'autocmd SessionLoadPost * 4bw!',
+ \ 'augroup END',
+ \ '',
+ \ 'func WriteErrors()',
+ \ ' call writefile([execute("messages")], "Xerrors")',
+ \ 'endfunc',
+ \ 'au VimLeave * call WriteErrors()',
+ \ ]
+ call writefile(content, 'Xvimrc')
+ call system(v:progpath. ' --headless -i NONE -u Xvimrc --noplugins -S Session.vim -c cq')
+ let errors = join(readfile('Xerrors'))
+ call assert_match('E814', errors)
+
+ set swapfile
+ for file in ['Session.vim', 'Xvimrc', 'Xerrors']
+ call delete(file)
+ endfor
+endfunc
+
+" SEGV occurs in older versions.
+function Test_autocmd_bufwipe_in_SessLoadPost2()
+ tabnew
+ set noswapfile
+ mksession!
+
+ let content = ['set nocp noswapfile',
+ \ 'function! DeleteInactiveBufs()',
+ \ ' tabfirst',
+ \ ' let tabblist = []',
+ \ ' for i in range(1, tabpagenr(''$''))',
+ \ ' call extend(tabblist, tabpagebuflist(i))',
+ \ ' endfor',
+ \ ' for b in range(1, bufnr(''$''))',
+ \ ' if bufexists(b) && buflisted(b) && (index(tabblist, b) == -1 || bufname(b) =~# ''^$'')',
+ \ ' exec ''bwipeout '' . b',
+ \ ' endif',
+ \ ' endfor',
+ \ ' echomsg "SessionLoadPost DONE"',
+ \ 'endfunction',
+ \ 'au SessionLoadPost * call DeleteInactiveBufs()',
+ \ '',
+ \ 'func WriteErrors()',
+ \ ' call writefile([execute("messages")], "Xerrors")',
+ \ 'endfunc',
+ \ 'au VimLeave * call WriteErrors()',
+ \ ]
+ call writefile(content, 'Xvimrc')
+ call system(v:progpath. ' --headless -i NONE -u Xvimrc --noplugins -S Session.vim -c cq')
+ let errors = join(readfile('Xerrors'))
+ " This probably only ever matches on unix.
+ call assert_notmatch('Caught deadly signal SEGV', errors)
+ call assert_match('SessionLoadPost DONE', errors)
+
+ set swapfile
+ for file in ['Session.vim', 'Xvimrc', 'Xerrors']
+ call delete(file)
+ endfor
+endfunc
diff --git a/src/nvim/testdir/test_breakindent.vim b/src/nvim/testdir/test_breakindent.vim
new file mode 100644
index 0000000000..7deffbe452
--- /dev/null
+++ b/src/nvim/testdir/test_breakindent.vim
@@ -0,0 +1,298 @@
+" Test for breakindent
+"
+" Note: if you get strange failures when adding new tests, it might be that
+" while the test is run, the breakindent cacheing gets in its way.
+" It helps to change the tabstop setting and force a redraw (e.g. see
+" Test_breakindent08())
+if !exists('+breakindent')
+ finish
+endif
+
+source view_util.vim
+
+let s:input ="\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP"
+
+function s:screen_lines(lnum, width) abort
+ return ScreenLines([a:lnum, a:lnum + 2], a:width)
+endfunction
+
+function! s:compare_lines(expect, actual)
+ call assert_equal(join(a:expect, "\n"), join(a:actual, "\n"))
+endfunction
+
+function s:test_windows(...)
+ call NewWindow(10, 20)
+ setl ts=4 sw=4 sts=4 breakindent
+ put =s:input
+ exe get(a:000, 0, '')
+endfunction
+
+function s:close_windows(...)
+ call CloseWindow()
+ exe get(a:000, 0, '')
+endfunction
+
+function Test_breakindent01()
+ " simple breakindent test
+ call s:test_windows('setl briopt=min:0')
+ let lines=s:screen_lines(line('.'),8)
+ let expect=[
+\ " abcd",
+\ " qrst",
+\ " GHIJ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunction
+
+function Test_breakindent02()
+ " simple breakindent test with showbreak set
+ call s:test_windows('setl briopt=min:0 sbr=>>')
+ let lines=s:screen_lines(line('.'),8)
+ let expect=[
+\ " abcd",
+\ " >>qr",
+\ " >>EF",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent03()
+ " simple breakindent test with showbreak set and briopt including sbr
+ call s:test_windows('setl briopt=sbr,min:0 sbr=++')
+ let lines=s:screen_lines(line('.'),8)
+ let expect=[
+\ " abcd",
+\ "++ qrst",
+\ "++ GHIJ",
+\ ]
+ call s:compare_lines(expect, lines)
+ " clean up
+ call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent04()
+ " breakindent set with min width 18
+ call s:test_windows('setl sbr= briopt=min:18')
+ let lines=s:screen_lines(line('.'),8)
+ let expect=[
+\ " abcd",
+\ " qrstuv",
+\ " IJKLMN",
+\ ]
+ call s:compare_lines(expect, lines)
+ " clean up
+ call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent05()
+ " breakindent set and shift by 2
+ call s:test_windows('setl briopt=shift:2,min:0')
+ let lines=s:screen_lines(line('.'),8)
+ let expect=[
+\ " abcd",
+\ " qr",
+\ " EF",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunction
+
+function Test_breakindent06()
+ " breakindent set and shift by -1
+ call s:test_windows('setl briopt=shift:-1,min:0')
+ let lines=s:screen_lines(line('.'),8)
+ let expect=[
+\ " abcd",
+\ " qrstu",
+\ " HIJKL",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunction
+
+function Test_breakindent07()
+ " breakindent set and shift by 1, Number set sbr=? and briopt:sbr
+ call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4 cpo+=n')
+ let lines=s:screen_lines(line('.'),10)
+ let expect=[
+\ " 2 ab",
+\ "? m",
+\ "? x",
+\ ]
+ call s:compare_lines(expect, lines)
+ " clean up
+ call s:close_windows('set sbr= cpo-=n')
+endfunction
+
+function Test_breakindent07a()
+ " breakindent set and shift by 1, Number set sbr=? and briopt:sbr
+ call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4')
+ let lines=s:screen_lines(line('.'),10)
+ let expect=[
+\ " 2 ab",
+\ " ? m",
+\ " ? x",
+\ ]
+ call s:compare_lines(expect, lines)
+ " clean up
+ call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent08()
+ " breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr
+ call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list cpo+=n ts=4')
+ " make sure, cache is invalidated!
+ set ts=8
+ redraw!
+ set ts=4
+ redraw!
+ let lines=s:screen_lines(line('.'),10)
+ let expect=[
+\ " 2 ^Iabcd",
+\ "# opq",
+\ "# BCD",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows('set sbr= cpo-=n')
+endfunction
+
+function Test_breakindent08a()
+ " breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr
+ call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list')
+ let lines=s:screen_lines(line('.'),10)
+ let expect=[
+\ " 2 ^Iabcd",
+\ " # opq",
+\ " # BCD",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent09()
+ " breakindent set and shift by 1, Number and list set sbr=#
+ call s:test_windows('setl briopt=shift:1,min:0 nu nuw=4 sbr=# list')
+ let lines=s:screen_lines(line('.'),10)
+ let expect=[
+\ " 2 ^Iabcd",
+\ " #op",
+\ " #AB",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent10()
+ " breakindent set, Number set sbr=~
+ call s:test_windows('setl cpo+=n sbr=~ nu nuw=4 nolist briopt=sbr,min:0')
+ " make sure, cache is invalidated!
+ set ts=8
+ redraw!
+ set ts=4
+ redraw!
+ let lines=s:screen_lines(line('.'),10)
+ let expect=[
+\ " 2 ab",
+\ "~ mn",
+\ "~ yz",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows('set sbr= cpo-=n')
+endfunction
+
+function Test_breakindent11()
+ " test strdisplaywidth()
+ call s:test_windows('setl cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4')
+ let text=getline(2)
+ let width = strlen(text[1:])+indent(2)+strlen(&sbr)*3 " text wraps 3 times
+ call assert_equal(width, strdisplaywidth(text))
+ call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent12()
+ " test breakindent with long indent
+ let s:input="\t\t\t\t\t{"
+ call s:test_windows('setl breakindent linebreak briopt=min:10 nu numberwidth=3 ts=4 list listchars=tab:>-')
+ let lines=s:screen_lines(2,16)
+ let expect=[
+\ " 2 >--->--->--->",
+\ " ---{ ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows('set nuw=4 listchars=')
+endfunction
+
+function Test_breakindent13()
+ let s:input=""
+ call s:test_windows('setl breakindent briopt=min:10 ts=8')
+ vert resize 20
+ call setline(1, [" a\tb\tc\td\te", " z y x w v"])
+ 1
+ norm! fbgj"ayl
+ 2
+ norm! fygj"byl
+ call assert_equal('d', @a)
+ call assert_equal('w', @b)
+ call s:close_windows()
+endfunction
+
+function Test_breakindent14()
+ let s:input=""
+ call s:test_windows('setl breakindent briopt= ts=8')
+ vert resize 30
+ norm! 3a1234567890
+ norm! a abcde
+ exec "norm! 0\<C-V>tex"
+ let lines=s:screen_lines(line('.'),8)
+ let expect=[
+\ "e ",
+\ "~ ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunction
+
+function Test_breakindent15()
+ let s:input=""
+ call s:test_windows('setl breakindent briopt= ts=8 sw=8')
+ vert resize 30
+ norm! 4a1234567890
+ exe "normal! >>\<C-V>3f0x"
+ let lines=s:screen_lines(line('.'),20)
+ let expect=[
+\ " 1234567890 ",
+\ "~ ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunction
+
+function Test_breakindent16()
+ " Check that overlong lines are indented correctly.
+ let s:input=""
+ call s:test_windows('setl breakindent briopt=min:0 ts=4')
+ call setline(1, "\t".repeat("1234567890", 10))
+ resize 6
+ norm! 1gg$
+ redraw!
+ let lines=s:screen_lines(1,10)
+ let expect=[
+\ " 789012",
+\ " 345678",
+\ " 901234",
+\ ]
+ call s:compare_lines(expect, lines)
+ let lines=s:screen_lines(4,10)
+ let expect=[
+\ " 567890",
+\ " 123456",
+\ " 7890 ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunction
diff --git a/src/nvim/testdir/test_bufwintabinfo.vim b/src/nvim/testdir/test_bufwintabinfo.vim
index 5c916e2dd7..1c9350c416 100644
--- a/src/nvim/testdir/test_bufwintabinfo.vim
+++ b/src/nvim/testdir/test_bufwintabinfo.vim
@@ -87,9 +87,17 @@ function Test_get_buf_options()
endfunc
function Test_get_win_options()
+ if has('folding')
+ set foldlevel=999
+ endif
+ set list
let opts = getwinvar(1, '&')
call assert_equal(v:t_dict, type(opts))
call assert_equal(0, opts.linebreak)
+ call assert_equal(1, opts.list)
+ if has('folding')
+ call assert_equal(999, opts.foldlevel)
+ endif
if has('signs')
call assert_equal('auto', opts.signcolumn)
endif
@@ -97,7 +105,12 @@ function Test_get_win_options()
let opts = gettabwinvar(1, 1, '&')
call assert_equal(v:t_dict, type(opts))
call assert_equal(0, opts.linebreak)
+ call assert_equal(1, opts.list)
if has('signs')
call assert_equal('auto', opts.signcolumn)
endif
+ set list&
+ if has('folding')
+ set foldlevel=0
+ endif
endfunc
diff --git a/src/nvim/testdir/test_charsearch.vim b/src/nvim/testdir/test_charsearch.vim
new file mode 100644
index 0000000000..8b313b5a35
--- /dev/null
+++ b/src/nvim/testdir/test_charsearch.vim
@@ -0,0 +1,62 @@
+
+function! Test_charsearch()
+ enew!
+ call append(0, ['Xabcdefghijkemnopqretuvwxyz',
+ \ 'Yabcdefghijkemnopqretuvwxyz',
+ \ 'Zabcdefghijkemnokqretkvwxyz'])
+ " check that "fe" and ";" work
+ 1
+ normal! ylfep;;p,,p
+ call assert_equal('XabcdeXfghijkeXmnopqreXtuvwxyz', getline(1))
+ " check that save/restore works
+ 2
+ normal! ylfep
+ let csave = getcharsearch()
+ normal! fip
+ call setcharsearch(csave)
+ normal! ;p;p
+ call assert_equal('YabcdeYfghiYjkeYmnopqreYtuvwxyz', getline(2))
+
+ " check that setcharsearch() changes the settings.
+ 3
+ normal! ylfep
+ call setcharsearch({'char': 'k'})
+ normal! ;p
+ call setcharsearch({'forward': 0})
+ normal! $;p
+ call setcharsearch({'until': 1})
+ set cpo-=;
+ normal! ;;p
+ call assert_equal('ZabcdeZfghijkZZemnokqretkZvwxyz', getline(3))
+ enew!
+endfunction
+
+" Test for t,f,F,T movement commands and 'cpo-;' setting
+function! Test_search_cmds()
+ enew!
+ call append(0, ["aaa two three four", " zzz", "yyy ",
+ \ "bbb yee yoo four", "ccc two three four",
+ \ "ddd yee yoo four"])
+ set cpo-=;
+ 1
+ normal! 0tt;D
+ 2
+ normal! 0fz;D
+ 3
+ normal! $Fy;D
+ 4
+ normal! $Ty;D
+ set cpo+=;
+ 5
+ normal! 0tt;;D
+ 6
+ normal! $Ty;;D
+
+ call assert_equal('aaa two', getline(1))
+ call assert_equal(' z', getline(2))
+ call assert_equal('y', getline(3))
+ call assert_equal('bbb y', getline(4))
+ call assert_equal('ccc', getline(5))
+ call assert_equal('ddd yee y', getline(6))
+ enew!
+endfunction
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim
index 21bb057fe1..2facffb067 100644
--- a/src/nvim/testdir/test_cmdline.vim
+++ b/src/nvim/testdir/test_cmdline.vim
@@ -2,7 +2,7 @@
func Test_complete_tab()
call writefile(['testfile'], 'Xtestfile')
- call feedkeys(":e Xtest\t\r", "tx")
+ call feedkeys(":e Xtestf\t\r", "tx")
call assert_equal('testfile', getline(1))
call delete('Xtestfile')
endfunc
@@ -17,7 +17,7 @@ func Test_complete_wildmenu()
call writefile(['testfile1'], 'Xtestfile1')
call writefile(['testfile2'], 'Xtestfile2')
set wildmenu
- call feedkeys(":e Xtest\t\t\r", "tx")
+ call feedkeys(":e Xtestf\t\t\r", "tx")
call assert_equal('testfile2', getline(1))
call delete('Xtestfile1')
@@ -85,6 +85,11 @@ func Test_getcompletion()
let l = getcompletion('paint', 'function')
call assert_equal([], l)
+ let Flambda = {-> 'hello'}
+ let l = getcompletion('', 'function')
+ let l = filter(l, {i, v -> v =~ 'lambda'})
+ call assert_equal(0, len(l))
+
let l = getcompletion('run', 'file')
call assert_true(index(l, 'runtest.vim') >= 0)
let l = getcompletion('walk', 'file')
@@ -125,6 +130,11 @@ func Test_getcompletion()
let l = getcompletion('dark', 'highlight')
call assert_equal([], l)
+ let l = getcompletion('', 'messages')
+ call assert_true(index(l, 'clear') >= 0)
+ let l = getcompletion('not', 'messages')
+ call assert_equal([], l)
+
if has('cscope')
let l = getcompletion('', 'cscope')
let cmds = ['add', 'find', 'help', 'kill', 'reset', 'show']
@@ -151,6 +161,20 @@ func Test_getcompletion()
call assert_equal(['Testing'], l)
endif
+ " Command line completion tests
+ let l = getcompletion('cd ', 'cmdline')
+ call assert_true(index(l, 'sautest/') >= 0)
+ let l = getcompletion('cd NoMatch', 'cmdline')
+ call assert_equal([], l)
+ let l = getcompletion('let v:n', 'cmdline')
+ call assert_true(index(l, 'v:null') >= 0)
+ let l = getcompletion('let v:notexists', 'cmdline')
+ call assert_equal([], l)
+ let l = getcompletion('call tag', 'cmdline')
+ call assert_true(index(l, 'taglist(') >= 0)
+ let l = getcompletion('call paint', 'cmdline')
+ call assert_equal([], l)
+
" For others test if the name is recognized.
let names = ['buffer', 'environment', 'file_in_path',
\ 'mapping', 'shellcmd', 'tag', 'tag_listfiles', 'user']
@@ -182,5 +206,53 @@ func Test_expand_star_star()
call writefile(['asdfasdf'], 'a/b/fileXname')
call feedkeys(":find **/fileXname\<Tab>\<CR>", 'xt')
call assert_equal('find a/b/fileXname', getreg(':'))
+ bwipe!
call delete('a', 'rf')
endfunc
+
+func Test_paste_in_cmdline()
+ let @a = "def"
+ call feedkeys(":abc \<C-R>a ghi\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"abc def ghi', @:)
+
+ new
+ call setline(1, 'asdf.x /tmp/some verylongword a;b-c*d ')
+
+ call feedkeys(":aaa \<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"aaa asdf bbb', @:)
+
+ call feedkeys("ft:aaa \<C-R>\<C-F> bbb\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"aaa /tmp/some bbb', @:)
+
+ set incsearch
+ call feedkeys("fy:aaa veryl\<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"aaa verylongword bbb', @:)
+
+ call feedkeys("f;:aaa \<C-R>\<C-A> bbb\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"aaa a;b-c*d bbb', @:)
+
+ call feedkeys(":\<C-\>etoupper(getline(1))\<CR>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"ASDF.X /TMP/SOME VERYLONGWORD A;B-C*D ', @:)
+ bwipe!
+endfunc
+
+func Test_remove_char_in_cmdline()
+ call feedkeys(":abc def\<S-Left>\<Del>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"abc ef', @:)
+
+ call feedkeys(":abc def\<S-Left>\<BS>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"abcdef', @:)
+
+ call feedkeys(":abc def ghi\<S-Left>\<C-W>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"abc ghi', @:)
+
+ call feedkeys(":abc def\<S-Left>\<C-U>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"def', @:)
+endfunc
+
+func Test_illegal_address()
+ new
+ 2;'(
+ 2;')
+ quit
+endfunc
diff --git a/src/nvim/testdir/test_command_count.vim b/src/nvim/testdir/test_command_count.vim
new file mode 100644
index 0000000000..e438a8b077
--- /dev/null
+++ b/src/nvim/testdir/test_command_count.vim
@@ -0,0 +1,191 @@
+" Test for user command counts.
+
+func Test_command_count_0()
+ set hidden
+ set noswapfile
+
+ split DoesNotExistEver
+ let lastbuf = bufnr('$')
+ call setline(1, 'asdf')
+ quit!
+
+ command! -range -addr=loaded_buffers RangeLoadedBuffers :let lines = [<line1>, <line2>]
+ command! -range=% -addr=loaded_buffers RangeLoadedBuffersAll :let lines = [<line1>, <line2>]
+ command! -range -addr=buffers RangeBuffers :let lines = [<line1>, <line2>]
+ command! -range=% -addr=buffers RangeBuffersAll :let lines = [<line1>, <line2>]
+
+ .,$RangeLoadedBuffers
+ call assert_equal([1, 1], lines)
+ %RangeLoadedBuffers
+ call assert_equal([1, 1], lines)
+ RangeLoadedBuffersAll
+ call assert_equal([1, 1], lines)
+ .,$RangeBuffers
+ call assert_equal([1, lastbuf], lines)
+ %RangeBuffers
+ call assert_equal([1, lastbuf], lines)
+ RangeBuffersAll
+ call assert_equal([1, lastbuf], lines)
+
+ delcommand RangeLoadedBuffers
+ delcommand RangeLoadedBuffersAll
+ delcommand RangeBuffers
+ delcommand RangeBuffersAll
+
+ set hidden&
+ set swapfile&
+endfunc
+
+func Test_command_count_1()
+ silent! %argd
+ arga a b c d e
+ argdo echo "loading buffers"
+ argu 3
+ command! -range -addr=arguments RangeArguments :let lines = [<line1>, <line2>]
+ command! -range=% -addr=arguments RangeArgumentsAll :let lines = [<line1>, <line2>]
+ .-,$-RangeArguments
+ call assert_equal([2, 4], lines)
+ %RangeArguments
+ call assert_equal([1, 5], lines)
+ RangeArgumentsAll
+ call assert_equal([1, 5], lines)
+ N
+ .RangeArguments
+ call assert_equal([2, 2], lines)
+ delcommand RangeArguments
+ delcommand RangeArgumentsAll
+
+ split|split|split|split
+ 3wincmd w
+ command! -range -addr=windows RangeWindows :let lines = [<line1>, <line2>]
+ .,$RangeWindows
+ call assert_equal([3, 5], lines)
+ %RangeWindows
+ call assert_equal([1, 5], lines)
+ delcommand RangeWindows
+
+ command! -range=% -addr=windows RangeWindowsAll :let lines = [<line1>, <line2>]
+ RangeWindowsAll
+ call assert_equal([1, 5], lines)
+ delcommand RangeWindowsAll
+ only
+ blast|bd
+
+ tabe|tabe|tabe|tabe
+ normal 2gt
+ command! -range -addr=tabs RangeTabs :let lines = [<line1>, <line2>]
+ .,$RangeTabs
+ call assert_equal([2, 5], lines)
+ %RangeTabs
+ call assert_equal([1, 5], lines)
+ delcommand RangeTabs
+
+ command! -range=% -addr=tabs RangeTabsAll :let lines = [<line1>, <line2>]
+ RangeTabsAll
+ call assert_equal([1, 5], lines)
+ delcommand RangeTabsAll
+ 1tabonly
+
+ s/\n/\r\r\r\r\r/
+ 2ma<
+ $-ma>
+ command! -range=% RangeLines :let lines = [<line1>, <line2>]
+ '<,'>RangeLines
+ call assert_equal([2, 5], lines)
+ delcommand RangeLines
+
+ command! -range=% -buffer LocalRangeLines :let lines = [<line1>, <line2>]
+ '<,'>LocalRangeLines
+ call assert_equal([2, 5], lines)
+ delcommand LocalRangeLines
+endfunc
+
+func Test_command_count_2()
+ silent! %argd
+ arga a b c d
+ call assert_fails('5argu', 'E16:')
+
+ $argu
+ call assert_equal('d', expand('%:t'))
+
+ 1argu
+ call assert_equal('a', expand('%:t'))
+
+ call assert_fails('300b', 'E16:')
+
+ split|split|split|split
+ 0close
+
+ $wincmd w
+ $close
+ call assert_equal(3, winnr())
+
+ call assert_fails('$+close', 'E16:')
+
+ $tabe
+ call assert_equal(2, tabpagenr())
+
+ call assert_fails('$+tabe', 'E16:')
+
+ only!
+ e x
+ 0tabm
+ normal 1gt
+ call assert_equal('x', expand('%:t'))
+
+ tabonly!
+ only!
+endfunc
+
+func Test_command_count_3()
+ se nohidden
+ e aaa
+ let buf_aaa = bufnr('%')
+ e bbb
+ let buf_bbb = bufnr('%')
+ e ccc
+ let buf_ccc = bufnr('%')
+ buf 1
+ call assert_equal([1, 1, 1], [buflisted(buf_aaa), buflisted(buf_bbb), buflisted(buf_ccc)])
+ exe buf_bbb . "," . buf_ccc . "bdelete"
+ call assert_equal([1, 0, 0], [buflisted(buf_aaa), buflisted(buf_bbb), buflisted(buf_ccc)])
+ exe buf_aaa . "bdelete"
+ call assert_equal([0, 0, 0], [buflisted(buf_aaa), buflisted(buf_bbb), buflisted(buf_ccc)])
+endfunc
+
+func Test_command_count_4()
+ %argd
+ let bufnr = bufnr('$') + 1
+ arga aa bb cc dd ee ff
+ 3argu
+ let args = []
+ .,$-argdo call add(args, expand('%'))
+ call assert_equal(['cc', 'dd', 'ee'], args)
+
+ " create windows to get 5
+ split|split|split|split
+ 2wincmd w
+ let windows = []
+ .,$-windo call add(windows, winnr())
+ call assert_equal([2, 3, 4], windows)
+ only!
+
+ exe bufnr . 'buf'
+ let buffers = []
+ .,$-bufdo call add(buffers, bufnr('%'))
+ call assert_equal([bufnr, bufnr + 1, bufnr + 2, bufnr + 3, bufnr + 4], buffers)
+
+ exe (bufnr + 3) . 'bdel'
+ let buffers = []
+ exe (bufnr + 2) . ',' . (bufnr + 5) . "bufdo call add(buffers, bufnr('%'))"
+ call assert_equal([bufnr + 2, bufnr + 4, bufnr + 5], buffers)
+
+ " create tabpages to get 5
+ tabe|tabe|tabe|tabe
+ normal! 2gt
+ let tabpages = []
+ .,$-tabdo call add(tabpages, tabpagenr())
+ call assert_equal([2, 3, 4], tabpages)
+ tabonly!
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_cscope.vim b/src/nvim/testdir/test_cscope.vim
index b6d70f0765..01a9a3f9ad 100644
--- a/src/nvim/testdir/test_cscope.vim
+++ b/src/nvim/testdir/test_cscope.vim
@@ -1,9 +1,262 @@
" Test for cscope commands.
-if !has('cscope')
+if !has('cscope') || !executable('cscope') || !has('quickfix')
finish
endif
+func CscopeSetupOrClean(setup)
+ if a:setup
+ noa sp samples/memfile_test.c
+ saveas! Xmemfile_test.c
+ call system('cscope -bk -fXcscope.out Xmemfile_test.c')
+ call system('cscope -bk -fXcscope2.out Xmemfile_test.c')
+ cscope add Xcscope.out
+ set cscopequickfix=s-,g-,d-,c-,t-,e-,f-,i-,a-
+ else
+ cscope kill -1
+ for file in ['Xcscope.out', 'Xcscope2.out', 'Xmemfile_test.c']
+ call delete(file)
+ endfo
+ endif
+endfunc
+
+func Test_cscopeWithCscopeConnections()
+ call CscopeSetupOrClean(1)
+ " Test 0: E568: duplicate cscope database not added
+ try
+ set nocscopeverbose
+ cscope add Xcscope.out
+ set cscopeverbose
+ catch
+ call assert_report('exception thrown')
+ endtry
+ call assert_fails('cscope add', 'E560')
+ call assert_fails('cscope add Xcscope.out', 'E568')
+ call assert_fails('cscope add doesnotexist.out', 'E563')
+
+ " Test 1: Find this C-Symbol
+ for cmd in ['cs find s main', 'cs find 0 main']
+ let a=execute(cmd)
+ " Test 1.1 test where it moves the cursor
+ call assert_equal('main(void)', getline('.'))
+ " Test 1.2 test the output of the :cs command
+ call assert_match('\n(1 of 1): <<main>> main(void )', a)
+ endfor
+
+ " Test 2: Find this definition
+ for cmd in ['cs find g test_mf_hash', 'cs find 1 test_mf_hash']
+ exe cmd
+ call assert_equal(['', '/*', ' * Test mf_hash_*() functions.', ' */', ' static void', 'test_mf_hash(void)', '{'], getline(line('.')-5, line('.')+1))
+ endfor
+
+ " Test 3: Find functions called by this function
+ for cmd in ['cs find d test_mf_hash', 'cs find 2 test_mf_hash']
+ let a=execute(cmd)
+ call assert_match('\n(1 of 42): <<mf_hash_init>> mf_hash_init(&ht);', a)
+ call assert_equal(' mf_hash_init(&ht);', getline('.'))
+ endfor
+
+ " Test 4: Find functions calling this function
+ for cmd in ['cs find c test_mf_hash', 'cs find 3 test_mf_hash']
+ let a=execute(cmd)
+ call assert_match('\n(1 of 1): <<main>> test_mf_hash();', a)
+ call assert_equal(' test_mf_hash();', getline('.'))
+ endfor
+
+ " Test 5: Find this text string
+ for cmd in ['cs find t Bram', 'cs find 4 Bram']
+ let a=execute(cmd)
+ call assert_match('(1 of 1): <<<unknown>>> \* VIM - Vi IMproved^Iby Bram Moolenaar', a)
+ call assert_equal(' * VIM - Vi IMproved by Bram Moolenaar', getline('.'))
+ endfor
+
+ " Test 6: Find this egrep pattern
+ " test all matches returned by cscope
+ for cmd in ['cs find e ^\#includ.', 'cs find 6 ^\#includ.']
+ let a=execute(cmd)
+ call assert_match('\n(1 of 3): <<<unknown>>> #include <assert.h>', a)
+ call assert_equal('#include <assert.h>', getline('.'))
+ cnext
+ call assert_equal('#include "main.c"', getline('.'))
+ cnext
+ call assert_equal('#include "memfile.c"', getline('.'))
+ call assert_fails('cnext', 'E553:')
+ endfor
+
+ " Test 7: Find the same egrep pattern using lcscope this time.
+ let a=execute('lcs find e ^\#includ.')
+ call assert_match('\n(1 of 3): <<<unknown>>> #include <assert.h>', a)
+ call assert_equal('#include <assert.h>', getline('.'))
+ lnext
+ call assert_equal('#include "main.c"', getline('.'))
+ lnext
+ call assert_equal('#include "memfile.c"', getline('.'))
+ call assert_fails('lnext', 'E553:')
+
+ " Test 8: Find this file
+ for cmd in ['cs find f Xmemfile_test.c', 'cs find 7 Xmemfile_test.c']
+ enew
+ let a=execute(cmd)
+ call assert_true(a =~ '"Xmemfile_test.c" \d\+L, \d\+C')
+ call assert_equal('Xmemfile_test.c', @%)
+ endfor
+
+ " Test 9: Find files #including this file
+ for cmd in ['cs find i assert.h', 'cs find 8 assert.h']
+ enew
+ let a=execute(cmd)
+ let alines = split(a, '\n', 1)
+ call assert_equal('', alines[0])
+ call assert_true(alines[1] =~ '"Xmemfile_test.c" \d\+L, \d\+C')
+ call assert_equal('(1 of 1): <<global>> #include <assert.h>', alines[2])
+ call assert_equal('#include <assert.h>', getline('.'))
+ endfor
+
+ " Test 10: Invalid find command
+ call assert_fails('cs find x', 'E560:')
+
+ " Test 11: Find places where this symbol is assigned a value
+ " this needs a cscope >= 15.8
+ " unfortunately, Travis has cscope version 15.7
+ let cscope_version=systemlist('cscope --version')[0]
+ let cs_version=str2float(matchstr(cscope_version, '\d\+\(\.\d\+\)\?'))
+ if cs_version >= 15.8
+ for cmd in ['cs find a item', 'cs find 9 item']
+ let a=execute(cmd)
+ call assert_equal(['', '(1 of 4): <<test_mf_hash>> item = (mf_hashitem_T *)lalloc_clear(sizeof(mf_hashtab_T), FALSE);'], split(a, '\n', 1))
+ call assert_equal(' item = (mf_hashitem_T *)lalloc_clear(sizeof(mf_hashtab_T), FALSE);', getline('.'))
+ cnext
+ call assert_equal(' item = mf_hash_find(&ht, key);', getline('.'))
+ cnext
+ call assert_equal(' item = mf_hash_find(&ht, key);', getline('.'))
+ cnext
+ call assert_equal(' item = mf_hash_find(&ht, key);', getline('.'))
+ endfor
+ endif
+
+ " Test 12: leading whitespace is not removed for cscope find text
+ let a=execute('cscope find t test_mf_hash')
+ call assert_equal(['', '(1 of 1): <<<unknown>>> test_mf_hash();'], split(a, '\n', 1))
+ call assert_equal(' test_mf_hash();', getline('.'))
+
+ " Test 13: test with scscope
+ let a=execute('scs find t Bram')
+ call assert_match('(1 of 1): <<<unknown>>> \* VIM - Vi IMproved^Iby Bram Moolenaar', a)
+ call assert_equal(' * VIM - Vi IMproved by Bram Moolenaar', getline('.'))
+
+ " Test 14: cscope help
+ for cmd in ['cs', 'cs help', 'cs xxx']
+ let a=execute(cmd)
+ call assert_match('^cscope commands:\n', a)
+ call assert_match('\nadd :', a)
+ call assert_match('\nfind :', a)
+ call assert_match('\nhelp : Show this message', a)
+ call assert_match('\nkill : Kill a connection', a)
+ call assert_match('\nreset: Reinit all connections', a)
+ call assert_match('\nshow : Show connections', a)
+ endfor
+ let a=execute('scscope help')
+ call assert_match('This cscope command does not support splitting the window\.', a)
+
+ " Test 15: reset connections
+ let a=execute('cscope reset')
+ call assert_match('\nAdded cscope database.*Xcscope.out (#0)', a)
+ call assert_match('\nAll cscope databases reset', a)
+
+ " Test 16: cscope show
+ let a=execute('cscope show')
+ call assert_match('\n 0 \d\+.*Xcscope.out\s*<none>', a)
+
+ " Test 17: cstag and 'csto' option
+ set csto=0
+ let a=execute('cstag TEST_COUNT')
+ call assert_match('(1 of 1): <<TEST_COUNT>> #define TEST_COUNT 50000', a)
+ call assert_equal('#define TEST_COUNT 50000', getline('.'))
+ set csto=1
+ let a=execute('cstag index_to_key')
+ call assert_match('(1 of 1): <<index_to_key>> #define index_to_key(i) ((i) ^ 15167)', a)
+ call assert_equal('#define index_to_key(i) ((i) ^ 15167)', getline('.'))
+ call assert_fails('cstag xxx', 'E257:')
+ call assert_fails('cstag', 'E562:')
+
+ " Test 18: 'cst' option
+ set nocst
+ call assert_fails('tag TEST_COUNT', 'E426:')
+ set cst
+ let a=execute('tag TEST_COUNT')
+ call assert_match('(1 of 1): <<TEST_COUNT>> #define TEST_COUNT 50000', a)
+ call assert_equal('#define TEST_COUNT 50000', getline('.'))
+ let a=execute('tags')
+ call assert_match('1 1 TEST_COUNT\s\+\d\+\s\+#define index_to_key', a)
+
+ " Test 19: this should trigger call to cs_print_tags()
+ " Unclear how to check result though, we just exercise the code.
+ set cst cscopequickfix=s0
+ call feedkeys(":cs find s main\<CR>", 't')
+
+ " Test 20: cscope kill
+ call assert_fails('cscope kill 2', 'E261:')
+ call assert_fails('cscope kill xxx', 'E261:')
+
+ let a=execute('cscope kill 0')
+ call assert_match('cscope connection 0 closed', a)
+
+ cscope add Xcscope.out
+ let a=execute('cscope kill Xcscope.out')
+ call assert_match('cscope connection Xcscope.out closed', a)
+
+ cscope add Xcscope.out .
+ let a=execute('cscope kill -1')
+ call assert_match('cscope connection .*Xcscope.out closed', a)
+ let a=execute('cscope kill -1')
+ call assert_equal('', a)
+
+ " Test 21: 'csprg' option
+ call assert_equal('cscope', &csprg)
+ set csprg=doesnotexist
+ call assert_fails('cscope add Xcscope2.out', 'E609:')
+ set csprg=cscope
+
+ " Test 22: multiple cscope connections
+ cscope add Xcscope.out
+ cscope add Xcscope2.out . -C
+ let a=execute('cscope show')
+ call assert_match('\n 0 \d\+.*Xcscope.out\s*<none>', a)
+ call assert_match('\n 1 \d\+.*Xcscope2.out\s*\.', a)
+
+ " Test 23: test Ex command line completion
+ call feedkeys(":cs \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"cs add find help kill reset show', @:)
+
+ call feedkeys(":scs \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"scs find', @:)
+
+ call feedkeys(":cs find \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"cs find a c d e f g i s t', @:)
+
+ call feedkeys(":cs kill \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"cs kill -1 0 1', @:)
+
+ call feedkeys(":cs add Xcscope\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"cs add Xcscope.out Xcscope2.out', @:)
+
+ " Test 24: cscope_connection()
+ call assert_equal(cscope_connection(), 1)
+ call assert_equal(cscope_connection(0, 'out'), 1)
+ call assert_equal(cscope_connection(0, 'xxx'), 1)
+ call assert_equal(cscope_connection(1, 'out'), 1)
+ call assert_equal(cscope_connection(1, 'xxx'), 0)
+ call assert_equal(cscope_connection(2, 'out'), 0)
+ call assert_equal(cscope_connection(3, 'xxx', '..'), 0)
+ call assert_equal(cscope_connection(3, 'out', 'xxx'), 0)
+ call assert_equal(cscope_connection(3, 'out', '.'), 1)
+ call assert_equal(cscope_connection(4, 'out', '.'), 0)
+
+ " CleanUp
+ call CscopeSetupOrClean(0)
+
+endfunc
+
func Test_cscopequickfix()
set cscopequickfix=s-,g-,d+,c-,t+,e-,f0,i-,a-
call assert_equal('s-,g-,d+,c-,t+,e-,f0,i-,a-', &cscopequickfix)
@@ -13,3 +266,14 @@ func Test_cscopequickfix()
call assert_fails('set cscopequickfix=s7', 'E474:')
call assert_fails('set cscopequickfix=s-a', 'E474:')
endfunc
+
+func Test_withoutCscopeConnection()
+ call assert_equal(cscope_connection(), 0)
+
+ call assert_fails('cscope find s main', 'E567:')
+ let a=execute('cscope show')
+ call assert_match('no cscope connections', a)
+endfunc
+
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_cursor_func.vim b/src/nvim/testdir/test_cursor_func.vim
index d819b7b092..e1b9651c84 100644
--- a/src/nvim/testdir/test_cursor_func.vim
+++ b/src/nvim/testdir/test_cursor_func.vim
@@ -1,13 +1,7 @@
" Tests for cursor().
func Test_wrong_arguments()
- try
- call cursor(1. 3)
- " not reached
- call assert_false(1)
- catch
- call assert_exception('E474:')
- endtry
+ call assert_fails('call cursor(1. 3)', 'E474:')
endfunc
func Test_move_cursor()
diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim
index 7666594862..f40e06ff33 100644
--- a/src/nvim/testdir/test_diffmode.vim
+++ b/src/nvim/testdir/test_diffmode.vim
@@ -202,3 +202,36 @@ func Test_diffget_diffput()
bwipe!
enew!
endfunc
+
+func Test_diffoff()
+ enew!
+ call setline(1, ['Two', 'Three'])
+ let normattr = screenattr(1, 1)
+ diffthis
+ botright vert new
+ call setline(1, ['One', '', 'Two', 'Three'])
+ diffthis
+ redraw
+ diffoff!
+ redraw
+ call assert_equal(normattr, screenattr(1, 1))
+ bwipe!
+ bwipe!
+endfunc
+
+func Test_setting_cursor()
+ new Xtest1
+ put =range(1,90)
+ wq
+ new Xtest2
+ put =range(1,100)
+ wq
+
+ tabe Xtest2
+ $
+ diffsp Xtest1
+ tabclose
+
+ call delete('Xtest1')
+ call delete('Xtest2')
+endfunc
diff --git a/src/nvim/testdir/test_digraph.vim b/src/nvim/testdir/test_digraph.vim
new file mode 100644
index 0000000000..6290680305
--- /dev/null
+++ b/src/nvim/testdir/test_digraph.vim
@@ -0,0 +1,461 @@
+" Tests for digraphs
+
+if !has("digraphs") || !has("multi_byte")
+ finish
+endif
+
+func! Put_Dig(chars)
+ exe "norm! o\<c-k>".a:chars
+endfu
+
+func! Put_Dig_BS(char1, char2)
+ exe "norm! o".a:char1."\<bs>".a:char2
+endfu
+
+func! Test_digraphs()
+ new
+ call Put_Dig("00")
+ call assert_equal("∞", getline('.'))
+ " not a digraph
+ call Put_Dig("el")
+ call assert_equal("l", getline('.'))
+ call Put_Dig("ht")
+ call assert_equal("þ", getline('.'))
+ " digraph "ab" is the same as "ba"
+ call Put_Dig("ab")
+ call Put_Dig("ba")
+ call assert_equal(["ã°","ã°"], getline(line('.')-1,line('.')))
+ " Euro sign
+ call Put_Dig("e=")
+ call Put_Dig("=e")
+ call Put_Dig("Eu")
+ call Put_Dig("uE")
+ call assert_equal(['е']+repeat(["€"],3), getline(line('.')-3,line('.')))
+ " Rouble sign
+ call Put_Dig("R=")
+ call Put_Dig("=R")
+ call Put_Dig("=P")
+ call Put_Dig("P=")
+ call assert_equal(['Р']+repeat(["₽"],2)+['П'], getline(line('.')-3,line('.')))
+ " Not a digraph
+ call Put_Dig("a\<bs>")
+ call Put_Dig("\<bs>a")
+ call assert_equal(["<BS>", "<BS>a"], getline(line('.')-1,line('.')))
+ " Grave
+ call Put_Dig("a!")
+ call Put_Dig("!e")
+ call Put_Dig("b!") " not defined
+ call assert_equal(["à", "è", "!"], getline(line('.')-2,line('.')))
+ " Acute accent
+ call Put_Dig("a'")
+ call Put_Dig("'e")
+ call Put_Dig("b'") " not defined
+ call assert_equal(["á", "é", "'"], getline(line('.')-2,line('.')))
+ " Cicumflex
+ call Put_Dig("a>")
+ call Put_Dig(">e")
+ call Put_Dig("b>") " not defined
+ call assert_equal(['â', 'ê', '>'], getline(line('.')-2,line('.')))
+ " Tilde
+ call Put_Dig("o~")
+ call Put_Dig("~u") " not defined
+ call Put_Dig("z~") " not defined
+ call assert_equal(['õ', 'u', '~'], getline(line('.')-2,line('.')))
+ " Tilde
+ call Put_Dig("o?")
+ call Put_Dig("?u")
+ call Put_Dig("z?") " not defined
+ call assert_equal(['õ', 'ũ', '?'], getline(line('.')-2,line('.')))
+ " Macron
+ call Put_Dig("o-")
+ call Put_Dig("-u")
+ call Put_Dig("z-") " not defined
+ call assert_equal(['Å', 'Å«', '-'], getline(line('.')-2,line('.')))
+ " Breve
+ call Put_Dig("o(")
+ call Put_Dig("(u")
+ call Put_Dig("z(") " not defined
+ call assert_equal(['Å', 'Å­', '('], getline(line('.')-2,line('.')))
+ " Dot above
+ call Put_Dig("b.")
+ call Put_Dig(".e")
+ call Put_Dig("a.") " not defined
+ call assert_equal(['ḃ', 'ė', '.'], getline(line('.')-2,line('.')))
+ " Diaresis
+ call Put_Dig("a:")
+ call Put_Dig(":u")
+ call Put_Dig("b:") " not defined
+ call assert_equal(['ä', 'ü', ':'], getline(line('.')-2,line('.')))
+ " Cedilla
+ call Put_Dig("',")
+ call Put_Dig(",C")
+ call Put_Dig("b,") " not defined
+ call assert_equal(['¸', 'Ç', ','], getline(line('.')-2,line('.')))
+ " Underline
+ call Put_Dig("B_")
+ call Put_Dig("_t")
+ call Put_Dig("a_") " not defined
+ call assert_equal(['Ḇ', 'ṯ', '_'], getline(line('.')-2,line('.')))
+ " Stroke
+ call Put_Dig("j/")
+ call Put_Dig("/l")
+ call Put_Dig("b/") " not defined
+ call assert_equal(['/', 'Å‚', '/'], getline(line('.')-2,line('.')))
+ " Double acute
+ call Put_Dig('O"')
+ call Put_Dig('"y')
+ call Put_Dig('b"') " not defined
+ call assert_equal(['Å', 'ÿ', '"'], getline(line('.')-2,line('.')))
+ " Ogonek
+ call Put_Dig('u;')
+ call Put_Dig(';E')
+ call Put_Dig('b;') " not defined
+ call assert_equal(['ų', 'Ę', ';'], getline(line('.')-2,line('.')))
+ " Caron
+ call Put_Dig('u<')
+ call Put_Dig('<E')
+ call Put_Dig('b<') " not defined
+ call assert_equal(['Ç”', 'Äš', '<'], getline(line('.')-2,line('.')))
+ " Ring above
+ call Put_Dig('u0')
+ call Put_Dig('0E') " not defined
+ call Put_Dig('b0') " not defined
+ call assert_equal(['ů', 'E', '0'], getline(line('.')-2,line('.')))
+ " Hook
+ call Put_Dig('u2')
+ call Put_Dig('2E')
+ call Put_Dig('b2') " not defined
+ call assert_equal(['ủ', 'Ẻ', '2'], getline(line('.')-2,line('.')))
+ " Horn
+ call Put_Dig('u9')
+ call Put_Dig('9E') " not defined
+ call Put_Dig('b9') " not defined
+ call assert_equal(['ư', 'E', '9'], getline(line('.')-2,line('.')))
+ " Cyrillic
+ call Put_Dig('u=')
+ call Put_Dig('=b')
+ call Put_Dig('=_')
+ call assert_equal(['у', 'б', '〓'], getline(line('.')-2,line('.')))
+ " Greek
+ call Put_Dig('u*')
+ call Put_Dig('*b')
+ call Put_Dig('*_')
+ call assert_equal(['υ', 'β', '々'], getline(line('.')-2,line('.')))
+ " Greek/Cyrillic special
+ call Put_Dig('u%')
+ call Put_Dig('%b') " not defined
+ call Put_Dig('%_') " not defined
+ call assert_equal(['Ï', 'b', '_'], getline(line('.')-2,line('.')))
+ " Arabic
+ call Put_Dig('u+')
+ call Put_Dig('+b')
+ call Put_Dig('+_') " japanese industrial symbol
+ call assert_equal(['+', 'ب', '〄'], getline(line('.')-2,line('.')))
+ " Hebrew
+ call Put_Dig('Q+')
+ call Put_Dig('+B')
+ call Put_Dig('+X')
+ call assert_equal(['ק', 'ב', 'ח'], getline(line('.')-2,line('.')))
+ " Latin
+ call Put_Dig('a3')
+ call Put_Dig('A3')
+ call Put_Dig('3X')
+ call assert_equal(['Ç£', 'Ç¢', 'X'], getline(line('.')-2,line('.')))
+ " Bopomofo
+ call Put_Dig('a4')
+ call Put_Dig('A4')
+ call Put_Dig('4X')
+ call assert_equal(['ㄚ', '4', 'X'], getline(line('.')-2,line('.')))
+ " Hiragana
+ call Put_Dig('a5')
+ call Put_Dig('A5')
+ call Put_Dig('5X')
+ call assert_equal(['ã‚', 'ã', 'X'], getline(line('.')-2,line('.')))
+ " Katakana
+ call Put_Dig('a6')
+ call Put_Dig('A6')
+ call Put_Dig('6X')
+ call assert_equal(['ã‚¡', 'ã‚¢', 'X'], getline(line('.')-2,line('.')))
+ " Superscripts
+ call Put_Dig('1S')
+ call Put_Dig('2S')
+ call Put_Dig('3S')
+ call assert_equal(['¹', '²', '³'], getline(line('.')-2,line('.')))
+ " Subscripts
+ call Put_Dig('1s')
+ call Put_Dig('2s')
+ call Put_Dig('3s')
+ call assert_equal(['â‚', 'â‚‚', '₃'], getline(line('.')-2,line('.')))
+ " Eszet (only lowercase)
+ call Put_Dig("ss")
+ call Put_Dig("SS") " start of string
+ call assert_equal(["ß", "˜"], getline(line('.')-1,line('.')))
+ " High bit set
+ call Put_Dig("a ")
+ call Put_Dig(" A")
+ call assert_equal(['á', 'Ã'], getline(line('.')-1,line('.')))
+ " Escape is not part of a digraph
+ call Put_Dig("a\<esc>")
+ call Put_Dig("\<esc>A")
+ call assert_equal(['', 'A'], getline(line('.')-1,line('.')))
+ " define some custom digraphs
+ " old: 00 ∞
+ " old: el l
+ digraph 00 9216
+ digraph el 0252
+ call Put_Dig("00")
+ call Put_Dig("el")
+ " Reset digraphs
+ digraph 00 8734
+ digraph el 108
+ call Put_Dig("00")
+ call Put_Dig("el")
+ call assert_equal(['â€', 'ü', '∞', 'l'], getline(line('.')-3,line('.')))
+ bw!
+endfunc
+
+func! Test_digraphs_option()
+ " reset whichwrap option, so that testing <esc><bs>A works,
+ " without moving up a line
+ set digraph ww=
+ new
+ call Put_Dig_BS("0","0")
+ call assert_equal("∞", getline('.'))
+ " not a digraph
+ call Put_Dig_BS("e","l")
+ call assert_equal("l", getline('.'))
+ call Put_Dig_BS("h","t")
+ call assert_equal("þ", getline('.'))
+ " digraph "ab" is the same as "ba"
+ call Put_Dig_BS("a","b")
+ call Put_Dig_BS("b","a")
+ call assert_equal(["ã°","ã°"], getline(line('.')-1,line('.')))
+ " Euro sign
+ call Put_Dig_BS("e","=")
+ call Put_Dig_BS("=","e")
+ call Put_Dig_BS("E","u")
+ call Put_Dig_BS("u","E")
+ call assert_equal(['е']+repeat(["€"],3), getline(line('.')-3,line('.')))
+ " Rouble sign
+ call Put_Dig_BS("R","=")
+ call Put_Dig_BS("=","R")
+ call Put_Dig_BS("=","P")
+ call Put_Dig_BS("P","=")
+ call assert_equal(['Р']+repeat(["₽"],2)+['П'], getline(line('.')-3,line('.')))
+ " Not a digraph: this is different from <c-k>!
+ call Put_Dig_BS("a","\<bs>")
+ call Put_Dig_BS("\<bs>","a")
+ call assert_equal(['','a'], getline(line('.')-1,line('.')))
+ " Grave
+ call Put_Dig_BS("a","!")
+ call Put_Dig_BS("!","e")
+ call Put_Dig_BS("b","!") " not defined
+ call assert_equal(["à", "è", "!"], getline(line('.')-2,line('.')))
+ " Acute accent
+ call Put_Dig_BS("a","'")
+ call Put_Dig_BS("'","e")
+ call Put_Dig_BS("b","'") " not defined
+ call assert_equal(["á", "é", "'"], getline(line('.')-2,line('.')))
+ " Cicumflex
+ call Put_Dig_BS("a",">")
+ call Put_Dig_BS(">","e")
+ call Put_Dig_BS("b",">") " not defined
+ call assert_equal(['â', 'ê', '>'], getline(line('.')-2,line('.')))
+ " Tilde
+ call Put_Dig_BS("o","~")
+ call Put_Dig_BS("~","u") " not defined
+ call Put_Dig_BS("z","~") " not defined
+ call assert_equal(['õ', 'u', '~'], getline(line('.')-2,line('.')))
+ " Tilde
+ call Put_Dig_BS("o","?")
+ call Put_Dig_BS("?","u")
+ call Put_Dig_BS("z","?") " not defined
+ call assert_equal(['õ', 'ũ', '?'], getline(line('.')-2,line('.')))
+ " Macron
+ call Put_Dig_BS("o","-")
+ call Put_Dig_BS("-","u")
+ call Put_Dig_BS("z","-") " not defined
+ call assert_equal(['Å', 'Å«', '-'], getline(line('.')-2,line('.')))
+ " Breve
+ call Put_Dig_BS("o","(")
+ call Put_Dig_BS("(","u")
+ call Put_Dig_BS("z","(") " not defined
+ call assert_equal(['Å', 'Å­', '('], getline(line('.')-2,line('.')))
+ " Dot above
+ call Put_Dig_BS("b",".")
+ call Put_Dig_BS(".","e")
+ call Put_Dig_BS("a",".") " not defined
+ call assert_equal(['ḃ', 'ė', '.'], getline(line('.')-2,line('.')))
+ " Diaresis
+ call Put_Dig_BS("a",":")
+ call Put_Dig_BS(":","u")
+ call Put_Dig_BS("b",":") " not defined
+ call assert_equal(['ä', 'ü', ':'], getline(line('.')-2,line('.')))
+ " Cedilla
+ call Put_Dig_BS("'",",")
+ call Put_Dig_BS(",","C")
+ call Put_Dig_BS("b",",") " not defined
+ call assert_equal(['¸', 'Ç', ','], getline(line('.')-2,line('.')))
+ " Underline
+ call Put_Dig_BS("B","_")
+ call Put_Dig_BS("_","t")
+ call Put_Dig_BS("a","_") " not defined
+ call assert_equal(['Ḇ', 'ṯ', '_'], getline(line('.')-2,line('.')))
+ " Stroke
+ call Put_Dig_BS("j","/")
+ call Put_Dig_BS("/","l")
+ call Put_Dig_BS("b","/") " not defined
+ call assert_equal(['/', 'Å‚', '/'], getline(line('.')-2,line('.')))
+ " Double acute
+ call Put_Dig_BS('O','"')
+ call Put_Dig_BS('"','y')
+ call Put_Dig_BS('b','"') " not defined
+ call assert_equal(['Å', 'ÿ', '"'], getline(line('.')-2,line('.')))
+ " Ogonek
+ call Put_Dig_BS('u',';')
+ call Put_Dig_BS(';','E')
+ call Put_Dig_BS('b',';') " not defined
+ call assert_equal(['ų', 'Ę', ';'], getline(line('.')-2,line('.')))
+ " Caron
+ call Put_Dig_BS('u','<')
+ call Put_Dig_BS('<','E')
+ call Put_Dig_BS('b','<') " not defined
+ call assert_equal(['Ç”', 'Äš', '<'], getline(line('.')-2,line('.')))
+ " Ring above
+ call Put_Dig_BS('u','0')
+ call Put_Dig_BS('0','E') " not defined
+ call Put_Dig_BS('b','0') " not defined
+ call assert_equal(['ů', 'E', '0'], getline(line('.')-2,line('.')))
+ " Hook
+ call Put_Dig_BS('u','2')
+ call Put_Dig_BS('2','E')
+ call Put_Dig_BS('b','2') " not defined
+ call assert_equal(['ủ', 'Ẻ', '2'], getline(line('.')-2,line('.')))
+ " Horn
+ call Put_Dig_BS('u','9')
+ call Put_Dig_BS('9','E') " not defined
+ call Put_Dig_BS('b','9') " not defined
+ call assert_equal(['ư', 'E', '9'], getline(line('.')-2,line('.')))
+ " Cyrillic
+ call Put_Dig_BS('u','=')
+ call Put_Dig_BS('=','b')
+ call Put_Dig_BS('=','_')
+ call assert_equal(['у', 'б', '〓'], getline(line('.')-2,line('.')))
+ " Greek
+ call Put_Dig_BS('u','*')
+ call Put_Dig_BS('*','b')
+ call Put_Dig_BS('*','_')
+ call assert_equal(['υ', 'β', '々'], getline(line('.')-2,line('.')))
+ " Greek/Cyrillic special
+ call Put_Dig_BS('u','%')
+ call Put_Dig_BS('%','b') " not defined
+ call Put_Dig_BS('%','_') " not defined
+ call assert_equal(['Ï', 'b', '_'], getline(line('.')-2,line('.')))
+ " Arabic
+ call Put_Dig_BS('u','+')
+ call Put_Dig_BS('+','b')
+ call Put_Dig_BS('+','_') " japanese industrial symbol
+ call assert_equal(['+', 'ب', '〄'], getline(line('.')-2,line('.')))
+ " Hebrew
+ call Put_Dig_BS('Q','+')
+ call Put_Dig_BS('+','B')
+ call Put_Dig_BS('+','X')
+ call assert_equal(['ק', 'ב', 'ח'], getline(line('.')-2,line('.')))
+ " Latin
+ call Put_Dig_BS('a','3')
+ call Put_Dig_BS('A','3')
+ call Put_Dig_BS('3','X')
+ call assert_equal(['Ç£', 'Ç¢', 'X'], getline(line('.')-2,line('.')))
+ " Bopomofo
+ call Put_Dig_BS('a','4')
+ call Put_Dig_BS('A','4')
+ call Put_Dig_BS('4','X')
+ call assert_equal(['ㄚ', '4', 'X'], getline(line('.')-2,line('.')))
+ " Hiragana
+ call Put_Dig_BS('a','5')
+ call Put_Dig_BS('A','5')
+ call Put_Dig_BS('5','X')
+ call assert_equal(['ã‚', 'ã', 'X'], getline(line('.')-2,line('.')))
+ " Katakana
+ call Put_Dig_BS('a','6')
+ call Put_Dig_BS('A','6')
+ call Put_Dig_BS('6','X')
+ call assert_equal(['ã‚¡', 'ã‚¢', 'X'], getline(line('.')-2,line('.')))
+ " Superscripts
+ call Put_Dig_BS('1','S')
+ call Put_Dig_BS('2','S')
+ call Put_Dig_BS('3','S')
+ call assert_equal(['¹', '²', '³'], getline(line('.')-2,line('.')))
+ " Subscripts
+ call Put_Dig_BS('1','s')
+ call Put_Dig_BS('2','s')
+ call Put_Dig_BS('3','s')
+ call assert_equal(['â‚', 'â‚‚', '₃'], getline(line('.')-2,line('.')))
+ " Eszet (only lowercase)
+ call Put_Dig_BS("s","s")
+ call Put_Dig_BS("S","S") " start of string
+ call assert_equal(["ß", "˜"], getline(line('.')-1,line('.')))
+ " High bit set (different from <c-k>)
+ call Put_Dig_BS("a"," ")
+ call Put_Dig_BS(" ","A")
+ call assert_equal([' ', 'A'], getline(line('.')-1,line('.')))
+ " Escape is not part of a digraph (different from <c-k>)
+ call Put_Dig_BS("a","\<esc>")
+ call Put_Dig_BS("\<esc>","A")
+ call assert_equal(['', ''], getline(line('.')-1,line('.')))
+ " define some custom digraphs
+ " old: 00 ∞
+ " old: el l
+ digraph 00 9216
+ digraph el 0252
+ call Put_Dig_BS("0","0")
+ call Put_Dig_BS("e","l")
+ " Reset digraphs
+ digraph 00 8734
+ digraph el 108
+ call Put_Dig_BS("0","0")
+ call Put_Dig_BS("e","l")
+ call assert_equal(['â€', 'ü', '∞', 'l'], getline(line('.')-3,line('.')))
+ set nodigraph ww&vim
+ bw!
+endfunc
+
+func! Test_digraphs_output()
+ new
+ let out = execute(':digraph')
+ call assert_equal('Eu € 8364', matchstr(out, '\C\<Eu\D*8364\>'))
+ call assert_equal('=e € 8364', matchstr(out, '\C=e\D*8364\>'))
+ call assert_equal('=R ₽ 8381', matchstr(out, '\C=R\D*8381\>'))
+ call assert_equal('=P ₽ 8381', matchstr(out, '\C=P\D*8381\>'))
+ call assert_equal('o: ö 246', matchstr(out, '\C\<o:\D*246\>'))
+ call assert_equal('v4 ㄪ 12586', matchstr(out, '\C\<v4\D*12586\>'))
+ call assert_equal("'0 Ëš 730", matchstr(out, '\C''0\D*730\>'))
+ call assert_equal('Z% Ж 1046', matchstr(out, '\C\<Z%\D*1046\>'))
+ call assert_equal('u- Å« 363', matchstr(out, '\C\<u-\D*363\>'))
+ call assert_equal('SH ^A 1', matchstr(out, '\C\<SH\D*1\>'))
+ bw!
+endfunc
+
+func! Test_loadkeymap()
+ if !has('keymap')
+ return
+ endif
+ new
+ set keymap=czech
+ set iminsert=0
+ call feedkeys("o|\<c-^>|01234567890|\<esc>", 'tx')
+ call assert_equal("|'é+ěšÄřžýáíé'", getline('.'))
+ " reset keymap and encoding option
+ set keymap=
+ bw!
+endfunc
+
+func! Test_digraph_cmndline()
+ " Create digraph on commandline
+ " This is a hack, to let Vim create the digraph in commandline mode
+ let s = ''
+ exe "sil! norm! :let s.='\<c-k>Eu'\<cr>"
+ call assert_equal("€", s)
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_display.vim b/src/nvim/testdir/test_display.vim
new file mode 100644
index 0000000000..0ed672d577
--- /dev/null
+++ b/src/nvim/testdir/test_display.vim
@@ -0,0 +1,71 @@
+" Test for displaying stuff
+
+" Nvim: `:set term` is not supported.
+" if !has('gui_running') && has('unix')
+" set term=ansi
+" endif
+
+source view_util.vim
+
+func! Test_display_foldcolumn()
+ if !has("folding")
+ return
+ endif
+ new
+ vnew
+ vert resize 25
+ call assert_equal(25, winwidth(winnr()))
+ set isprint=@
+
+ 1put='e more noise blah blah‚ more stuff here'
+
+ let expect = [
+ \ "e more noise blah blah<82",
+ \ "> more stuff here "
+ \ ]
+
+ call cursor(2, 1)
+ norm! zt
+ let lines=ScreenLines([1,2], winwidth(0))
+ call assert_equal(expect, lines)
+ set fdc=2
+ let lines=ScreenLines([1,2], winwidth(0))
+ let expect = [
+ \ " e more noise blah blah<",
+ \ " 82> more stuff here "
+ \ ]
+ call assert_equal(expect, lines)
+
+ quit!
+ quit!
+endfunc
+
+func! Test_display_foldtext_mbyte()
+ if !has("folding") || !has("multi_byte")
+ return
+ endif
+ call NewWindow(10, 40)
+ call append(0, range(1,20))
+ exe "set foldmethod=manual foldtext=foldtext() fillchars=fold:\u2500,vert:\u2502 fdc=2"
+ call cursor(2, 1)
+ norm! zf13G
+ let lines=ScreenLines([1,3], winwidth(0)+1)
+ let expect=[
+ \ " 1 \u2502",
+ \ "+ +-- 12 lines: 2". repeat("\u2500", 23). "\u2502",
+ \ " 14 \u2502",
+ \ ]
+ call assert_equal(expect, lines)
+
+ set fillchars=fold:-,vert:\|
+ let lines=ScreenLines([1,3], winwidth(0)+1)
+ let expect=[
+ \ " 1 |",
+ \ "+ +-- 12 lines: 2". repeat("-", 23). "|",
+ \ " 14 |",
+ \ ]
+ call assert_equal(expect, lines)
+
+ set foldtext& fillchars& foldmethod& fdc&
+ bw!
+endfunc
diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim
index 7483973fca..d32facaa98 100644
--- a/src/nvim/testdir/test_expr.vim
+++ b/src/nvim/testdir/test_expr.vim
@@ -1,20 +1,5 @@
" Tests for expressions.
-func Test_version()
- call assert_true(has('patch-7.4.001'))
- call assert_true(has('patch-7.4.01'))
- call assert_true(has('patch-7.4.1'))
- call assert_true(has('patch-6.9.999'))
- call assert_true(has('patch-7.1.999'))
- call assert_true(has('patch-7.4.123'))
-
- call assert_false(has('patch-7'))
- call assert_false(has('patch-7.4'))
- call assert_false(has('patch-7.4.'))
- call assert_false(has('patch-9.1.0'))
- call assert_false(has('patch-9.9.1'))
-endfunc
-
func Test_equal()
let base = {}
func base.method()
@@ -37,6 +22,35 @@ func Test_equal()
call assert_fails('echo base.method > instance.method')
endfunc
+func Test_version()
+ call assert_true(has('patch-7.4.001'))
+ call assert_true(has('patch-7.4.01'))
+ call assert_true(has('patch-7.4.1'))
+ call assert_true(has('patch-6.9.999'))
+ call assert_true(has('patch-7.1.999'))
+ call assert_true(has('patch-7.4.123'))
+
+ call assert_false(has('patch-7'))
+ call assert_false(has('patch-7.4'))
+ call assert_false(has('patch-7.4.'))
+ call assert_false(has('patch-9.1.0'))
+ call assert_false(has('patch-9.9.1'))
+endfunc
+
+func Test_dict()
+ let d = {'': 'empty', 'a': 'a', 0: 'zero'}
+ call assert_equal('empty', d[''])
+ call assert_equal('a', d['a'])
+ call assert_equal('zero', d[0])
+ call assert_true(has_key(d, ''))
+ call assert_true(has_key(d, 'a'))
+
+ let d[''] = 'none'
+ let d['a'] = 'aaa'
+ call assert_equal('none', d[''])
+ call assert_equal('aaa', d['a'])
+endfunc
+
func Test_strgetchar()
call assert_equal(char2nr('a'), strgetchar('axb', 0))
call assert_equal(char2nr('x'), strgetchar('axb', 1))
@@ -61,24 +75,10 @@ func Test_strcharpart()
call assert_equal('a', strcharpart('axb', -1, 2))
endfunc
-func Test_dict()
- let d = {'': 'empty', 'a': 'a', 0: 'zero'}
- call assert_equal('empty', d[''])
- call assert_equal('a', d['a'])
- call assert_equal('zero', d[0])
- call assert_true(has_key(d, ''))
- call assert_true(has_key(d, 'a'))
-
- let d[''] = 'none'
- let d['a'] = 'aaa'
- call assert_equal('none', d[''])
- call assert_equal('aaa', d['a'])
-endfunc
-
func Test_loop_over_null_list()
let null_list = submatch(1, 1)
for i in null_list
- call assert_true(0, 'should not get here')
+ call assert_report('should not get here')
endfor
endfunc
@@ -92,3 +92,350 @@ endfunc
func Test_set_reg_null_list()
call setreg('x', v:_null_list)
endfunc
+
+func Test_special_char()
+ " The failure is only visible using valgrind.
+ call assert_fails('echo "\<C-">')
+endfunc
+
+func Test_option_value()
+ " boolean
+ set bri
+ call assert_equal(1, &bri)
+ set nobri
+ call assert_equal(0, &bri)
+
+ " number
+ set ts=1
+ call assert_equal(1, &ts)
+ set ts=8
+ call assert_equal(8, &ts)
+
+ " string
+ exe "set cedit=\<Esc>"
+ call assert_equal("\<Esc>", &cedit)
+ set cpo=
+ call assert_equal("", &cpo)
+ set cpo=abcdefi
+ call assert_equal("abcdefi", &cpo)
+ set cpo&vim
+endfunc
+
+function Test_printf_64bit()
+ if has('num64')
+ call assert_equal("123456789012345", printf('%d', 123456789012345))
+ endif
+endfunc
+
+func Test_setmatches()
+ hi def link 1 Comment
+ hi def link 2 PreProc
+ let set = [{"group": 1, "pattern": 2, "id": 3, "priority": 4}]
+ let exp = [{"group": '1', "pattern": '2', "id": 3, "priority": 4}]
+ if has('conceal')
+ let set[0]['conceal'] = 5
+ let exp[0]['conceal'] = '5'
+ endif
+ call setmatches(set)
+ call assert_equal(exp, getmatches())
+endfunc
+
+function Test_printf_spec_s()
+ " number
+ call assert_equal("1234567890", printf('%s', 1234567890))
+
+ " string
+ call assert_equal("abcdefgi", printf('%s', "abcdefgi"))
+
+ " float
+ call assert_equal("1.23", printf('%s', 1.23))
+
+ " list
+ let value = [1, 'two', ['three', 4]]
+ call assert_equal(string(value), printf('%s', value))
+
+ " dict
+ let value = {'key1' : 'value1', 'key2' : ['list', 'value'], 'key3' : {'dict' : 'value'}}
+ call assert_equal(string(value), printf('%s', value))
+
+ " funcref
+ call assert_equal('printf', printf('%s', function('printf')))
+
+ " partial
+ call assert_equal(string(function('printf', ['%s'])), printf('%s', function('printf', ['%s'])))
+endfunc
+
+function Test_printf_misc()
+ call assert_equal('123', printf('%d', 123))
+ call assert_equal('123', printf('%i', 123))
+ call assert_equal('123', printf('%D', 123))
+ call assert_equal('123', printf('%U', 123))
+ call assert_equal('173', printf('%o', 123))
+ call assert_equal('173', printf('%O', 123))
+ call assert_equal('7b', printf('%x', 123))
+ call assert_equal('7B', printf('%X', 123))
+ call assert_equal('{', printf('%c', 123))
+ call assert_equal('abc', printf('%s', 'abc'))
+ call assert_equal('abc', printf('%S', 'abc'))
+
+ call assert_equal('+123', printf('%+d', 123))
+ call assert_equal('-123', printf('%+d', -123))
+ call assert_equal('+123', printf('%+ d', 123))
+ call assert_equal(' 123', printf('% d', 123))
+ call assert_equal(' 123', printf('% d', 123))
+ call assert_equal('-123', printf('% d', -123))
+
+ call assert_equal('123', printf('%2d', 123))
+ call assert_equal(' 123', printf('%6d', 123))
+ call assert_equal('000123', printf('%06d', 123))
+ call assert_equal('+00123', printf('%+06d', 123))
+ call assert_equal(' 00123', printf('% 06d', 123))
+ call assert_equal(' +123', printf('%+6d', 123))
+ call assert_equal(' 123', printf('% 6d', 123))
+ call assert_equal(' -123', printf('% 6d', -123))
+
+ " Test left adjusted.
+ call assert_equal('123 ', printf('%-6d', 123))
+ call assert_equal('+123 ', printf('%-+6d', 123))
+ call assert_equal(' 123 ', printf('%- 6d', 123))
+ call assert_equal('-123 ', printf('%- 6d', -123))
+
+ call assert_equal(' 00123', printf('%7.5d', 123))
+ call assert_equal(' -00123', printf('%7.5d', -123))
+ call assert_equal(' +00123', printf('%+7.5d', 123))
+ " Precision field should not be used when combined with %0
+ call assert_equal(' 00123', printf('%07.5d', 123))
+ call assert_equal(' -00123', printf('%07.5d', -123))
+
+ call assert_equal(' 123', printf('%*d', 5, 123))
+ call assert_equal('123 ', printf('%*d', -5, 123))
+ call assert_equal('00123', printf('%.*d', 5, 123))
+ call assert_equal(' 123', printf('% *d', 5, 123))
+ call assert_equal(' +123', printf('%+ *d', 5, 123))
+
+ " Simple quote (thousand grouping char) is ignored.
+ call assert_equal('+00123456', printf("%+'09d", 123456))
+
+ " Unrecognized format specifier kept as-is.
+ call assert_equal('_123', printf("%_%d", 123))
+
+ " Test alternate forms.
+ call assert_equal('0x7b', printf('%#x', 123))
+ call assert_equal('0X7B', printf('%#X', 123))
+ call assert_equal('0173', printf('%#o', 123))
+ call assert_equal('0173', printf('%#O', 123))
+ call assert_equal('abc', printf('%#s', 'abc'))
+ call assert_equal('abc', printf('%#S', 'abc'))
+ call assert_equal(' 0173', printf('%#6o', 123))
+ call assert_equal(' 00173', printf('%#6.5o', 123))
+ call assert_equal(' 0173', printf('%#6.2o', 123))
+ call assert_equal(' 0173', printf('%#6.2o', 123))
+ call assert_equal('0173', printf('%#2.2o', 123))
+
+ call assert_equal(' 00123', printf('%6.5d', 123))
+ call assert_equal(' 0007b', printf('%6.5x', 123))
+
+ call assert_equal('abc', printf('%2s', 'abc'))
+ call assert_equal('abc', printf('%2S', 'abc'))
+ call assert_equal('abc', printf('%.4s', 'abc'))
+ call assert_equal('abc', printf('%.4S', 'abc'))
+ call assert_equal('ab', printf('%.2s', 'abc'))
+ call assert_equal('ab', printf('%.2S', 'abc'))
+ call assert_equal('', printf('%.0s', 'abc'))
+ call assert_equal('', printf('%.s', 'abc'))
+ call assert_equal(' abc', printf('%4s', 'abc'))
+ call assert_equal(' abc', printf('%4S', 'abc'))
+ call assert_equal('0abc', printf('%04s', 'abc'))
+ call assert_equal('0abc', printf('%04S', 'abc'))
+ call assert_equal('abc ', printf('%-4s', 'abc'))
+ call assert_equal('abc ', printf('%-4S', 'abc'))
+
+ call assert_equal('1%', printf('%d%%', 1))
+endfunc
+
+function Test_printf_float()
+ call assert_equal('1.000000', printf('%f', 1))
+ call assert_equal('1.230000', printf('%f', 1.23))
+ call assert_equal('1.230000', printf('%F', 1.23))
+ call assert_equal('9999999.9', printf('%g', 9999999.9))
+ call assert_equal('9999999.9', printf('%G', 9999999.9))
+ call assert_equal('1.00000001e7', printf('%.8g', 10000000.1))
+ call assert_equal('1.00000001E7', printf('%.8G', 10000000.1))
+ call assert_equal('1.230000e+00', printf('%e', 1.23))
+ call assert_equal('1.230000E+00', printf('%E', 1.23))
+ call assert_equal('1.200000e-02', printf('%e', 0.012))
+ call assert_equal('-1.200000e-02', printf('%e', -0.012))
+ call assert_equal('0.33', printf('%.2f', 1.0/3.0))
+ call assert_equal(' 0.33', printf('%6.2f', 1.0/3.0))
+ call assert_equal(' -0.33', printf('%6.2f', -1.0/3.0))
+ call assert_equal('000.33', printf('%06.2f', 1.0/3.0))
+ call assert_equal('-00.33', printf('%06.2f', -1.0/3.0))
+ call assert_equal('-00.33', printf('%+06.2f', -1.0/3.0))
+ call assert_equal('+00.33', printf('%+06.2f', 1.0/3.0))
+ call assert_equal(' 00.33', printf('% 06.2f', 1.0/3.0))
+ call assert_equal('000.33', printf('%06.2g', 1.0/3.0))
+ call assert_equal('-00.33', printf('%06.2g', -1.0/3.0))
+ call assert_equal('0.33', printf('%3.2f', 1.0/3.0))
+ call assert_equal('003.33e-01', printf('%010.2e', 1.0/3.0))
+ call assert_equal(' 03.33e-01', printf('% 010.2e', 1.0/3.0))
+ call assert_equal('+03.33e-01', printf('%+010.2e', 1.0/3.0))
+ call assert_equal('-03.33e-01', printf('%010.2e', -1.0/3.0))
+
+ " When precision is 0, the dot should be omitted.
+ call assert_equal(' 2', printf('%3.f', 7.0/3.0))
+ call assert_equal(' 2', printf('%3.g', 7.0/3.0))
+ call assert_equal(' 2e+00', printf('%7.e', 7.0/3.0))
+
+ " Float zero can be signed.
+ call assert_equal('+0.000000', printf('%+f', 0.0))
+ call assert_equal('0.000000', printf('%f', 1.0/(1.0/0.0)))
+ call assert_equal('-0.000000', printf('%f', 1.0/(-1.0/0.0)))
+ call assert_equal('0.0', printf('%s', 1.0/(1.0/0.0)))
+ call assert_equal('-0.0', printf('%s', 1.0/(-1.0/0.0)))
+ call assert_equal('0.0', printf('%S', 1.0/(1.0/0.0)))
+ call assert_equal('-0.0', printf('%S', 1.0/(-1.0/0.0)))
+
+ " Float infinity can be signed.
+ call assert_equal('inf', printf('%f', 1.0/0.0))
+ call assert_equal('-inf', printf('%f', -1.0/0.0))
+ call assert_equal('inf', printf('%g', 1.0/0.0))
+ call assert_equal('-inf', printf('%g', -1.0/0.0))
+ call assert_equal('inf', printf('%e', 1.0/0.0))
+ call assert_equal('-inf', printf('%e', -1.0/0.0))
+ call assert_equal('INF', printf('%F', 1.0/0.0))
+ call assert_equal('-INF', printf('%F', -1.0/0.0))
+ call assert_equal('INF', printf('%E', 1.0/0.0))
+ call assert_equal('-INF', printf('%E', -1.0/0.0))
+ call assert_equal('INF', printf('%E', 1.0/0.0))
+ call assert_equal('-INF', printf('%G', -1.0/0.0))
+ call assert_equal('+inf', printf('%+f', 1.0/0.0))
+ call assert_equal('-inf', printf('%+f', -1.0/0.0))
+ call assert_equal(' inf', printf('% f', 1.0/0.0))
+ call assert_equal(' inf', printf('%6f', 1.0/0.0))
+ call assert_equal(' -inf', printf('%6f', -1.0/0.0))
+ call assert_equal(' inf', printf('%6g', 1.0/0.0))
+ call assert_equal(' -inf', printf('%6g', -1.0/0.0))
+ call assert_equal(' +inf', printf('%+6f', 1.0/0.0))
+ call assert_equal(' inf', printf('% 6f', 1.0/0.0))
+ call assert_equal(' +inf', printf('%+06f', 1.0/0.0))
+ call assert_equal('inf ', printf('%-6f', 1.0/0.0))
+ call assert_equal('-inf ', printf('%-6f', -1.0/0.0))
+ call assert_equal('+inf ', printf('%-+6f', 1.0/0.0))
+ call assert_equal(' inf ', printf('%- 6f', 1.0/0.0))
+ call assert_equal('-INF ', printf('%-6F', -1.0/0.0))
+ call assert_equal('+INF ', printf('%-+6F', 1.0/0.0))
+ call assert_equal(' INF ', printf('%- 6F', 1.0/0.0))
+ call assert_equal('INF ', printf('%-6G', 1.0/0.0))
+ call assert_equal('-INF ', printf('%-6G', -1.0/0.0))
+ call assert_equal('INF ', printf('%-6E', 1.0/0.0))
+ call assert_equal('-INF ', printf('%-6E', -1.0/0.0))
+ call assert_equal("str2float('inf')", printf('%s', 1.0/0.0))
+ call assert_equal("-str2float('inf')", printf('%s', -1.0/0.0))
+
+ " Float nan (not a number) has no sign.
+ call assert_equal('nan', printf('%f', sqrt(-1.0)))
+ call assert_equal('nan', printf('%f', 0.0/0.0))
+ call assert_equal('nan', printf('%f', -0.0/0.0))
+ call assert_equal('nan', printf('%g', 0.0/0.0))
+ call assert_equal('nan', printf('%e', 0.0/0.0))
+ call assert_equal('NAN', printf('%F', 0.0/0.0))
+ call assert_equal('NAN', printf('%G', 0.0/0.0))
+ call assert_equal('NAN', printf('%E', 0.0/0.0))
+ call assert_equal('NAN', printf('%F', -0.0/0.0))
+ call assert_equal('NAN', printf('%G', -0.0/0.0))
+ call assert_equal('NAN', printf('%E', -0.0/0.0))
+ call assert_equal(' nan', printf('%6f', 0.0/0.0))
+ call assert_equal(' nan', printf('%06f', 0.0/0.0))
+ call assert_equal('nan ', printf('%-6f', 0.0/0.0))
+ call assert_equal('nan ', printf('%- 6f', 0.0/0.0))
+ call assert_equal("str2float('nan')", printf('%s', 0.0/0.0))
+ call assert_equal("str2float('nan')", printf('%s', -0.0/0.0))
+ call assert_equal("str2float('nan')", printf('%S', 0.0/0.0))
+ call assert_equal("str2float('nan')", printf('%S', -0.0/0.0))
+
+ call assert_fails('echo printf("%f", "a")', 'E807:')
+endfunc
+
+function Test_printf_errors()
+ call assert_fails('echo printf("%d", {})', 'E728:')
+ call assert_fails('echo printf("%d", [])', 'E745:')
+ call assert_fails('echo printf("%d", 1, 2)', 'E767:')
+ call assert_fails('echo printf("%*d", 1)', 'E766:')
+ call assert_fails('echo printf("%d", 1.2)', 'E805:')
+endfunc
+
+function Test_max_min_errors()
+ call assert_fails('call max(v:true)', 'E712:')
+ call assert_fails('call max(v:true)', 'max()')
+ call assert_fails('call min(v:true)', 'E712:')
+ call assert_fails('call min(v:true)', 'min()')
+endfunc
+
+func Test_substitute_expr()
+ let g:val = 'XXX'
+ call assert_equal('XXX', substitute('yyy', 'y*', '\=g:val', ''))
+ call assert_equal('XXX', substitute('yyy', 'y*', {-> g:val}, ''))
+ call assert_equal("-\u1b \uf2-", substitute("-%1b %f2-", '%\(\x\x\)',
+ \ '\=nr2char("0x" . submatch(1))', 'g'))
+ call assert_equal("-\u1b \uf2-", substitute("-%1b %f2-", '%\(\x\x\)',
+ \ {-> nr2char("0x" . submatch(1))}, 'g'))
+
+ call assert_equal('231', substitute('123', '\(.\)\(.\)\(.\)',
+ \ {-> submatch(2) . submatch(3) . submatch(1)}, ''))
+
+ func Recurse()
+ return substitute('yyy', 'y\(.\)y', {-> submatch(1)}, '')
+ endfunc
+ " recursive call works
+ call assert_equal('-y-x-', substitute('xxx', 'x\(.\)x', {-> '-' . Recurse() . '-' . submatch(1) . '-'}, ''))
+endfunc
+
+func Test_invalid_submatch()
+ " This was causing invalid memory access in Vim-7.4.2232 and older
+ call assert_fails("call substitute('x', '.', {-> submatch(10)}, '')", 'E935:')
+endfunc
+
+func Test_substitute_expr_arg()
+ call assert_equal('123456789-123456789=', substitute('123456789',
+ \ '\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)',
+ \ {m -> m[0] . '-' . m[1] . m[2] . m[3] . m[4] . m[5] . m[6] . m[7] . m[8] . m[9] . '='}, ''))
+
+ call assert_equal('123456-123456=789', substitute('123456789',
+ \ '\(.\)\(.\)\(.\)\(a*\)\(n*\)\(.\)\(.\)\(.\)\(x*\)',
+ \ {m -> m[0] . '-' . m[1] . m[2] . m[3] . m[4] . m[5] . m[6] . m[7] . m[8] . m[9] . '='}, ''))
+
+ call assert_equal('123456789-123456789x=', substitute('123456789',
+ \ '\(.\)\(.\)\(.*\)',
+ \ {m -> m[0] . '-' . m[1] . m[2] . m[3] . 'x' . m[4] . m[5] . m[6] . m[7] . m[8] . m[9] . '='}, ''))
+
+ call assert_fails("call substitute('xxx', '.', {m -> string(add(m, 'x'))}, '')", 'E742:')
+ call assert_fails("call substitute('xxx', '.', {m -> string(insert(m, 'x'))}, '')", 'E742:')
+ call assert_fails("call substitute('xxx', '.', {m -> string(extend(m, ['x']))}, '')", 'E742:')
+ call assert_fails("call substitute('xxx', '.', {m -> string(remove(m, 1))}, '')", 'E742:')
+endfunc
+
+func Test_function_with_funcref()
+ let s:f = function('type')
+ let s:fref = function(s:f)
+ call assert_equal(v:t_string, s:fref('x'))
+ call assert_fails("call function('s:f')", 'E700:')
+
+ call assert_fails("call function('foo()')", 'E475:')
+ call assert_fails("call function('foo()')", 'foo()')
+endfunc
+
+func Test_funcref()
+ func! One()
+ return 1
+ endfunc
+ let OneByName = function('One')
+ let OneByRef = funcref('One')
+ func! One()
+ return 2
+ endfunc
+ call assert_equal(2, OneByName())
+ call assert_equal(1, OneByRef())
+ let OneByRef = funcref('One')
+ call assert_equal(2, OneByRef())
+ call assert_fails('echo funcref("{")', 'E475:')
+endfunc
diff --git a/src/nvim/testdir/test_expr_utf8.vim b/src/nvim/testdir/test_expr_utf8.vim
index 097d708329..9ea6d8872b 100644
--- a/src/nvim/testdir/test_expr_utf8.vim
+++ b/src/nvim/testdir/test_expr_utf8.vim
@@ -35,60 +35,3 @@ func Test_strcharpart_utf8()
call assert_equal('̀', strcharpart('àxb', 1, 1))
call assert_equal('x', strcharpart('àxb', 2, 1))
endfunc
-
-func s:classes_test()
- set isprint=@,161-255
- call assert_equal('Motörhead', matchstr('Motörhead', '[[:print:]]\+'))
-
- let alphachars = ''
- let lowerchars = ''
- let upperchars = ''
- let alnumchars = ''
- let printchars = ''
- let punctchars = ''
- let xdigitchars = ''
- let i = 1
- while i <= 255
- let c = nr2char(i)
- if c =~ '[[:alpha:]]'
- let alphachars .= c
- endif
- if c =~ '[[:lower:]]'
- let lowerchars .= c
- endif
- if c =~ '[[:upper:]]'
- let upperchars .= c
- endif
- if c =~ '[[:alnum:]]'
- let alnumchars .= c
- endif
- if c =~ '[[:print:]]'
- let printchars .= c
- endif
- if c =~ '[[:punct:]]'
- let punctchars .= c
- endif
- if c =~ '[[:xdigit:]]'
- let xdigitchars .= c
- endif
- let i += 1
- endwhile
-
- call assert_equal('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', alphachars)
- call assert_equal('abcdefghijklmnopqrstuvwxyzµßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ', lowerchars)
- call assert_equal('ABCDEFGHIJKLMNOPQRSTUVWXYZÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖØÙÚÛÜÃÞ', upperchars)
- call assert_equal('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', alnumchars)
- call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖרÙÚÛÜÃÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ', printchars)
- call assert_equal('!"#$%&''()*+,-./:;<=>?@[\]^_`{|}~', punctchars)
- call assert_equal('0123456789ABCDEFabcdef', xdigitchars)
-endfunc
-
-func Test_classes_re1()
- set re=1
- call s:classes_test()
-endfunc
-
-func Test_classes_re2()
- set re=2
- call s:classes_test()
-endfunc
diff --git a/src/nvim/testdir/test_farsi.vim b/src/nvim/testdir/test_farsi.vim
new file mode 100644
index 0000000000..e094191599
--- /dev/null
+++ b/src/nvim/testdir/test_farsi.vim
@@ -0,0 +1,84 @@
+" Simplistic testing of Farsi mode.
+
+if !has('farsi') || has('nvim') " Not supported in Nvim. #6192
+ finish
+endif
+" Farsi uses a single byte encoding.
+set enc=latin1
+
+func Test_farsi_toggle()
+ new
+
+ set altkeymap
+ call assert_equal(0, &fkmap)
+ call assert_equal(0, &rl)
+ call feedkeys("\<F8>", 'x')
+ call assert_equal(1, &fkmap)
+ call assert_equal(1, &rl)
+ call feedkeys("\<F8>", 'x')
+ call assert_equal(0, &fkmap)
+ call assert_equal(0, &rl)
+
+ set rl
+ " conversion from Farsi 3342 to Farsi VIM.
+ call setline(1, join(map(range(0x80, 0xff), 'nr2char(v:val)'), ''))
+ call feedkeys("\<F9>", 'x')
+ let exp = [0xfc, 0xf8, 0xc1, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ \ 0xc8, 0xc9, 0xca, 0xd0, 0xd1, 0xd2, 0xd3, 0xd6,
+ \ 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd8, 0xd9, 0xda,
+ \ 0xdb, 0xdc, 0xdc, 0xc1, 0xdd, 0xde, 0xe0, 0xe0,
+ \ 0xe1, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
+ \ 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae,
+ \ 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+ \ 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe,
+ \ 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6,
+ \ 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce,
+ \ 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
+ \ 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
+ \ 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
+ \ 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xfb, 0xfb, 0xfe,
+ \ 0xfe, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
+ \ 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xe1,
+ \ ]
+ call assert_equal(join(map(exp, 'nr2char(v:val)'), ''), getline(1))
+
+ " conversion from Farsi VIM to Farsi 3342.
+ call setline(1, join(map(range(0x80, 0xff), 'nr2char(v:val)'), ''))
+ call feedkeys("\<F9>", 'x')
+ let exp = [0xfc, 0xf8, 0xc1, 0x83, 0x84, 0x85, 0x86, 0x87,
+ \ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x90,
+ \ 0x90, 0x90, 0x92, 0x93, 0x93, 0x95, 0x96, 0x97,
+ \ 0x98, 0xdc, 0x9a, 0x9b, 0x9c, 0x9e, 0x9e, 0xff,
+ \ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ \ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ \ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ \ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ \ 0xc0, 0xc1, 0xc2, 0x83, 0x84, 0x85, 0x86, 0x87,
+ \ 0x88, 0x89, 0x8a, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ \ 0x8b, 0x8c, 0x8d, 0x8e, 0xd4, 0xd5, 0x90, 0x93,
+ \ 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0xdf,
+ \ 0x9d, 0xff, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ \ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xec, 0xee, 0xef,
+ \ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ \ 0xf8, 0xf9, 0xfa, 0xec, 0x80, 0xfd, 0xee, 0xff,
+ \ ]
+ call assert_equal(join(map(exp, 'nr2char(v:val)'), ''), getline(1))
+
+ bwipe!
+endfunc
+
+func Test_farsi_map()
+ new
+
+ set altkeymap
+ set rl
+ " RHS of mapping is reversed.
+ imap xyz abc
+ call feedkeys("axyz\<Esc>", 'tx')
+ call assert_equal('cba', getline(1))
+
+ set norl
+ iunmap xyz
+ set noaltkeymap
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_fileformat.vim b/src/nvim/testdir/test_fileformat.vim
new file mode 100644
index 0000000000..584f20cdfc
--- /dev/null
+++ b/src/nvim/testdir/test_fileformat.vim
@@ -0,0 +1,17 @@
+" Test behavior of fileformat after bwipeout of last buffer
+
+func Test_fileformat_after_bw()
+ bwipeout
+ set fileformat&
+ if &fileformat == 'dos'
+ let test_fileformats = 'unix'
+ elseif &fileformat == 'unix'
+ let test_fileformats = 'mac'
+ else " must be mac
+ let test_fileformats = 'dos'
+ endif
+ exec 'set fileformats='.test_fileformats
+ bwipeout!
+ call assert_equal(test_fileformats, &fileformat)
+ set fileformats&
+endfunc
diff --git a/src/nvim/testdir/test_filter_cmd.vim b/src/nvim/testdir/test_filter_cmd.vim
new file mode 100644
index 0000000000..5aa5fa64df
--- /dev/null
+++ b/src/nvim/testdir/test_filter_cmd.vim
@@ -0,0 +1,76 @@
+" Test the :filter command modifier
+
+func Test_filter()
+ edit Xdoesnotmatch
+ edit Xwillmatch
+ call assert_equal('"Xwillmatch"', substitute(execute('filter willma ls'), '[^"]*\(".*"\)[^"]*', '\1', ''))
+ bwipe Xdoesnotmatch
+ bwipe Xwillmatch
+
+ new
+ call setline(1, ['foo1', 'foo2', 'foo3', 'foo4', 'foo5'])
+ call assert_equal("\nfoo2\nfoo4", execute('filter /foo[24]/ 1,$print'))
+ call assert_equal("\n 2 foo2\n 4 foo4", execute('filter /foo[24]/ 1,$number'))
+ call assert_equal("\nfoo2$\nfoo4$", execute('filter /foo[24]/ 1,$list'))
+
+ call assert_equal("\nfoo1$\nfoo3$\nfoo5$", execute('filter! /foo[24]/ 1,$list'))
+ bwipe!
+
+ command XTryThis echo 'this'
+ command XTryThat echo 'that'
+ command XDoThat echo 'that'
+ let lines = split(execute('filter XTry command'), "\n")
+ call assert_equal(3, len(lines))
+ call assert_match("XTryThat", lines[1])
+ call assert_match("XTryThis", lines[2])
+ delcommand XTryThis
+ delcommand XTryThat
+ delcommand XDoThat
+
+ map f1 the first key
+ map f2 the second key
+ map f3 not a key
+ let lines = split(execute('filter the map f'), "\n")
+ call assert_equal(2, len(lines))
+ call assert_match("f2", lines[0])
+ call assert_match("f1", lines[1])
+ unmap f1
+ unmap f2
+ unmap f3
+endfunc
+
+func Test_filter_fails()
+ call assert_fails('filter', 'E471:')
+ call assert_fails('filter pat', 'E476:')
+ call assert_fails('filter /pat', 'E476:')
+ call assert_fails('filter /pat/', 'E476:')
+ call assert_fails('filter /pat/ asdf', 'E492:')
+
+ call assert_fails('filter!', 'E471:')
+ call assert_fails('filter! pat', 'E476:')
+ call assert_fails('filter! /pat', 'E476:')
+ call assert_fails('filter! /pat/', 'E476:')
+ call assert_fails('filter! /pat/ asdf', 'E492:')
+endfunc
+
+function s:complete_filter_cmd(filtcmd)
+ let keystroke = "\<TAB>\<C-R>=execute('let cmdline = getcmdline()')\<CR>\<C-C>"
+ let cmdline = ''
+ call feedkeys(':' . a:filtcmd . keystroke, 'ntx')
+ return cmdline
+endfunction
+
+func Test_filter_cmd_completion()
+ " Do not complete pattern
+ call assert_equal("filter \t", s:complete_filter_cmd('filter '))
+ call assert_equal("filter pat\t", s:complete_filter_cmd('filter pat'))
+ call assert_equal("filter /pat\t", s:complete_filter_cmd('filter /pat'))
+ call assert_equal("filter /pat/\t", s:complete_filter_cmd('filter /pat/'))
+
+ " Complete after string pattern
+ call assert_equal('filter pat print', s:complete_filter_cmd('filter pat pri'))
+
+ " Complete after regexp pattern
+ call assert_equal('filter /pat/ print', s:complete_filter_cmd('filter /pat/ pri'))
+ call assert_equal('filter #pat# print', s:complete_filter_cmd('filter #pat# pri'))
+endfunc
diff --git a/src/nvim/testdir/test_filter_map.vim b/src/nvim/testdir/test_filter_map.vim
new file mode 100644
index 0000000000..c8d64ce0a4
--- /dev/null
+++ b/src/nvim/testdir/test_filter_map.vim
@@ -0,0 +1,81 @@
+" Test filter() and map()
+
+" list with expression string
+func Test_filter_map_list_expr_string()
+ " filter()
+ call assert_equal([2, 3, 4], filter([1, 2, 3, 4], 'v:val > 1'))
+ call assert_equal([3, 4], filter([1, 2, 3, 4], 'v:key > 1'))
+ call assert_equal([], filter([1, 2, 3, 4], 0))
+
+ " map()
+ call assert_equal([2, 4, 6, 8], map([1, 2, 3, 4], 'v:val * 2'))
+ call assert_equal([0, 2, 4, 6], map([1, 2, 3, 4], 'v:key * 2'))
+ call assert_equal([9, 9, 9, 9], map([1, 2, 3, 4], 9))
+endfunc
+
+" dict with expression string
+func Test_filter_map_dict_expr_string()
+ let dict = {"foo": 1, "bar": 2, "baz": 3}
+
+ " filter()
+ call assert_equal({"bar": 2, "baz": 3}, filter(copy(dict), 'v:val > 1'))
+ call assert_equal({"foo": 1, "baz": 3}, filter(copy(dict), 'v:key > "bar"'))
+ call assert_equal({}, filter(copy(dict), 0))
+
+ " map()
+ call assert_equal({"foo": 2, "bar": 4, "baz": 6}, map(copy(dict), 'v:val * 2'))
+ call assert_equal({"foo": "f", "bar": "b", "baz": "b"}, map(copy(dict), 'v:key[0]'))
+ call assert_equal({"foo": 9, "bar": 9, "baz": 9}, map(copy(dict), 9))
+endfunc
+
+" list with funcref
+func Test_filter_map_list_expr_funcref()
+ " filter()
+ func! s:filter1(index, val) abort
+ return a:val > 1
+ endfunc
+ call assert_equal([2, 3, 4], filter([1, 2, 3, 4], function('s:filter1')))
+
+ func! s:filter2(index, val) abort
+ return a:index > 1
+ endfunc
+ call assert_equal([3, 4], filter([1, 2, 3, 4], function('s:filter2')))
+
+ " map()
+ func! s:filter3(index, val) abort
+ return a:val * 2
+ endfunc
+ call assert_equal([2, 4, 6, 8], map([1, 2, 3, 4], function('s:filter3')))
+
+ func! s:filter4(index, val) abort
+ return a:index * 2
+ endfunc
+ call assert_equal([0, 2, 4, 6], map([1, 2, 3, 4], function('s:filter4')))
+endfunc
+
+" dict with funcref
+func Test_filter_map_dict_expr_funcref()
+ let dict = {"foo": 1, "bar": 2, "baz": 3}
+
+ " filter()
+ func! s:filter1(key, val) abort
+ return a:val > 1
+ endfunc
+ call assert_equal({"bar": 2, "baz": 3}, filter(copy(dict), function('s:filter1')))
+
+ func! s:filter2(key, val) abort
+ return a:key > "bar"
+ endfunc
+ call assert_equal({"foo": 1, "baz": 3}, filter(copy(dict), function('s:filter2')))
+
+ " map()
+ func! s:filter3(key, val) abort
+ return a:val * 2
+ endfunc
+ call assert_equal({"foo": 2, "bar": 4, "baz": 6}, map(copy(dict), function('s:filter3')))
+
+ func! s:filter4(key, val) abort
+ return a:key[0]
+ endfunc
+ call assert_equal({"foo": "f", "bar": "b", "baz": "b"}, map(copy(dict), function('s:filter4')))
+endfunc
diff --git a/src/nvim/testdir/test_float_func.vim b/src/nvim/testdir/test_float_func.vim
new file mode 100644
index 0000000000..5ea5192994
--- /dev/null
+++ b/src/nvim/testdir/test_float_func.vim
@@ -0,0 +1,332 @@
+" test float functions
+
+if !has('float')
+ finish
+end
+
+func Test_abs()
+ call assert_equal('1.23', string(abs(1.23)))
+ call assert_equal('1.23', string(abs(-1.23)))
+ call assert_equal('0.0', string(abs(0.0)))
+ call assert_equal('0.0', string(abs(1.0/(1.0/0.0))))
+ call assert_equal('0.0', string(abs(-1.0/(1.0/0.0))))
+ call assert_equal("str2float('inf')", string(abs(1.0/0.0)))
+ call assert_equal("str2float('inf')", string(abs(-1.0/0.0)))
+ call assert_equal("str2float('nan')", string(abs(0.0/0.0)))
+ call assert_equal('12', string(abs('-12abc')))
+ call assert_fails("call abs([])", 'E745:')
+ call assert_fails("call abs({})", 'E728:')
+ call assert_fails("call abs(function('string'))", 'E703:')
+endfunc
+
+func Test_sqrt()
+ call assert_equal('0.0', string(sqrt(0.0)))
+ call assert_equal('1.414214', string(sqrt(2.0)))
+ call assert_equal("str2float('inf')", string(sqrt(1.0/0.0)))
+ call assert_equal("str2float('nan')", string(sqrt(-1.0)))
+ call assert_equal("str2float('nan')", string(sqrt(0.0/0.0)))
+ call assert_fails('call sqrt("")', 'E808:')
+endfunc
+
+func Test_log()
+ call assert_equal('0.0', string(log(1.0)))
+ call assert_equal('-0.693147', string(log(0.5)))
+ call assert_equal("-str2float('inf')", string(log(0.0)))
+ call assert_equal("str2float('nan')", string(log(-1.0)))
+ call assert_equal("str2float('inf')", string(log(1.0/0.0)))
+ call assert_equal("str2float('nan')", string(log(0.0/0.0)))
+ call assert_fails('call log("")', 'E808:')
+endfunc
+
+func Test_log10()
+ call assert_equal('0.0', string(log10(1.0)))
+ call assert_equal('2.0', string(log10(100.0)))
+ call assert_equal('2.079181', string(log10(120.0)))
+ call assert_equal("-str2float('inf')", string(log10(0.0)))
+ call assert_equal("str2float('nan')", string(log10(-1.0)))
+ call assert_equal("str2float('inf')", string(log10(1.0/0.0)))
+ call assert_equal("str2float('nan')", string(log10(0.0/0.0)))
+ call assert_fails('call log10("")', 'E808:')
+endfunc
+
+func Test_exp()
+ call assert_equal('1.0', string(exp(0.0)))
+ call assert_equal('7.389056', string(exp(2.0)))
+ call assert_equal('0.367879', string(exp(-1.0)))
+ call assert_equal("str2float('inf')", string(exp(1.0/0.0)))
+ call assert_equal('0.0', string(exp(-1.0/0.0)))
+ call assert_equal("str2float('nan')", string(exp(0.0/0.0)))
+ call assert_fails('call exp("")', 'E808:')
+endfunc
+
+func Test_sin()
+ call assert_equal('0.0', string(sin(0.0)))
+ call assert_equal('0.841471', string(sin(1.0)))
+ call assert_equal('-0.479426', string(sin(-0.5)))
+ call assert_equal("str2float('nan')", string(sin(0.0/0.0)))
+ call assert_equal("str2float('nan')", string(sin(1.0/0.0)))
+ call assert_equal('0.0', string(sin(1.0/(1.0/0.0))))
+ call assert_equal('-0.0', string(sin(-1.0/(1.0/0.0))))
+ call assert_fails('call sin("")', 'E808:')
+endfunc
+
+func Test_asin()
+ call assert_equal('0.0', string(asin(0.0)))
+ call assert_equal('1.570796', string(asin(1.0)))
+ call assert_equal('-0.523599', string(asin(-0.5)))
+ call assert_equal("str2float('nan')", string(asin(1.1)))
+ call assert_equal("str2float('nan')", string(asin(1.0/0.0)))
+ call assert_equal("str2float('nan')", string(asin(0.0/0.0)))
+ call assert_fails('call asin("")', 'E808:')
+endfunc
+
+func Test_sinh()
+ call assert_equal('0.0', string(sinh(0.0)))
+ call assert_equal('0.521095', string(sinh(0.5)))
+ call assert_equal('-1.026517', string(sinh(-0.9)))
+ call assert_equal("str2float('inf')", string(sinh(1.0/0.0)))
+ call assert_equal("-str2float('inf')", string(sinh(-1.0/0.0)))
+ call assert_equal("str2float('nan')", string(sinh(0.0/0.0)))
+ call assert_fails('call sinh("")', 'E808:')
+endfunc
+
+func Test_cos()
+ call assert_equal('1.0', string(cos(0.0)))
+ call assert_equal('0.540302', string(cos(1.0)))
+ call assert_equal('0.877583', string(cos(-0.5)))
+ call assert_equal("str2float('nan')", string(cos(0.0/0.0)))
+ call assert_equal("str2float('nan')", string(cos(1.0/0.0)))
+ call assert_fails('call cos("")', 'E808:')
+endfunc
+
+func Test_acos()
+ call assert_equal('1.570796', string(acos(0.0)))
+ call assert_equal('0.0', string(acos(1.0)))
+ call assert_equal('3.141593', string(acos(-1.0)))
+ call assert_equal('2.094395', string(acos(-0.5)))
+ call assert_equal("str2float('nan')", string(acos(1.1)))
+ call assert_equal("str2float('nan')", string(acos(1.0/0.0)))
+ call assert_equal("str2float('nan')", string(acos(0.0/0.0)))
+ call assert_fails('call acos("")', 'E808:')
+endfunc
+
+func Test_cosh()
+ call assert_equal('1.0', string(cosh(0.0)))
+ call assert_equal('1.127626', string(cosh(0.5)))
+ call assert_equal("str2float('inf')", string(cosh(1.0/0.0)))
+ call assert_equal("str2float('inf')", string(cosh(-1.0/0.0)))
+ call assert_equal("str2float('nan')", string(cosh(0.0/0.0)))
+ call assert_fails('call cosh("")', 'E808:')
+endfunc
+
+func Test_tan()
+ call assert_equal('0.0', string(tan(0.0)))
+ call assert_equal('0.546302', string(tan(0.5)))
+ call assert_equal('-0.546302', string(tan(-0.5)))
+ call assert_equal("str2float('nan')", string(tan(1.0/0.0)))
+ call assert_equal("str2float('nan')", string(cos(0.0/0.0)))
+ call assert_equal('0.0', string(tan(1.0/(1.0/0.0))))
+ call assert_equal('-0.0', string(tan(-1.0/(1.0/0.0))))
+ call assert_fails('call tan("")', 'E808:')
+endfunc
+
+func Test_atan()
+ call assert_equal('0.0', string(atan(0.0)))
+ call assert_equal('0.463648', string(atan(0.5)))
+ call assert_equal('-0.785398', string(atan(-1.0)))
+ call assert_equal('1.570796', string(atan(1.0/0.0)))
+ call assert_equal('-1.570796', string(atan(-1.0/0.0)))
+ call assert_equal("str2float('nan')", string(atan(0.0/0.0)))
+ call assert_fails('call atan("")', 'E808:')
+endfunc
+
+func Test_atan2()
+ call assert_equal('-2.356194', string(atan2(-1, -1)))
+ call assert_equal('2.356194', string(atan2(1, -1)))
+ call assert_equal('0.0', string(atan2(1.0, 1.0/0.0)))
+ call assert_equal('1.570796', string(atan2(1.0/0.0, 1.0)))
+ call assert_equal("str2float('nan')", string(atan2(0.0/0.0, 1.0)))
+ call assert_fails('call atan2("", -1)', 'E808:')
+ call assert_fails('call atan2(-1, "")', 'E808:')
+endfunc
+
+func Test_tanh()
+ call assert_equal('0.0', string(tanh(0.0)))
+ call assert_equal('0.462117', string(tanh(0.5)))
+ call assert_equal('-0.761594', string(tanh(-1.0)))
+ call assert_equal('1.0', string(tanh(1.0/0.0)))
+ call assert_equal('-1.0', string(tanh(-1.0/0.0)))
+ call assert_equal("str2float('nan')", string(tanh(0.0/0.0)))
+ call assert_fails('call tanh("")', 'E808:')
+endfunc
+
+func Test_fmod()
+ call assert_equal('0.13', string(fmod(12.33, 1.22)))
+ call assert_equal('-0.13', string(fmod(-12.33, 1.22)))
+ call assert_equal("str2float('nan')", string(fmod(1.0/0.0, 1.0)))
+ " On Windows we get "nan" instead of 1.0, accept both.
+ let res = string(fmod(1.0, 1.0/0.0))
+ if res != "str2float('nan')"
+ call assert_equal('1.0', res)
+ endif
+ call assert_equal("str2float('nan')", string(fmod(1.0, 0.0)))
+ call assert_fails("call fmod('', 1.22)", 'E808:')
+ call assert_fails("call fmod(12.33, '')", 'E808:')
+endfunc
+
+func Test_pow()
+ call assert_equal('1.0', string(pow(0.0, 0.0)))
+ call assert_equal('8.0', string(pow(2.0, 3.0)))
+ call assert_equal("str2float('nan')", string(pow(2.0, 0.0/0.0)))
+ call assert_equal("str2float('nan')", string(pow(0.0/0.0, 3.0)))
+ call assert_equal("str2float('nan')", string(pow(0.0/0.0, 3.0)))
+ call assert_equal("str2float('inf')", string(pow(2.0, 1.0/0.0)))
+ call assert_equal("str2float('inf')", string(pow(1.0/0.0, 3.0)))
+ call assert_fails("call pow('', 2.0)", 'E808:')
+ call assert_fails("call pow(2.0, '')", 'E808:')
+endfunc
+
+func Test_str2float()
+ call assert_equal('1.0', string(str2float('1')))
+ call assert_equal('1.0', string(str2float(' 1 ')))
+ call assert_equal('1.0', string(str2float(' 1.0 ')))
+ call assert_equal('1.23', string(str2float('1.23')))
+ call assert_equal('1.23', string(str2float('1.23abc')))
+ call assert_equal('1.0e40', string(str2float('1e40')))
+ call assert_equal('-1.23', string(str2float('-1.23')))
+ call assert_equal('1.23', string(str2float(' + 1.23 ')))
+
+ call assert_equal('1.0', string(str2float('+1')))
+ call assert_equal('1.0', string(str2float('+1')))
+ call assert_equal('1.0', string(str2float(' +1 ')))
+ call assert_equal('1.0', string(str2float(' + 1 ')))
+
+ call assert_equal('-1.0', string(str2float('-1')))
+ call assert_equal('-1.0', string(str2float('-1')))
+ call assert_equal('-1.0', string(str2float(' -1 ')))
+ call assert_equal('-1.0', string(str2float(' - 1 ')))
+
+ call assert_equal('0.0', string(str2float('+0.0')))
+ call assert_equal('-0.0', string(str2float('-0.0')))
+ call assert_equal("str2float('inf')", string(str2float('1e1000')))
+ call assert_equal("str2float('inf')", string(str2float('inf')))
+ call assert_equal("-str2float('inf')", string(str2float('-inf')))
+ call assert_equal("str2float('inf')", string(str2float('+inf')))
+ call assert_equal("str2float('inf')", string(str2float('Inf')))
+ call assert_equal("str2float('inf')", string(str2float(' +inf ')))
+ call assert_equal("str2float('nan')", string(str2float('nan')))
+ call assert_equal("str2float('nan')", string(str2float('NaN')))
+ call assert_equal("str2float('nan')", string(str2float(' nan ')))
+
+ call assert_fails("call str2float(1.2)", 'E806:')
+ call assert_fails("call str2float([])", 'E730:')
+ call assert_fails("call str2float({})", 'E731:')
+ call assert_fails("call str2float(function('string'))", 'E729:')
+endfunc
+
+func Test_float2nr()
+ call assert_equal(1, float2nr(1.234))
+ call assert_equal(123, float2nr(1.234e2))
+ call assert_equal(12, float2nr(123.4e-1))
+ let max_number = 1/0
+ let min_number = -max_number
+ call assert_equal(max_number/2+1, float2nr(pow(2, 62)))
+ call assert_equal(max_number, float2nr(pow(2, 63)))
+ call assert_equal(max_number, float2nr(pow(2, 64)))
+ call assert_equal(min_number/2-1, float2nr(-pow(2, 62)))
+ call assert_equal(min_number, float2nr(-pow(2, 63)))
+ call assert_equal(min_number, float2nr(-pow(2, 64)))
+endfunc
+
+func Test_floor()
+ call assert_equal('2.0', string(floor(2.0)))
+ call assert_equal('2.0', string(floor(2.11)))
+ call assert_equal('2.0', string(floor(2.99)))
+ call assert_equal('-3.0', string(floor(-2.11)))
+ call assert_equal('-3.0', string(floor(-2.99)))
+ call assert_equal("str2float('nan')", string(floor(0.0/0.0)))
+ call assert_equal("str2float('inf')", string(floor(1.0/0.0)))
+ call assert_equal("-str2float('inf')", string(floor(-1.0/0.0)))
+ call assert_fails("call floor('')", 'E808:')
+endfunc
+
+func Test_ceil()
+ call assert_equal('2.0', string(ceil(2.0)))
+ call assert_equal('3.0', string(ceil(2.11)))
+ call assert_equal('3.0', string(ceil(2.99)))
+ call assert_equal('-2.0', string(ceil(-2.11)))
+ call assert_equal('-2.0', string(ceil(-2.99)))
+ call assert_equal("str2float('nan')", string(ceil(0.0/0.0)))
+ call assert_equal("str2float('inf')", string(ceil(1.0/0.0)))
+ call assert_equal("-str2float('inf')", string(ceil(-1.0/0.0)))
+ call assert_fails("call ceil('')", 'E808:')
+endfunc
+
+func Test_round()
+ call assert_equal('2.0', string(round(2.1)))
+ call assert_equal('3.0', string(round(2.5)))
+ call assert_equal('3.0', string(round(2.9)))
+ call assert_equal('-2.0', string(round(-2.1)))
+ call assert_equal('-3.0', string(round(-2.5)))
+ call assert_equal('-3.0', string(round(-2.9)))
+ call assert_equal("str2float('nan')", string(round(0.0/0.0)))
+ call assert_equal("str2float('inf')", string(round(1.0/0.0)))
+ call assert_equal("-str2float('inf')", string(round(-1.0/0.0)))
+ call assert_fails("call round('')", 'E808:')
+endfunc
+
+func Test_trunc()
+ call assert_equal('2.0', string(trunc(2.1)))
+ call assert_equal('2.0', string(trunc(2.5)))
+ call assert_equal('2.0', string(trunc(2.9)))
+ call assert_equal('-2.0', string(trunc(-2.1)))
+ call assert_equal('-2.0', string(trunc(-2.5)))
+ call assert_equal('-2.0', string(trunc(-2.9)))
+ call assert_equal("str2float('nan')", string(trunc(0.0/0.0)))
+ call assert_equal("str2float('inf')", string(trunc(1.0/0.0)))
+ call assert_equal("-str2float('inf')", string(trunc(-1.0/0.0)))
+ call assert_fails("call trunc('')", 'E808:')
+endfunc
+
+func Test_isnan()
+ throw 'skipped: Nvim does not support isnan()'
+ call assert_equal(0, isnan(1.0))
+ call assert_equal(1, isnan(0.0/0.0))
+ call assert_equal(0, isnan(1.0/0.0))
+ call assert_equal(0, isnan('a'))
+ call assert_equal(0, isnan([]))
+ call assert_equal(0, isnan({}))
+endfunc
+
+" This was converted from test65
+func Test_float_misc()
+ call assert_equal('123.456000', printf('%f', 123.456))
+ call assert_equal('1.234560e+02', printf('%e', 123.456))
+ call assert_equal('123.456', printf('%g', 123.456))
+ " +=
+ let v = 1.234
+ let v += 6.543
+ call assert_equal('7.777', printf('%g', v))
+ let v = 1.234
+ let v += 5
+ call assert_equal('6.234', printf('%g', v))
+ let v = 5
+ let v += 3.333
+ call assert_equal('8.333', string(v))
+ " ==
+ let v = 1.234
+ call assert_true(v == 1.234)
+ call assert_false(v == 1.2341)
+ " add-subtract
+ call assert_equal('5.234', printf('%g', 4 + 1.234))
+ call assert_equal('-6.766', printf('%g', 1.234 - 8))
+ " mult-div
+ call assert_equal('4.936', printf('%g', 4 * 1.234))
+ call assert_equal('0.003241', printf('%g', 4.0 / 1234))
+ " dict
+ call assert_equal("{'x': 1.234, 'y': -2.0e20}", string({'x': 1.234, 'y': -2.0e20}))
+ " list
+ call assert_equal('[-123.4, 2.0e-20]', string([-123.4, 2.0e-20]))
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_fnameescape.vim b/src/nvim/testdir/test_fnameescape.vim
new file mode 100644
index 0000000000..cdff0dfbd9
--- /dev/null
+++ b/src/nvim/testdir/test_fnameescape.vim
@@ -0,0 +1,21 @@
+
+" Test if fnameescape is correct for special chars like !
+function! Test_fnameescape()
+ let fname = 'Xspa ce'
+ let status = v:false
+ try
+ exe "w! " . fnameescape(fname)
+ let status = v:true
+ endtry
+ call assert_true(status, "Space")
+ call delete(fname)
+
+ let fname = 'Xemark!'
+ let status = v:false
+ try
+ exe "w! " . fnameescape(fname)
+ let status = v:true
+ endtry
+ call assert_true(status, "ExclamationMark")
+ call delete(fname)
+endfunction
diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim
new file mode 100644
index 0000000000..46c54e8614
--- /dev/null
+++ b/src/nvim/testdir/test_fold.vim
@@ -0,0 +1,362 @@
+" Test for folding
+
+func! PrepIndent(arg)
+ return [a:arg] + repeat(["\t".a:arg], 5)
+endfu
+
+func! Test_address_fold()
+ new
+ call setline(1, ['int FuncName() {/*{{{*/', 1, 2, 3, 4, 5, '}/*}}}*/',
+ \ 'after fold 1', 'after fold 2', 'after fold 3'])
+ setl fen fdm=marker
+ " The next ccommands should all copy the same part of the buffer,
+ " regardless of the adressing type, since the part to be copied
+ " is folded away
+ :1y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+ :.y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+ :.+y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+ :.,.y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+ :sil .1,.y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+ " use silent to make E493 go away
+ :sil .+,.y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+ :,y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+ :,+y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/','after fold 1'], getreg(0,1,1))
+ " using .+3 as second address should copy the whole folded line + the next 3
+ " lines
+ :.,+3y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/',
+ \ 'after fold 1', 'after fold 2', 'after fold 3'], getreg(0,1,1))
+ :sil .,-2y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+
+ " now test again with folding disabled
+ set nofoldenable
+ :1y
+ call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
+ :.y
+ call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
+ :.+y
+ call assert_equal(['1'], getreg(0,1,1))
+ :.,.y
+ call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
+ " use silent to make E493 go away
+ :sil .1,.y
+ call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
+ " use silent to make E493 go away
+ :sil .+,.y
+ call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
+ :,y
+ call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
+ :,+y
+ call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
+ " using .+3 as second address should copy the whole folded line + the next 3
+ " lines
+ :.,+3y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3'], getreg(0,1,1))
+ :7
+ :sil .,-2y
+ call assert_equal(['4', '5', '}/*}}}*/'], getreg(0,1,1))
+
+ quit!
+endfunc
+
+func! Test_indent_fold()
+ new
+ call setline(1, ['', 'a', ' b', ' c'])
+ setl fen fdm=indent
+ 2
+ norm! >>
+ let a=map(range(1,4), 'foldclosed(v:val)')
+ call assert_equal([-1,-1,-1,-1], a)
+endfunc
+
+func! Test_indent_fold()
+ new
+ call setline(1, ['', 'a', ' b', ' c'])
+ setl fen fdm=indent
+ 2
+ norm! >>
+ let a=map(range(1,4), 'foldclosed(v:val)')
+ call assert_equal([-1,-1,-1,-1], a)
+ bw!
+endfunc
+
+func! Test_indent_fold2()
+ new
+ call setline(1, ['', '{{{', '}}}', '{{{', '}}}'])
+ setl fen fdm=marker
+ 2
+ norm! >>
+ let a=map(range(1,5), 'foldclosed(v:val)')
+ call assert_equal([-1,-1,-1,4,4], a)
+ bw!
+endfunc
+
+func Test_manual_fold_with_filter()
+ if !executable('cat')
+ return
+ endif
+ for type in ['manual', 'marker']
+ exe 'set foldmethod=' . type
+ new
+ call setline(1, range(1, 20))
+ 4,$fold
+ %foldopen
+ 10,$fold
+ %foldopen
+ " This filter command should not have an effect
+ 1,8! cat
+ call feedkeys('5ggzdzMGdd', 'xt')
+ call assert_equal(['1', '2', '3', '4', '5', '6', '7', '8', '9'], getline(1, '$'))
+
+ bwipe!
+ set foldmethod&
+ endfor
+endfunc
+
+func! Test_indent_fold_with_read()
+ new
+ set foldmethod=indent
+ call setline(1, repeat(["\<Tab>a"], 4))
+ for n in range(1, 4)
+ call assert_equal(1, foldlevel(n))
+ endfor
+
+ call writefile(["a", "", "\<Tab>a"], 'Xfile')
+ foldopen
+ 2read Xfile
+ %foldclose
+ call assert_equal(1, foldlevel(1))
+ call assert_equal(2, foldclosedend(1))
+ call assert_equal(0, foldlevel(3))
+ call assert_equal(0, foldlevel(4))
+ call assert_equal(1, foldlevel(5))
+ call assert_equal(7, foldclosedend(5))
+
+ bwipe!
+ set foldmethod&
+ call delete('Xfile')
+endfunc
+
+func Test_combining_folds_indent()
+ new
+ let one = "\<Tab>a"
+ let zero = 'a'
+ call setline(1, [one, one, zero, zero, zero, one, one, one])
+ set foldmethod=indent
+ 3,5d
+ %foldclose
+ call assert_equal(5, foldclosedend(1))
+
+ set foldmethod&
+ bwipe!
+endfunc
+
+func Test_combining_folds_marker()
+ new
+ call setline(1, ['{{{', '}}}', '', '', '', '{{{', '', '}}}'])
+ set foldmethod=marker
+ 3,5d
+ %foldclose
+ call assert_equal(2, foldclosedend(1))
+
+ set foldmethod&
+ bwipe!
+endfunc
+
+func Test_folds_marker_in_comment()
+ new
+ call setline(1, ['" foo', 'bar', 'baz'])
+ setl fen fdm=marker
+ setl com=sO:\"\ -,mO:\"\ \ ,eO:\"\",:\" cms=\"%s
+ norm! zf2j
+ setl nofen
+ :1y
+ call assert_equal(['" foo{{{'], getreg(0,1,1))
+ :+2y
+ call assert_equal(['baz"}}}'], getreg(0,1,1))
+
+ set foldmethod&
+ bwipe!
+endfunc
+
+func s:TestFoldExpr(lnum)
+ let thisline = getline(a:lnum)
+ if thisline == 'a'
+ return 1
+ elseif thisline == 'b'
+ return 0
+ elseif thisline == 'c'
+ return '<1'
+ elseif thisline == 'd'
+ return '>1'
+ endif
+ return 0
+endfunction
+
+func Test_update_folds_expr_read()
+ new
+ call setline(1, ['a', 'a', 'a', 'a', 'a', 'a'])
+ set foldmethod=expr
+ set foldexpr=s:TestFoldExpr(v:lnum)
+ 2
+ foldopen
+ call writefile(['b', 'b', 'a', 'a', 'd', 'a', 'a', 'c'], 'Xfile')
+ read Xfile
+ %foldclose
+ call assert_equal(2, foldclosedend(1))
+ call assert_equal(0, foldlevel(3))
+ call assert_equal(0, foldlevel(4))
+ call assert_equal(6, foldclosedend(5))
+ call assert_equal(10, foldclosedend(7))
+ call assert_equal(14, foldclosedend(11))
+
+ call delete('Xfile')
+ bwipe!
+ set foldmethod& foldexpr&
+endfunc
+
+func! Test_move_folds_around_manual()
+ new
+ let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
+ call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
+ let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
+ " all folds closed
+ set foldenable foldlevel=0 fdm=indent
+ " needs a forced redraw
+ redraw!
+ set fdm=manual
+ call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+ call assert_equal(input, getline(1, '$'))
+ 7,12m0
+ call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
+ call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+ 10,12m0
+ call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$'))
+ call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
+ " moving should not close the folds
+ %d
+ call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
+ set fdm=indent
+ redraw!
+ set fdm=manual
+ call cursor(2, 1)
+ %foldopen
+ 7,12m0
+ let folds=repeat([-1], 18)
+ call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
+ call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+ norm! zM
+ " folds are not corrupted and all have been closed
+ call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
+ %d
+ call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
+ set fdm=indent
+ redraw!
+ set fdm=manual
+ %foldopen
+ 3m4
+ %foldclose
+ call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
+ call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
+ %d
+ call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
+ set fdm=indent foldlevel=0
+ set fdm=manual
+ %foldopen
+ 3m1
+ %foldclose
+ call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
+ call assert_equal(0, foldlevel(2))
+ call assert_equal(5, foldclosedend(3))
+ call assert_equal([-1, -1, 3, 3, 3, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
+ 2,6m$
+ %foldclose
+ call assert_equal(5, foldclosedend(2))
+ call assert_equal(0, foldlevel(6))
+ call assert_equal(9, foldclosedend(7))
+ call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
+ %d
+ " Ensure moving around the edges still works.
+ call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
+ set fdm=indent foldlevel=0
+ set fdm=manual
+ %foldopen
+ 6m$
+ " The first fold has been truncated to the 5'th line.
+ " Second fold has been moved up because the moved line is now below it.
+ call assert_equal([0, 1, 1, 1, 1, 0, 0, 0, 1, 0], map(range(1, line('$')), 'foldlevel(v:val)'))
+ bw!
+endfunc
+
+func! Test_move_folds_around_indent()
+ new
+ let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
+ call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
+ let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
+ " all folds closed
+ set fdm=indent
+ call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+ call assert_equal(input, getline(1, '$'))
+ 7,12m0
+ call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
+ call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+ 10,12m0
+ call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$'))
+ call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
+ " moving should not close the folds
+ %d
+ call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
+ set fdm=indent
+ call cursor(2, 1)
+ %foldopen
+ 7,12m0
+ let folds=repeat([-1], 18)
+ call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
+ call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+ norm! zM
+ " folds are not corrupted and all have been closed
+ call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
+ %d
+ call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
+ set fdm=indent
+ %foldopen
+ 3m4
+ %foldclose
+ call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
+ call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
+ %d
+ call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
+ set fdm=indent foldlevel=0
+ %foldopen
+ 3m1
+ %foldclose
+ call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
+ call assert_equal(1, foldlevel(2))
+ call assert_equal(5, foldclosedend(3))
+ call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
+ 2,6m$
+ %foldclose
+ call assert_equal(9, foldclosedend(2))
+ call assert_equal(1, foldlevel(6))
+ call assert_equal(9, foldclosedend(7))
+ call assert_equal([-1, 2, 2, 2, 2, 2, 2, 2, 2, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
+ " Ensure moving around the edges still works.
+ %d
+ call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
+ set fdm=indent foldlevel=0
+ %foldopen
+ 6m$
+ " The first fold has been truncated to the 5'th line.
+ " Second fold has been moved up because the moved line is now below it.
+ call assert_equal([0, 1, 1, 1, 1, 0, 0, 0, 1, 1], map(range(1, line('$')), 'foldlevel(v:val)'))
+ bw!
+endfunc
diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim
new file mode 100644
index 0000000000..237a2dc820
--- /dev/null
+++ b/src/nvim/testdir/test_functions.vim
@@ -0,0 +1,194 @@
+" Tests for various functions.
+
+func Test_str2nr()
+ call assert_equal(0, str2nr(''))
+ call assert_equal(1, str2nr('1'))
+ call assert_equal(1, str2nr(' 1 '))
+
+ call assert_equal(1, str2nr('+1'))
+ call assert_equal(1, str2nr('+ 1'))
+ call assert_equal(1, str2nr(' + 1 '))
+
+ call assert_equal(-1, str2nr('-1'))
+ call assert_equal(-1, str2nr('- 1'))
+ call assert_equal(-1, str2nr(' - 1 '))
+
+ call assert_equal(123456789, str2nr('123456789'))
+ call assert_equal(-123456789, str2nr('-123456789'))
+endfunc
+
+func Test_setbufvar_options()
+ " This tests that aucmd_prepbuf() and aucmd_restbuf() properly restore the
+ " window layout.
+ call assert_equal(1, winnr('$'))
+ split dummy_preview
+ resize 2
+ set winfixheight winfixwidth
+ let prev_id = win_getid()
+
+ wincmd j
+ let wh = winheight('.')
+ let dummy_buf = bufnr('dummy_buf1', v:true)
+ call setbufvar(dummy_buf, '&buftype', 'nofile')
+ execute 'belowright vertical split #' . dummy_buf
+ call assert_equal(wh, winheight('.'))
+ let dum1_id = win_getid()
+
+ wincmd h
+ let wh = winheight('.')
+ let dummy_buf = bufnr('dummy_buf2', v:true)
+ call setbufvar(dummy_buf, '&buftype', 'nofile')
+ execute 'belowright vertical split #' . dummy_buf
+ call assert_equal(wh, winheight('.'))
+
+ bwipe!
+ call win_gotoid(prev_id)
+ bwipe!
+ call win_gotoid(dum1_id)
+ bwipe!
+endfunc
+
+func Test_tolower()
+ call assert_equal("", tolower(""))
+
+ " Test with all printable ASCII characters.
+ call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~',
+ \ tolower(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'))
+
+ if !has('multi_byte')
+ return
+ endif
+
+ " Test with a few uppercase diacritics.
+ call assert_equal("aàáâãäåÄăąǎǟǡả", tolower("AÀÃÂÃÄÅĀĂĄÇǞǠẢ"))
+ call assert_equal("bḃḇ", tolower("BḂḆ"))
+ call assert_equal("cçćĉċÄ", tolower("CÇĆĈĊČ"))
+ call assert_equal("dÄđḋá¸á¸‘", tolower("DÄŽÄḊḎá¸"))
+ call assert_equal("eèéêëēĕėęěẻẽ", tolower("EÈÉÊËĒĔĖĘĚẺẼ"))
+ call assert_equal("fḟ ", tolower("FḞ "))
+ call assert_equal("gÄğġģǥǧǵḡ", tolower("GĜĞĠĢǤǦǴḠ"))
+ call assert_equal("hĥħḣḧḩ", tolower("HĤĦḢḦḨ"))
+ call assert_equal("iìíîïĩīĭįiÇỉ", tolower("IÃŒÃÃŽÃĨĪĬĮİÇỈ"))
+ call assert_equal("jĵ", tolower("JĴ"))
+ call assert_equal("kķǩḱḵ", tolower("KĶǨḰḴ"))
+ call assert_equal("lĺļľŀłḻ", tolower("LĹĻĽĿÅḺ"))
+ call assert_equal("mḿá¹", tolower("MḾṀ"))
+ call assert_equal("nñńņňṅṉ", tolower("NÑŃŅŇṄṈ"))
+ call assert_equal("oòóôõöøÅÅőơǒǫǭá»", tolower("OÃ’Ã“Ã”Ã•Ã–Ã˜ÅŒÅŽÅÆ Ç‘ǪǬỎ"))
+ call assert_equal("pṕṗ", tolower("PṔṖ"))
+ call assert_equal("q", tolower("Q"))
+ call assert_equal("rŕŗřṙṟ", tolower("RŔŖŘṘṞ"))
+ call assert_equal("sÅ›Åşšṡ", tolower("SŚŜŞŠṠ"))
+ call assert_equal("tţťŧṫṯ", tolower("TŢŤŦṪṮ"))
+ call assert_equal("uùúûüũūŭůűųưǔủ", tolower("UÙÚÛÜŨŪŬŮŰŲƯǓỦ"))
+ call assert_equal("vá¹½", tolower("Vá¹¼"))
+ call assert_equal("wŵáºáºƒáº…ẇ", tolower("WŴẀẂẄẆ"))
+ call assert_equal("xẋáº", tolower("XẊẌ"))
+ call assert_equal("yýŷÿáºá»³á»·á»¹", tolower("YÃŶŸẎỲỶỸ"))
+ call assert_equal("zźżžƶẑẕ", tolower("ZŹŻŽƵáºáº”"))
+
+ " Test with a few lowercase diacritics, which should remain unchanged.
+ call assert_equal("aàáâãäåÄăąǎǟǡả", tolower("aàáâãäåÄăąǎǟǡả"))
+ call assert_equal("bḃḇ", tolower("bḃḇ"))
+ call assert_equal("cçćĉċÄ", tolower("cçćĉċÄ"))
+ call assert_equal("dÄđḋá¸á¸‘", tolower("dÄđḋá¸á¸‘"))
+ call assert_equal("eèéêëēĕėęěẻẽ", tolower("eèéêëēĕėęěẻẽ"))
+ call assert_equal("fḟ", tolower("fḟ"))
+ call assert_equal("gÄğġģǥǧǵḡ", tolower("gÄğġģǥǧǵḡ"))
+ call assert_equal("hĥħḣḧḩẖ", tolower("hĥħḣḧḩẖ"))
+ call assert_equal("iìíîïĩīĭįÇỉ", tolower("iìíîïĩīĭįÇỉ"))
+ call assert_equal("jĵǰ", tolower("jĵǰ"))
+ call assert_equal("kķǩḱḵ", tolower("kķǩḱḵ"))
+ call assert_equal("lĺļľŀłḻ", tolower("lĺļľŀłḻ"))
+ call assert_equal("mḿṠ", tolower("mḿṠ"))
+ call assert_equal("nñńņňʼnṅṉ", tolower("nñńņňʼnṅṉ"))
+ call assert_equal("oòóôõöøÅÅőơǒǫǭá»", tolower("oòóôõöøÅÅőơǒǫǭá»"))
+ call assert_equal("pṕṗ", tolower("pṕṗ"))
+ call assert_equal("q", tolower("q"))
+ call assert_equal("rŕŗřṙṟ", tolower("rŕŗřṙṟ"))
+ call assert_equal("sÅ›Åşšṡ", tolower("sÅ›Åşšṡ"))
+ call assert_equal("tţťŧṫṯẗ", tolower("tţťŧṫṯẗ"))
+ call assert_equal("uùúûüũūŭůűųưǔủ", tolower("uùúûüũūŭůűųưǔủ"))
+ call assert_equal("vá¹½", tolower("vá¹½"))
+ call assert_equal("wŵáºáºƒáº…ẇẘ", tolower("wŵáºáºƒáº…ẇẘ"))
+ call assert_equal("ẋáº", tolower("ẋáº"))
+ call assert_equal("yýÿŷáºáº™á»³á»·á»¹", tolower("yýÿŷáºáº™á»³á»·á»¹"))
+ call assert_equal("zźżžƶẑẕ", tolower("zźżžƶẑẕ"))
+
+ " According to https://twitter.com/jifa/status/625776454479970304
+ " Ⱥ (U+023A) and Ⱦ (U+023E) are the *only* code points to increase
+ " in length (2 to 3 bytes) when lowercased. So let's test them.
+ call assert_equal("ⱥ ⱦ", tolower("Ⱥ Ⱦ"))
+endfunc
+
+func Test_toupper()
+ call assert_equal("", toupper(""))
+
+ " Test with all printable ASCII characters.
+ call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~',
+ \ toupper(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'))
+
+ if !has('multi_byte')
+ return
+ endif
+
+ " Test with a few lowercase diacritics.
+ call assert_equal("AÀÃÂÃÄÅĀĂĄÇǞǠẢ", toupper("aàáâãäåÄăąǎǟǡả"))
+ call assert_equal("BḂḆ", toupper("bḃḇ"))
+ call assert_equal("CÇĆĈĊČ", toupper("cçćĉċÄ"))
+ call assert_equal("DÄŽÄḊḎá¸", toupper("dÄđḋá¸á¸‘"))
+ call assert_equal("EÈÉÊËĒĔĖĘĚẺẼ", toupper("eèéêëēĕėęěẻẽ"))
+ call assert_equal("FḞ", toupper("fḟ"))
+ call assert_equal("GĜĞĠĢǤǦǴḠ", toupper("gÄğġģǥǧǵḡ"))
+ call assert_equal("HĤĦḢḦḨẖ", toupper("hĥħḣḧḩẖ"))
+ call assert_equal("IÃŒÃÃŽÃĨĪĬĮÇỈ", toupper("iìíîïĩīĭįÇỉ"))
+ call assert_equal("JĴǰ", toupper("jĵǰ"))
+ call assert_equal("KĶǨḰḴ", toupper("kķǩḱḵ"))
+ call assert_equal("LĹĻĽĿÅḺ", toupper("lĺļľŀłḻ"))
+ call assert_equal("MḾṀ ", toupper("mḿṠ"))
+ call assert_equal("NÑŃŅŇʼnṄṈ", toupper("nñńņňʼnṅṉ"))
+ call assert_equal("OÃ’Ã“Ã”Ã•Ã–Ã˜ÅŒÅŽÅÆ Ç‘ǪǬỎ", toupper("oòóôõöøÅÅőơǒǫǭá»"))
+ call assert_equal("PṔṖ", toupper("pṕṗ"))
+ call assert_equal("Q", toupper("q"))
+ call assert_equal("RŔŖŘṘṞ", toupper("rŕŗřṙṟ"))
+ call assert_equal("SŚŜŞŠṠ", toupper("sÅ›Åşšṡ"))
+ call assert_equal("TŢŤŦṪṮẗ", toupper("tţťŧṫṯẗ"))
+ call assert_equal("UÙÚÛÜŨŪŬŮŰŲƯǓỦ", toupper("uùúûüũūŭůűųưǔủ"))
+ call assert_equal("Vá¹¼", toupper("vá¹½"))
+ call assert_equal("WŴẀẂẄẆẘ", toupper("wŵáºáºƒáº…ẇẘ"))
+ call assert_equal("ẊẌ", toupper("ẋáº"))
+ call assert_equal("YßŶẎẙỲỶỸ", toupper("yýÿŷáºáº™á»³á»·á»¹"))
+ call assert_equal("ZŹŻŽƵáºáº”", toupper("zźżžƶẑẕ"))
+
+ " Test that uppercase diacritics, which should remain unchanged.
+ call assert_equal("AÀÃÂÃÄÅĀĂĄÇǞǠẢ", toupper("AÀÃÂÃÄÅĀĂĄÇǞǠẢ"))
+ call assert_equal("BḂḆ", toupper("BḂḆ"))
+ call assert_equal("CÇĆĈĊČ", toupper("CÇĆĈĊČ"))
+ call assert_equal("DÄŽÄḊḎá¸", toupper("DÄŽÄḊḎá¸"))
+ call assert_equal("EÈÉÊËĒĔĖĘĚẺẼ", toupper("EÈÉÊËĒĔĖĘĚẺẼ"))
+ call assert_equal("FḞ ", toupper("FḞ "))
+ call assert_equal("GĜĞĠĢǤǦǴḠ", toupper("GĜĞĠĢǤǦǴḠ"))
+ call assert_equal("HĤĦḢḦḨ", toupper("HĤĦḢḦḨ"))
+ call assert_equal("IÃŒÃÃŽÃĨĪĬĮİÇỈ", toupper("IÃŒÃÃŽÃĨĪĬĮİÇỈ"))
+ call assert_equal("JÄ´", toupper("JÄ´"))
+ call assert_equal("KĶǨḰḴ", toupper("KĶǨḰḴ"))
+ call assert_equal("LĹĻĽĿÅḺ", toupper("LĹĻĽĿÅḺ"))
+ call assert_equal("MḾṀ", toupper("MḾṀ"))
+ call assert_equal("NÑŃŅŇṄṈ", toupper("NÑŃŅŇṄṈ"))
+ call assert_equal("OÃ’Ã“Ã”Ã•Ã–Ã˜ÅŒÅŽÅÆ Ç‘ǪǬỎ", toupper("OÃ’Ã“Ã”Ã•Ã–Ã˜ÅŒÅŽÅÆ Ç‘ǪǬỎ"))
+ call assert_equal("PṔṖ", toupper("PṔṖ"))
+ call assert_equal("Q", toupper("Q"))
+ call assert_equal("RŔŖŘṘṞ", toupper("RŔŖŘṘṞ"))
+ call assert_equal("SŚŜŞŠṠ", toupper("SŚŜŞŠṠ"))
+ call assert_equal("TŢŤŦṪṮ", toupper("TŢŤŦṪṮ"))
+ call assert_equal("UÙÚÛÜŨŪŬŮŰŲƯǓỦ", toupper("UÙÚÛÜŨŪŬŮŰŲƯǓỦ"))
+ call assert_equal("Vá¹¼", toupper("Vá¹¼"))
+ call assert_equal("WŴẀẂẄẆ", toupper("WŴẀẂẄẆ"))
+ call assert_equal("XẊẌ", toupper("XẊẌ"))
+ call assert_equal("YÃŶŸẎỲỶỸ", toupper("YÃŶŸẎỲỶỸ"))
+ call assert_equal("ZŹŻŽƵáºáº”", toupper("ZŹŻŽƵáºáº”"))
+
+ call assert_equal("ⱥ ⱦ", tolower("Ⱥ Ⱦ"))
+endfunc
+
+
diff --git a/src/nvim/testdir/test_gf.vim b/src/nvim/testdir/test_gf.vim
new file mode 100644
index 0000000000..c4aa6f9218
--- /dev/null
+++ b/src/nvim/testdir/test_gf.vim
@@ -0,0 +1,33 @@
+
+" This is a test if a URL is recognized by "gf", with the cursor before and
+" after the "://". Also test ":\\".
+function! Test_gf_url()
+ enew!
+ call append(0, [
+ \ "first test for URL://machine.name/tmp/vimtest2a and other text",
+ \ "second test for URL://machine.name/tmp/vimtest2b. And other text",
+ \ "third test for URL:\\\\machine.name\\vimtest2c and other text",
+ \ "fourth test for URL:\\\\machine.name\\tmp\\vimtest2d, and other text"
+ \ ])
+ call cursor(1,1)
+ call search("^first")
+ call search("tmp")
+ call assert_equal("URL://machine.name/tmp/vimtest2a", expand("<cfile>"))
+ call search("^second")
+ call search("URL")
+ call assert_equal("URL://machine.name/tmp/vimtest2b", expand("<cfile>"))
+ if has("ebcdic")
+ set isf=@,240-249,/,.,-,_,+,,,$,:,~,\
+ else
+ set isf=@,48-57,/,.,-,_,+,,,$,:,~,\
+ endif
+ call search("^third")
+ call search("name")
+ call assert_equal("URL:\\\\machine.name\\vimtest2c", expand("<cfile>"))
+ call search("^fourth")
+ call search("URL")
+ call assert_equal("URL:\\\\machine.name\\tmp\\vimtest2d", expand("<cfile>"))
+
+ set isf&vim
+ enew!
+endfunction
diff --git a/src/nvim/testdir/test_glob2regpat.vim b/src/nvim/testdir/test_glob2regpat.vim
new file mode 100644
index 0000000000..fdf17946b6
--- /dev/null
+++ b/src/nvim/testdir/test_glob2regpat.vim
@@ -0,0 +1,30 @@
+" Test glob2regpat()
+
+func Test_invalid()
+ call assert_fails('call glob2regpat(1.33)', 'E806:')
+ call assert_fails('call glob2regpat("}")', 'E219:')
+ call assert_fails('call glob2regpat("{")', 'E220:')
+endfunc
+
+func Test_valid()
+ call assert_equal('^foo\.', glob2regpat('foo.*'))
+ call assert_equal('^foo.$', glob2regpat('foo?'))
+ call assert_equal('\.vim$', glob2regpat('*.vim'))
+ call assert_equal('^[abc]$', glob2regpat('[abc]'))
+ call assert_equal('^foo bar$', glob2regpat('foo\ bar'))
+ call assert_equal('^foo,bar$', glob2regpat('foo,bar'))
+ call assert_equal('^\(foo\|bar\)$', glob2regpat('{foo,bar}'))
+ call assert_equal('.*', glob2regpat('**'))
+
+ if exists('+shellslash')
+ call assert_equal('^foo[\/].$', glob2regpat('foo\?'))
+ call assert_equal('^\(foo[\/]\|bar\|foobar\)$', glob2regpat('{foo\,bar,foobar}'))
+ call assert_equal('^[\/]\(foo\|bar[\/]\)$', glob2regpat('\{foo,bar\}'))
+ call assert_equal('^[\/][\/]\(foo\|bar[\/][\/]\)$', glob2regpat('\\{foo,bar\\}'))
+ else
+ call assert_equal('^foo?$', glob2regpat('foo\?'))
+ call assert_equal('^\(foo,bar\|foobar\)$', glob2regpat('{foo\,bar,foobar}'))
+ call assert_equal('^{foo,bar}$', glob2regpat('\{foo,bar\}'))
+ call assert_equal('^\\\(foo\|bar\\\)$', glob2regpat('\\{foo,bar\\}'))
+ endif
+endfunc
diff --git a/src/nvim/testdir/test_gn.vim b/src/nvim/testdir/test_gn.vim
index 3eca99bd99..7a5cdabaa3 100644
--- a/src/nvim/testdir/test_gn.vim
+++ b/src/nvim/testdir/test_gn.vim
@@ -90,4 +90,4 @@ func Test_gn_command()
sil! %d _
endfu
-" vim: tabstop=2 shiftwidth=0 expandtab
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_goto.vim b/src/nvim/testdir/test_goto.vim
index 2afd96b296..2573401707 100644
--- a/src/nvim/testdir/test_goto.vim
+++ b/src/nvim/testdir/test_goto.vim
@@ -1,20 +1,290 @@
" Test commands that jump somewhere.
-func Test_geeDEE()
+" Create a new buffer using "lines" and place the cursor on the word after the
+" first occurrence of return and invoke "cmd". The cursor should now be
+" positioned at the given line and col.
+func XTest_goto_decl(cmd, lines, line, col)
new
- call setline(1, ["Filename x;", "", "int Filename", "int func() {", "Filename y;"])
- /y;/
- normal gD
- call assert_equal(1, line('.'))
+ call setline(1, a:lines)
+ /return/
+ normal! W
+ execute 'norm! ' . a:cmd
+ call assert_equal(a:line, line('.'))
+ call assert_equal(a:col, col('.'))
quit!
endfunc
-func Test_gee_dee()
+func Test_gD()
+ let lines = [
+ \ 'int x;',
+ \ '',
+ \ 'int func(void)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gD', lines, 1, 5)
+endfunc
+
+func Test_gD_too()
+ let lines = [
+ \ 'Filename x;',
+ \ '',
+ \ 'int Filename',
+ \ 'int func() {',
+ \ ' Filename x;',
+ \ ' return x;',
+ \ ]
+ call XTest_goto_decl('gD', lines, 1, 10)
+endfunc
+
+func Test_gD_comment()
+ let lines = [
+ \ '/* int x; */',
+ \ 'int x;',
+ \ '',
+ \ 'int func(void)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gD', lines, 2, 5)
+endfunc
+
+func Test_gD_inline_comment()
+ let lines = [
+ \ 'int y /* , x */;',
+ \ 'int x;',
+ \ '',
+ \ 'int func(void)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gD', lines, 2, 5)
+endfunc
+
+func Test_gD_string()
+ let lines = [
+ \ 'char *s[] = "x";',
+ \ 'int x = 1;',
+ \ '',
+ \ 'int func(void)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gD', lines, 2, 5)
+endfunc
+
+func Test_gD_string_same_line()
+ let lines = [
+ \ 'char *s[] = "x", int x = 1;',
+ \ '',
+ \ 'int func(void)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gD', lines, 1, 22)
+endfunc
+
+func Test_gD_char()
+ let lines = [
+ \ "char c = 'x';",
+ \ 'int x = 1;',
+ \ '',
+ \ 'int func(void)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gD', lines, 2, 5)
+endfunc
+
+func Test_gd()
+ let lines = [
+ \ 'int x;',
+ \ '',
+ \ 'int func(int x)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 3, 14)
+endfunc
+
+func Test_gd_not_local()
+ let lines = [
+ \ 'int func1(void)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ '',
+ \ 'int func2(int x)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 3, 10)
+endfunc
+
+func Test_gd_kr_style()
+ let lines = [
+ \ 'int func(x)',
+ \ ' int x;',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 2, 7)
+endfunc
+
+func Test_gd_missing_braces()
+ let lines = [
+ \ 'def func1(a)',
+ \ ' a + 1',
+ \ 'end',
+ \ '',
+ \ 'a = 1',
+ \ '',
+ \ 'def func2()',
+ \ ' return a',
+ \ 'end',
+ \ ]
+ call XTest_goto_decl('gd', lines, 1, 11)
+endfunc
+
+func Test_gd_comment()
+ let lines = [
+ \ 'int func(void)',
+ \ '{',
+ \ ' /* int x; */',
+ \ ' int x;',
+ \ ' return x;',
+ \ '}',
+ \]
+ call XTest_goto_decl('gd', lines, 4, 7)
+endfunc
+
+func Test_gd_comment_in_string()
+ let lines = [
+ \ 'int func(void)',
+ \ '{',
+ \ ' char *s ="//"; int x;',
+ \ ' int x;',
+ \ ' return x;',
+ \ '}',
+ \]
+ call XTest_goto_decl('gd', lines, 3, 22)
+endfunc
+
+func Test_gd_string_in_comment()
+ set comments=
+ let lines = [
+ \ 'int func(void)',
+ \ '{',
+ \ ' /* " */ int x;',
+ \ ' int x;',
+ \ ' return x;',
+ \ '}',
+ \]
+ call XTest_goto_decl('gd', lines, 3, 15)
+ set comments&
+endfunc
+
+func Test_gd_inline_comment()
+ let lines = [
+ \ 'int func(/* x is an int */ int x)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 1, 32)
+endfunc
+
+func Test_gd_inline_comment_only()
+ let lines = [
+ \ 'int func(void) /* one lonely x */',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 3, 10)
+endfunc
+
+func Test_gd_inline_comment_body()
+ let lines = [
+ \ 'int func(void)',
+ \ '{',
+ \ ' int y /* , x */;',
+ \ '',
+ \ ' for (/* int x = 0 */; y < 2; y++);',
+ \ '',
+ \ ' int x = 0;',
+ \ '',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 7, 7)
+endfunc
+
+func Test_gd_trailing_multiline_comment()
+ let lines = [
+ \ 'int func(int x) /* x is an int */',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 1, 14)
+endfunc
+
+func Test_gd_trailing_comment()
+ let lines = [
+ \ 'int func(int x) // x is an int',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 1, 14)
+endfunc
+
+func Test_gd_string()
+ let lines = [
+ \ 'int func(void)',
+ \ '{',
+ \ ' char *s = "x";',
+ \ ' int x = 1;',
+ \ '',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 4, 7)
+endfunc
+
+func Test_gd_string_only()
+ let lines = [
+ \ 'int func(void)',
+ \ '{',
+ \ ' char *s = "x";',
+ \ '',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 5, 10)
+endfunc
+
+" Check that setting 'cursorline' does not change curswant
+func Test_cursorline_keep_col()
new
- call setline(1, ["int x;", "", "int func(int x)", "{", " return x;", "}"])
- /return/
- normal $hgd
- call assert_equal(3, line('.'))
- call assert_equal(14, col('.'))
- quit!
+ call setline(1, ['long long long line', 'short line'])
+ normal ggfi
+ let pos = getcurpos()
+ normal j
+ set cursorline
+ normal k
+ call assert_equal(pos, getcurpos())
+ bwipe!
+ set nocursorline
endfunc
+
diff --git a/src/nvim/testdir/test_help.vim b/src/nvim/testdir/test_help.vim
new file mode 100644
index 0000000000..26edc16107
--- /dev/null
+++ b/src/nvim/testdir/test_help.vim
@@ -0,0 +1,16 @@
+
+" Tests for :help
+
+func Test_help_restore_snapshot()
+ help
+ set buftype=
+ help
+ edit x
+ help
+ helpclose
+endfunc
+
+func Test_help_errors()
+ call assert_fails('help doesnotexist', 'E149:')
+ call assert_fails('help!', 'E478:')
+endfunc
diff --git a/src/nvim/testdir/test_help_tagjump.vim b/src/nvim/testdir/test_help_tagjump.vim
index cc1c81c7f6..1ca0f722cf 100644
--- a/src/nvim/testdir/test_help_tagjump.vim
+++ b/src/nvim/testdir/test_help_tagjump.vim
@@ -162,4 +162,36 @@ func Test_help_complete()
endtry
endfunc
-" vim: et sw=2:
+func Test_help_respect_current_file_lang()
+ try
+ let list = []
+ call s:doc_config_setup()
+
+ if has('multi_lang')
+ function s:check_help_file_ext(help_keyword, ext)
+ exec 'help ' . a:help_keyword
+ call assert_equal(a:ext, expand('%:e'))
+ call feedkeys("\<C-]>", 'tx')
+ call assert_equal(a:ext, expand('%:e'))
+ pop
+ helpclose
+ endfunc
+
+ set rtp+=Xdir1/doc-ab
+ set rtp+=Xdir1/doc-ja
+
+ set helplang=ab
+ call s:check_help_file_ext('test-char', 'abx')
+ call s:check_help_file_ext('test-char@ja', 'jax')
+ set helplang=ab,ja
+ call s:check_help_file_ext('test-char@ja', 'jax')
+ call s:check_help_file_ext('test-char@en', 'txt')
+ endif
+ catch
+ call assert_exception('X')
+ finally
+ call s:doc_config_teardown()
+ endtry
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_hide.vim b/src/nvim/testdir/test_hide.vim
new file mode 100644
index 0000000000..128b8ff945
--- /dev/null
+++ b/src/nvim/testdir/test_hide.vim
@@ -0,0 +1,97 @@
+" Tests for :hide command/modifier and 'hidden' option
+
+function SetUp()
+ let s:save_hidden = &hidden
+ let s:save_bufhidden = &bufhidden
+ let s:save_autowrite = &autowrite
+ set nohidden
+ set bufhidden=
+ set noautowrite
+endfunc
+
+function TearDown()
+ let &hidden = s:save_hidden
+ let &bufhidden = s:save_bufhidden
+ let &autowrite = s:save_autowrite
+endfunc
+
+function Test_hide()
+ let orig_bname = bufname('')
+ let orig_winnr = winnr('$')
+
+ new Xf1
+ set modified
+ call assert_fails('edit Xf2')
+ bwipeout! Xf1
+
+ new Xf1
+ set modified
+ edit! Xf2
+ call assert_equal(['Xf2', 2], [bufname(''), winnr('$')])
+ call assert_equal([1, 0], [buflisted('Xf1'), bufloaded('Xf1')])
+ bwipeout! Xf1
+ bwipeout! Xf2
+
+ new Xf1
+ set modified
+ " :hide as a command
+ hide
+ call assert_equal([orig_bname, orig_winnr], [bufname(''), winnr('$')])
+ call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+ bwipeout! Xf1
+
+ new Xf1
+ set modified
+ " :hide as a command with trailing comment
+ hide " comment
+ call assert_equal([orig_bname, orig_winnr], [bufname(''), winnr('$')])
+ call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+ bwipeout! Xf1
+
+ new Xf1
+ set modified
+ " :hide as a command with bar
+ hide | new Xf2 " comment
+ call assert_equal(['Xf2', 2], [bufname(''), winnr('$')])
+ call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+ bwipeout! Xf1
+ bwipeout! Xf2
+
+ new Xf1
+ set modified
+ " :hide as a modifier with trailing comment
+ hide edit Xf2 " comment
+ call assert_equal(['Xf2', 2], [bufname(''), winnr('$')])
+ call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+ bwipeout! Xf1
+ bwipeout! Xf2
+
+ new Xf1
+ set modified
+ " To check that the bar is not recognized to separate commands
+ hide echo "one|two"
+ call assert_equal(['Xf1', 2], [bufname(''), winnr('$')])
+ call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+ bwipeout! Xf1
+
+ " set hidden
+ new Xf1
+ set hidden
+ set modified
+ edit Xf2 " comment
+ call assert_equal(['Xf2', 2], [bufname(''), winnr('$')])
+ call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+ bwipeout! Xf1
+ bwipeout! Xf2
+
+ " set hidden bufhidden=wipe
+ new Xf1
+ set bufhidden=wipe
+ set modified
+ hide edit! Xf2 " comment
+ call assert_equal(['Xf2', 2], [bufname(''), winnr('$')])
+ call assert_equal([0, 0], [buflisted('Xf1'), bufloaded('Xf1')])
+ bwipeout! Xf2
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_history.vim b/src/nvim/testdir/test_history.vim
index ee6acfffc3..ca31e3f06c 100644
--- a/src/nvim/testdir/test_history.vim
+++ b/src/nvim/testdir/test_history.vim
@@ -31,6 +31,30 @@ function History_Tests(hist)
call assert_equal('ls', histget(a:hist, -1))
call assert_equal(4, histnr(a:hist))
+ let a=execute('history ' . a:hist)
+ call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a)
+ let a=execute('history all')
+ call assert_match("^\n # .* history\n 3 buffers\n> 4 ls", a)
+
+ if len(a:hist) > 0
+ let a=execute('history ' . a:hist . ' 2')
+ call assert_match("^\n # \\S* history$", a)
+ let a=execute('history ' . a:hist . ' 3')
+ call assert_match("^\n # \\S* history\n 3 buffers$", a)
+ let a=execute('history ' . a:hist . ' 4')
+ call assert_match("^\n # \\S* history\n> 4 ls$", a)
+ let a=execute('history ' . a:hist . ' 3,4')
+ call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a)
+ let a=execute('history ' . a:hist . ' -1')
+ call assert_match("^\n # \\S* history\n> 4 ls$", a)
+ let a=execute('history ' . a:hist . ' -2')
+ call assert_match("^\n # \\S* history\n 3 buffers$", a)
+ let a=execute('history ' . a:hist . ' -2,')
+ call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a)
+ let a=execute('history ' . a:hist . ' -3')
+ call assert_match("^\n # \\S* history$", a)
+ endif
+
" Test for removing entries matching a pattern
for i in range(1, 3)
call histadd(a:hist, 'text_' . i)
@@ -63,3 +87,20 @@ function Test_History()
call assert_equal(-1, histnr('abc'))
call assert_fails('call histnr([])', 'E730:')
endfunction
+
+function Test_Search_history_window()
+ new
+ call setline(1, ['a', 'b', 'a', 'b'])
+ 1
+ call feedkeys("/a\<CR>", 'xt')
+ call assert_equal('a', getline('.'))
+ 1
+ call feedkeys("/b\<CR>", 'xt')
+ call assert_equal('b', getline('.'))
+ 1
+ " select the previous /a command
+ call feedkeys("q/kk\<CR>", 'x!')
+ call assert_equal('a', getline('.'))
+ call assert_equal('a', @/)
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_hlsearch.vim b/src/nvim/testdir/test_hlsearch.vim
new file mode 100644
index 0000000000..066fdd0250
--- /dev/null
+++ b/src/nvim/testdir/test_hlsearch.vim
@@ -0,0 +1,34 @@
+" Test for v:hlsearch
+
+function! Test_hlsearch()
+ new
+ call setline(1, repeat(['aaa'], 10))
+ set hlsearch nolazyredraw
+ let r=[]
+ " redraw is needed to make hlsearch highlight the matches
+ exe "normal! /aaa\<CR>" | redraw
+ let r1 = screenattr(1, 1)
+ nohlsearch | redraw
+ call assert_notequal(r1, screenattr(1,1))
+ let v:hlsearch=1 | redraw
+ call assert_equal(r1, screenattr(1,1))
+ let v:hlsearch=0 | redraw
+ call assert_notequal(r1, screenattr(1,1))
+ set hlsearch | redraw
+ call assert_equal(r1, screenattr(1,1))
+ let v:hlsearch=0 | redraw
+ call assert_notequal(r1, screenattr(1,1))
+ exe "normal! n" | redraw
+ call assert_equal(r1, screenattr(1,1))
+ let v:hlsearch=0 | redraw
+ call assert_notequal(r1, screenattr(1,1))
+ exe "normal! /\<CR>" | redraw
+ call assert_equal(r1, screenattr(1,1))
+ set nohls
+ exe "normal! /\<CR>" | redraw
+ call assert_notequal(r1, screenattr(1,1))
+ call assert_fails('let v:hlsearch=[]', 'E745')
+ call garbagecollect(1)
+ call getchar(1)
+ enew!
+endfunction
diff --git a/src/nvim/testdir/test_increment.vim b/src/nvim/testdir/test_increment.vim
new file mode 100644
index 0000000000..8bfd95d810
--- /dev/null
+++ b/src/nvim/testdir/test_increment.vim
@@ -0,0 +1,760 @@
+" Tests for using Ctrl-A/Ctrl-X on visual selections
+
+func SetUp()
+ new dummy
+ set nrformats&vim
+endfunc
+
+func TearDown()
+ bwipe!
+endfunc
+
+" 1) Ctrl-A on visually selected number
+" Text:
+" foobar-10
+" Expected:
+" 1) Ctrl-A on start of line:
+" foobar-9
+" 2) Ctrl-A on visually selected "-10":
+" foobar-9
+" 3) Ctrl-A on visually selected "10":
+" foobar-11
+" 4) Ctrl-X on visually selected "-10"
+" foobar-11
+" 5) Ctrl-X on visually selected "10"
+" foobar-9
+func Test_visual_increment_01()
+ call setline(1, repeat(["foobaar-10"], 5))
+
+ call cursor(1, 1)
+ exec "norm! \<C-A>"
+ call assert_equal("foobaar-9", getline('.'))
+ call assert_equal([0, 1, 9, 0], getpos('.'))
+
+ call cursor(2, 1)
+ exec "norm! f-v$\<C-A>"
+ call assert_equal("foobaar-9", getline('.'))
+ call assert_equal([0, 2, 8, 0], getpos('.'))
+
+ call cursor(3, 1)
+ exec "norm! f1v$\<C-A>"
+ call assert_equal("foobaar-11", getline('.'))
+ call assert_equal([0, 3, 9, 0], getpos('.'))
+
+ call cursor(4, 1)
+ exec "norm! f-v$\<C-X>"
+ call assert_equal("foobaar-11", getline('.'))
+ call assert_equal([0, 4, 8, 0], getpos('.'))
+
+ call cursor(5, 1)
+ exec "norm! f1v$\<C-X>"
+ call assert_equal("foobaar-9", getline('.'))
+ call assert_equal([0, 5, 9, 0], getpos('.'))
+endfunc
+
+" 2) Ctrl-A on visually selected lines
+" Text:
+" 10
+" 20
+" 30
+" 40
+"
+" Expected:
+" 1) Ctrl-A on visually selected lines:
+" 11
+" 21
+" 31
+" 41
+"
+" 2) Ctrl-X on visually selected lines:
+" 9
+" 19
+" 29
+" 39
+func Test_visual_increment_02()
+ call setline(1, ["10", "20", "30", "40"])
+ exec "norm! GV3k$\<C-A>"
+ call assert_equal(["11", "21", "31", "41"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ call setline(1, ["10", "20", "30", "40"])
+ exec "norm! GV3k$\<C-X>"
+ call assert_equal(["9", "19", "29", "39"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 3) g Ctrl-A on visually selected lines, with non-numbers in between
+" Text:
+" 10
+"
+" 20
+"
+" 30
+"
+" 40
+"
+" Expected:
+" 1) 2 g Ctrl-A on visually selected lines:
+" 12
+"
+" 24
+"
+" 36
+"
+" 48
+" 2) 2 g Ctrl-X on visually selected lines
+" 8
+"
+" 16
+"
+" 24
+"
+" 32
+func Test_visual_increment_03()
+ call setline(1, ["10", "", "20", "", "30", "", "40"])
+ exec "norm! GV6k2g\<C-A>"
+ call assert_equal(["12", "", "24", "", "36", "", "48"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ call setline(1, ["10", "", "20", "", "30", "", "40"])
+ exec "norm! GV6k2g\<C-X>"
+ call assert_equal(["8", "", "16", "", "24", "", "32"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 4) Ctrl-A on non-number
+" Text:
+" foobar-10
+" Expected:
+" 1) visually select foobar:
+" foobar-10
+func Test_visual_increment_04()
+ call setline(1, ["foobar-10"])
+ exec "norm! vf-\<C-A>"
+ call assert_equal(["foobar-10"], getline(1, '$'))
+ " NOTE: I think this is correct behavior...
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 5) g<Ctrl-A> on letter
+" Test:
+" a
+" a
+" a
+" a
+" Expected:
+" 1) g Ctrl-A on visually selected lines
+" b
+" c
+" d
+" e
+func Test_visual_increment_05()
+ set nrformats+=alpha
+ call setline(1, repeat(["a"], 4))
+ exec "norm! GV3kg\<C-A>"
+ call assert_equal(["b", "c", "d", "e"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 6) g<Ctrl-A> on letter
+" Test:
+" z
+" z
+" z
+" z
+" Expected:
+" 1) g Ctrl-X on visually selected lines
+" y
+" x
+" w
+" v
+func Test_visual_increment_06()
+ set nrformats+=alpha
+ call setline(1, repeat(["z"], 4))
+ exec "norm! GV3kg\<C-X>"
+ call assert_equal(["y", "x", "w", "v"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 7) <Ctrl-A> on letter
+" Test:
+" 2
+" 1
+" 0
+" -1
+" -2
+"
+" Expected:
+" 1) Ctrl-A on visually selected lines
+" 3
+" 2
+" 1
+" 0
+" -1
+"
+" 2) Ctrl-X on visually selected lines
+" 1
+" 0
+" -1
+" -2
+" -3
+func Test_visual_increment_07()
+ call setline(1, ["2", "1", "0", "-1", "-2"])
+ exec "norm! GV4k\<C-A>"
+ call assert_equal(["3", "2", "1", "0", "-1"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ call setline(1, ["2", "1", "0", "-1", "-2"])
+ exec "norm! GV4k\<C-X>"
+ call assert_equal(["1", "0", "-1", "-2", "-3"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 8) Block increment on 0x9
+" Text:
+" 0x9
+" 0x9
+" Expected:
+" 1) Ctrl-A on visually block selected region (cursor at beginning):
+" 0xa
+" 0xa
+" 2) Ctrl-A on visually block selected region (cursor at end)
+" 0xa
+" 0xa
+func Test_visual_increment_08()
+ call setline(1, repeat(["0x9"], 2))
+ exec "norm! \<C-V>j$\<C-A>"
+ call assert_equal(["0xa", "0xa"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ call setline(1, repeat(["0x9"], 2))
+ exec "norm! gg$\<C-V>+\<C-A>"
+ call assert_equal(["0xa", "0xa"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 9) Increment and redo
+" Text:
+" 2
+" 2
+"
+" 3
+" 3
+"
+" Expected:
+" 1) 2 Ctrl-A on first 2 visually selected lines
+" 4
+" 4
+" 2) redo (.) on 3
+" 5
+" 5
+func Test_visual_increment_09()
+ call setline(1, ["2", "2", "", "3", "3", ""])
+ exec "norm! ggVj2\<C-A>"
+ call assert_equal(["4", "4", "", "3", "3", ""], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ exec "norm! 3j."
+ call assert_equal(["4", "4", "", "5", "5", ""], getline(1, '$'))
+ call assert_equal([0, 4, 1, 0], getpos('.'))
+endfunc
+
+" 10) sequentially decrement 1
+" Text:
+" 1
+" 1
+" 1
+" 1
+" Expected:
+" 1) g Ctrl-X on visually selected lines
+" 0
+" -1
+" -2
+" -3
+func Test_visual_increment_10()
+ call setline(1, repeat(["1"], 4))
+ exec "norm! GV3kg\<C-X>"
+ call assert_equal(["0", "-1", "-2", "-3"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 11) visually block selected indented lines
+" Text:
+" 1
+" 1
+" 1
+" 1
+" Expexted:
+" 1) g Ctrl-A on block selected indented lines
+" 2
+" 1
+" 3
+" 4
+func Test_visual_increment_11()
+ call setline(1, [" 1", "1", " 1", " 1"])
+ exec "norm! f1\<C-V>3jg\<C-A>"
+ call assert_equal([" 2", "1", " 3", " 4"], getline(1, '$'))
+ call assert_equal([0, 1, 5, 0], getpos('.'))
+endfunc
+
+" 12) visually selected several columns
+" Text:
+" 0 0
+" 0 0
+" 0 0
+" Expected:
+" 1) 'v' select last zero and first zeroes
+" 0 1
+" 1 0
+" 1 0
+func Test_visual_increment_12()
+ call setline(1, repeat(["0 0"], 3))
+ exec "norm! $v++\<C-A>"
+ call assert_equal(["0 1", "1 0", "1 0"], getline(1, '$'))
+ call assert_equal([0, 1, 3, 0], getpos('.'))
+endfunc
+
+" 13) visually selected part of columns
+" Text:
+" max: 100px
+" max: 200px
+" max: 300px
+" max: 400px
+" Expected:
+" 1) 'v' on first two numbers Ctrl-A
+" max: 110px
+" max: 220px
+" max: 330px
+" max: 400px
+" 2) 'v' on first two numbers Ctrl-X
+" max: 90px
+" max: 190px
+" max: 290px
+" max: 400px
+func Test_visual_increment_13()
+ call setline(1, ["max: 100px", "max: 200px", "max: 300px", "max: 400px"])
+ exec "norm! f1\<C-V>l2j\<C-A>"
+ call assert_equal(["max: 110px", "max: 210px", "max: 310px", "max: 400px"], getline(1, '$'))
+ call assert_equal([0, 1, 6, 0], getpos('.'))
+
+ call setline(1, ["max: 100px", "max: 200px", "max: 300px", "max: 400px"])
+ exec "norm! ggf1\<C-V>l2j\<C-X>"
+ call assert_equal(["max: 90px", "max: 190px", "max: 290px", "max: 400px"], getline(1, '$'))
+ call assert_equal([0, 1, 6, 0], getpos('.'))
+endfunc
+
+" 14) redo in block mode
+" Text:
+" 1 1
+" 1 1
+" Expected:
+" 1) Ctrl-a on first column, redo on second column
+" 2 2
+" 2 2
+func Test_visual_increment_14()
+ call setline(1, repeat(["1 1"], 2))
+ exec "norm! G\<C-V>k\<C-A>w."
+ call assert_equal(["2 2", "2 2"], getline(1, '$'))
+ call assert_equal([0, 1, 3, 0], getpos('.'))
+endfunc
+
+" 15) block select single numbers
+" Text:
+" 101
+" Expected:
+" 1) Ctrl-a on visually selected zero
+" 111
+func Test_visual_increment_15()
+ call setline(1, ["101"])
+ exec "norm! lv\<C-A>"
+ call assert_equal(["111"], getline(1, '$'))
+ call assert_equal([0, 1, 2, 0], getpos('.'))
+endfunc
+
+" 16) increment right aligned numbers
+" Text:
+" 1
+" 19
+" 119
+" Expected:
+" 1) Ctrl-a on line selected region
+" 2
+" 20
+" 120
+func Test_visual_increment_16()
+ call setline(1, [" 1", " 19", " 119"])
+ exec "norm! VG\<C-A>"
+ call assert_equal([" 2", " 20", " 120"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 17) block-wise increment and redo
+" Text:
+" 100
+" 1
+"
+" 100
+" 1
+"
+" Expected:
+" 1) Ctrl-V j $ on first block, afterwards '.' on second
+" 101
+" 2
+"
+" 101
+" 2
+func Test_visual_increment_17()
+ call setline(1, [" 100", " 1", "", " 100", " 1"])
+ exec "norm! \<C-V>j$\<C-A>2j."
+ call assert_equal([" 101", " 2", "", " 101", " 1"], getline(1, '$'))
+ call assert_equal([0, 3, 1, 0], getpos('.'))
+endfunc
+
+" 18) repeat of g<Ctrl-a>
+" Text:
+" 0
+" 0
+" 0
+" 0
+"
+" Expected:
+" 1) V 4j g<ctrl-a>, repeat twice afterwards with .
+" 3
+" 6
+" 9
+" 12
+func Test_visual_increment_18()
+ call setline(1, repeat(["0"], 4))
+ exec "norm! GV3kg\<C-A>"
+ exec "norm! .."
+ call assert_equal(["3", "6", "9", "12"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 19) increment on number with nrformat including alpha
+" Text:
+" 1
+" 1a
+"
+" Expected:
+" 1) <Ctrl-V>j$ <ctrl-a>
+" 2
+" 2a
+func Test_visual_increment_19()
+ set nrformats+=alpha
+ call setline(1, ["1", "1a"])
+ exec "norm! \<C-V>G$\<C-A>"
+ call assert_equal(["2", "2a"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 20) increment a single letter
+" Text:
+" a
+"
+" Expected:
+" 1) <Ctrl-a> and cursor is on a
+" b
+func Test_visual_increment_20()
+ set nrformats+=alpha
+ call setline(1, ["a"])
+ exec "norm! \<C-A>"
+ call assert_equal(["b"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 21) block-wise increment on part of hexadecimal
+" Text:
+" 0x123456
+"
+" Expected:
+" 1) Ctrl-V f3 <ctrl-a>
+" 0x124456
+func Test_visual_increment_21()
+ call setline(1, ["0x123456"])
+ exec "norm! \<C-V>f3\<C-A>"
+ call assert_equal(["0x124456"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 22) Block increment on 0b0
+" Text:
+" 0b1
+" 0b1
+" Expected:
+" 1) Ctrl-A on visually block selected region (cursor at beginning):
+" 0b10
+" 0b10
+" 2) Ctrl-A on visually block selected region (cursor at end)
+" 0b10
+" 0b10
+func Test_visual_increment_22()
+ call setline(1, repeat(["0b1"], 2))
+ exec "norm! \<C-V>j$\<C-A>"
+ call assert_equal(repeat(["0b10"], 2), getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ call setline(1, repeat(["0b1"], 2))
+ exec "norm! $\<C-V>+\<C-A>"
+ call assert_equal(repeat(["0b10"], 2), getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 23) block-wise increment on part of binary
+" Text:
+" 0b1001
+"
+" Expected:
+" 1) Ctrl-V 5l <ctrl-a>
+" 0b1011
+func Test_visual_increment_23()
+ call setline(1, ["0b1001"])
+ exec "norm! \<C-V>4l\<C-A>"
+ call assert_equal(["0b1011"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 24) increment hexadecimal
+" Text:
+" 0x0b1001
+"
+" Expected:
+" 1) <ctrl-a>
+" 0x0b1002
+func Test_visual_increment_24()
+ call setline(1, ["0x0b1001"])
+ exec "norm! \<C-V>$\<C-A>"
+ call assert_equal(["0x0b1002"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 25) increment binary with nrformats including alpha
+" Text:
+" 0b1001a
+"
+" Expected:
+" 1) <ctrl-a>
+" 0b1010a
+func Test_visual_increment_25()
+ set nrformats+=alpha
+ call setline(1, ["0b1001a"])
+ exec "norm! \<C-V>$\<C-A>"
+ call assert_equal(["0b1010a"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 26) increment binary with 32 bits
+" Text:
+" 0b11111111111111111111111111111110
+"
+" Expected:
+" 1) <ctrl-a>
+" 0b11111111111111111111111111111111
+func Test_visual_increment_26()
+ set nrformats+=alpha
+ call setline(1, ["0b11111111111111111111111111111110"])
+ exec "norm! \<C-V>$\<C-A>"
+ call assert_equal(["0b11111111111111111111111111111111"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+ set nrformats-=alpha
+endfunc
+
+" 27) increment with 'rightreft', if supported
+func Test_visual_increment_27()
+ if exists('+rightleft')
+ set rightleft
+ call setline(1, ["1234 56"])
+
+ exec "norm! $\<C-A>"
+ call assert_equal(["1234 57"], getline(1, '$'))
+ call assert_equal([0, 1, 7, 0], getpos('.'))
+
+ exec "norm! \<C-A>"
+ call assert_equal(["1234 58"], getline(1, '$'))
+ call assert_equal([0, 1, 7, 0], getpos('.'))
+ set norightleft
+ endif
+endfunc
+
+" Tab code and linewise-visual inc/dec
+func Test_visual_increment_28()
+ call setline(1, ["x\<TAB>10", "\<TAB>-1"])
+ exec "norm! Vj\<C-A>"
+ call assert_equal(["x\<TAB>11", "\<TAB>0"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ call setline(1, ["x\<TAB>10", "\<TAB>-1"])
+ exec "norm! ggVj\<C-X>"
+ call assert_equal(["x\<TAB>9", "\<TAB>-2"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" Tab code and linewise-visual inc/dec with 'nrformats'+=alpha
+func Test_visual_increment_29()
+ set nrformats+=alpha
+ call setline(1, ["x\<TAB>10", "\<TAB>-1"])
+ exec "norm! Vj\<C-A>"
+ call assert_equal(["y\<TAB>10", "\<TAB>0"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ call setline(1, ["x\<TAB>10", "\<TAB>-1"])
+ exec "norm! ggVj\<C-X>"
+ call assert_equal(["w\<TAB>10", "\<TAB>-2"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" Tab code and character-visual inc/dec
+func Test_visual_increment_30()
+ call setline(1, ["x\<TAB>10", "\<TAB>-1"])
+ exec "norm! f1vjf1\<C-A>"
+ call assert_equal(["x\<TAB>11", "\<TAB>0"], getline(1, '$'))
+ call assert_equal([0, 1, 3, 0], getpos('.'))
+
+ call setline(1, ["x\<TAB>10", "\<TAB>-1"])
+ exec "norm! ggf1vjf1\<C-X>"
+ call assert_equal(["x\<TAB>9", "\<TAB>-2"], getline(1, '$'))
+ call assert_equal([0, 1, 3, 0], getpos('.'))
+endfunc
+
+" Tab code and blockwise-visual inc/dec
+func Test_visual_increment_31()
+ call setline(1, ["x\<TAB>10", "\<TAB>-1"])
+ exec "norm! f1\<C-V>jl\<C-A>"
+ call assert_equal(["x\<TAB>11", "\<TAB>0"], getline(1, '$'))
+ call assert_equal([0, 1, 3, 0], getpos('.'))
+
+ call setline(1, ["x\<TAB>10", "\<TAB>-1"])
+ exec "norm! ggf1\<C-V>jl\<C-X>"
+ call assert_equal(["x\<TAB>9", "\<TAB>-2"], getline(1, '$'))
+ call assert_equal([0, 1, 3, 0], getpos('.'))
+endfunc
+
+" Tab code and blockwise-visual decrement with 'linebreak' and 'showbreak'
+func Test_visual_increment_32()
+ 28vnew dummy_31
+ set linebreak showbreak=+
+ call setline(1, ["x\<TAB>\<TAB>\<TAB>10", "\<TAB>\<TAB>\<TAB>\<TAB>-1"])
+ exec "norm! ggf0\<C-V>jg_\<C-X>"
+ call assert_equal(["x\<TAB>\<TAB>\<TAB>1-1", "\<TAB>\<TAB>\<TAB>\<TAB>-2"], getline(1, '$'))
+ call assert_equal([0, 1, 6, 0], getpos('.'))
+ bwipe!
+endfunc
+
+" Tab code and blockwise-visual increment with $
+func Test_visual_increment_33()
+ call setline(1, ["\<TAB>123", "456"])
+ exec "norm! gg0\<C-V>j$\<C-A>"
+ call assert_equal(["\<TAB>124", "457"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" Tab code and blockwise-visual increment and redo
+func Test_visual_increment_34()
+ call setline(1, ["\<TAB>123", " 456789"])
+ exec "norm! gg0\<C-V>j\<C-A>"
+ call assert_equal(["\<TAB>123", " 457789"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ exec "norm! .."
+ call assert_equal(["\<TAB>123", " 459789"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" Tab code, spaces and character-visual increment and redo
+func Test_visual_increment_35()
+ call setline(1, ["\<TAB>123", " 123", "\<TAB>123", "\<TAB>123"])
+ exec "norm! ggvjf3\<C-A>..."
+ call assert_equal(["\<TAB>127", " 127", "\<TAB>123", "\<TAB>123"], getline(1, '$'))
+ call assert_equal([0, 1, 2, 0], getpos('.'))
+endfunc
+
+" Tab code, spaces and blockwise-visual increment and redo
+func Test_visual_increment_36()
+ call setline(1, [" 123", "\<TAB>456789"])
+ exec "norm! G0\<C-V>kl\<C-A>"
+ call assert_equal([" 123", "\<TAB>556789"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ exec "norm! ..."
+ call assert_equal([" 123", "\<TAB>856789"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" block-wise increment and dot-repeat
+" Text:
+" 1 23
+" 4 56
+"
+" Expected:
+" 1) f2 Ctrl-V jl <ctrl-a>, repeat twice afterwards with .
+" 1 26
+" 4 59
+"
+" Try with and without indent.
+func Test_visual_increment_37()
+ call setline(1, [" 1 23", " 4 56"])
+ exec "norm! ggf2\<C-V>jl\<C-A>.."
+ call assert_equal([" 1 26", " 4 59"], getline(1, 2))
+
+ call setline(1, ["1 23", "4 56"])
+ exec "norm! ggf2\<C-V>jl\<C-A>.."
+ call assert_equal(["1 26", "4 59"], getline(1, 2))
+endfunc
+
+" Check redo after the normal mode increment
+func Test_visual_increment_38()
+ exec "norm! i10\<ESC>5\<C-A>."
+ call assert_equal(["20"], getline(1, '$'))
+ call assert_equal([0, 1, 2, 0], getpos('.'))
+endfunc
+
+" Test what patch 7.3.414 fixed. Ctrl-A on "000" drops the leading zeros.
+func Test_normal_increment_01()
+ call setline(1, "000")
+ exec "norm! gg0\<C-A>"
+ call assert_equal("001", getline(1))
+
+ call setline(1, "000")
+ exec "norm! gg$\<C-A>"
+ call assert_equal("001", getline(1))
+
+ call setline(1, "001")
+ exec "norm! gg0\<C-A>"
+ call assert_equal("002", getline(1))
+
+ call setline(1, "001")
+ exec "norm! gg$\<C-A>"
+ call assert_equal("002", getline(1))
+endfunc
+
+" Test a regression of patch 7.4.1087 fixed.
+func Test_normal_increment_02()
+ call setline(1, ["hello 10", "world"])
+ exec "norm! ggl\<C-A>jx"
+ call assert_equal(["hello 11", "worl"], getline(1, '$'))
+ call assert_equal([0, 2, 4, 0], getpos('.'))
+endfunc
+
+" The test35 unified to this file.
+func Test_normal_increment_03()
+ call setline(1, ["100 0x100 077 0",
+ \ "100 0x100 077 ",
+ \ "100 0x100 077 0xfF 0xFf",
+ \ "100 0x100 077 "])
+ set nrformats=octal,hex
+ exec "norm! gg\<C-A>102\<C-X>\<C-A>l\<C-X>l\<C-A>64\<C-A>128\<C-X>$\<C-X>"
+ set nrformats=octal
+ exec "norm! j0\<C-A>102\<C-X>\<C-A>l\<C-X>2\<C-A>w65\<C-A>129\<C-X>blx6lD"
+ set nrformats=hex
+ exec "norm! j0101\<C-X>l257\<C-X>\<C-A>Txldt \<C-A> \<C-X> \<C-X>"
+ set nrformats=
+ exec "norm! j0200\<C-X>l100\<C-X>w78\<C-X>\<C-A>k"
+ call assert_equal(["0 0x0ff 0000 -1",
+ \ "0 1x100 0777777",
+ \ "-1 0x0 078 0xFE 0xfe",
+ \ "-100 -100x100 000 "], getline(1, '$'))
+ call assert_equal([0, 3, 25, 0], getpos('.'))
+endfunc
+
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_increment_dbcs.vim b/src/nvim/testdir/test_increment_dbcs.vim
new file mode 100644
index 0000000000..474a16feeb
--- /dev/null
+++ b/src/nvim/testdir/test_increment_dbcs.vim
@@ -0,0 +1,29 @@
+" Tests for using Ctrl-A/Ctrl-X using DBCS.
+if !has('multi_byte')
+ finish
+endif
+scriptencoding cp932
+
+func SetUp()
+ new
+ set nrformats&
+endfunc
+
+func TearDown()
+ bwipe!
+endfunc
+
+func Test_increment_dbcs_1()
+ set nrformats+=alpha
+ call setline(1, ["ŽR1"])
+ exec "norm! 0\<C-A>"
+ call assert_equal(["ŽR2"], getline(1, '$'))
+ call assert_equal([0, 1, 4, 0], getpos('.'))
+
+ call setline(1, ["‚`‚a‚b0xDE‚e"])
+ exec "norm! 0\<C-X>"
+ call assert_equal(["‚`‚a‚b0xDD‚e"], getline(1, '$'))
+ call assert_equal([0, 1, 13, 0], getpos('.'))
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_lambda.vim b/src/nvim/testdir/test_lambda.vim
new file mode 100644
index 0000000000..311cc6e2cb
--- /dev/null
+++ b/src/nvim/testdir/test_lambda.vim
@@ -0,0 +1,287 @@
+" Test for lambda and closure
+
+function! Test_lambda_feature()
+ call assert_equal(1, has('lambda'))
+endfunction
+
+function! Test_lambda_with_filter()
+ let s:x = 2
+ call assert_equal([2, 3], filter([1, 2, 3], {i, v -> v >= s:x}))
+endfunction
+
+function! Test_lambda_with_map()
+ let s:x = 1
+ call assert_equal([2, 3, 4], map([1, 2, 3], {i, v -> v + s:x}))
+endfunction
+
+function! Test_lambda_with_sort()
+ call assert_equal([1, 2, 3, 4, 7], sort([3,7,2,1,4], {a, b -> a - b}))
+endfunction
+
+function! Test_lambda_with_timer()
+ if !has('timers')
+ return
+ endif
+
+ let s:n = 0
+ let s:timer_id = 0
+ function! s:Foo()
+ "let n = 0
+ let s:timer_id = timer_start(50, {-> execute("let s:n += 1 | echo s:n", "")}, {"repeat": -1})
+ endfunction
+
+ call s:Foo()
+ sleep 200ms
+ " do not collect lambda
+ call garbagecollect()
+ let m = s:n
+ sleep 200ms
+ call timer_stop(s:timer_id)
+ call assert_true(m > 1)
+ call assert_true(s:n > m + 1)
+ call assert_true(s:n < 9)
+endfunction
+
+function! Test_lambda_with_partial()
+ let l:Cb = function({... -> ['zero', a:1, a:2, a:3]}, ['one', 'two'])
+ call assert_equal(['zero', 'one', 'two', 'three'], l:Cb('three'))
+endfunction
+
+function Test_lambda_fails()
+ call assert_equal(3, {a, b -> a + b}(1, 2))
+ call assert_fails('echo {a, a -> a + a}(1, 2)', 'E15:')
+ call assert_fails('echo {a, b -> a + b)}(1, 2)', 'E15:')
+endfunc
+
+func Test_not_lambda()
+ let x = {'>' : 'foo'}
+ call assert_equal('foo', x['>'])
+endfunc
+
+function! Test_lambda_capture_by_reference()
+ let v = 1
+ let l:F = {x -> x + v}
+ let v = 2
+ call assert_equal(12, l:F(10))
+endfunction
+
+function! Test_lambda_side_effect()
+ function! s:update_and_return(arr)
+ let a:arr[1] = 5
+ return a:arr
+ endfunction
+
+ function! s:foo(arr)
+ return {-> s:update_and_return(a:arr)}
+ endfunction
+
+ let arr = [3,2,1]
+ call assert_equal([3, 5, 1], s:foo(arr)())
+endfunction
+
+function! Test_lambda_refer_local_variable_from_other_scope()
+ function! s:foo(X)
+ return a:X() " refer l:x in s:bar()
+ endfunction
+
+ function! s:bar()
+ let x = 123
+ return s:foo({-> x})
+ endfunction
+
+ call assert_equal(123, s:bar())
+endfunction
+
+function! Test_lambda_do_not_share_local_variable()
+ function! s:define_funcs()
+ let l:One = {-> split(execute("let a = 'abc' | echo a"))[0]}
+ let l:Two = {-> exists("a") ? a : "no"}
+ return [l:One, l:Two]
+ endfunction
+
+ let l:F = s:define_funcs()
+
+ call assert_equal('no', l:F[1]())
+ call assert_equal('abc', l:F[0]())
+ call assert_equal('no', l:F[1]())
+endfunction
+
+function! Test_lambda_closure_counter()
+ function! s:foo()
+ let x = 0
+ return {-> [execute("let x += 1"), x][-1]}
+ endfunction
+
+ let l:F = s:foo()
+ call garbagecollect()
+ call assert_equal(1, l:F())
+ call assert_equal(2, l:F())
+ call assert_equal(3, l:F())
+ call assert_equal(4, l:F())
+endfunction
+
+function! Test_lambda_with_a_var()
+ function! s:foo()
+ let x = 2
+ return {... -> a:000 + [x]}
+ endfunction
+ function! s:bar()
+ return s:foo()(1)
+ endfunction
+
+ call assert_equal([1, 2], s:bar())
+endfunction
+
+function! Test_lambda_call_lambda_from_lambda()
+ function! s:foo(x)
+ let l:F1 = {-> {-> a:x}}
+ return {-> l:F1()}
+ endfunction
+
+ let l:F = s:foo(1)
+ call assert_equal(1, l:F()())
+endfunction
+
+function! Test_lambda_delfunc()
+ function! s:gen()
+ let pl = l:
+ let l:Foo = {-> get(pl, "Foo", get(pl, "Bar", {-> 0}))}
+ let l:Bar = l:Foo
+ delfunction l:Foo
+ return l:Bar
+ endfunction
+
+ let l:F = s:gen()
+ call assert_fails(':call l:F()', 'E933:')
+endfunction
+
+function! Test_lambda_scope()
+ function! s:NewCounter()
+ let c = 0
+ return {-> [execute('let c += 1'), c][-1]}
+ endfunction
+
+ function! s:NewCounter2()
+ return {-> [execute('let c += 100'), c][-1]}
+ endfunction
+
+ let l:C = s:NewCounter()
+ let l:D = s:NewCounter2()
+
+ call assert_equal(1, l:C())
+ call assert_fails(':call l:D()', 'E15:') " E121: then E15:
+ call assert_equal(2, l:C())
+endfunction
+
+function! Test_lambda_share_scope()
+ function! s:New()
+ let c = 0
+ let l:Inc0 = {-> [execute('let c += 1'), c][-1]}
+ let l:Dec0 = {-> [execute('let c -= 1'), c][-1]}
+ return [l:Inc0, l:Dec0]
+ endfunction
+
+ let [l:Inc, l:Dec] = s:New()
+
+ call assert_equal(1, l:Inc())
+ call assert_equal(2, l:Inc())
+ call assert_equal(1, l:Dec())
+endfunction
+
+function! Test_lambda_circular_reference()
+ function! s:Foo()
+ let d = {}
+ let d.f = {-> d}
+ return d.f
+ endfunction
+
+ call s:Foo()
+ call garbagecollect()
+ let i = 0 | while i < 10000 | call s:Foo() | let i+= 1 | endwhile
+ call garbagecollect()
+endfunction
+
+function! Test_lambda_combination()
+ call assert_equal(2, {x -> {x -> x}}(1)(2))
+ call assert_equal(10, {y -> {x -> x(y)(10)}({y -> y})}({z -> z}))
+ call assert_equal(5.0, {x -> {y -> x / y}}(10)(2.0))
+ call assert_equal(6, {x -> {y -> {z -> x + y + z}}}(1)(2)(3))
+
+ call assert_equal(6, {x -> {f -> f(x)}}(3)({x -> x * 2}))
+ call assert_equal(6, {f -> {x -> f(x)}}({x -> x * 2})(3))
+
+ " Z combinator
+ let Z = {f -> {x -> f({y -> x(x)(y)})}({x -> f({y -> x(x)(y)})})}
+ let Fact = {f -> {x -> x == 0 ? 1 : x * f(x - 1)}}
+ call assert_equal(120, Z(Fact)(5))
+endfunction
+
+function! Test_closure_counter()
+ function! s:foo()
+ let x = 0
+ function! s:bar() closure
+ let x += 1
+ return x
+ endfunction
+ return function('s:bar')
+ endfunction
+
+ let l:F = s:foo()
+ call garbagecollect()
+ call assert_equal(1, l:F())
+ call assert_equal(2, l:F())
+ call assert_equal(3, l:F())
+ call assert_equal(4, l:F())
+endfunction
+
+function! Test_closure_unlet()
+ function! s:foo()
+ let x = 1
+ function! s:bar() closure
+ unlet x
+ endfunction
+ call s:bar()
+ return l:
+ endfunction
+
+ call assert_false(has_key(s:foo(), 'x'))
+ call garbagecollect()
+endfunction
+
+function! LambdaFoo()
+ let x = 0
+ function! LambdaBar() closure
+ let x += 1
+ return x
+ endfunction
+ return function('LambdaBar')
+endfunction
+
+func Test_closure_refcount()
+ let g:Count = LambdaFoo()
+ call test_garbagecollect_now()
+ call assert_equal(1, g:Count())
+ let g:Count2 = LambdaFoo()
+ call test_garbagecollect_now()
+ call assert_equal(1, g:Count2())
+ call assert_equal(2, g:Count())
+ call assert_equal(3, g:Count2())
+
+ delfunc LambdaFoo
+ delfunc LambdaBar
+endfunc
+
+" This test is causing a use-after-free on shutdown.
+func Test_named_function_closure()
+ func! Afoo()
+ let x = 14
+ func! s:Abar() closure
+ return x
+ endfunc
+ call assert_equal(14, s:Abar())
+ endfunc
+ call Afoo()
+ call assert_equal(14, s:Abar())
+ call garbagecollect()
+ call assert_equal(14, s:Abar())
+endfunc
diff --git a/src/nvim/testdir/test_largefile.vim b/src/nvim/testdir/test_largefile.vim
new file mode 100644
index 0000000000..1b3e02a0c8
--- /dev/null
+++ b/src/nvim/testdir/test_largefile.vim
@@ -0,0 +1,34 @@
+" Tests for large files
+" This is only executed manually: "make test_largefile".
+" This is not run as part of "make test".
+
+func Test_largefile()
+ let fname = 'Xlarge.txt'
+
+ call delete(fname)
+ exe "e" fname
+ " Make sure that a line break is 1 byte (LF).
+ set ff=unix
+ set undolevels=-1
+ " Input 99 'A's. The line becomes 100 bytes including a line break.
+ exe "normal 99iA\<Esc>"
+ yank
+ " Put 39,999,999 times. The file becomes 4,000,000,000 bytes.
+ normal 39999999p
+ " Moving around in the file randomly.
+ normal G
+ normal 10%
+ normal 90%
+ normal 50%
+ normal gg
+ w
+ " Check if the file size is 4,000,000,000 bytes.
+ let fsize=getfsize(fname)
+ if has('num64')
+ call assert_true(fsize == 4000000000)
+ else
+ " getfsize() returns -2 if a Number is 32 bits.
+ call assert_true(fsize == -2)
+ endif
+ call delete(fname)
+endfunc
diff --git a/src/nvim/testdir/test_listlbr.vim b/src/nvim/testdir/test_listlbr.vim
new file mode 100644
index 0000000000..7856ee82ab
--- /dev/null
+++ b/src/nvim/testdir/test_listlbr.vim
@@ -0,0 +1,235 @@
+" Test for linebreak and list option (non-utf8)
+
+set encoding=latin1
+scriptencoding latin1
+
+if !exists("+linebreak") || !has("conceal")
+ finish
+endif
+
+source view_util.vim
+
+function s:screen_lines(lnum, width) abort
+ return ScreenLines(a:lnum, a:width)
+endfunction
+
+function! s:compare_lines(expect, actual)
+ call assert_equal(join(a:expect, "\n"), join(a:actual, "\n"))
+endfunction
+
+function s:test_windows(...)
+ call NewWindow(10, 20)
+ setl ts=8 sw=4 sts=4 linebreak sbr= wrap
+ exe get(a:000, 0, '')
+endfunction
+
+function s:close_windows(...)
+ call CloseWindow()
+ exe get(a:000, 0, '')
+endfunction
+
+func Test_set_linebreak()
+ call s:test_windows('setl ts=4 sbr=+')
+ call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP ")
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ " abcdef ",
+\ "+hijklmn ",
+\ "+pqrstuvwxyz_1060ABC",
+\ "+DEFGHIJKLMNOP ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_linebreak_with_list()
+ call s:test_windows('setl ts=4 sbr=+ list listchars=')
+ call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP ")
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ "^Iabcdef hijklmn^I ",
+\ "+pqrstuvwxyz_1060ABC",
+\ "+DEFGHIJKLMNOP ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_linebreak_with_nolist()
+ call s:test_windows('setl ts=4 sbr=+ nolist')
+ call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP ")
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ " abcdef ",
+\ "+hijklmn ",
+\ "+pqrstuvwxyz_1060ABC",
+\ "+DEFGHIJKLMNOP ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_should_break()
+ call s:test_windows('setl sbr=+ nolist')
+ call setline(1, "1\t" . repeat('a', winwidth(0)-2))
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ "1 ",
+\ "+aaaaaaaaaaaaaaaaaa ",
+\ "~ ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_linebreak_with_conceal()
+ call s:test_windows('setl cpo&vim sbr=+ list conceallevel=2 concealcursor=nv listchars=tab:ab')
+ call setline(1, "_S_\t bla")
+ syn match ConcealVar contained /_/ conceal
+ syn match All /.*/ contains=ConcealVar
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ "Sabbbbbb bla ",
+\ "~ ",
+\ "~ ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_virtual_block()
+ call s:test_windows('setl sbr=+')
+ call setline(1, [
+\ "REMOVE: this not",
+\ "REMOVE: aaaaaaaaaaaaa",
+\ ])
+ exe "norm! 1/^REMOVE:"
+ exe "norm! 0\<C-V>jf x"
+ $put
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ "this not ",
+\ "aaaaaaaaaaaaa ",
+\ "REMOVE: ",
+\ "REMOVE: ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_virtual_block_and_vbA()
+ call s:test_windows()
+ call setline(1, "long line: " . repeat("foobar ", 40) . "TARGET at end")
+ exe "norm! $3B\<C-v>eAx\<Esc>"
+ let lines = s:screen_lines([1, 10], winwidth(0))
+ let expect = [
+\ "foobar foobar ",
+\ "foobar foobar ",
+\ "foobar foobar ",
+\ "foobar foobar ",
+\ "foobar foobar ",
+\ "foobar foobar ",
+\ "foobar foobar ",
+\ "foobar foobar ",
+\ "foobar foobar ",
+\ "foobar TARGETx at ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_virtual_char_and_block()
+ call s:test_windows()
+ call setline(1, "1111-1111-1111-11-1111-1111-1111")
+ exe "norm! 0f-lv3lc2222\<Esc>bgj."
+ let lines = s:screen_lines([1, 2], winwidth(0))
+ let expect = [
+\ "1111-2222-1111-11- ",
+\ "1111-2222-1111 ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_undo_after_block_visual()
+ call s:test_windows()
+ call setline(1, ["aaa", "aaa", "a"])
+ exe "norm! gg\<C-V>2j~e."
+ let lines = s:screen_lines([1, 3], winwidth(0))
+ let expect = [
+\ "AaA ",
+\ "AaA ",
+\ "A ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_norm_after_block_visual()
+ call s:test_windows()
+ call setline(1, ["abcd{ef", "ghijklm", "no}pgrs"])
+ exe "norm! ggf{\<C-V>\<C-V>c%"
+ let lines = s:screen_lines([1, 3], winwidth(0))
+ let expect = [
+\ "abcdpgrs ",
+\ "~ ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_block_replace_after_wrapping()
+ call s:test_windows()
+ call setline(1, repeat("a", 150))
+ exe "norm! 0yypk147|\<C-V>jr0"
+ call assert_equal(repeat("a", 146) . "0aaa", getline(1))
+ call assert_equal(repeat("a", 146) . "0aaa", getline(2))
+ let lines = s:screen_lines([1, 10], winwidth(0))
+ let expect = [
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaa0aaa ",
+\ "@ ",
+\ "@ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_list_with_listchars()
+ call s:test_windows('setl list listchars=space:_,trail:-,tab:>-,eol:$')
+ call setline(1, "a aaaaaaaaaaaaaaaaaaaaaa\ta ")
+ let lines = s:screen_lines([1, 3], winwidth(0))
+ let expect = [
+\ "a_ ",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aa>-----a-$ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_list_with_tab_and_skipping_first_chars()
+ call s:test_windows('setl list listchars=tab:>- ts=70 nowrap')
+ call setline(1, ["iiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa"])
+ call cursor(4,64)
+ norm! 2zl
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ "---------------aaaaa",
+\ "---------------aaaaa",
+\ "---------------aaaaa",
+\ "iiiiiiiii>-----aaaaa",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfu
diff --git a/src/nvim/testdir/test_listlbr_utf8.vim b/src/nvim/testdir/test_listlbr_utf8.vim
new file mode 100644
index 0000000000..980d67d49d
--- /dev/null
+++ b/src/nvim/testdir/test_listlbr_utf8.vim
@@ -0,0 +1,229 @@
+" Test for linebreak and list option in utf-8 mode
+
+set encoding=utf-8
+scriptencoding utf-8
+
+if !exists("+linebreak") || !has("conceal") || !has("signs")
+ finish
+endif
+
+source view_util.vim
+
+function s:screen_lines(lnum, width) abort
+ return ScreenLines(a:lnum, a:width)
+endfunction
+
+function! s:compare_lines(expect, actual)
+ call assert_equal(a:expect, a:actual)
+endfunction
+
+function s:screen_attr(lnum, chars, ...) abort
+ let line = getline(a:lnum)
+ let attr = []
+ let prefix = get(a:000, 0, 0)
+ for i in range(a:chars[0], a:chars[1])
+ let scol = strdisplaywidth(strcharpart(line, 0, i-1)) + 1
+ let attr += [screenattr(a:lnum, scol + prefix)]
+ endfor
+ return attr
+endfunction
+
+function s:test_windows(...)
+ call NewWindow(10, 20)
+ setl ts=4 sw=4 sts=4 linebreak sbr=+ wrap
+ exe get(a:000, 0, '')
+endfunction
+
+function s:close_windows(...)
+ call CloseWindow()
+ exe get(a:000, 0, '')
+endfunction
+
+func Test_linebreak_with_fancy_listchars()
+ call s:test_windows("setl list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
+ call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz\u00a01060ABCDEFGHIJKLMNOP ")
+ redraw!
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ "▕———abcdef ",
+\ "+hijklmn▕——— ",
+\ "+pqrstuvwxyzâ£1060ABC",
+\ "+DEFGHIJKLMNOPˑ¶ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_nolinebreak_with_list()
+ call s:test_windows("setl nolinebreak list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
+ call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz\u00a01060ABCDEFGHIJKLMNOP ")
+ redraw!
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ "▕———abcdef hijklmn▕—",
+\ "+pqrstuvwxyzâ£1060ABC",
+\ "+DEFGHIJKLMNOPˑ¶ ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_linebreak_with_nolist()
+ call s:test_windows('setl nolist')
+ call setline(1, "\t*mask = nil;")
+ redraw!
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ " *mask = nil; ",
+\ "~ ",
+\ "~ ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_list_and_concealing1()
+ call s:test_windows('setl list listchars=tab:>- cole=1')
+ call setline(1, [
+\ "#define ABCDE\t\t1",
+\ "#define ABCDEF\t\t1",
+\ "#define ABCDEFG\t\t1",
+\ "#define ABCDEFGH\t1",
+\ "#define MSG_MODE_FILE\t\t\t1",
+\ "#define MSG_MODE_CONSOLE\t\t2",
+\ "#define MSG_MODE_FILE_AND_CONSOLE\t3",
+\ "#define MSG_MODE_FILE_THEN_CONSOLE\t4",
+\ ])
+ vert resize 40
+ syn match Conceal conceal cchar=>'AB\|MSG_MODE'
+ redraw!
+ let lines = s:screen_lines([1, 7], winwidth(0))
+ let expect = [
+\ "#define ABCDE>-->---1 ",
+\ "#define >CDEF>-->---1 ",
+\ "#define >CDEFG>->---1 ",
+\ "#define >CDEFGH>----1 ",
+\ "#define >_FILE>--------->--->---1 ",
+\ "#define >_CONSOLE>---------->---2 ",
+\ "#define >_FILE_AND_CONSOLE>---------3 ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_list_and_concealing2()
+ call s:test_windows('setl nowrap ts=2 list listchars=tab:>- cole=2 concealcursor=n')
+ call setline(1, "bbeeeeee\t\t;\tsome text")
+ vert resize 40
+ syn clear
+ syn match meaning /;\s*\zs.*/
+ syn match hasword /^\x\{8}/ contains=word
+ syn match word /\<\x\{8}\>/ contains=beginword,endword contained
+ syn match beginword /\<\x\x/ contained conceal
+ syn match endword /\x\{6}\>/ contained
+ hi meaning guibg=blue
+ hi beginword guibg=green
+ hi endword guibg=red
+ redraw!
+ let lines = s:screen_lines([1, 1], winwidth(0))
+ let expect = [
+\ "eeeeee>--->-;>some text ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_screenattr_for_comment()
+ call s:test_windows("setl ft=c ts=7 list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
+ call setline(1, " /*\t\t and some more */")
+ norm! gg0
+ syntax on
+ hi SpecialKey term=underline ctermfg=red guifg=red
+ redraw!
+ let line = getline(1)
+ let attr = s:screen_attr(1, [1, 6])
+ call assert_notequal(attr[0], attr[1])
+ call assert_notequal(attr[1], attr[3])
+ call assert_notequal(attr[3], attr[5])
+ call s:close_windows()
+endfunc
+
+func Test_visual_block_and_selection_exclusive()
+ call s:test_windows('setl selection=exclusive')
+ call setline(1, "long line: " . repeat("foobar ", 40) . "TARGETÃ' at end")
+ exe "norm! $3B\<C-v>eAx\<Esc>"
+ let lines = s:screen_lines([1, 10], winwidth(0))
+ let expect = [
+\ "+foobar foobar ",
+\ "+foobar foobar ",
+\ "+foobar foobar ",
+\ "+foobar foobar ",
+\ "+foobar foobar ",
+\ "+foobar foobar ",
+\ "+foobar foobar ",
+\ "+foobar foobar ",
+\ "+foobar foobar ",
+\ "+foobar TARGETÃx' ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_multibyte_sign_and_colorcolumn()
+ call s:test_windows("setl nolinebreak cc=3 list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
+ call setline(1, ["", "a b c", "a b c"])
+ exe "sign define foo text=\uff0b"
+ exe "sign place 1 name=foo line=2 buffer=" . bufnr('%')
+ redraw!
+ norm! ggj0
+ let signwidth = strdisplaywidth("\uff0b")
+ let attr1 = s:screen_attr(2, [1, 3], signwidth)
+ let attr2 = s:screen_attr(3, [1, 3], signwidth)
+ call assert_equal(attr1[0], attr2[0])
+ call assert_equal(attr1[1], attr2[1])
+ call assert_equal(attr1[2], attr2[2])
+ let lines = s:screen_lines([1, 3], winwidth(0))
+ let expect = [
+\ " ¶ ",
+\ "+a b c¶ ",
+\ " a b c¶ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_chinese_char_on_wrap_column()
+ call s:test_windows("setl nolbr wrap sbr=")
+ syntax off
+ call setline(1, [
+\ 'aaaaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'hello'])
+ call cursor(1,1)
+ norm! $
+ redraw!
+ let expect=[
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中hello ']
+ let lines = s:screen_lines([1, 10], winwidth(0))
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfu
diff --git a/src/nvim/testdir/test_mapping.vim b/src/nvim/testdir/test_mapping.vim
new file mode 100644
index 0000000000..7f93ddd56e
--- /dev/null
+++ b/src/nvim/testdir/test_mapping.vim
@@ -0,0 +1,160 @@
+" Tests for mappings and abbreviations
+
+if !has('multi_byte')
+ finish
+endif
+
+func Test_abbreviation()
+ " abbreviation with 0x80 should work
+ inoreab чкпр vim
+ call feedkeys("Goчкпр \<Esc>", "xt")
+ call assert_equal('vim ', getline('$'))
+ iunab чкпр
+ set nomodified
+endfunc
+
+func Test_map_ctrl_c_insert()
+ " mapping of ctrl-c in Insert mode
+ set cpo-=< cpo-=k
+ inoremap <c-c> <ctrl-c>
+ cnoremap <c-c> dummy
+ cunmap <c-c>
+ call feedkeys("GoTEST2: CTRL-C |\<C-C>A|\<Esc>", "xt")
+ call assert_equal('TEST2: CTRL-C |<ctrl-c>A|', getline('$'))
+ unmap! <c-c>
+ set nomodified
+endfunc
+
+func Test_map_ctrl_c_visual()
+ " mapping of ctrl-c in Visual mode
+ vnoremap <c-c> :<C-u>$put ='vmap works'
+ call feedkeys("GV\<C-C>\<CR>", "xt")
+ call assert_equal('vmap works', getline('$'))
+ vunmap <c-c>
+ set nomodified
+endfunc
+
+func Test_map_langmap()
+ if !has('langmap')
+ return
+ endif
+
+ " check langmap applies in normal mode
+ set langmap=+- nolangremap
+ new
+ call setline(1, ['a', 'b', 'c'])
+ 2
+ call assert_equal('b', getline('.'))
+ call feedkeys("+", "xt")
+ call assert_equal('a', getline('.'))
+
+ " check no remapping
+ map x +
+ 2
+ call feedkeys("x", "xt")
+ call assert_equal('c', getline('.'))
+
+ " check with remapping
+ set langremap
+ 2
+ call feedkeys("x", "xt")
+ call assert_equal('a', getline('.'))
+
+ unmap x
+ bwipe!
+
+ " 'langnoremap' follows 'langremap' and vise versa
+ set langremap
+ set langnoremap
+ call assert_equal(0, &langremap)
+ set langremap
+ call assert_equal(0, &langnoremap)
+ set nolangremap
+ call assert_equal(1, &langnoremap)
+
+ " check default values
+ set langnoremap&
+ call assert_equal(1, &langnoremap)
+ call assert_equal(0, &langremap)
+ set langremap&
+ call assert_equal(1, &langnoremap)
+ call assert_equal(0, &langremap)
+
+ " langmap should not apply in insert mode, 'langremap' doesn't matter
+ set langmap=+{ nolangremap
+ call feedkeys("Go+\<Esc>", "xt")
+ call assert_equal('+', getline('$'))
+ set langmap=+{ langremap
+ call feedkeys("Go+\<Esc>", "xt")
+ call assert_equal('+', getline('$'))
+
+ " langmap used for register name in insert mode.
+ call setreg('a', 'aaaa')
+ call setreg('b', 'bbbb')
+ call setreg('c', 'cccc')
+ set langmap=ab langremap
+ call feedkeys("Go\<C-R>a\<Esc>", "xt")
+ call assert_equal('bbbb', getline('$'))
+ call feedkeys("Go\<C-R>\<C-R>a\<Esc>", "xt")
+ call assert_equal('bbbb', getline('$'))
+ " mapping does not apply
+ imap c a
+ call feedkeys("Go\<C-R>c\<Esc>", "xt")
+ call assert_equal('cccc', getline('$'))
+ imap a c
+ call feedkeys("Go\<C-R>a\<Esc>", "xt")
+ call assert_equal('bbbb', getline('$'))
+
+ " langmap should not apply in Command-line mode
+ set langmap=+{ nolangremap
+ call feedkeys(":call append(line('$'), '+')\<CR>", "xt")
+ call assert_equal('+', getline('$'))
+
+ set nomodified
+endfunc
+
+func Test_map_feedkeys()
+ " issue #212 (feedkeys insert mapping at current position)
+ nnoremap . :call feedkeys(".", "in")<cr>
+ call setline('$', ['a b c d', 'a b c d'])
+ $-1
+ call feedkeys("0qqdw.ifoo\<Esc>qj0@q\<Esc>", "xt")
+ call assert_equal(['fooc d', 'fooc d'], getline(line('$') - 1, line('$')))
+ unmap .
+ set nomodified
+endfunc
+
+func Test_map_cursor()
+ " <c-g>U<cursor> works only within a single line
+ imapclear
+ imap ( ()<c-g>U<left>
+ call feedkeys("G2o\<Esc>ki\<CR>Test1: text with a (here some more text\<Esc>k.", "xt")
+ call assert_equal('Test1: text with a (here some more text)', getline(line('$') - 2))
+ call assert_equal('Test1: text with a (here some more text)', getline(line('$') - 1))
+
+ " test undo
+ call feedkeys("G2o\<Esc>ki\<CR>Test2: text wit a (here some more text [und undo]\<C-G>u\<Esc>k.u", "xt")
+ call assert_equal('', getline(line('$') - 2))
+ call assert_equal('Test2: text wit a (here some more text [und undo])', getline(line('$') - 1))
+ set nomodified
+ imapclear
+endfunc
+
+" This isn't actually testing a mapping, but similar use of CTRL-G U as above.
+func Test_break_undo()
+ :set whichwrap=<,>,[,]
+ call feedkeys("G4o2k", "xt")
+ exe ":norm! iTest3: text with a (parenthesis here\<C-G>U\<Right>new line here\<esc>\<up>\<up>."
+ call assert_equal('new line here', getline(line('$') - 3))
+ call assert_equal('Test3: text with a (parenthesis here', getline(line('$') - 2))
+ call assert_equal('new line here', getline(line('$') - 1))
+ set nomodified
+endfunc
+
+func Test_map_meta_quotes()
+ imap <M-"> foo
+ call feedkeys("Go-\<M-\">-\<Esc>", "xt")
+ call assert_equal("-foo-", getline('$'))
+ set nomodified
+ iunmap <M-">
+endfunc
diff --git a/src/nvim/testdir/test_marks.vim b/src/nvim/testdir/test_marks.vim
new file mode 100644
index 0000000000..d00b1ddc88
--- /dev/null
+++ b/src/nvim/testdir/test_marks.vim
@@ -0,0 +1,26 @@
+
+" Test that a deleted mark is restored after delete-undo-redo-undo.
+function! Test_Restore_DelMark()
+ enew!
+ call append(0, [" textline A", " textline B", " textline C"])
+ normal! 2gg
+ set nocp viminfo+=nviminfo
+ exe "normal! i\<C-G>u\<Esc>"
+ exe "normal! maddu\<C-R>u"
+ let pos = getpos("'a")
+ call assert_equal(2, pos[1])
+ call assert_equal(1, pos[2])
+ enew!
+endfunction
+
+" Test that CTRL-A and CTRL-X updates last changed mark '[, '].
+function! Test_Incr_Marks()
+ enew!
+ call append(0, ["123 123 123", "123 123 123", "123 123 123"])
+ normal! gg
+ execute "normal! \<C-A>`[v`]rAjwvjw\<C-X>`[v`]rX"
+ call assert_equal("AAA 123 123", getline(1))
+ call assert_equal("123 XXXXXXX", getline(2))
+ call assert_equal("XXX 123 123", getline(3))
+ enew!
+endfunction
diff --git a/src/nvim/testdir/test_match.vim b/src/nvim/testdir/test_match.vim
index 7748dee87f..066bb2f6a1 100644
--- a/src/nvim/testdir/test_match.vim
+++ b/src/nvim/testdir/test_match.vim
@@ -198,6 +198,16 @@ func Test_matchaddpos()
call assert_equal(screenattr(2,2), screenattr(1,10))
call assert_notequal(screenattr(2,2), screenattr(1,11))
+ " Check overlapping pos
+ call clearmatches()
+ call setline(1, ['1234567890', 'NH'])
+ call matchaddpos('Error', [[1,1,5], [1,3,5], [2,2]])
+ redraw!
+ call assert_notequal(screenattr(2,2), 0)
+ call assert_equal(screenattr(2,2), screenattr(1,5))
+ call assert_equal(screenattr(2,2), screenattr(1,7))
+ call assert_notequal(screenattr(2,2), screenattr(1,8))
+
nohl
call clearmatches()
syntax off
@@ -231,4 +241,4 @@ func Test_matchaddpos_using_negative_priority()
set hlsearch&
endfunc
-" vim: et ts=2 sw=2
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_matchadd_conceal.vim b/src/nvim/testdir/test_matchadd_conceal.vim
index bc1c28d6e9..c11f1a84a9 100644
--- a/src/nvim/testdir/test_matchadd_conceal.vim
+++ b/src/nvim/testdir/test_matchadd_conceal.vim
@@ -260,3 +260,26 @@ function! Test_matchadd_repeat_conceal_with_syntax_off()
quit!
endfunction
+
+function! Test_matchadd_and_syn_conceal()
+ new
+ let cnt='Inductive bool : Type := | true : bool | false : bool.'
+ let expect = 'Inductive - : Type := | true : - | false : -.'
+ 0put =cnt
+ " set filetype and :syntax on to change screenattr()
+ set cole=1 cocu=nv
+ hi link CheckedByCoq WarningMsg
+ syntax on
+ syntax keyword coqKwd bool conceal cchar=-
+ redraw!
+ call assert_equal(expect, s:screenline(1))
+ call assert_notequal(screenattr(1, 10) , screenattr(1, 11))
+ call assert_notequal(screenattr(1, 11) , screenattr(1, 12))
+ call assert_equal(screenattr(1, 11) , screenattr(1, 32))
+ call matchadd('CheckedByCoq', '\%<2l\%>9c\%<16c')
+ redraw!
+ call assert_equal(expect, s:screenline(1))
+ call assert_notequal(screenattr(1, 10) , screenattr(1, 11))
+ call assert_notequal(screenattr(1, 11) , screenattr(1, 12))
+ call assert_equal(screenattr(1, 11) , screenattr(1, 32))
+endfunction
diff --git a/src/nvim/testdir/test_menu.vim b/src/nvim/testdir/test_menu.vim
index be559467c8..af18760065 100644
--- a/src/nvim/testdir/test_menu.vim
+++ b/src/nvim/testdir/test_menu.vim
@@ -4,6 +4,6 @@ func Test_load_menu()
try
source $VIMRUNTIME/menu.vim
catch
- call assert_false(1, 'error while loading menus: ' . v:exception)
+ call assert_report('error while loading menus: ' . v:exception)
endtry
endfunc
diff --git a/src/nvim/testdir/test_nested_function.vim b/src/nvim/testdir/test_nested_function.vim
new file mode 100644
index 0000000000..afaaea6ceb
--- /dev/null
+++ b/src/nvim/testdir/test_nested_function.vim
@@ -0,0 +1,63 @@
+"Tests for nested functions
+"
+func NestedFunc()
+ func! Func1()
+ let g:text .= 'Func1 '
+ endfunc
+ call Func1()
+ func! s:func2()
+ let g:text .= 's:func2 '
+ endfunc
+ call s:func2()
+ func! s:_func3()
+ let g:text .= 's:_func3 '
+ endfunc
+ call s:_func3()
+ let fn = 'Func4'
+ func! {fn}()
+ let g:text .= 'Func4 '
+ endfunc
+ call {fn}()
+ let fn = 'func5'
+ func! s:{fn}()
+ let g:text .= 's:func5'
+ endfunc
+ call s:{fn}()
+endfunc
+
+func Test_nested_functions()
+ let g:text = ''
+ call NestedFunc()
+ call assert_equal('Func1 s:func2 s:_func3 Func4 s:func5', g:text)
+endfunction
+
+func Test_nested_argument()
+ func g:X()
+ let g:Y = function('sort')
+ endfunc
+ let g:Y = function('sort')
+ echo g:Y([], g:X())
+ delfunc g:X
+ unlet g:Y
+endfunc
+
+func Recurse(count)
+ if a:count > 0
+ call Recurse(a:count - 1)
+ endif
+endfunc
+
+func Test_max_nesting()
+ let call_depth_here = 2
+ let ex_depth_here = 5
+ set mfd&
+
+ call Recurse(99 - call_depth_here)
+ call assert_fails('call Recurse(' . (100 - call_depth_here) . ')', 'E132:')
+
+ set mfd=210
+ call Recurse(209 - ex_depth_here)
+ call assert_fails('call Recurse(' . (210 - ex_depth_here) . ')', 'E169:')
+
+ set mfd&
+endfunc
diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim
new file mode 100644
index 0000000000..4747d5704d
--- /dev/null
+++ b/src/nvim/testdir/test_normal.vim
@@ -0,0 +1,2337 @@
+" Test for various Normal mode commands
+
+func! Setup_NewWindow()
+ 10new
+ call setline(1, range(1,100))
+endfunc
+
+func! MyFormatExpr()
+ " Adds '->$' at lines having numbers followed by trailing whitespace
+ for ln in range(v:lnum, v:lnum+v:count-1)
+ let line = getline(ln)
+ if getline(ln) =~# '\d\s\+$'
+ call setline(ln, substitute(line, '\s\+$', '', '') . '->$')
+ endif
+ endfor
+endfunc
+
+func! CountSpaces(type, ...)
+ " for testing operatorfunc
+ " will count the number of spaces
+ " and return the result in g:a
+ let sel_save = &selection
+ let &selection = "inclusive"
+ let reg_save = @@
+
+ if a:0 " Invoked from Visual mode, use gv command.
+ silent exe "normal! gvy"
+ elseif a:type == 'line'
+ silent exe "normal! '[V']y"
+ else
+ silent exe "normal! `[v`]y"
+ endif
+ let g:a=strlen(substitute(@@, '[^ ]', '', 'g'))
+ let &selection = sel_save
+ let @@ = reg_save
+endfunc
+
+func! OpfuncDummy(type, ...)
+ " for testing operatorfunc
+ let g:opt=&linebreak
+
+ if a:0 " Invoked from Visual mode, use gv command.
+ silent exe "normal! gvy"
+ elseif a:type == 'line'
+ silent exe "normal! '[V']y"
+ else
+ silent exe "normal! `[v`]y"
+ endif
+ " Create a new dummy window
+ new
+ let g:bufnr=bufnr('%')
+endfunc
+
+fun! Test_normal00_optrans()
+ new
+ call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
+ 1
+ exe "norm! Sfoobar\<esc>"
+ call assert_equal(['foobar', '2 This is the second line', '3 this is the third line', ''], getline(1,'$'))
+ 2
+ exe "norm! $vbsone"
+ call assert_equal(['foobar', '2 This is the second one', '3 this is the third line', ''], getline(1,'$'))
+ norm! VS Second line here
+ call assert_equal(['foobar', ' Second line here', '3 this is the third line', ''], getline(1, '$'))
+ %d
+ call append(0, ['4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line'])
+ call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
+
+ 1
+ norm! 2D
+ call assert_equal(['3 this is the third line', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$'))
+ " Nvim: no "#" flag in 'cpoptions'.
+ " set cpo+=#
+ " norm! 4D
+ " call assert_equal(['', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$'))
+
+ " clean up
+ set cpo-=#
+ bw!
+endfunc
+
+func! Test_normal01_keymodel()
+ throw "skipped: Nvim regression: 'keymodel'"
+ call Setup_NewWindow()
+ " Test 1: depending on 'keymodel' <s-down> does something different
+ 50
+ call feedkeys("V\<S-Up>y", 'tx')
+ call assert_equal(['47', '48', '49', '50'], getline("'<", "'>"))
+ set keymodel=startsel
+ 50
+ call feedkeys("V\<S-Up>y", 'tx')
+ call assert_equal(['49', '50'], getline("'<", "'>"))
+ " Start visual mode when keymodel = startsel
+ 50
+ call feedkeys("\<S-Up>y", 'tx')
+ call assert_equal(['49', '5'], getreg(0, 0, 1))
+ " Do not start visual mode when keymodel=
+ set keymodel=
+ 50
+ call feedkeys("\<S-Up>y$", 'tx')
+ call assert_equal(['42'], getreg(0, 0, 1))
+ " Stop visual mode when keymodel=stopsel
+ set keymodel=stopsel
+ 50
+ call feedkeys("Vkk\<Up>yy", 'tx')
+ call assert_equal(['47'], getreg(0, 0, 1))
+
+ set keymodel=
+ 50
+ call feedkeys("Vkk\<Up>yy", 'tx')
+ call assert_equal(['47', '48', '49', '50'], getreg(0, 0, 1))
+
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal02_selectmode()
+ " some basic select mode tests
+ call Setup_NewWindow()
+ 50
+ norm! gHy
+ call assert_equal('y51', getline('.'))
+ call setline(1, range(1,100))
+ 50
+ exe ":norm! V9jo\<c-g>y"
+ call assert_equal('y60', getline('.'))
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal02_selectmode2()
+ " some basic select mode tests
+ call Setup_NewWindow()
+ 50
+ call feedkeys(":set im\n\<c-o>gHc\<c-o>:set noim\n", 'tx')
+ call assert_equal('c51', getline('.'))
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal03_join()
+ " basic join test
+ call Setup_NewWindow()
+ 50
+ norm! VJ
+ call assert_equal('50 51', getline('.'))
+ $
+ norm! J
+ call assert_equal('100', getline('.'))
+ $
+ norm! V9-gJ
+ call assert_equal('919293949596979899100', getline('.'))
+ call setline(1, range(1,100))
+ $
+ :j 10
+ call assert_equal('100', getline('.'))
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal04_filter()
+ " basic filter test
+ " only test on non windows platform
+ if has('win32')
+ return
+ endif
+ call Setup_NewWindow()
+ 1
+ call feedkeys("!!sed -e 's/^/| /'\n", 'tx')
+ call assert_equal('| 1', getline('.'))
+ 90
+ :sil :!echo one
+ call feedkeys('.', 'tx')
+ call assert_equal('| 90', getline('.'))
+ 95
+ set cpo+=!
+ " 2 <CR>, 1: for executing the command,
+ " 2: clear hit-enter-prompt
+ call feedkeys("!!\n", 'tx')
+ call feedkeys(":!echo one\n\n", 'tx')
+ call feedkeys(".", 'tx')
+ call assert_equal('one', getline('.'))
+ set cpo-=!
+ bw!
+endfunc
+
+func! Test_normal05_formatexpr()
+ " basic formatexpr test
+ call Setup_NewWindow()
+ %d_
+ call setline(1, ['here: 1 ', '2', 'here: 3 ', '4', 'not here: '])
+ 1
+ set formatexpr=MyFormatExpr()
+ norm! gqG
+ call assert_equal(['here: 1->$', '2', 'here: 3->$', '4', 'not here: '], getline(1,'$'))
+ set formatexpr=
+ bw!
+endfunc
+
+func Test_normal05_formatexpr_newbuf()
+ " Edit another buffer in the 'formatexpr' function
+ new
+ func! Format()
+ edit another
+ endfunc
+ set formatexpr=Format()
+ norm gqG
+ bw!
+ set formatexpr=
+endfunc
+
+func Test_normal05_formatexpr_setopt()
+ " Change the 'formatexpr' value in the function
+ new
+ func! Format()
+ set formatexpr=
+ endfunc
+ set formatexpr=Format()
+ norm gqG
+ bw!
+ set formatexpr=
+endfunc
+
+func! Test_normal06_formatprg()
+ " basic test for formatprg
+ " only test on non windows platform
+ if has('win32')
+ return
+ endif
+
+ " uses sed to number non-empty lines
+ call writefile(['#!/bin/sh', 'sed ''/./=''|sed ''/./{', 'N', 's/\n/ /', '}'''], 'Xsed_format.sh')
+ call system('chmod +x ./Xsed_format.sh')
+ let text = ['a', '', 'c', '', ' ', 'd', 'e']
+ let expected = ['1 a', '', '3 c', '', '5 ', '6 d', '7 e']
+
+ 10new
+ call setline(1, text)
+ set formatprg=./Xsed_format.sh
+ norm! gggqG
+ call assert_equal(expected, getline(1, '$'))
+ bw!
+
+ 10new
+ call setline(1, text)
+ set formatprg=donothing
+ setlocal formatprg=./Xsed_format.sh
+ norm! gggqG
+ call assert_equal(expected, getline(1, '$'))
+ bw!
+
+ " clean up
+ set formatprg=
+ setlocal formatprg=
+ call delete('Xsed_format.sh')
+endfunc
+
+func! Test_normal07_internalfmt()
+ " basic test for internal formmatter to textwidth of 12
+ let list=range(1,11)
+ call map(list, 'v:val." "')
+ 10new
+ call setline(1, list)
+ set tw=12
+ norm! gggqG
+ call assert_equal(['1 2 3', '4 5 6', '7 8 9', '10 11 '], getline(1, '$'))
+ " clean up
+ set tw=0
+ bw!
+endfunc
+
+func! Test_normal08_fold()
+ " basic tests for foldopen/folddelete
+ if !has("folding")
+ return
+ endif
+ call Setup_NewWindow()
+ 50
+ setl foldenable fdm=marker
+ " First fold
+ norm! V4jzf
+ " check that folds have been created
+ call assert_equal(['50/*{{{*/', '51', '52', '53', '54/*}}}*/'], getline(50,54))
+ " Second fold
+ 46
+ norm! V10jzf
+ " check that folds have been created
+ call assert_equal('46/*{{{*/', getline(46))
+ call assert_equal('60/*}}}*/', getline(60))
+ norm! k
+ call assert_equal('45', getline('.'))
+ norm! j
+ call assert_equal('46/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('61', getline('.'))
+ norm! k
+ " open a fold
+ norm! Vzo
+ norm! k
+ call assert_equal('45', getline('.'))
+ norm! j
+ call assert_equal('46/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('47', getline('.'))
+ norm! k
+ norm! zcVzO
+ call assert_equal('46/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('47', getline('.'))
+ norm! j
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51', getline('.'))
+ " delete folds
+ :46
+ " collapse fold
+ norm! V14jzC
+ " delete all folds recursively
+ norm! VzD
+ call assert_equal(['46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60'], getline(46,60))
+
+ " clean up
+ setl nofoldenable fdm=marker
+ bw!
+endfunc
+
+func! Test_normal09_operatorfunc()
+ " Test operatorfunc
+ call Setup_NewWindow()
+ " Add some spaces for counting
+ 50,60s/$/ /
+ unlet! g:a
+ let g:a=0
+ nmap <buffer><silent> ,, :set opfunc=CountSpaces<CR>g@
+ vmap <buffer><silent> ,, :<C-U>call CountSpaces(visualmode(), 1)<CR>
+ 50
+ norm V2j,,
+ call assert_equal(6, g:a)
+ norm V,,
+ call assert_equal(2, g:a)
+ norm ,,l
+ call assert_equal(0, g:a)
+ 50
+ exe "norm 0\<c-v>10j2l,,"
+ call assert_equal(11, g:a)
+ 50
+ norm V10j,,
+ call assert_equal(22, g:a)
+
+ " clean up
+ unmap <buffer> ,,
+ set opfunc=
+ unlet! g:a
+ bw!
+endfunc
+
+func! Test_normal09a_operatorfunc()
+ " Test operatorfunc
+ call Setup_NewWindow()
+ " Add some spaces for counting
+ 50,60s/$/ /
+ unlet! g:opt
+ set linebreak
+ nmap <buffer><silent> ,, :set opfunc=OpfuncDummy<CR>g@
+ 50
+ norm ,,j
+ exe "bd!" g:bufnr
+ call assert_true(&linebreak)
+ call assert_equal(g:opt, &linebreak)
+ set nolinebreak
+ norm ,,j
+ exe "bd!" g:bufnr
+ call assert_false(&linebreak)
+ call assert_equal(g:opt, &linebreak)
+
+ " clean up
+ unmap <buffer> ,,
+ set opfunc=
+ bw!
+ unlet! g:opt
+endfunc
+
+func! Test_normal10_expand()
+ " Test for expand()
+ 10new
+ call setline(1, ['1', 'ifooar,,cbar'])
+ 2
+ norm! $
+ let a=expand('<cword>')
+ let b=expand('<cWORD>')
+ call assert_equal('cbar', a)
+ call assert_equal('ifooar,,cbar', b)
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal11_showcmd()
+ " test for 'showcmd'
+ 10new
+ exe "norm! ofoobar\<esc>"
+ call assert_equal(2, line('$'))
+ set showcmd
+ exe "norm! ofoobar2\<esc>"
+ call assert_equal(3, line('$'))
+ exe "norm! VAfoobar3\<esc>"
+ call assert_equal(3, line('$'))
+ exe "norm! 0d3\<del>2l"
+ call assert_equal('obar2foobar3', getline('.'))
+ bw!
+endfunc
+
+func! Test_normal12_nv_error()
+ " Test for nv_error
+ 10new
+ call setline(1, range(1,5))
+ " should not do anything, just beep
+ exe "norm! <c-k>"
+ call assert_equal(map(range(1,5), 'string(v:val)'), getline(1,'$'))
+ bw!
+endfunc
+
+func! Test_normal13_help()
+ " Test for F1
+ call assert_equal(1, winnr())
+ call feedkeys("\<f1>", 'txi')
+ call assert_match('help\.txt', bufname('%'))
+ call assert_equal(2, winnr('$'))
+ bw!
+endfunc
+
+func! Test_normal14_page()
+ " basic test for Ctrl-F and Ctrl-B
+ call Setup_NewWindow()
+ exe "norm! \<c-f>"
+ call assert_equal('9', getline('.'))
+ exe "norm! 2\<c-f>"
+ call assert_equal('25', getline('.'))
+ exe "norm! 2\<c-b>"
+ call assert_equal('18', getline('.'))
+ 1
+ set scrolloff=5
+ exe "norm! 2\<c-f>"
+ call assert_equal('21', getline('.'))
+ exe "norm! \<c-b>"
+ call assert_equal('13', getline('.'))
+ 1
+ set scrolloff=99
+ exe "norm! \<c-f>"
+ call assert_equal('13', getline('.'))
+ set scrolloff=0
+ 100
+ exe "norm! $\<c-b>"
+ call assert_equal('92', getline('.'))
+ call assert_equal([0, 92, 1, 0, 1], getcurpos())
+ 100
+ set nostartofline
+ exe "norm! $\<c-b>"
+ call assert_equal('92', getline('.'))
+ call assert_equal([0, 92, 2, 0, 2147483647], getcurpos())
+ " cleanup
+ set startofline
+ bw!
+endfunc
+
+func! Test_normal14_page_eol()
+ 10new
+ norm oxxxxxxx
+ exe "norm 2\<c-f>"
+ " check with valgrind that cursor is put back in column 1
+ exe "norm 2\<c-b>"
+ bw!
+endfunc
+
+func! Test_normal15_z_scroll_vert()
+ " basic test for z commands that scroll the window
+ call Setup_NewWindow()
+ 100
+ norm! >>
+ " Test for z<cr>
+ exe "norm! z\<cr>"
+ call assert_equal(' 100', getline('.'))
+ call assert_equal(100, winsaveview()['topline'])
+ call assert_equal([0, 100, 2, 0, 9], getcurpos())
+
+ " Test for zt
+ 21
+ norm! >>0zt
+ call assert_equal(' 21', getline('.'))
+ call assert_equal(21, winsaveview()['topline'])
+ call assert_equal([0, 21, 1, 0, 8], getcurpos())
+
+ " Test for zb
+ 30
+ norm! >>$ztzb
+ call assert_equal(' 30', getline('.'))
+ call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
+ call assert_equal([0, 30, 3, 0, 2147483647], getcurpos())
+
+ " Test for z-
+ 1
+ 30
+ norm! 0z-
+ call assert_equal(' 30', getline('.'))
+ call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
+ call assert_equal([0, 30, 2, 0, 9], getcurpos())
+
+ " Test for z{height}<cr>
+ call assert_equal(10, winheight(0))
+ exe "norm! z12\<cr>"
+ call assert_equal(12, winheight(0))
+ exe "norm! z10\<cr>"
+ call assert_equal(10, winheight(0))
+
+ " Test for z.
+ 1
+ 21
+ norm! 0z.
+ call assert_equal(' 21', getline('.'))
+ call assert_equal(17, winsaveview()['topline'])
+ call assert_equal([0, 21, 2, 0, 9], getcurpos())
+
+ " Test for zz
+ 1
+ 21
+ norm! 0zz
+ call assert_equal(' 21', getline('.'))
+ call assert_equal(17, winsaveview()['topline'])
+ call assert_equal([0, 21, 1, 0, 8], getcurpos())
+
+ " Test for z+
+ 11
+ norm! zt
+ norm! z+
+ call assert_equal(' 21', getline('.'))
+ call assert_equal(21, winsaveview()['topline'])
+ call assert_equal([0, 21, 2, 0, 9], getcurpos())
+
+ " Test for [count]z+
+ 1
+ norm! 21z+
+ call assert_equal(' 21', getline('.'))
+ call assert_equal(21, winsaveview()['topline'])
+ call assert_equal([0, 21, 2, 0, 9], getcurpos())
+
+ " Test for z^
+ norm! 22z+0
+ norm! z^
+ call assert_equal(' 21', getline('.'))
+ call assert_equal(12, winsaveview()['topline'])
+ call assert_equal([0, 21, 2, 0, 9], getcurpos())
+
+ " Test for [count]z^
+ 1
+ norm! 30z^
+ call assert_equal(' 21', getline('.'))
+ call assert_equal(12, winsaveview()['topline'])
+ call assert_equal([0, 21, 2, 0, 9], getcurpos())
+
+ " cleanup
+ bw!
+endfunc
+
+func! Test_normal16_z_scroll_hor()
+ " basic test for z commands that scroll the window
+ 10new
+ 15vsp
+ set nowrap listchars=
+ let lineA='abcdefghijklmnopqrstuvwxyz'
+ let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ $put =lineA
+ $put =lineB
+ 1d
+
+ " Test for zl
+ 1
+ norm! 5zl
+ call assert_equal(lineA, getline('.'))
+ call assert_equal(6, col('.'))
+ call assert_equal(5, winsaveview()['leftcol'])
+ norm! yl
+ call assert_equal('f', @0)
+
+ " Test for zh
+ norm! 2zh
+ call assert_equal(lineA, getline('.'))
+ call assert_equal(6, col('.'))
+ norm! yl
+ call assert_equal('f', @0)
+ call assert_equal(3, winsaveview()['leftcol'])
+
+ " Test for zL
+ norm! zL
+ call assert_equal(11, col('.'))
+ norm! yl
+ call assert_equal('k', @0)
+ call assert_equal(10, winsaveview()['leftcol'])
+ norm! 2zL
+ call assert_equal(25, col('.'))
+ norm! yl
+ call assert_equal('y', @0)
+ call assert_equal(24, winsaveview()['leftcol'])
+
+ " Test for zH
+ norm! 2zH
+ call assert_equal(25, col('.'))
+ call assert_equal(10, winsaveview()['leftcol'])
+ norm! yl
+ call assert_equal('y', @0)
+
+ " Test for zs
+ norm! $zs
+ call assert_equal(26, col('.'))
+ call assert_equal(25, winsaveview()['leftcol'])
+ norm! yl
+ call assert_equal('z', @0)
+
+ " Test for ze
+ norm! ze
+ call assert_equal(26, col('.'))
+ call assert_equal(11, winsaveview()['leftcol'])
+ norm! yl
+ call assert_equal('z', @0)
+
+ " cleanup
+ set wrap listchars=eol:$
+ bw!
+endfunc
+
+func! Test_normal17_z_scroll_hor2()
+ " basic test for z commands that scroll the window
+ " using 'sidescrolloff' setting
+ 10new
+ 20vsp
+ set nowrap listchars= sidescrolloff=5
+ let lineA='abcdefghijklmnopqrstuvwxyz'
+ let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ $put =lineA
+ $put =lineB
+ 1d
+
+ " Test for zl
+ 1
+ norm! 5zl
+ call assert_equal(lineA, getline('.'))
+ call assert_equal(11, col('.'))
+ call assert_equal(5, winsaveview()['leftcol'])
+ norm! yl
+ call assert_equal('k', @0)
+
+ " Test for zh
+ norm! 2zh
+ call assert_equal(lineA, getline('.'))
+ call assert_equal(11, col('.'))
+ norm! yl
+ call assert_equal('k', @0)
+ call assert_equal(3, winsaveview()['leftcol'])
+
+ " Test for zL
+ norm! 0zL
+ call assert_equal(16, col('.'))
+ norm! yl
+ call assert_equal('p', @0)
+ call assert_equal(10, winsaveview()['leftcol'])
+ norm! 2zL
+ call assert_equal(26, col('.'))
+ norm! yl
+ call assert_equal('z', @0)
+ call assert_equal(15, winsaveview()['leftcol'])
+
+ " Test for zH
+ norm! 2zH
+ call assert_equal(15, col('.'))
+ call assert_equal(0, winsaveview()['leftcol'])
+ norm! yl
+ call assert_equal('o', @0)
+
+ " Test for zs
+ norm! $zs
+ call assert_equal(26, col('.'))
+ call assert_equal(20, winsaveview()['leftcol'])
+ norm! yl
+ call assert_equal('z', @0)
+
+ " Test for ze
+ norm! ze
+ call assert_equal(26, col('.'))
+ call assert_equal(11, winsaveview()['leftcol'])
+ norm! yl
+ call assert_equal('z', @0)
+
+ " cleanup
+ set wrap listchars=eol:$ sidescrolloff=0
+ bw!
+endfunc
+
+func! Test_normal18_z_fold()
+ " basic tests for foldopen/folddelete
+ if !has("folding")
+ return
+ endif
+ call Setup_NewWindow()
+ 50
+ setl foldenable fdm=marker foldlevel=5
+
+ " Test for zF
+ " First fold
+ norm! 4zF
+ " check that folds have been created
+ call assert_equal(['50/*{{{*/', '51', '52', '53/*}}}*/'], getline(50,53))
+
+ " Test for zd
+ 51
+ norm! 2zF
+ call assert_equal(2, foldlevel('.'))
+ norm! kzd
+ call assert_equal(['50', '51/*{{{*/', '52/*}}}*/', '53'], getline(50,53))
+ norm! j
+ call assert_equal(1, foldlevel('.'))
+
+ " Test for zD
+ " also deletes partially selected folds recursively
+ 51
+ norm! zF
+ call assert_equal(2, foldlevel('.'))
+ norm! kV2jzD
+ call assert_equal(['50', '51', '52', '53'], getline(50,53))
+
+ " Test for zE
+ 85
+ norm! 4zF
+ 86
+ norm! 2zF
+ 90
+ norm! 4zF
+ call assert_equal(['85/*{{{*/', '86/*{{{*/', '87/*}}}*/', '88/*}}}*/', '89', '90/*{{{*/', '91', '92', '93/*}}}*/'], getline(85,93))
+ norm! zE
+ call assert_equal(['85', '86', '87', '88', '89', '90', '91', '92', '93'], getline(85,93))
+
+ " Test for zn
+ 50
+ set foldlevel=0
+ norm! 2zF
+ norm! zn
+ norm! k
+ call assert_equal('49', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+ call assert_equal(0, &foldenable)
+
+ " Test for zN
+ 49
+ norm! zN
+ call assert_equal('49', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+ call assert_equal(1, &foldenable)
+
+ " Test for zi
+ norm! zi
+ call assert_equal(0, &foldenable)
+ norm! zi
+ call assert_equal(1, &foldenable)
+ norm! zi
+ call assert_equal(0, &foldenable)
+ norm! zi
+ call assert_equal(1, &foldenable)
+
+ " Test for za
+ 50
+ norm! za
+ norm! k
+ call assert_equal('49', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+ 50
+ norm! za
+ norm! k
+ call assert_equal('49', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+
+ 49
+ norm! 5zF
+ norm! k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+ 49
+ norm! za
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+ set nofoldenable
+ " close fold and set foldenable
+ norm! za
+ call assert_equal(1, &foldenable)
+
+ 50
+ " have to use {count}za to open all folds and make the cursor visible
+ norm! 2za
+ norm! 2k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+
+ " Test for zA
+ 49
+ set foldlevel=0
+ 50
+ norm! zA
+ norm! 2k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+
+ " zA on a opened fold when foldenale is not set
+ 50
+ set nofoldenable
+ norm! zA
+ call assert_equal(1, &foldenable)
+ norm! k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " Test for zc
+ norm! zE
+ 50
+ norm! 2zF
+ 49
+ norm! 5zF
+ set nofoldenable
+ 50
+ " There most likely is a bug somewhere:
+ " https://groups.google.com/d/msg/vim_dev/v2EkfJ_KQjI/u-Cvv94uCAAJ
+ " TODO: Should this only close the inner most fold or both folds?
+ norm! zc
+ call assert_equal(1, &foldenable)
+ norm! k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+ set nofoldenable
+ 50
+ norm! Vjzc
+ norm! k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " Test for zC
+ set nofoldenable
+ 50
+ norm! zCk
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " Test for zx
+ " 1) close folds at line 49-54
+ set nofoldenable
+ 48
+ norm! zx
+ call assert_equal(1, &foldenable)
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " 2) do not close fold under curser
+ 51
+ set nofoldenable
+ norm! zx
+ call assert_equal(1, &foldenable)
+ norm! 3k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+ norm! j
+ call assert_equal('53', getline('.'))
+ norm! j
+ call assert_equal('54/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " 3) close one level of folds
+ 48
+ set nofoldenable
+ set foldlevel=1
+ norm! zx
+ call assert_equal(1, &foldenable)
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+ norm! j
+ call assert_equal('53', getline('.'))
+ norm! j
+ call assert_equal('54/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " Test for zX
+ " Close all folds
+ set foldlevel=0 nofoldenable
+ 50
+ norm! zX
+ call assert_equal(1, &foldenable)
+ norm! k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " Test for zm
+ 50
+ set nofoldenable foldlevel=2
+ norm! zm
+ call assert_equal(1, &foldenable)
+ call assert_equal(1, &foldlevel)
+ norm! zm
+ call assert_equal(0, &foldlevel)
+ norm! zm
+ call assert_equal(0, &foldlevel)
+ norm! k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " Test for zM
+ 48
+ set nofoldenable foldlevel=99
+ norm! zM
+ call assert_equal(1, &foldenable)
+ call assert_equal(0, &foldlevel)
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " Test for zr
+ 48
+ set nofoldenable foldlevel=0
+ norm! zr
+ call assert_equal(0, &foldenable)
+ call assert_equal(1, &foldlevel)
+ set foldlevel=0 foldenable
+ norm! zr
+ call assert_equal(1, &foldenable)
+ call assert_equal(1, &foldlevel)
+ norm! zr
+ call assert_equal(2, &foldlevel)
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+
+ " Test for zR
+ 48
+ set nofoldenable foldlevel=0
+ norm! zR
+ call assert_equal(0, &foldenable)
+ call assert_equal(2, &foldlevel)
+ set foldenable foldlevel=0
+ norm! zR
+ call assert_equal(1, &foldenable)
+ call assert_equal(2, &foldlevel)
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+ call append(50, ['a /*{{{*/', 'b /*}}}*/'])
+ 48
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('a /*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+ 48
+ norm! zR
+ call assert_equal(1, &foldenable)
+ call assert_equal(3, &foldlevel)
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('a /*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('b /*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+
+ " clean up
+ setl nofoldenable fdm=marker foldlevel=0
+ bw!
+endfunc
+
+func! Test_normal19_z_spell()
+ throw "skipped: Nvim 'spell' requires download"
+ if !has("spell") || !has('syntax')
+ return
+ endif
+ new
+ call append(0, ['1 good', '2 goood', '3 goood'])
+ set spell spellfile=./Xspellfile.add spelllang=en
+ let oldlang=v:lang
+ lang C
+
+ " Test for zg
+ 1
+ norm! ]s
+ call assert_equal('2 goood', getline('.'))
+ norm! zg
+ 1
+ let a=execute('unsilent :norm! ]s')
+ call assert_equal('1 good', getline('.'))
+ call assert_equal('search hit BOTTOM, continuing at TOP', a[1:])
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('goood', cnt[0])
+
+ " Test for zw
+ 2
+ norm! $zw
+ 1
+ norm! ]s
+ call assert_equal('2 goood', getline('.'))
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('#oood', cnt[0])
+ call assert_equal('goood/!', cnt[1])
+
+ " Test for zg in visual mode
+ let a=execute('unsilent :norm! V$zg')
+ call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:])
+ 1
+ norm! ]s
+ call assert_equal('3 goood', getline('.'))
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('2 goood', cnt[2])
+ " Remove "2 good" from spellfile
+ 2
+ let a=execute('unsilent norm! V$zw')
+ call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:])
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('2 goood/!', cnt[3])
+
+ " Test for zG
+ let a=execute('unsilent norm! V$zG')
+ call assert_match("Word '2 goood' added to .*", a)
+ let fname=matchstr(a, 'to\s\+\zs\f\+$')
+ let cnt=readfile(fname)
+ call assert_equal('2 goood', cnt[0])
+
+ " Test for zW
+ let a=execute('unsilent norm! V$zW')
+ call assert_match("Word '2 goood' added to .*", a)
+ let cnt=readfile(fname)
+ call assert_equal('# goood', cnt[0])
+ call assert_equal('2 goood/!', cnt[1])
+
+ " Test for zuW
+ let a=execute('unsilent norm! V$zuW')
+ call assert_match("Word '2 goood' removed from .*", a)
+ let cnt=readfile(fname)
+ call assert_equal('# goood', cnt[0])
+ call assert_equal('# goood/!', cnt[1])
+
+ " Test for zuG
+ let a=execute('unsilent norm! $zG')
+ call assert_match("Word 'goood' added to .*", a)
+ let cnt=readfile(fname)
+ call assert_equal('# goood', cnt[0])
+ call assert_equal('# goood/!', cnt[1])
+ call assert_equal('goood', cnt[2])
+ let a=execute('unsilent norm! $zuG')
+ let cnt=readfile(fname)
+ call assert_match("Word 'goood' removed from .*", a)
+ call assert_equal('# goood', cnt[0])
+ call assert_equal('# goood/!', cnt[1])
+ call assert_equal('#oood', cnt[2])
+ " word not found in wordlist
+ let a=execute('unsilent norm! V$zuG')
+ let cnt=readfile(fname)
+ call assert_match("", a)
+ call assert_equal('# goood', cnt[0])
+ call assert_equal('# goood/!', cnt[1])
+ call assert_equal('#oood', cnt[2])
+
+ " Test for zug
+ call delete('./Xspellfile.add')
+ 2
+ let a=execute('unsilent norm! $zg')
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('goood', cnt[0])
+ let a=execute('unsilent norm! $zug')
+ call assert_match("Word 'goood' removed from \./Xspellfile.add", a)
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('#oood', cnt[0])
+ " word not in wordlist
+ let a=execute('unsilent norm! V$zug')
+ call assert_match('', a)
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('#oood', cnt[0])
+
+ " Test for zuw
+ call delete('./Xspellfile.add')
+ 2
+ let a=execute('unsilent norm! Vzw')
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('2 goood/!', cnt[0])
+ let a=execute('unsilent norm! Vzuw')
+ call assert_match("Word '2 goood' removed from \./Xspellfile.add", a)
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('# goood/!', cnt[0])
+ " word not in wordlist
+ let a=execute('unsilent norm! $zug')
+ call assert_match('', a)
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('# goood/!', cnt[0])
+
+ " add second entry to spellfile setting
+ set spellfile=./Xspellfile.add,./Xspellfile2.add
+ call delete('./Xspellfile.add')
+ 2
+ let a=execute('unsilent norm! $2zg')
+ let cnt=readfile('./Xspellfile2.add')
+ call assert_match("Word 'goood' added to ./Xspellfile2.add", a)
+ call assert_equal('goood', cnt[0])
+
+ " clean up
+ exe "lang" oldlang
+ call delete("./Xspellfile.add")
+ call delete("./Xspellfile2.add")
+ call delete("./Xspellfile.add.spl")
+ call delete("./Xspellfile2.add.spl")
+
+ " zux -> no-op
+ 2
+ norm! $zux
+ call assert_equal([], glob('Xspellfile.add',0,1))
+ call assert_equal([], glob('Xspellfile2.add',0,1))
+
+ set spellfile=
+ bw!
+endfunc
+
+func! Test_normal20_exmode()
+ if !has("unix")
+ " Reading from redirected file doesn't work on MS-Windows
+ return
+ endif
+ call writefile(['1a', 'foo', 'bar', '.', 'w! Xfile2', 'q!'], 'Xscript')
+ call writefile(['1', '2'], 'Xfile')
+ call system(v:progpath .' -e -s < Xscript Xfile')
+ let a=readfile('Xfile2')
+ call assert_equal(['1', 'foo', 'bar', '2'], a)
+
+ " clean up
+ for file in ['Xfile', 'Xfile2', 'Xscript']
+ call delete(file)
+ endfor
+ bw!
+endfunc
+
+func! Test_normal21_nv_hat()
+ set hidden
+ new
+ " to many buffers opened already, will not work
+ "call assert_fails(":b#", 'E23')
+ "call assert_equal('', @#)
+ e Xfoobar
+ e Xfile2
+ call feedkeys("\<c-^>", 't')
+ call assert_equal("Xfile2", fnamemodify(bufname('%'), ':t'))
+ call feedkeys("f\<c-^>", 't')
+ call assert_equal("Xfile2", fnamemodify(bufname('%'), ':t'))
+ " clean up
+ set nohidden
+ bw!
+endfunc
+
+func! Test_normal22_zet()
+ " Test for ZZ
+ " let shell = &shell
+ " let &shell = 'sh'
+
+ " Remove any stale test files from previous run.
+ for file in ['Xfile_Test_normal22_zet']
+ call delete(file)
+ endfor
+
+ call writefile(['1', '2'], 'Xfile_Test_normal22_zet')
+ let args = ' --headless -u NONE -N -U NONE -i NONE --noplugins'
+ call system(v:progpath . args . ' -c "%d" -c ":norm! ZZ" Xfile_Test_normal22_zet')
+ let a = readfile('Xfile_Test_normal22_zet')
+ call assert_equal([], a)
+ " Test for ZQ
+ call writefile(['1', '2'], 'Xfile_Test_normal22_zet')
+ call system(v:progpath . args . ' -c "%d" -c ":norm! ZQ" Xfile_Test_normal22_zet')
+ let a = readfile('Xfile_Test_normal22_zet')
+ call assert_equal(['1', '2'], a)
+
+ " Nvim: This sometimes hangs the TSAN build.
+ " for file in ['Xfile_Test_normal22_zet']
+ " call delete(file)
+ " endfor
+ " let &shell = shell
+endfunc
+
+func! Test_normal23_K()
+ " Test for K command
+ new
+ call append(0, ['helphelp.txt', 'man', 'aa%bb', 'cc|dd'])
+ let k = &keywordprg
+ set keywordprg=:help
+ 1
+ norm! VK
+ call assert_equal('helphelp.txt', fnamemodify(bufname('%'), ':t'))
+ call assert_equal('help', &ft)
+ call assert_match('\*helphelp.txt\*', getline('.'))
+ helpclose
+ norm! 0K
+ call assert_equal('helphelp.txt', fnamemodify(bufname('%'), ':t'))
+ call assert_equal('help', &ft)
+ call assert_match('Help on help files', getline('.'))
+ helpclose
+
+ set keywordprg=:new
+ set iskeyword+=%
+ set iskeyword+=\|
+ 2
+ norm! K
+ call assert_equal('man', fnamemodify(bufname('%'), ':t'))
+ bwipe!
+ 3
+ norm! K
+ call assert_equal('aa%bb', fnamemodify(bufname('%'), ':t'))
+ bwipe!
+ if !has('win32')
+ 4
+ norm! K
+ call assert_equal('cc|dd', fnamemodify(bufname('%'), ':t'))
+ bwipe!
+ endif
+ set iskeyword-=%
+ set iskeyword-=\|
+
+ " Only expect "man" to work on Unix
+ if !has("unix")
+ let &keywordprg = k
+ bw!
+ return
+ endif
+ set keywordprg=man\ --pager=cat
+ " Test for using man
+ 2
+ let a = execute('unsilent norm! K')
+ call assert_match("man --pager=cat 'man'", a)
+
+ " clean up
+ let &keywordprg = k
+ bw!
+endfunc
+
+func! Test_normal24_rot13()
+ " This test uses multi byte characters
+ if !has("multi_byte")
+ return
+ endif
+ " Testing for g?? g?g?
+ new
+ call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
+ 1
+ norm! g??
+ call assert_equal('nopqrstuvwxyzabcdefghijklmäüö', getline('.'))
+ norm! g?g?
+ call assert_equal('abcdefghijklmnopqrstuvwxyzäüö', getline('.'))
+
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal25_tag()
+ " Testing for CTRL-] g CTRL-] g]
+ " CTRL-W g] CTRL-W CTRL-] CTRL-W g CTRL-]
+ h
+ " Test for CTRL-]
+ call search('\<x\>$')
+ exe "norm! \<c-]>"
+ call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
+ norm! yiW
+ call assert_equal("*x*", @0)
+ exe ":norm \<c-o>"
+
+ " Test for g_CTRL-]
+ call search('\<v_u\>$')
+ exe "norm! g\<c-]>"
+ call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
+ norm! yiW
+ call assert_equal("*v_u*", @0)
+ exe ":norm \<c-o>"
+
+ " Test for g]
+ call search('\<i_<Esc>$')
+ let a = execute(":norm! g]")
+ call assert_match('i_<Esc>.*insert.txt', a)
+
+ if !empty(exepath('cscope')) && has('cscope')
+ " setting cscopetag changes how g] works
+ set cst
+ exe "norm! g]"
+ call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
+ norm! yiW
+ call assert_equal("*i_<Esc>*", @0)
+ exe ":norm \<c-o>"
+ " Test for CTRL-W g]
+ exe "norm! \<C-W>g]"
+ call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
+ norm! yiW
+ call assert_equal("*i_<Esc>*", @0)
+ call assert_equal(3, winnr('$'))
+ helpclose
+ set nocst
+ endif
+
+ " Test for CTRL-W g]
+ let a = execute("norm! \<C-W>g]")
+ call assert_match('i_<Esc>.*insert.txt', a)
+
+ " Test for CTRL-W CTRL-]
+ exe "norm! \<C-W>\<C-]>"
+ call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
+ norm! yiW
+ call assert_equal("*i_<Esc>*", @0)
+ call assert_equal(3, winnr('$'))
+ helpclose
+
+ " Test for CTRL-W g CTRL-]
+ exe "norm! \<C-W>g\<C-]>"
+ call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
+ norm! yiW
+ call assert_equal("*i_<Esc>*", @0)
+ call assert_equal(3, winnr('$'))
+ helpclose
+
+ " clean up
+ helpclose
+endfunc
+
+func! Test_normal26_put()
+ " Test for ]p ]P [p and [P
+ new
+ call append(0, ['while read LINE', 'do', ' ((count++))', ' if [ $? -ne 0 ]; then', " echo 'Error writing file'", ' fi', 'done'])
+ 1
+ /Error/y a
+ 2
+ norm! "a]pj"a[p
+ call assert_equal(['do', "echo 'Error writing file'", " echo 'Error writing file'", ' ((count++))'], getline(2,5))
+ 1
+ /^\s\{4}/
+ exe "norm! \"a]P3Eldt'"
+ exe "norm! j\"a[P2Eldt'"
+ call assert_equal([' if [ $? -ne 0 ]; then', " echo 'Error writing'", " echo 'Error'", " echo 'Error writing file'", ' fi'], getline(6,10))
+
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal27_bracket()
+ " Test for [' [` ]' ]`
+ call Setup_NewWindow()
+ 1,21s/.\+/ & b/
+ 1
+ norm! $ma
+ 5
+ norm! $mb
+ 10
+ norm! $mc
+ 15
+ norm! $md
+ 20
+ norm! $me
+
+ " Test for ['
+ 9
+ norm! 2['
+ call assert_equal(' 1 b', getline('.'))
+ call assert_equal(1, line('.'))
+ call assert_equal(3, col('.'))
+
+ " Test for ]'
+ norm! ]'
+ call assert_equal(' 5 b', getline('.'))
+ call assert_equal(5, line('.'))
+ call assert_equal(3, col('.'))
+
+ " No mark after line 21, cursor moves to first non blank on current line
+ 21
+ norm! $]'
+ call assert_equal(' 21 b', getline('.'))
+ call assert_equal(21, line('.'))
+ call assert_equal(3, col('.'))
+
+ " Test for [`
+ norm! 2[`
+ call assert_equal(' 15 b', getline('.'))
+ call assert_equal(15, line('.'))
+ call assert_equal(8, col('.'))
+
+ " Test for ]`
+ norm! ]`
+ call assert_equal(' 20 b', getline('.'))
+ call assert_equal(20, line('.'))
+ call assert_equal(8, col('.'))
+
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal28_parenthesis()
+ " basic testing for ( and )
+ new
+ call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
+
+ $
+ norm! d(
+ call assert_equal(['This is a test. With some sentences!', '', 'Even with a question? And one more. ', ''], getline(1, '$'))
+ norm! 2d(
+ call assert_equal(['This is a test. With some sentences!', '', ' ', ''], getline(1, '$'))
+ 1
+ norm! 0d)
+ call assert_equal(['With some sentences!', '', ' ', ''], getline(1, '$'))
+
+ call append('$', ['This is a long sentence', '', 'spanning', 'over several lines. '])
+ $
+ norm! $d(
+ call assert_equal(['With some sentences!', '', ' ', '', 'This is a long sentence', ''], getline(1, '$'))
+
+ " clean up
+ bw!
+endfunc
+
+fun! Test_normal29_brace()
+ " basic test for { and } movements
+ let text= ['A paragraph begins after each empty line, and also at each of a set of',
+ \ 'paragraph macros, specified by the pairs of characters in the ''paragraphs''',
+ \ 'option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to',
+ \ 'the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in',
+ \ 'the first column). A section boundary is also a paragraph boundary.',
+ \ 'Note that a blank line (only containing white space) is NOT a paragraph',
+ \ 'boundary.',
+ \ '',
+ \ '',
+ \ 'Also note that this does not include a ''{'' or ''}'' in the first column. When',
+ \ 'the ''{'' flag is in ''cpoptions'' then ''{'' in the first column is used as a',
+ \ 'paragraph boundary |posix|.',
+ \ '{',
+ \ 'This is no paragaraph',
+ \ 'unless the ''{'' is set',
+ \ 'in ''cpoptions''',
+ \ '}',
+ \ '.IP',
+ \ 'The nroff macros IP seperates a paragraph',
+ \ 'That means, it must be a ''.''',
+ \ 'followed by IP',
+ \ '.LPIt does not matter, if afterwards some',
+ \ 'more characters follow.',
+ \ '.SHAlso section boundaries from the nroff',
+ \ 'macros terminate a paragraph. That means',
+ \ 'a character like this:',
+ \ '.NH',
+ \ 'End of text here']
+ new
+ call append(0, text)
+ 1
+ norm! 0d2}
+ call assert_equal(['.IP',
+ \ 'The nroff macros IP seperates a paragraph', 'That means, it must be a ''.''', 'followed by IP',
+ \ '.LPIt does not matter, if afterwards some', 'more characters follow.', '.SHAlso section boundaries from the nroff',
+ \ 'macros terminate a paragraph. That means', 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
+ norm! 0d}
+ call assert_equal(['.LPIt does not matter, if afterwards some', 'more characters follow.',
+ \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means',
+ \ 'a character like this:', '.NH', 'End of text here', ''], getline(1, '$'))
+ $
+ norm! d{
+ call assert_equal(['.LPIt does not matter, if afterwards some', 'more characters follow.',
+ \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means', 'a character like this:', ''], getline(1, '$'))
+ norm! d{
+ call assert_equal(['.LPIt does not matter, if afterwards some', 'more characters follow.', ''], getline(1,'$'))
+ " Test with { in cpooptions
+ %d
+ call append(0, text)
+ " Nvim: no "{" flag in 'cpoptions'.
+ " set cpo+={
+ " 1
+ " norm! 0d2}
+ " call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}',
+ " \ '.IP', 'The nroff macros IP seperates a paragraph', 'That means, it must be a ''.''',
+ " \ 'followed by IP', '.LPIt does not matter, if afterwards some', 'more characters follow.',
+ " \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means',
+ " \ 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
+ " $
+ " norm! d}
+ " call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}',
+ " \ '.IP', 'The nroff macros IP seperates a paragraph', 'That means, it must be a ''.''',
+ " \ 'followed by IP', '.LPIt does not matter, if afterwards some', 'more characters follow.',
+ " \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means',
+ " \ 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
+ " norm! gg}
+ " norm! d5}
+ " call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', ''], getline(1,'$'))
+
+ " clean up
+ set cpo-={
+ bw!
+endfunc
+
+fun! Test_normal30_changecase()
+ " This test uses multi byte characters
+ if !has("multi_byte")
+ return
+ endif
+ new
+ call append(0, 'This is a simple test: äüöß')
+ norm! 1ggVu
+ call assert_equal('this is a simple test: äüöß', getline('.'))
+ norm! VU
+ call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
+ norm! guu
+ call assert_equal('this is a simple test: äüöss', getline('.'))
+ norm! gUgU
+ call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
+ norm! gugu
+ call assert_equal('this is a simple test: äüöss', getline('.'))
+ norm! gUU
+ call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
+ norm! 010~
+ call assert_equal('this is a SIMPLE TEST: ÄÜÖSS', getline('.'))
+ norm! V~
+ call assert_equal('THIS IS A simple test: äüöss', getline('.'))
+
+ " Turkish ASCII turns to multi-byte. On some systems Turkish locale
+ " is available but toupper()/tolower() don't do the right thing.
+ try
+ lang tr_TR.UTF-8
+ set casemap=
+ let iupper = toupper('i')
+ if iupper == "\u0130"
+ call setline(1, 'iI')
+ 1normal gUU
+ call assert_equal("\u0130I", getline(1))
+ call assert_equal("\u0130I", toupper("iI"))
+
+ call setline(1, 'iI')
+ 1normal guu
+ call assert_equal("i\u0131", getline(1))
+ call assert_equal("i\u0131", tolower("iI"))
+ elseif iupper == "I"
+ call setline(1, 'iI')
+ 1normal gUU
+ call assert_equal("II", getline(1))
+ call assert_equal("II", toupper("iI"))
+
+ call setline(1, 'iI')
+ 1normal guu
+ call assert_equal("ii", getline(1))
+ call assert_equal("ii", tolower("iI"))
+ else
+ call assert_true(false, "expected toupper('i') to be either 'I' or '\u0131'")
+ endif
+ set casemap&
+ call setline(1, 'iI')
+ 1normal gUU
+ call assert_equal("II", getline(1))
+ call assert_equal("II", toupper("iI"))
+
+ call setline(1, 'iI')
+ 1normal guu
+ call assert_equal("ii", getline(1))
+ call assert_equal("ii", tolower("iI"))
+
+ lang en_US.UTF-8
+ catch /E197:/
+ " can't use Turkish locale
+ throw 'Skipped: Turkish locale not available'
+ endtry
+
+ " clean up
+ bw!
+endfunc
+
+fun! Test_normal31_r_cmd()
+ " Test for r command
+ new
+ call append(0, 'This is a simple test: abcd')
+ exe "norm! 1gg$r\<cr>"
+ call assert_equal(['This is a simple test: abc', '', ''], getline(1,'$'))
+ exe "norm! 1gg2wlr\<cr>"
+ call assert_equal(['This is a', 'simple test: abc', '', ''], getline(1,'$'))
+ exe "norm! 2gg0W5r\<cr>"
+ call assert_equal(['This is a', 'simple ', ' abc', '', ''], getline('1', '$'))
+ set autoindent
+ call setline(2, ['simple test: abc', ''])
+ exe "norm! 2gg0W5r\<cr>"
+ call assert_equal(['This is a', 'simple ', 'abc', '', '', ''], getline('1', '$'))
+ exe "norm! 1ggVr\<cr>"
+ call assert_equal('^M^M^M^M^M^M^M^M^M', strtrans(getline(1)))
+ call setline(1, 'This is a')
+ exe "norm! 1gg05rf"
+ call assert_equal('fffffis a', getline(1))
+
+ " clean up
+ set noautoindent
+ bw!
+endfunc
+
+func! Test_normal32_g_cmd1()
+ " Test for g*, g#
+ new
+ call append(0, ['abc.x_foo', 'x_foobar.abc'])
+ 1
+ norm! $g*
+ call assert_equal('x_foo', @/)
+ call assert_equal('x_foobar.abc', getline('.'))
+ norm! $g#
+ call assert_equal('abc', @/)
+ call assert_equal('abc.x_foo', getline('.'))
+
+ " clean up
+ bw!
+endfunc
+
+fun! Test_normal33_g_cmd2()
+ if !has("jumplist")
+ return
+ endif
+ " Tests for g cmds
+ call Setup_NewWindow()
+ " Test for g`
+ clearjumps
+ norm! ma10j
+ let a=execute(':jumps')
+ " empty jumplist
+ call assert_equal('>', a[-1:])
+ norm! g`a
+ call assert_equal('>', a[-1:])
+ call assert_equal(1, line('.'))
+ call assert_equal('1', getline('.'))
+
+ " Test for g; and g,
+ norm! g;
+ " there is only one change in the changelist
+ " currently, when we setup the window
+ call assert_equal(2, line('.'))
+ call assert_fails(':norm! g;', 'E662')
+ call assert_fails(':norm! g,', 'E663')
+ let &ul=&ul
+ call append('$', ['a', 'b', 'c', 'd'])
+ let &ul=&ul
+ call append('$', ['Z', 'Y', 'X', 'W'])
+ let a = execute(':changes')
+ call assert_match('2\s\+0\s\+2', a)
+ call assert_match('101\s\+0\s\+a', a)
+ call assert_match('105\s\+0\s\+Z', a)
+ norm! 3g;
+ call assert_equal(2, line('.'))
+ norm! 2g,
+ call assert_equal(105, line('.'))
+
+ " Test for g& - global substitute
+ %d
+ call setline(1, range(1,10))
+ call append('$', ['a', 'b', 'c', 'd'])
+ $s/\w/&&/g
+ exe "norm! /[1-8]\<cr>"
+ norm! g&
+ call assert_equal(['11', '22', '33', '44', '55', '66', '77', '88', '9', '110', 'a', 'b', 'c', 'dd'], getline(1, '$'))
+
+ " Test for gv
+ %d
+ call append('$', repeat(['abcdefgh'], 8))
+ exe "norm! 2gg02l\<c-v>2j2ly"
+ call assert_equal(['cde', 'cde', 'cde'], getreg(0, 1, 1))
+ " in visual mode, gv swaps current and last selected region
+ exe "norm! G0\<c-v>4k4lgvd"
+ call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh'], getline(1,'$'))
+ exe "norm! G0\<c-v>4k4ly"
+ exe "norm! gvood"
+ call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$'))
+
+ " Test for gk/gj
+ %d
+ 15vsp
+ set wrap listchars= sbr=
+ let lineA='abcdefghijklmnopqrstuvwxyz'
+ let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ $put =lineA
+ $put =lineB
+
+ norm! 3gg0dgk
+ call assert_equal(['', 'abcdefghijklmno', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'], getline(1, '$'))
+ set nu
+ norm! 3gg0gjdgj
+ call assert_equal(['', 'abcdefghijklmno', '0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
+
+ " Test for gJ
+ norm! 2gggJ
+ call assert_equal(['', 'abcdefghijklmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
+ call assert_equal(16, col('.'))
+ " shouldn't do anything
+ norm! 10gJ
+ call assert_equal(1, col('.'))
+
+ " Test for g0 g^ gm g$
+ exe "norm! 2gg0gji "
+ call assert_equal(['', 'abcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
+ norm! g0yl
+ call assert_equal(12, col('.'))
+ call assert_equal(' ', getreg(0))
+ norm! g$yl
+ call assert_equal(22, col('.'))
+ call assert_equal('3', getreg(0))
+ norm! gmyl
+ call assert_equal(17, col('.'))
+ call assert_equal('n', getreg(0))
+ norm! g^yl
+ call assert_equal(15, col('.'))
+ call assert_equal('l', getreg(0))
+
+ " Test for g Ctrl-G
+ set ff=unix
+ let a=execute(":norm! g\<c-g>")
+ call assert_match('Col 15 of 43; Line 2 of 2; Word 2 of 2; Byte 16 of 45', a)
+
+ " Test for gI
+ norm! gIfoo
+ call assert_equal(['', 'fooabcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
+
+ " Test for gi
+ wincmd c
+ %d
+ set tw=0
+ call setline(1, ['foobar', 'new line'])
+ norm! A next word
+ $put ='third line'
+ norm! gi another word
+ call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$'))
+
+ " clean up
+ bw!
+endfunc
+
+fun! Test_normal34_g_cmd3()
+ if !has("multi_byte")
+ return
+ endif
+ " Test for g8
+ new
+ call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
+ let a=execute(':norm! 1gg$g8')
+ call assert_equal('c3 b6 ', a[1:])
+
+ " Test for gp gP
+ call append(1, range(1,10))
+ " clean up
+ bw!
+endfunc
+
+fun! Test_normal35_g_cmd4()
+ " Test for g<
+ " Cannot capture its output,
+ " probably a bug, therefore, test disabled:
+ throw "Skipped: output of g< can't be tested currently"
+ echo "a\nb\nc\nd"
+ let b=execute(':norm! g<')
+ call assert_true(!empty(b), 'failed `execute(g<)`')
+endfunc
+
+fun! Test_normal36_g_cmd5()
+ new
+ call append(0, 'abcdefghijklmnopqrstuvwxyz')
+ set ff=unix
+ " Test for gp gP
+ call append(1, range(1,10))
+ 1
+ norm! 1yy
+ 3
+ norm! gp
+ call assert_equal([0, 5, 1, 0, 1], getcurpos())
+ $
+ norm! gP
+ call assert_equal([0, 14, 1, 0, 1], getcurpos())
+
+ " Test for go
+ norm! 26go
+ call assert_equal([0, 1, 26, 0, 26], getcurpos())
+ norm! 27go
+ call assert_equal([0, 1, 26, 0, 26], getcurpos())
+ norm! 28go
+ call assert_equal([0, 2, 1, 0, 1], getcurpos())
+ set ff=dos
+ norm! 29go
+ call assert_equal([0, 2, 1, 0, 1], getcurpos())
+ set ff=unix
+ norm! gg0
+ norm! 101go
+ call assert_equal([0, 13, 26, 0, 26], getcurpos())
+ norm! 103go
+ call assert_equal([0, 14, 1, 0, 1], getcurpos())
+ " count > buffer content
+ norm! 120go
+ call assert_equal([0, 14, 1, 0, 2147483647], getcurpos())
+ " clean up
+ bw!
+endfunc
+
+fun! Test_normal37_g_cmd6()
+ " basic test for gt and gT
+ tabnew 1.txt
+ tabnew 2.txt
+ tabnew 3.txt
+ norm! 1gt
+ call assert_equal(1, tabpagenr())
+ norm! 3gt
+ call assert_equal(3, tabpagenr())
+ norm! 1gT
+ " count gT goes not to the absolute tabpagenumber
+ " but, but goes to the count previous tabpagenumber
+ call assert_equal(2, tabpagenr())
+ " wrap around
+ norm! 3gT
+ call assert_equal(3, tabpagenr())
+ " gt does not wrap around
+ norm! 5gt
+ call assert_equal(3, tabpagenr())
+
+ for i in range(3)
+ tabclose
+ endfor
+ " clean up
+ call assert_fails(':tabclose', 'E784')
+endfunc
+
+fun! Test_normal38_nvhome()
+ " Test for <Home> and <C-Home> key
+ new
+ call setline(1, range(10))
+ $
+ setl et sw=2
+ norm! V10>$
+ " count is ignored
+ exe "norm! 10\<home>"
+ call assert_equal(1, col('.'))
+ exe "norm! \<home>"
+ call assert_equal([0, 10, 1, 0, 1], getcurpos())
+ exe "norm! 5\<c-home>"
+ call assert_equal([0, 5, 1, 0, 1], getcurpos())
+ exe "norm! \<c-home>"
+ call assert_equal([0, 1, 1, 0, 1], getcurpos())
+
+ " clean up
+ bw!
+endfunc
+
+fun! Test_normal39_cw()
+ " Test for cw and cW on whitespace
+ " and cpo+=w setting
+ new
+ set tw=0
+ call append(0, 'here are some words')
+ norm! 1gg0elcwZZZ
+ call assert_equal('hereZZZare some words', getline('.'))
+ norm! 1gg0elcWYYY
+ call assert_equal('hereZZZareYYYsome words', getline('.'))
+ " Nvim: no "w" flag in 'cpoptions'.
+ " set cpo+=w
+ " call setline(1, 'here are some words')
+ " norm! 1gg0elcwZZZ
+ " call assert_equal('hereZZZ are some words', getline('.'))
+ " norm! 1gg2elcWYYY
+ " call assert_equal('hereZZZ areYYY some words', getline('.'))
+ set cpo-=w
+ norm! 2gg0cwfoo
+ call assert_equal('foo', getline('.'))
+
+ " clean up
+ bw!
+endfunc
+
+fun! Test_normal40_ctrl_bsl()
+ " Basic test for CTRL-\ commands
+ new
+ call append(0, 'here are some words')
+ exe "norm! 1gg0a\<C-\>\<C-N>"
+ call assert_equal('n', mode())
+ call assert_equal(1, col('.'))
+ call assert_equal('', visualmode())
+ exe "norm! 1gg0viw\<C-\>\<C-N>"
+ call assert_equal('n', mode())
+ call assert_equal(4, col('.'))
+ exe "norm! 1gg0a\<C-\>\<C-G>"
+ call assert_equal('n', mode())
+ call assert_equal(1, col('.'))
+ "imap <buffer> , <c-\><c-n>
+ set im
+ exe ":norm! \<c-\>\<c-n>dw"
+ set noim
+ call assert_equal('are some words', getline(1))
+ call assert_false(&insertmode)
+
+ " clean up
+ bw!
+endfunc
+
+fun! Test_normal41_insert_reg()
+ " Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>=
+ " in insert mode
+ new
+ set sts=2 sw=2 ts=8 tw=0
+ call append(0, ["aaa\tbbb\tccc", '', '', ''])
+ let a=getline(1)
+ norm! 2gg0
+ exe "norm! a\<c-r>=a\<cr>"
+ norm! 3gg0
+ exe "norm! a\<c-r>\<c-r>=a\<cr>"
+ norm! 4gg0
+ exe "norm! a\<c-r>\<c-o>=a\<cr>"
+ call assert_equal(['aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', ''], getline(1, '$'))
+
+ " clean up
+ set sts=0 sw=8 ts=8
+ bw!
+endfunc
+
+func! Test_normal42_halfpage()
+ " basic test for Ctrl-D and Ctrl-U
+ call Setup_NewWindow()
+ call assert_equal(5, &scroll)
+ exe "norm! \<c-d>"
+ call assert_equal('6', getline('.'))
+ exe "norm! 2\<c-d>"
+ call assert_equal('8', getline('.'))
+ call assert_equal(2, &scroll)
+ set scroll=5
+ exe "norm! \<c-u>"
+ call assert_equal('3', getline('.'))
+ 1
+ set scrolloff=5
+ exe "norm! \<c-d>"
+ call assert_equal('10', getline('.'))
+ exe "norm! \<c-u>"
+ call assert_equal('5', getline('.'))
+ 1
+ set scrolloff=99
+ exe "norm! \<c-d>"
+ call assert_equal('10', getline('.'))
+ set scrolloff=0
+ 100
+ exe "norm! $\<c-u>"
+ call assert_equal('95', getline('.'))
+ call assert_equal([0, 95, 1, 0, 1], getcurpos())
+ 100
+ set nostartofline
+ exe "norm! $\<c-u>"
+ call assert_equal('95', getline('.'))
+ call assert_equal([0, 95, 2, 0, 2147483647], getcurpos())
+ " cleanup
+ set startofline
+ bw!
+endfunc
+
+fun! Test_normal43_textobject1()
+ " basic tests for text object aw
+ new
+ call append(0, ['foobar,eins,foobar', 'foo,zwei,foo '])
+ " diw
+ norm! 1gg0diw
+ call assert_equal([',eins,foobar', 'foo,zwei,foo ', ''], getline(1,'$'))
+ " daw
+ norm! 2ggEdaw
+ call assert_equal([',eins,foobar', 'foo,zwei,', ''], getline(1, '$'))
+ %d
+ call append(0, ["foo\teins\tfoobar", "foo\tzwei\tfoo "])
+ " diW
+ norm! 2ggwd2iW
+ call assert_equal(['foo eins foobar', 'foo foo ', ''], getline(1,'$'))
+ " daW
+ norm! 1ggd2aW
+ call assert_equal(['foobar', 'foo foo ', ''], getline(1,'$'))
+
+ %d
+ call append(0, ["foo\teins\tfoobar", "foo\tzwei\tfoo "])
+ " aw in visual line mode switches to characterwise mode
+ norm! 2gg$Vawd
+ call assert_equal(['foo eins foobar', 'foo zwei foo'], getline(1,'$'))
+ norm! 1gg$Viwd
+ call assert_equal(['foo eins ', 'foo zwei foo'], getline(1,'$'))
+
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal44_textobjects2()
+ " basic testing for is and as text objects
+ new
+ call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
+ " Test for dis - does not remove trailing whitespace
+ norm! 1gg0dis
+ call assert_equal([' With some sentences!', '', 'Even with a question? And one more. And no sentence here', ''], getline(1,'$'))
+ " Test for das - removes leading whitespace
+ norm! 3ggf?ldas
+ call assert_equal([' With some sentences!', '', 'Even with a question? And no sentence here', ''], getline(1,'$'))
+ " when used in visual mode, is made characterwise
+ norm! 3gg$Visy
+ call assert_equal('v', visualmode())
+ " reset visualmode()
+ norm! 3ggVy
+ norm! 3gg$Vasy
+ call assert_equal('v', visualmode())
+ " basic testing for textobjects a< and at
+ %d
+ call setline(1, ['<div> ','<a href="foobar" class="foo">xyz</a>',' </div>', ' '])
+ " a<
+ norm! 1gg0da<
+ call assert_equal([' ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$'))
+ norm! 1pj
+ call assert_equal([' <div>', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$'))
+ " at
+ norm! d2at
+ call assert_equal([' '], getline(1,'$'))
+ %d
+ call setline(1, ['<div> ','<a href="foobar" class="foo">xyz</a>',' </div>', ' '])
+ " i<
+ norm! 1gg0di<
+ call assert_equal(['<> ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$'))
+ norm! 1Pj
+ call assert_equal(['<div> ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$'))
+ norm! d2it
+ call assert_equal(['<div></div>',' '], getline(1,'$'))
+ " basic testing for a[ and i[ text object
+ %d
+ call setline(1, [' ', '[', 'one [two]', 'thre', ']'])
+ norm! 3gg0di[
+ call assert_equal([' ', '[', ']'], getline(1,'$'))
+ call setline(1, [' ', '[', 'one [two]', 'thre', ']'])
+ norm! 3gg0ftd2a[
+ call assert_equal([' '], getline(1,'$'))
+ %d
+ " Test for i" when cursor is in front of a quoted object
+ call append(0, 'foo "bar"')
+ norm! 1gg0di"
+ call assert_equal(['foo ""', ''], getline(1,'$'))
+
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal45_drop()
+ if !has("dnd")
+ return
+ endif
+ " basic test for :drop command
+ " unfortunately, without a gui, we can't really test much here,
+ " so simply test that ~p fails (which uses the drop register)
+ new
+ call assert_fails(':norm! "~p', 'E353')
+ call assert_equal([], getreg('~', 1, 1))
+ " the ~ register is read only
+ call assert_fails(':let @~="1"', 'E354')
+ bw!
+endfunc
+
+func! Test_normal46_ignore()
+ " This test uses multi byte characters
+ if !has("multi_byte")
+ return
+ endif
+
+ new
+ " How to test this?
+ " let's just for now test, that the buffer
+ " does not change
+ call feedkeys("\<c-s>", 't')
+ call assert_equal([''], getline(1,'$'))
+
+ " no valid commands
+ exe "norm! \<char-0x100>"
+ call assert_equal([''], getline(1,'$'))
+
+ exe "norm! ä"
+ call assert_equal([''], getline(1,'$'))
+
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal47_visual_buf_wipe()
+ " This was causing a crash or ml_get error.
+ enew!
+ call setline(1,'xxx')
+ normal $
+ new
+ call setline(1, range(1,2))
+ 2
+ exe "norm \<C-V>$"
+ bw!
+ norm yp
+ set nomodified
+endfunc
+
+func! Test_normal47_autocmd()
+ " disabled, does not seem to be possible currently
+ throw "Skipped: not possible to test cursorhold autocmd while waiting for input in normal_cmd"
+ new
+ call append(0, repeat('-',20))
+ au CursorHold * call feedkeys('2l', '')
+ 1
+ set updatetime=20
+ " should delete 12 chars (d12l)
+ call feedkeys('d1', '!')
+ call assert_equal('--------', getline(1))
+
+ " clean up
+ au! CursorHold
+ set updatetime=4000
+ bw!
+endfunc
+
+func! Test_normal48_wincmd()
+ new
+ exe "norm! \<c-w>c"
+ call assert_equal(1, winnr('$'))
+ call assert_fails(":norm! \<c-w>c", "E444")
+endfunc
+
+func! Test_normal49_counts()
+ new
+ call setline(1, 'one two three four five six seven eight nine ten')
+ 1
+ norm! 3d2w
+ call assert_equal('seven eight nine ten', getline(1))
+ bw!
+endfunc
+
+func! Test_normal50_commandline()
+ if !has("timers") || !has("cmdline_hist") || !has("vertsplit")
+ return
+ endif
+ func! DoTimerWork(id)
+ call assert_equal('[Command Line]', bufname(''))
+ " should fail, with E11, but does fail with E23?
+ "call feedkeys("\<c-^>", 'tm')
+
+ " should also fail with E11
+ call assert_fails(":wincmd p", 'E11')
+ " return from commandline window
+ call feedkeys("\<cr>")
+ endfunc
+
+ let oldlang=v:lang
+ lang C
+ set updatetime=20
+ call timer_start(100, 'DoTimerWork')
+ try
+ " throws E23, for whatever reason...
+ call feedkeys('q:', 'x!')
+ catch /E23/
+ " no-op
+ endtry
+ " clean up
+ set updatetime=4000
+ exe "lang" oldlang
+ bw!
+endfunc
+
+func! Test_normal51_FileChangedRO()
+ if !has("autocmd")
+ return
+ endif
+ call writefile(['foo'], 'Xreadonly.log')
+ new Xreadonly.log
+ setl ro
+ au FileChangedRO <buffer> :call feedkeys("\<c-^>", 'tix')
+ call assert_fails(":norm! Af", 'E788')
+ call assert_equal(['foo'], getline(1,'$'))
+ call assert_equal('Xreadonly.log', bufname(''))
+
+ " cleanup
+ bw!
+ call delete("Xreadonly.log")
+endfunc
+
+func! Test_normal52_rl()
+ if !has("rightleft")
+ return
+ endif
+ new
+ call setline(1, 'abcde fghij klmnopq')
+ norm! 1gg$
+ set rl
+ call assert_equal(19, col('.'))
+ call feedkeys('l', 'tx')
+ call assert_equal(18, col('.'))
+ call feedkeys('h', 'tx')
+ call assert_equal(19, col('.'))
+ call feedkeys("\<right>", 'tx')
+ call assert_equal(18, col('.'))
+ call feedkeys("\<s-right>", 'tx')
+ call assert_equal(13, col('.'))
+ call feedkeys("\<c-right>", 'tx')
+ call assert_equal(7, col('.'))
+ call feedkeys("\<c-left>", 'tx')
+ call assert_equal(13, col('.'))
+ call feedkeys("\<s-left>", 'tx')
+ call assert_equal(19, col('.'))
+ call feedkeys("<<", 'tx')
+ call assert_equal(' abcde fghij klmnopq',getline(1))
+ call feedkeys(">>", 'tx')
+ call assert_equal('abcde fghij klmnopq',getline(1))
+
+ " cleanup
+ set norl
+ bw!
+endfunc
+
+func! Test_normal53_digraph()
+ if !has('digraphs')
+ return
+ endif
+ new
+ call setline(1, 'abcdefgh|')
+ exe "norm! 1gg0f\<c-k>!!"
+ call assert_equal(9, col('.'))
+ set cpo+=D
+ exe "norm! 1gg0f\<c-k>!!"
+ call assert_equal(1, col('.'))
+
+ set cpo-=D
+ bw!
+endfunc
+
+func! Test_normal54_Ctrl_bsl()
+ new
+ call setline(1, 'abcdefghijklmn')
+ exe "norm! df\<c-\>\<c-n>"
+ call assert_equal(['abcdefghijklmn'], getline(1,'$'))
+ exe "norm! df\<c-\>\<c-g>"
+ call assert_equal(['abcdefghijklmn'], getline(1,'$'))
+ exe "norm! df\<c-\>m"
+ call assert_equal(['abcdefghijklmn'], getline(1,'$'))
+ if !has("multi_byte")
+ return
+ endif
+ call setline(2, 'abcdefghijklmnÄf')
+ norm! 2gg0
+ exe "norm! df\<Char-0x101>"
+ call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
+ norm! 1gg0
+ exe "norm! df\<esc>"
+ call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
+
+ " clean up
+ bw!
+endfunc
diff --git a/src/nvim/testdir/test_partial.vim b/src/nvim/testdir/test_partial.vim
index 3a6e162453..de5c26c2dd 100644
--- a/src/nvim/testdir/test_partial.vim
+++ b/src/nvim/testdir/test_partial.vim
@@ -14,6 +14,14 @@ func MySort(up, one, two)
return a:one < a:two ? 1 : -1
endfunc
+func MyMap(sub, index, val)
+ return a:val - a:sub
+endfunc
+
+func MyFilter(threshold, index, val)
+ return a:val > a:threshold
+endfunc
+
func Test_partial_args()
let Cb = function('MyFunc', ["foo", "bar"])
@@ -36,6 +44,16 @@ func Test_partial_args()
call assert_equal([1, 2, 3], sort([3, 1, 2], Sort))
let Sort = function('MySort', [0])
call assert_equal([3, 2, 1], sort([3, 1, 2], Sort))
+
+ let Map = function('MyMap', [2])
+ call assert_equal([-1, 0, 1], map([1, 2, 3], Map))
+ let Map = function('MyMap', [3])
+ call assert_equal([-2, -1, 0], map([1, 2, 3], Map))
+
+ let Filter = function('MyFilter', [1])
+ call assert_equal([2, 3], filter([1, 2, 3], Filter))
+ let Filter = function('MyFilter', [2])
+ call assert_equal([3], filter([1, 2, 3], Filter))
endfunc
func MyDictFunc(arg1, arg2) dict
@@ -59,6 +77,9 @@ func Test_partial_dict()
call assert_equal("hello/xxx/yyy", Cb("xxx", "yyy"))
call assert_fails('Cb("fff")', 'E492:')
+ let Cb = function('MyDictFunc', dict)
+ call assert_equal({"foo": "hello/foo/1", "bar": "hello/bar/2"}, map({"foo": 1, "bar": 2}, Cb))
+
let dict = {"tr": function('tr', ['hello', 'h', 'H'])}
call assert_equal("Hello", dict.tr())
endfunc
diff --git a/src/nvim/testdir/test_popup.vim b/src/nvim/testdir/test_popup.vim
index 50110dd622..e1ba142d1c 100644
--- a/src/nvim/testdir/test_popup.vim
+++ b/src/nvim/testdir/test_popup.vim
@@ -7,10 +7,10 @@ func! ListMonths()
if g:setting != ''
exe ":set" g:setting
endif
- let mth=copy(g:months)
+ let mth = copy(g:months)
let entered = strcharpart(getline('.'),0,col('.'))
if !empty(entered)
- let mth=filter(mth, 'v:val=~"^".entered')
+ let mth = filter(mth, 'v:val=~"^".entered')
endif
call complete(1, mth)
return ''
@@ -468,7 +468,7 @@ endfunc
" auto-wrap text.
func Test_completion_ctrl_e_without_autowrap()
new
- let tw_save=&tw
+ let tw_save = &tw
set tw=78
let li = [
\ '" zzz',
@@ -478,8 +478,96 @@ func Test_completion_ctrl_e_without_autowrap()
call feedkeys("A\<C-X>\<C-N>\<C-E>\<Esc>", "tx")
call assert_equal(li, getline(1, '$'))
- let &tw=tw_save
+ let &tw = tw_save
q!
endfunc
+func Test_completion_respect_bs_option()
+ new
+ let li = ["aaa", "aaa12345", "aaaabcdef", "aaaABC"]
+
+ set bs=indent,eol
+ call setline(1, li)
+ 1
+ call feedkeys("A\<C-X>\<C-N>\<C-P>\<BS>\<BS>\<BS>\<Esc>", "tx")
+ call assert_equal('aaa', getline(1))
+
+ %d
+ set bs=indent,eol,start
+ call setline(1, li)
+ 1
+ call feedkeys("A\<C-X>\<C-N>\<C-P>\<BS>\<BS>\<BS>\<Esc>", "tx")
+ call assert_equal('', getline(1))
+
+ bw!
+endfunc
+
+func CompleteUndo() abort
+ call complete(1, g:months)
+ return ''
+endfunc
+
+func Test_completion_can_undo()
+ inoremap <Right> <c-r>=CompleteUndo()<cr>
+ set completeopt+=noinsert,noselect
+
+ new
+ call feedkeys("a\<Right>a\<Esc>", 'xt')
+ call assert_equal('a', getline(1))
+ undo
+ call assert_equal('', getline(1))
+
+ bwipe!
+ set completeopt&
+ iunmap <Right>
+endfunc
+
+func Test_completion_comment_formatting()
+ new
+ setl formatoptions=tcqro
+ call feedkeys("o/*\<cr>\<cr>/\<esc>", 'tx')
+ call assert_equal(['', '/*', ' *', ' */'], getline(1,4))
+ %d
+ call feedkeys("o/*\<cr>foobar\<cr>/\<esc>", 'tx')
+ call assert_equal(['', '/*', ' * foobar', ' */'], getline(1,4))
+ %d
+ try
+ call feedkeys("o/*\<cr>\<cr>\<c-x>\<c-u>/\<esc>", 'tx')
+ call assert_report('completefunc not set, should have failed')
+ catch
+ call assert_exception('E764:')
+ endtry
+ call assert_equal(['', '/*', ' *', ' */'], getline(1,4))
+ bwipe!
+endfunc
+
+function! DummyCompleteSix()
+ call complete(1, ['Hello', 'World'])
+ return ''
+endfunction
+
+" complete() correctly clears the list of autocomplete candidates
+func Test_completion_clear_candidate_list()
+ new
+ %d
+ " select first entry from the completion popup
+ call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>", "tx")
+ call assert_equal('Hello', getline(1))
+ %d
+ " select second entry from the completion popup
+ call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>", "tx")
+ call assert_equal('World', getline(1))
+ %d
+ " select original text
+ call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>", "tx")
+ call assert_equal(' xxx', getline(1))
+ %d
+ " back at first entry from completion list
+ call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>\<C-N>", "tx")
+ call assert_equal('Hello', getline(1))
+
+ bw!
+endfunc
+
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim
index f30902b915..aff5fc2eed 100644
--- a/src/nvim/testdir/test_quickfix.vim
+++ b/src/nvim/testdir/test_quickfix.vim
@@ -6,7 +6,7 @@ endif
set encoding=utf-8
-function! s:setup_commands(cchar)
+func s:setup_commands(cchar)
if a:cchar == 'c'
command! -nargs=* -bang Xlist <mods>clist<bang> <args>
command! -nargs=* Xgetexpr <mods>cgetexpr <args>
@@ -68,10 +68,10 @@ function! s:setup_commands(cchar)
let g:Xgetlist = function('getloclist', [0])
let g:Xsetlist = function('setloclist', [0])
endif
-endfunction
+endfunc
" Tests for the :clist and :llist commands
-function XlistTests(cchar)
+func XlistTests(cchar)
call s:setup_commands(a:cchar)
" With an empty list, command should return error
@@ -128,17 +128,17 @@ function XlistTests(cchar)
let l = split(result, "\n")
call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
\ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
-endfunction
+endfunc
-function Test_clist()
+func Test_clist()
call XlistTests('c')
call XlistTests('l')
-endfunction
+endfunc
" Tests for the :colder, :cnewer, :lolder and :lnewer commands
" Note that this test assumes that a quickfix/location list is
" already set by the caller.
-function XageTests(cchar)
+func XageTests(cchar)
call s:setup_commands(a:cchar)
" Jumping to a non existent list should return error
@@ -171,20 +171,20 @@ function XageTests(cchar)
Xnewer 2
let l = g:Xgetlist()
call assert_equal('Line3', l[0].text)
-endfunction
+endfunc
-function Test_cage()
+func Test_cage()
let list = [{'bufnr': 1, 'lnum': 1}]
call setqflist(list)
call XageTests('c')
call setloclist(0, list)
call XageTests('l')
-endfunction
+endfunc
" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
" commands
-function XwindowTests(cchar)
+func XwindowTests(cchar)
call s:setup_commands(a:cchar)
" Create a list with no valid entries
@@ -227,16 +227,16 @@ function XwindowTests(cchar)
" Calling cwindow should close the quickfix window with no valid errors
Xwindow
call assert_true(winnr('$') == 1)
-endfunction
+endfunc
-function Test_cwindow()
+func Test_cwindow()
call XwindowTests('c')
call XwindowTests('l')
-endfunction
+endfunc
" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
" commands.
-function XfileTests(cchar)
+func XfileTests(cchar)
call s:setup_commands(a:cchar)
call writefile(['Xtestfile1:700:10:Line 700',
@@ -275,16 +275,16 @@ function XfileTests(cchar)
\ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
call delete('Xqftestfile1')
-endfunction
+endfunc
-function Test_cfile()
+func Test_cfile()
call XfileTests('c')
call XfileTests('l')
-endfunction
+endfunc
" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
" :lgetbuffer commands.
-function XbufferTests(cchar)
+func XbufferTests(cchar)
call s:setup_commands(a:cchar)
enew!
@@ -316,26 +316,26 @@ function XbufferTests(cchar)
\ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
enew!
-endfunction
+endfunc
-function Test_cbuffer()
+func Test_cbuffer()
call XbufferTests('c')
call XbufferTests('l')
-endfunction
+endfunc
-function XexprTests(cchar)
+func XexprTests(cchar)
call s:setup_commands(a:cchar)
call assert_fails('Xexpr 10', 'E777:')
-endfunction
+endfunc
-function Test_cexpr()
+func Test_cexpr()
call XexprTests('c')
call XexprTests('l')
-endfunction
+endfunc
" Tests for :cnext, :cprev, :cfirst, :clast commands
-function Xtest_browse(cchar)
+func Xtest_browse(cchar)
call s:setup_commands(a:cchar)
call s:create_test_file('Xqftestfile1')
@@ -366,14 +366,14 @@ function Xtest_browse(cchar)
call delete('Xqftestfile1')
call delete('Xqftestfile2')
-endfunction
+endfunc
-function Test_browse()
+func Test_browse()
call Xtest_browse('c')
call Xtest_browse('l')
-endfunction
+endfunc
-function! s:test_xhelpgrep(cchar)
+func s:test_xhelpgrep(cchar)
call s:setup_commands(a:cchar)
Xhelpgrep quickfix
Xopen
@@ -385,10 +385,11 @@ function! s:test_xhelpgrep(cchar)
call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
" This wipes out the buffer, make sure that doesn't cause trouble.
Xclose
-endfunction
+endfunc
-function Test_helpgrep()
+func Test_helpgrep()
call s:test_xhelpgrep('c')
+ helpclose
call s:test_xhelpgrep('l')
endfunc
@@ -424,7 +425,7 @@ func Test_vimgreptitle()
augroup! QfBufWinEnter
endfunc
-function XqfTitleTests(cchar)
+func XqfTitleTests(cchar)
call s:setup_commands(a:cchar)
Xgetexpr ['file:1:1:message']
@@ -443,16 +444,16 @@ function XqfTitleTests(cchar)
endif
call assert_equal(title, w:quickfix_title)
Xclose
-endfunction
+endfunc
" Tests for quickfix window's title
-function Test_qf_title()
+func Test_qf_title()
call XqfTitleTests('c')
call XqfTitleTests('l')
-endfunction
+endfunc
" Tests for 'errorformat'
-function Test_efm()
+func Test_efm()
let save_efm = &efm
set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
cgetexpr ['WWWW', 'EEEE', 'CCCC']
@@ -465,7 +466,7 @@ function Test_efm()
let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
let &efm = save_efm
-endfunction
+endfunc
" This will test for problems in quickfix:
" A. incorrectly copying location lists which caused the location list to show
@@ -476,7 +477,7 @@ endfunction
" window it belongs to.
"
" Set up the test environment:
-function! ReadTestProtocol(name)
+func ReadTestProtocol(name)
let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
let word = substitute(base, '\v(.*)\..*', '\1', '')
@@ -495,9 +496,9 @@ function! ReadTestProtocol(name)
setl nomodifiable
setl readonly
exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
-endfunction
+endfunc
-function Test_locationlist()
+func Test_locationlist()
enew
augroup testgroup
@@ -577,15 +578,15 @@ function Test_locationlist()
wincmd n | only
augroup! testgroup
-endfunction
+ endfunc
-function Test_locationlist_curwin_was_closed()
+func Test_locationlist_curwin_was_closed()
augroup testgroup
au!
autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
augroup END
- function! R(n)
+ func! R(n)
quit
endfunc
@@ -596,10 +597,26 @@ function Test_locationlist_curwin_was_closed()
call assert_fails('lrewind', 'E924:')
augroup! testgroup
-endfunction
+ endfunc
+
+func Test_locationlist_cross_tab_jump()
+ call writefile(['loclistfoo'], 'loclistfoo')
+ call writefile(['loclistbar'], 'loclistbar')
+ set switchbuf=usetab
+
+ edit loclistfoo
+ tabedit loclistbar
+ silent lgrep loclistfoo loclist*
+ call assert_equal(1, tabpagenr())
+
+ enew | only | tabonly
+ set switchbuf&vim
+ call delete('loclistfoo')
+ call delete('loclistbar')
+endfunc
" More tests for 'errorformat'
-function! Test_efm1()
+func Test_efm1()
if !has('unix')
" The 'errorformat' setting is different on non-Unix systems.
" This test works only on Unix-like systems.
@@ -717,10 +734,10 @@ function! Test_efm1()
call delete('Xerrorfile1')
call delete('Xerrorfile2')
call delete('Xtestfile')
-endfunction
+ endfunc
" Test for quickfix directory stack support
-function! s:dir_stack_tests(cchar)
+func s:dir_stack_tests(cchar)
call s:setup_commands(a:cchar)
let save_efm=&efm
@@ -762,10 +779,10 @@ function! s:dir_stack_tests(cchar)
call assert_equal(5, qf[11].lnum)
let &efm=save_efm
-endfunction
+endfunc
" Tests for %D and %X errorformat options
-function! Test_efm_dirstack()
+func Test_efm_dirstack()
" Create the directory stack and files
call mkdir('dir1')
call mkdir('dir1/a')
@@ -797,10 +814,33 @@ function! Test_efm_dirstack()
call delete('dir1', 'rf')
call delete('dir2', 'rf')
call delete('habits1.txt')
-endfunction
+endfunc
+
+" Test for resync after continuing an ignored message
+func Xefm_ignore_continuations(cchar)
+ call s:setup_commands(a:cchar)
+
+ let save_efm = &efm
+
+ let &efm =
+ \ '%Eerror %m %l,' .
+ \ '%-Wignored %m %l,' .
+ \ '%+Cmore ignored %m %l,' .
+ \ '%Zignored end'
+ Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
+ let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
+ call assert_equal([['resync', 1, 4, 'E']], l)
+
+ let &efm = save_efm
+endfunc
+
+func Test_efm_ignore_continuations()
+ call Xefm_ignore_continuations('c')
+ call Xefm_ignore_continuations('l')
+endfunc
" Tests for invalid error format specifies
-function Xinvalid_efm_Tests(cchar)
+func Xinvalid_efm_Tests(cchar)
call s:setup_commands(a:cchar)
let save_efm = &efm
@@ -833,17 +873,17 @@ function Xinvalid_efm_Tests(cchar)
call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
let &efm = save_efm
-endfunction
+endfunc
-function Test_invalid_efm()
+func Test_invalid_efm()
call Xinvalid_efm_Tests('c')
call Xinvalid_efm_Tests('l')
-endfunction
+endfunc
" TODO:
" Add tests for the following formats in 'errorformat'
" %r %O
-function! Test_efm2()
+func Test_efm2()
let save_efm = &efm
" Test for %s format in efm
@@ -904,20 +944,44 @@ function! Test_efm2()
call assert_equal('E', l[0].type)
call assert_equal("\nunknown variable 'i'", l[0].text)
+ " Test for %A, %C and other formats
+ let lines = [
+ \"==============================================================",
+ \"FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)",
+ \"--------------------------------------------------------------",
+ \"Traceback (most recent call last):",
+ \' File "unittests/dbfacadeTest.py", line 89, in testFoo',
+ \" self.assertEquals(34, dtid)",
+ \' File "/usr/lib/python2.2/unittest.py", line 286, in',
+ \" failUnlessEqual",
+ \" raise self.failureException, \\",
+ \"AssertionError: 34 != 33",
+ \"",
+ \"--------------------------------------------------------------",
+ \"Ran 27 tests in 0.063s"
+ \]
+ set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m
+ cgetexpr lines
+ let l = getqflist()
+ call assert_equal(8, len(l))
+ call assert_equal(89, l[4].lnum)
+ call assert_equal(1, l[4].valid)
+ call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
+
let &efm = save_efm
-endfunction
+endfunc
-function XquickfixChangedByAutocmd(cchar)
+func XquickfixChangedByAutocmd(cchar)
call s:setup_commands(a:cchar)
if a:cchar == 'c'
let ErrorNr = 'E925'
- function! ReadFunc()
+ func! ReadFunc()
colder
cgetexpr []
endfunc
else
let ErrorNr = 'E926'
- function! ReadFunc()
+ func! ReadFunc()
lolder
lgetexpr []
endfunc
@@ -940,10 +1004,10 @@ function XquickfixChangedByAutocmd(cchar)
augroup! testgroup
endfunc
-function Test_quickfix_was_changed_by_autocmd()
+func Test_quickfix_was_changed_by_autocmd()
call XquickfixChangedByAutocmd('c')
call XquickfixChangedByAutocmd('l')
-endfunction
+endfunc
func Test_caddbuffer_to_empty()
helpgr quickfix
@@ -965,7 +1029,7 @@ func Test_cgetexpr_works()
endfunc
" Tests for the setqflist() and setloclist() functions
-function SetXlistTests(cchar, bnum)
+func SetXlistTests(cchar, bnum)
call s:setup_commands(a:cchar)
call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
@@ -1000,9 +1064,9 @@ function SetXlistTests(cchar, bnum)
call g:Xsetlist([])
let l = g:Xgetlist()
call assert_equal(0, len(l))
-endfunction
+endfunc
-function Test_setqflist()
+func Test_setqflist()
new Xtestfile | only
let bnum = bufnr('%')
call setline(1, range(1,5))
@@ -1012,9 +1076,9 @@ function Test_setqflist()
enew!
call delete('Xtestfile')
-endfunction
+endfunc
-function Xlist_empty_middle(cchar)
+func Xlist_empty_middle(cchar)
call s:setup_commands(a:cchar)
" create three quickfix lists
@@ -1037,12 +1101,12 @@ function Xlist_empty_middle(cchar)
call assert_equal(matchlen, len(g:Xgetlist()))
endfunc
-function Test_setqflist_empty_middle()
+func Test_setqflist_empty_middle()
call Xlist_empty_middle('c')
call Xlist_empty_middle('l')
-endfunction
+endfunc
-function Xlist_empty_older(cchar)
+func Xlist_empty_older(cchar)
call s:setup_commands(a:cchar)
" create three quickfix lists
@@ -1063,14 +1127,14 @@ function Xlist_empty_older(cchar)
call assert_equal(twolen, len(g:Xgetlist()))
Xnewer
call assert_equal(threelen, len(g:Xgetlist()))
-endfunction
+endfunc
-function Test_setqflist_empty_older()
+func Test_setqflist_empty_older()
call Xlist_empty_older('c')
call Xlist_empty_older('l')
-endfunction
+endfunc
-function! XquickfixSetListWithAct(cchar)
+func XquickfixSetListWithAct(cchar)
call s:setup_commands(a:cchar)
let list1 = [{'filename': 'fnameA', 'text': 'A'},
@@ -1144,12 +1208,12 @@ function! XquickfixSetListWithAct(cchar)
call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
endfunc
-function Test_quickfix_set_list_with_act()
+func Test_quickfix_set_list_with_act()
call XquickfixSetListWithAct('c')
call XquickfixSetListWithAct('l')
-endfunction
+endfunc
-function XLongLinesTests(cchar)
+func XLongLinesTests(cchar)
let l = g:Xgetlist()
call assert_equal(4, len(l))
@@ -1167,9 +1231,9 @@ function XLongLinesTests(cchar)
call assert_equal(10, len(l[3].text))
call g:Xsetlist([], 'r')
-endfunction
+endfunc
-function s:long_lines_tests(cchar)
+func s:long_lines_tests(cchar)
call s:setup_commands(a:cchar)
let testfile = 'samples/quickfix.txt'
@@ -1190,22 +1254,22 @@ function s:long_lines_tests(cchar)
exe 'edit' testfile
exe 'Xbuffer' bufnr('%')
call XLongLinesTests(a:cchar)
-endfunction
+endfunc
-function Test_long_lines()
+func Test_long_lines()
call s:long_lines_tests('c')
call s:long_lines_tests('l')
-endfunction
+endfunc
-function! s:create_test_file(filename)
+func s:create_test_file(filename)
let l = []
for i in range(1, 20)
call add(l, 'Line' . i)
endfor
call writefile(l, a:filename)
-endfunction
+endfunc
-function! Test_switchbuf()
+func Test_switchbuf()
call s:create_test_file('Xqftestfile1')
call s:create_test_file('Xqftestfile2')
call s:create_test_file('Xqftestfile3')
@@ -1292,20 +1356,21 @@ function! Test_switchbuf()
call delete('Xqftestfile1')
call delete('Xqftestfile2')
call delete('Xqftestfile3')
-endfunction
+endfunc
-function! Xadjust_qflnum(cchar)
+func Xadjust_qflnum(cchar)
call s:setup_commands(a:cchar)
enew | only
- call s:create_test_file('Xqftestfile')
- edit Xqftestfile
+ let fname = 'Xqftestfile' . a:cchar
+ call s:create_test_file(fname)
+ exe 'edit ' . fname
- Xgetexpr ['Xqftestfile:5:Line5',
- \ 'Xqftestfile:10:Line10',
- \ 'Xqftestfile:15:Line15',
- \ 'Xqftestfile:20:Line20']
+ Xgetexpr [fname . ':5:Line5',
+ \ fname . ':10:Line10',
+ \ fname . ':15:Line15',
+ \ fname . ':20:Line20']
6,14delete
call append(6, ['Buffer', 'Window'])
@@ -1317,16 +1382,18 @@ function! Xadjust_qflnum(cchar)
call assert_equal(13, l[3].lnum)
enew!
- call delete('Xqftestfile')
-endfunction
+ call delete(fname)
+endfunc
-function! Test_adjust_lnum()
+func Test_adjust_lnum()
+ call setloclist(0, [])
call Xadjust_qflnum('c')
+ call setqflist([])
call Xadjust_qflnum('l')
-endfunction
+endfunc
" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
-function! s:test_xgrep(cchar)
+func s:test_xgrep(cchar)
call s:setup_commands(a:cchar)
" The following lines are used for the grep test. Don't remove.
@@ -1345,9 +1412,9 @@ function! s:test_xgrep(cchar)
set makeef=Temp_File_##
silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
call assert_true(len(g:Xgetlist()) == 6)
-endfunction
+endfunc
-function! Test_grep()
+func Test_grep()
if !has('unix')
" The grepprg may not be set on non-Unix systems
return
@@ -1355,9 +1422,9 @@ function! Test_grep()
call s:test_xgrep('c')
call s:test_xgrep('l')
-endfunction
+endfunc
-function! Test_two_windows()
+func Test_two_windows()
" Use one 'errorformat' for two windows. Add an expression to each of them,
" make sure they each keep their own state.
set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
@@ -1383,12 +1450,10 @@ function! Test_two_windows()
laddexpr 'one.txt:3:one one one'
let loc_one = getloclist(one_id)
-echo string(loc_one)
call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
call assert_equal(3, loc_one[1].lnum)
let loc_two = getloclist(two_id)
-echo string(loc_two)
call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
call assert_equal(5, loc_two[1].lnum)
@@ -1400,7 +1465,7 @@ echo string(loc_two)
call delete('Xtwo', 'rf')
endfunc
-function XbottomTests(cchar)
+func XbottomTests(cchar)
call s:setup_commands(a:cchar)
call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
@@ -1416,7 +1481,195 @@ function XbottomTests(cchar)
endfunc
" Tests for the :cbottom and :lbottom commands
-function Test_cbottom()
+func Test_cbottom()
call XbottomTests('c')
call XbottomTests('l')
-endfunction
+endfunc
+
+func HistoryTest(cchar)
+ call s:setup_commands(a:cchar)
+
+ call assert_fails(a:cchar . 'older 99', 'E380:')
+ " clear all lists after the first one, then replace the first one.
+ call g:Xsetlist([])
+ Xolder
+ let entry = {'filename': 'foo', 'lnum': 42}
+ call g:Xsetlist([entry], 'r')
+ call g:Xsetlist([entry, entry])
+ call g:Xsetlist([entry, entry, entry])
+ let res = split(execute(a:cchar . 'hist'), "\n")
+ call assert_equal(3, len(res))
+ let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
+ call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
+ call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
+ call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
+endfunc
+
+func Test_history()
+ call HistoryTest('c')
+ call HistoryTest('l')
+endfunc
+
+func Test_duplicate_buf()
+ " make sure we can get the highest buffer number
+ edit DoesNotExist
+ edit DoesNotExist2
+ let last_buffer = bufnr("$")
+
+ " make sure only one buffer is created
+ call writefile(['this one', 'that one'], 'Xgrepthis')
+ vimgrep one Xgrepthis
+ vimgrep one Xgrepthis
+ call assert_equal(last_buffer + 1, bufnr("$"))
+
+ call delete('Xgrepthis')
+endfunc
+
+" Quickfix/Location list set/get properties tests
+func Xproperty_tests(cchar)
+ call s:setup_commands(a:cchar)
+
+ " Error cases
+ call assert_fails('call g:Xgetlist(99)', 'E715:')
+ call assert_fails('call g:Xsetlist(99)', 'E714:')
+ call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
+
+ " Set and get the title
+ Xopen
+ wincmd p
+ call g:Xsetlist([{'filename':'foo', 'lnum':27}])
+ call g:Xsetlist([], 'a', {'title' : 'Sample'})
+ let d = g:Xgetlist({"title":1})
+ call assert_equal('Sample', d.title)
+
+ Xopen
+ call assert_equal('Sample', w:quickfix_title)
+ Xclose
+
+ " Tests for action argument
+ silent! Xolder 999
+ let qfnr = g:Xgetlist({'all':1}).nr
+ call g:Xsetlist([], 'r', {'title' : 'N1'})
+ call assert_equal('N1', g:Xgetlist({'all':1}).title)
+ call g:Xsetlist([], ' ', {'title' : 'N2'})
+ call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
+
+ let res = g:Xgetlist({'nr': 0})
+ call assert_equal(qfnr + 1, res.nr)
+ call assert_equal(['nr'], keys(res))
+
+ call g:Xsetlist([], ' ', {'title' : 'N3'})
+ call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
+
+ " Invalid arguments
+ call assert_fails('call g:Xgetlist([])', 'E715')
+ call assert_fails('call g:Xsetlist([], "a", [])', 'E715')
+ let s = g:Xsetlist([], 'a', {'abc':1})
+ call assert_equal(-1, s)
+
+ call assert_equal({}, g:Xgetlist({'abc':1}))
+
+ if a:cchar == 'l'
+ call assert_equal({}, getloclist(99, {'title': 1}))
+ endif
+ endfunc
+
+func Test_qf_property()
+ call Xproperty_tests('c')
+ call Xproperty_tests('l')
+ endfunc
+
+" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
+func QfAutoCmdHandler(loc, cmd)
+ call add(g:acmds, a:loc . a:cmd)
+endfunc
+
+func Test_Autocmd()
+ autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
+ autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
+
+ let g:acmds = []
+ cexpr "F1:10:Line 10"
+ caddexpr "F1:20:Line 20"
+ cgetexpr "F1:30:Line 30"
+ enew! | call append(0, "F2:10:Line 10")
+ cbuffer!
+ enew! | call append(0, "F2:20:Line 20")
+ cgetbuffer
+ enew! | call append(0, "F2:30:Line 30")
+ caddbuffer
+
+ let l = ['precexpr',
+ \ 'postcexpr',
+ \ 'precaddexpr',
+ \ 'postcaddexpr',
+ \ 'precgetexpr',
+ \ 'postcgetexpr',
+ \ 'precbuffer',
+ \ 'postcbuffer',
+ \ 'precgetbuffer',
+ \ 'postcgetbuffer',
+ \ 'precaddbuffer',
+ \ 'postcaddbuffer']
+ call assert_equal(l, g:acmds)
+endfunc
+
+func Test_Autocmd_Exception()
+ set efm=%m
+ lgetexpr '?'
+
+ try
+ call DoesNotExit()
+ catch
+ lgetexpr '1'
+ finally
+ lgetexpr '1'
+ endtry
+
+ call assert_equal('1', getloclist(0)[0].text)
+
+ set efm&vim
+endfunc
+
+func Test_caddbuffer_wrong()
+ " This used to cause a memory access in freed memory.
+ let save_efm = &efm
+ set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
+ cgetexpr ['WWWW', 'EEEE', 'CCCC']
+ let &efm = save_efm
+ caddbuffer
+ bwipe!
+endfunc
+
+func Test_caddexpr_wrong()
+ " This used to cause a memory access in freed memory.
+ cbuffer
+ cbuffer
+ copen
+ let save_efm = &efm
+ set efm=%
+ call assert_fails('caddexpr ""', 'E376:')
+ let &efm = save_efm
+endfunc
+
+func Test_dirstack_cleanup()
+ " This used to cause a memory access in freed memory.
+ let save_efm = &efm
+ lexpr '0'
+ lopen
+ fun X(c)
+ let save_efm=&efm
+ set efm=%D%f
+ if a:c == 'c'
+ caddexpr '::'
+ else
+ laddexpr ':0:0'
+ endif
+ let &efm=save_efm
+ endfun
+ call X('c')
+ call X('l')
+ call setqflist([], 'r')
+ caddbuffer
+ let &efm = save_efm
+endfunc
diff --git a/src/nvim/testdir/test_regexp_utf8.vim b/src/nvim/testdir/test_regexp_utf8.vim
index ecb03a0f8c..a2f4286d4f 100644
--- a/src/nvim/testdir/test_regexp_utf8.vim
+++ b/src/nvim/testdir/test_regexp_utf8.vim
@@ -31,6 +31,65 @@ func Test_equivalence_re2()
set re=0
endfunc
+func s:classes_test()
+ set isprint=@,161-255
+ call assert_equal('Motörhead', matchstr('Motörhead', '[[:print:]]\+'))
+
+ let alphachars = ''
+ let lowerchars = ''
+ let upperchars = ''
+ let alnumchars = ''
+ let printchars = ''
+ let punctchars = ''
+ let xdigitchars = ''
+ let i = 1
+ while i <= 255
+ let c = nr2char(i)
+ if c =~ '[[:alpha:]]'
+ let alphachars .= c
+ endif
+ if c =~ '[[:lower:]]'
+ let lowerchars .= c
+ endif
+ if c =~ '[[:upper:]]'
+ let upperchars .= c
+ endif
+ if c =~ '[[:alnum:]]'
+ let alnumchars .= c
+ endif
+ if c =~ '[[:print:]]'
+ let printchars .= c
+ endif
+ if c =~ '[[:punct:]]'
+ let punctchars .= c
+ endif
+ if c =~ '[[:xdigit:]]'
+ let xdigitchars .= c
+ endif
+ let i += 1
+ endwhile
+
+ call assert_equal('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', alphachars)
+ call assert_equal('abcdefghijklmnopqrstuvwxyzµßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ', lowerchars)
+ call assert_equal('ABCDEFGHIJKLMNOPQRSTUVWXYZÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖØÙÚÛÜÃÞ', upperchars)
+ call assert_equal('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', alnumchars)
+ call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖרÙÚÛÜÃÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ', printchars)
+ call assert_equal('!"#$%&''()*+,-./:;<=>?@[\]^_`{|}~', punctchars)
+ call assert_equal('0123456789ABCDEFabcdef', xdigitchars)
+endfunc
+
+func Test_classes_re1()
+ set re=1
+ call s:classes_test()
+ set re=0
+endfunc
+
+func Test_classes_re2()
+ set re=2
+ call s:classes_test()
+ set re=0
+endfunc
+
func Test_recursive_substitute()
new
s/^/\=execute("s#^##gn")
@@ -38,3 +97,27 @@ func Test_recursive_substitute()
call setwinvar(1, 'myvar', 1)
bwipe!
endfunc
+
+func Test_nested_backrefs()
+ " Check example in change.txt.
+ new
+ for re in range(0, 2)
+ exe 'set re=' . re
+ call setline(1, 'aa ab x')
+ 1s/\(\(a[a-d] \)*\)\(x\)/-\1- -\2- -\3-/
+ call assert_equal('-aa ab - -ab - -x-', getline(1))
+
+ call assert_equal('-aa ab - -ab - -x-', substitute('aa ab x', '\(\(a[a-d] \)*\)\(x\)', '-\1- -\2- -\3-', ''))
+ endfor
+ bwipe!
+ set re=0
+endfunc
+
+func Test_eow_with_optional()
+ let expected = ['abc def', 'abc', 'def', '', '', '', '', '', '', '']
+ for re in range(0, 2)
+ exe 'set re=' . re
+ let actual = matchlist('abc def', '\(abc\>\)\?\s*\(def\)')
+ call assert_equal(expected, actual)
+ endfor
+endfunc
diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim
new file mode 100644
index 0000000000..a333e7f206
--- /dev/null
+++ b/src/nvim/testdir/test_search.vim
@@ -0,0 +1,300 @@
+" Test for the search command
+
+func Test_search_cmdline()
+ " See test/functional/legacy/search_spec.lua
+ throw 'skipped: Nvim does not support test_disable_char_avail()'
+ if !exists('+incsearch')
+ return
+ endif
+ " need to disable char_avail,
+ " so that expansion of commandline works
+ call test_disable_char_avail(1)
+ new
+ call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar'])
+ " Test 1
+ " CTRL-N / CTRL-P skips through the previous search history
+ set noincsearch
+ :1
+ call feedkeys("/foobar\<cr>", 'tx')
+ call feedkeys("/the\<cr>",'tx')
+ call assert_equal('the', @/)
+ call feedkeys("/thes\<C-P>\<C-P>\<cr>",'tx')
+ call assert_equal('foobar', @/)
+
+ " Test 2
+ " Ctrl-G goes from one match to the next
+ " until the end of the buffer
+ set incsearch nowrapscan
+ :1
+ " first match
+ call feedkeys("/the\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ :1
+ " second match
+ call feedkeys("/the\<C-G>\<cr>", 'tx')
+ call assert_equal(' 3 the', getline('.'))
+ call assert_equal([0, 0, 0, 0], getpos('"'))
+ :1
+ " third match
+ call feedkeys("/the".repeat("\<C-G>", 2)."\<cr>", 'tx')
+ call assert_equal(' 4 their', getline('.'))
+ :1
+ " fourth match
+ call feedkeys("/the".repeat("\<C-G>", 3)."\<cr>", 'tx')
+ call assert_equal(' 5 there', getline('.'))
+ :1
+ " fifth match
+ call feedkeys("/the".repeat("\<C-G>", 4)."\<cr>", 'tx')
+ call assert_equal(' 6 their', getline('.'))
+ :1
+ " sixth match
+ call feedkeys("/the".repeat("\<C-G>", 5)."\<cr>", 'tx')
+ call assert_equal(' 7 the', getline('.'))
+ :1
+ " seventh match
+ call feedkeys("/the".repeat("\<C-G>", 6)."\<cr>", 'tx')
+ call assert_equal(' 8 them', getline('.'))
+ :1
+ " eigth match
+ call feedkeys("/the".repeat("\<C-G>", 7)."\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+ :1
+ " no further match
+ call feedkeys("/the".repeat("\<C-G>", 8)."\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+ call assert_equal([0, 0, 0, 0], getpos('"'))
+
+ " Test 3
+ " Ctrl-G goes from one match to the next
+ " and continues back at the top
+ set incsearch wrapscan
+ :1
+ " first match
+ call feedkeys("/the\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ :1
+ " second match
+ call feedkeys("/the\<C-G>\<cr>", 'tx')
+ call assert_equal(' 3 the', getline('.'))
+ :1
+ " third match
+ call feedkeys("/the".repeat("\<C-G>", 2)."\<cr>", 'tx')
+ call assert_equal(' 4 their', getline('.'))
+ :1
+ " fourth match
+ call feedkeys("/the".repeat("\<C-G>", 3)."\<cr>", 'tx')
+ call assert_equal(' 5 there', getline('.'))
+ :1
+ " fifth match
+ call feedkeys("/the".repeat("\<C-G>", 4)."\<cr>", 'tx')
+ call assert_equal(' 6 their', getline('.'))
+ :1
+ " sixth match
+ call feedkeys("/the".repeat("\<C-G>", 5)."\<cr>", 'tx')
+ call assert_equal(' 7 the', getline('.'))
+ :1
+ " seventh match
+ call feedkeys("/the".repeat("\<C-G>", 6)."\<cr>", 'tx')
+ call assert_equal(' 8 them', getline('.'))
+ :1
+ " eigth match
+ call feedkeys("/the".repeat("\<C-G>", 7)."\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+ :1
+ " back at first match
+ call feedkeys("/the".repeat("\<C-G>", 8)."\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+
+ " Test 4
+ " CTRL-T goes to the previous match
+ set incsearch nowrapscan
+ $
+ " first match
+ call feedkeys("?the\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+ $
+ " first match
+ call feedkeys("?the\<C-G>\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+ $
+ " second match
+ call feedkeys("?the".repeat("\<C-T>", 1)."\<cr>", 'tx')
+ call assert_equal(' 8 them', getline('.'))
+ $
+ " last match
+ call feedkeys("?the".repeat("\<C-T>", 7)."\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ $
+ " last match
+ call feedkeys("?the".repeat("\<C-T>", 8)."\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+
+ " Test 5
+ " CTRL-T goes to the previous match
+ set incsearch wrapscan
+ $
+ " first match
+ call feedkeys("?the\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+ $
+ " first match at the top
+ call feedkeys("?the\<C-G>\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ $
+ " second match
+ call feedkeys("?the".repeat("\<C-T>", 1)."\<cr>", 'tx')
+ call assert_equal(' 8 them', getline('.'))
+ $
+ " last match
+ call feedkeys("?the".repeat("\<C-T>", 7)."\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ $
+ " back at the bottom of the buffer
+ call feedkeys("?the".repeat("\<C-T>", 8)."\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+
+ " Test 6
+ " CTRL-L adds to the search pattern
+ set incsearch wrapscan
+ 1
+ " first match
+ call feedkeys("/the\<c-l>\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ 1
+ " go to next match of 'thes'
+ call feedkeys("/the\<c-l>\<C-G>\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+ 1
+ " wrap around
+ call feedkeys("/the\<c-l>\<C-G>\<C-G>\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ 1
+ " wrap around
+ set nowrapscan
+ call feedkeys("/the\<c-l>\<C-G>\<C-G>\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+
+ " Test 7
+ " <bs> remove from match, but stay at current match
+ set incsearch wrapscan
+ 1
+ " first match
+ call feedkeys("/thei\<cr>", 'tx')
+ call assert_equal(' 4 their', getline('.'))
+ 1
+ " delete one char, add another
+ call feedkeys("/thei\<bs>s\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ 1
+ " delete one char, add another, go to previous match, add one char
+ call feedkeys("/thei\<bs>s\<bs>\<C-T>\<c-l>\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+ 1
+ " delete all chars, start from the beginning again
+ call feedkeys("/them". repeat("\<bs>",4).'the\>'."\<cr>", 'tx')
+ call assert_equal(' 3 the', getline('.'))
+
+ " clean up
+ call test_disable_char_avail(0)
+ bw!
+endfunc
+
+func Test_search_cmdline2()
+ " See test/functional/legacy/search_spec.lua
+ throw 'skipped: Nvim does not support test_disable_char_avail()'
+ if !exists('+incsearch')
+ return
+ endif
+ " need to disable char_avail,
+ " so that expansion of commandline works
+ call test_disable_char_avail(1)
+ new
+ call setline(1, [' 1', ' 2 these', ' 3 the theother'])
+ " Test 1
+ " Ctrl-T goes correctly back and forth
+ set incsearch
+ 1
+ " first match
+ call feedkeys("/the\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ 1
+ " go to next match (on next line)
+ call feedkeys("/the\<C-G>\<cr>", 'tx')
+ call assert_equal(' 3 the theother', getline('.'))
+ 1
+ " go to next match (still on line 3)
+ call feedkeys("/the\<C-G>\<C-G>\<cr>", 'tx')
+ call assert_equal(' 3 the theother', getline('.'))
+ 1
+ " go to next match (still on line 3)
+ call feedkeys("/the\<C-G>\<C-G>\<C-G>\<cr>", 'tx')
+ call assert_equal(' 3 the theother', getline('.'))
+ 1
+ " go to previous match (on line 3)
+ call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<cr>", 'tx')
+ call assert_equal(' 3 the theother', getline('.'))
+ 1
+ " go to previous match (on line 3)
+ call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<cr>", 'tx')
+ call assert_equal(' 3 the theother', getline('.'))
+ 1
+ " go to previous match (on line 2)
+ call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<C-T>\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+
+ " Test 2: keep the view,
+ " after deleting a character from the search cmd
+ call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar'])
+ resize 5
+ 1
+ call feedkeys("/foo\<bs>\<cr>", 'tx')
+ redraw
+ call assert_equal({'lnum': 10, 'leftcol': 0, 'col': 4, 'topfill': 0, 'topline': 6, 'coladd': 0, 'skipcol': 0, 'curswant': 4}, winsaveview())
+
+ " remove all history entries
+ for i in range(10)
+ call histdel('/')
+ endfor
+
+ " Test 3: reset the view,
+ " after deleting all characters from the search cmd
+ norm! 1gg0
+ " unfortunately, neither "/foo\<c-w>\<cr>", nor "/foo\<bs>\<bs>\<bs>\<cr>",
+ " nor "/foo\<c-u>\<cr>" works to delete the commandline.
+ " In that case Vim should return "E35 no previous regular expression",
+ " but it looks like Vim still sees /foo and therefore the test fails.
+ " Therefore, disableing this test
+ "call assert_fails(feedkeys("/foo\<c-w>\<cr>", 'tx'), 'E35')
+ "call assert_equal({'lnum': 1, 'leftcol': 0, 'col': 0, 'topfill': 0, 'topline': 1, 'coladd': 0, 'skipcol': 0, 'curswant': 0}, winsaveview())
+
+ " clean up
+ set noincsearch
+ call test_disable_char_avail(0)
+ bw!
+endfunc
+
+func Test_use_sub_pat()
+ split
+ let @/ = ''
+ func X()
+ s/^/a/
+ /
+ endfunc
+ call X()
+ bwipe!
+endfunc
+
+func Test_searchpair()
+ new
+ call setline(1, ['other code here', '', '[', '" cursor here', ']'])
+ 4
+ let a=searchpair('\[','',']','bW')
+ call assert_equal(3, a)
+ set nomagic
+ 4
+ let a=searchpair('\[','',']','bW')
+ call assert_equal(3, a)
+ set magic
+ q!
+endfunc
+
diff --git a/src/nvim/testdir/test_smartindent.vim b/src/nvim/testdir/test_smartindent.vim
new file mode 100644
index 0000000000..d00eac9798
--- /dev/null
+++ b/src/nvim/testdir/test_smartindent.vim
@@ -0,0 +1,14 @@
+
+" Tests for not doing smart indenting when it isn't set.
+function! Test_nosmartindent()
+ new
+ call append(0, [" some test text",
+ \ " test text",
+ \ "test text",
+ \ " test text"])
+ set nocindent nosmartindent autoindent
+ exe "normal! gg/some\<CR>"
+ exe "normal! 2cc#test\<Esc>"
+ call assert_equal(" #test", getline(1))
+ enew! | close
+endfunction
diff --git a/src/nvim/testdir/test_source_utf8.vim b/src/nvim/testdir/test_source_utf8.vim
new file mode 100644
index 0000000000..edb76fc43d
--- /dev/null
+++ b/src/nvim/testdir/test_source_utf8.vim
@@ -0,0 +1,33 @@
+" Test the :source! command
+if !has('multi_byte')
+ finish
+endif
+
+func Test_source_utf8()
+ " check that sourcing a script with 0x80 as second byte works
+ new
+ call setline(1, [':%s/àx/--à1234--/g', ':%s/Àx/--À1234--/g'])
+ write! Xscript
+ bwipe!
+ new
+ call setline(1, [' àx ', ' Àx '])
+ source! Xscript | echo
+ call assert_equal(' --à1234-- ', getline(1))
+ call assert_equal(' --À1234-- ', getline(2))
+ bwipe!
+ call delete('Xscript')
+endfunc
+
+func Test_source_latin()
+ " check that sourcing a latin1 script with a 0xc0 byte works
+ new
+ call setline(1, ["call feedkeys('r')", "call feedkeys('\xc0', 'xt')"])
+ write! Xscript
+ bwipe!
+ new
+ call setline(1, ['xxx'])
+ source Xscript
+ call assert_equal("\u00c0xx", getline(1))
+ bwipe!
+ call delete('Xscript')
+endfunc
diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim
new file mode 100644
index 0000000000..11e26d03aa
--- /dev/null
+++ b/src/nvim/testdir/test_startup.vim
@@ -0,0 +1,242 @@
+" Tests for startup.
+
+source shared.vim
+
+" Check that loading startup.vim works.
+func Test_startup_script()
+ throw 'skipped: Nvim does not need defaults.vim'
+ set compatible
+ source $VIMRUNTIME/defaults.vim
+
+ call assert_equal(0, &compatible)
+endfunc
+
+" Verify the order in which plugins are loaded:
+" 1. plugins in non-after directories
+" 2. packages
+" 3. plugins in after directories
+func Test_after_comes_later()
+ if !has('packages')
+ return
+ endif
+ let before = [
+ \ 'set nocp viminfo+=nviminfo',
+ \ 'set guioptions+=M',
+ \ 'let $HOME = "/does/not/exist"',
+ \ 'set loadplugins',
+ \ 'set rtp=Xhere,Xafter,Xanother',
+ \ 'set packpath=Xhere,Xafter',
+ \ 'set nomore',
+ \ 'let g:sequence = ""',
+ \ ]
+ let after = [
+ \ 'redir! > Xtestout',
+ \ 'scriptnames',
+ \ 'redir END',
+ \ 'redir! > Xsequence',
+ \ 'echo g:sequence',
+ \ 'redir END',
+ \ 'quit',
+ \ ]
+ call mkdir('Xhere/plugin', 'p')
+ call writefile(['let g:sequence .= "here "'], 'Xhere/plugin/here.vim')
+ call mkdir('Xanother/plugin', 'p')
+ call writefile(['let g:sequence .= "another "'], 'Xanother/plugin/another.vim')
+ call mkdir('Xhere/pack/foo/start/foobar/plugin', 'p')
+ call writefile(['let g:sequence .= "pack "'], 'Xhere/pack/foo/start/foobar/plugin/foo.vim')
+
+ call mkdir('Xafter/plugin', 'p')
+ call writefile(['let g:sequence .= "after "'], 'Xafter/plugin/later.vim')
+
+ if RunVim(before, after, '')
+
+ let lines = readfile('Xtestout')
+ let expected = ['Xbefore.vim', 'here.vim', 'another.vim', 'foo.vim', 'later.vim', 'Xafter.vim']
+ let found = []
+ for line in lines
+ for one in expected
+ if line =~ one
+ call add(found, one)
+ endif
+ endfor
+ endfor
+ call assert_equal(expected, found)
+ endif
+
+ call assert_equal('here another pack after', substitute(join(readfile('Xsequence', 1), ''), '\s\+$', '', ''))
+
+ call delete('Xtestout')
+ call delete('Xsequence')
+ call delete('Xhere', 'rf')
+ call delete('Xanother', 'rf')
+ call delete('Xafter', 'rf')
+endfunc
+
+func Test_pack_in_rtp_when_plugins_run()
+ if !has('packages')
+ return
+ endif
+ let before = [
+ \ 'set nocp viminfo+=nviminfo',
+ \ 'set guioptions+=M',
+ \ 'let $HOME = "/does/not/exist"',
+ \ 'set loadplugins',
+ \ 'set rtp=Xhere',
+ \ 'set packpath=Xhere',
+ \ 'set nomore',
+ \ ]
+ let after = [
+ \ 'quit',
+ \ ]
+ call mkdir('Xhere/plugin', 'p')
+ call writefile(['redir! > Xtestout', 'silent set runtimepath?', 'silent! call foo#Trigger()', 'redir END'], 'Xhere/plugin/here.vim')
+ call mkdir('Xhere/pack/foo/start/foobar/autoload', 'p')
+ call writefile(['function! foo#Trigger()', 'echo "autoloaded foo"', 'endfunction'], 'Xhere/pack/foo/start/foobar/autoload/foo.vim')
+
+ if RunVim(before, after, '')
+
+ let lines = filter(readfile('Xtestout'), '!empty(v:val)')
+ call assert_match('Xhere[/\\]pack[/\\]foo[/\\]start[/\\]foobar', get(lines, 0))
+ call assert_match('autoloaded foo', get(lines, 1))
+ endif
+
+ call delete('Xtestout')
+ call delete('Xhere', 'rf')
+endfunc
+
+func Test_help_arg()
+ if !has('unix') && has('gui')
+ " this doesn't work with gvim on MS-Windows
+ return
+ endif
+ if RunVim([], [], '--help >Xtestout')
+ let lines = readfile('Xtestout')
+ call assert_true(len(lines) > 20)
+ call assert_match('Usage:', lines[0])
+
+ " check if couple of lines are there
+ let found = []
+ for line in lines
+ if line =~ '-R.*Read-only mode'
+ call add(found, 'Readonly mode')
+ endif
+ " Watch out for a second --version line in the Gnome version.
+ if line =~ '--version.*Print version information'
+ call add(found, "--version")
+ endif
+ endfor
+ call assert_equal(['Readonly mode', '--version'], found)
+ endif
+ call delete('Xtestout')
+endfunc
+
+func Test_compatible_args()
+ throw "skipped: Nvim is always 'nocompatible'"
+ let after = [
+ \ 'call writefile([string(&compatible)], "Xtestout")',
+ \ 'set viminfo+=nviminfo',
+ \ 'quit',
+ \ ]
+ if RunVim([], after, '-C')
+ let lines = readfile('Xtestout')
+ call assert_equal('1', lines[0])
+ endif
+
+ if RunVim([], after, '-N')
+ let lines = readfile('Xtestout')
+ call assert_equal('0', lines[0])
+ endif
+
+ call delete('Xtestout')
+endfunc
+
+func Test_file_args()
+ let after = [
+ \ 'call writefile(argv(), "Xtestout")',
+ \ 'qall',
+ \ ]
+ if RunVim([], after, '')
+ let lines = readfile('Xtestout')
+ call assert_equal(0, len(lines))
+ endif
+
+ if RunVim([], after, 'one')
+ let lines = readfile('Xtestout')
+ call assert_equal(1, len(lines))
+ call assert_equal('one', lines[0])
+ endif
+
+ if RunVim([], after, 'one two three')
+ let lines = readfile('Xtestout')
+ call assert_equal(3, len(lines))
+ call assert_equal('one', lines[0])
+ call assert_equal('two', lines[1])
+ call assert_equal('three', lines[2])
+ endif
+
+ if RunVim([], after, 'one -c echo two')
+ let lines = readfile('Xtestout')
+ call assert_equal(2, len(lines))
+ call assert_equal('one', lines[0])
+ call assert_equal('two', lines[1])
+ endif
+
+ if RunVim([], after, 'one -- -c echo two')
+ let lines = readfile('Xtestout')
+ call assert_equal(4, len(lines))
+ call assert_equal('one', lines[0])
+ call assert_equal('-c', lines[1])
+ call assert_equal('echo', lines[2])
+ call assert_equal('two', lines[3])
+ endif
+
+ call delete('Xtestout')
+endfunc
+
+func Test_startuptime()
+ if !has('startuptime')
+ return
+ endif
+ let after = ['qall']
+ if RunVim([], after, '--startuptime Xtestout one')
+ let lines = readfile('Xtestout')
+ let expected = ['parsing arguments', 'inits 3', 'opening buffers']
+ let found = []
+ for line in lines
+ for exp in expected
+ if line =~ exp
+ call add(found, exp)
+ endif
+ endfor
+ endfor
+ call assert_equal(expected, found)
+ endif
+ call delete('Xtestout')
+endfunc
+
+func Test_read_stdin()
+ let after = [
+ \ 'write Xtestout',
+ \ 'quit!',
+ \ ]
+ if RunVimPiped([], after, '-', 'echo something | ')
+ let lines = readfile('Xtestout')
+ " MS-Windows adds a space after the word
+ call assert_equal(['something'], split(lines[0]))
+ endif
+ call delete('Xtestout')
+endfunc
+
+func Test_progpath()
+ " Tests normally run with "./vim" or "../vim", these must have been expanded
+ " to a full path.
+ if has('unix')
+ call assert_equal('/', v:progpath[0])
+ elseif has('win32')
+ call assert_equal(':', v:progpath[1])
+ call assert_match('[/\\]', v:progpath[2])
+ endif
+
+ " Only expect "vim" to appear in v:progname.
+ call assert_match('vim\c', v:progname)
+endfunc
diff --git a/src/nvim/testdir/test_startup_utf8.vim b/src/nvim/testdir/test_startup_utf8.vim
new file mode 100644
index 0000000000..d179a4cc79
--- /dev/null
+++ b/src/nvim/testdir/test_startup_utf8.vim
@@ -0,0 +1,64 @@
+" Tests for startup using utf-8.
+if !has('multi_byte')
+ finish
+endif
+
+source shared.vim
+
+func Test_read_stdin_utf8()
+ let linesin = ['テスト', '€ÀÈÌÒÙ']
+ call writefile(linesin, 'Xtestin')
+ let before = [
+ \ 'set enc=utf-8',
+ \ 'set fencs=cp932,utf-8',
+ \ ]
+ let after = [
+ \ 'write ++enc=utf-8 Xtestout',
+ \ 'quit!',
+ \ ]
+ if has('win32')
+ let pipecmd = 'type Xtestin | '
+ else
+ let pipecmd = 'cat Xtestin | '
+ endif
+ if RunVimPiped(before, after, '-', pipecmd)
+ let lines = readfile('Xtestout')
+ call assert_equal(linesin, lines)
+ else
+ call assert_equal('', 'RunVimPiped failed.')
+ endif
+ call delete('Xtestout')
+ call delete('Xtestin')
+endfunc
+
+func Test_read_fifo_utf8()
+ if !has('unix')
+ return
+ endif
+ " Using bash/zsh's process substitution.
+ if executable('bash')
+ set shell=bash
+ elseif executable('zsh')
+ set shell=zsh
+ else
+ return
+ endif
+ let linesin = ['テスト', '€ÀÈÌÒÙ']
+ call writefile(linesin, 'Xtestin')
+ let before = [
+ \ 'set enc=utf-8',
+ \ 'set fencs=cp932,utf-8',
+ \ ]
+ let after = [
+ \ 'write ++enc=utf-8 Xtestout',
+ \ 'quit!',
+ \ ]
+ if RunVim(before, after, '<(cat Xtestin)')
+ let lines = readfile('Xtestout')
+ call assert_equal(linesin, lines)
+ else
+ call assert_equal('', 'RunVim failed.')
+ endif
+ call delete('Xtestout')
+ call delete('Xtestin')
+endfunc
diff --git a/src/nvim/testdir/test_stat.vim b/src/nvim/testdir/test_stat.vim
new file mode 100644
index 0000000000..89ca9ef379
--- /dev/null
+++ b/src/nvim/testdir/test_stat.vim
@@ -0,0 +1,64 @@
+" Tests for stat functions and checktime
+
+func Test_existent_file()
+ let fname='Xtest.tmp'
+
+ let ts=localtime()
+ sleep 1
+ let fl=['Hello World!']
+ call writefile(fl, fname)
+ let tf=getftime(fname)
+ sleep 1
+ let te=localtime()
+
+ call assert_true(ts <= tf && tf <= te)
+ call assert_equal(strlen(fl[0] . "\n"), getfsize(fname))
+ call assert_equal('file', getftype(fname))
+ call assert_equal('rw-', getfperm(fname)[0:2])
+endfunc
+
+func Test_existent_directory()
+ let dname='.'
+
+ call assert_equal(0, getfsize(dname))
+ call assert_equal('dir', getftype(dname))
+ call assert_equal('rwx', getfperm(dname)[0:2])
+endfunc
+
+func Test_checktime()
+ let fname='Xtest.tmp'
+
+ let fl=['Hello World!']
+ call writefile(fl, fname)
+ set autoread
+ exec 'e' fname
+ sleep 2
+ let fl=readfile(fname)
+ let fl[0] .= ' - checktime'
+ call writefile(fl, fname)
+ checktime
+ call assert_equal(fl[0], getline(1))
+endfunc
+
+func Test_nonexistent_file()
+ let fname='Xtest.tmp'
+
+ call delete(fname)
+ call assert_equal(-1, getftime(fname))
+ call assert_equal(-1, getfsize(fname))
+ call assert_equal('', getftype(fname))
+ call assert_equal('', getfperm(fname))
+endfunc
+
+func Test_win32_symlink_dir()
+ " On Windows, non-admin users cannot create symlinks.
+ " So we use an existing symlink for this test.
+ if has('win32')
+ " Check if 'C:\Users\All Users' is a symlink to a directory.
+ let res=system('dir C:\Users /a')
+ if match(res, '\C<SYMLINKD> *All Users') >= 0
+ " Get the filetype of the symlink.
+ call assert_equal('dir', getftype('C:\Users\All Users'))
+ endif
+ endif
+endfunc
diff --git a/src/nvim/testdir/test_substitute.vim b/src/nvim/testdir/test_substitute.vim
new file mode 100644
index 0000000000..e2b6de03c3
--- /dev/null
+++ b/src/nvim/testdir/test_substitute.vim
@@ -0,0 +1,41 @@
+" Tests for multi-line regexps with ":s".
+
+function! Test_multiline_subst()
+ enew!
+ call append(0, ["1 aa",
+ \ "bb",
+ \ "cc",
+ \ "2 dd",
+ \ "ee",
+ \ "3 ef",
+ \ "gh",
+ \ "4 ij",
+ \ "5 a8",
+ \ "8b c9",
+ \ "9d",
+ \ "6 e7",
+ \ "77f",
+ \ "xxxxx"])
+
+ 1
+ " test if replacing a line break works with a back reference
+ /^1/,/^2/s/\n\(.\)/ \1/
+ " test if inserting a line break works with a back reference
+ /^3/,/^4/s/\(.\)$/\r\1/
+ " test if replacing a line break with another line break works
+ /^5/,/^6/s/\(\_d\{3}\)/x\1x/
+ call assert_equal('1 aa bb cc 2 dd ee', getline(1))
+ call assert_equal('3 e', getline(2))
+ call assert_equal('f', getline(3))
+ call assert_equal('g', getline(4))
+ call assert_equal('h', getline(5))
+ call assert_equal('4 i', getline(6))
+ call assert_equal('j', getline(7))
+ call assert_equal('5 ax8', getline(8))
+ call assert_equal('8xb cx9', getline(9))
+ call assert_equal('9xd', getline(10))
+ call assert_equal('6 ex7', getline(11))
+ call assert_equal('7x7f', getline(12))
+ call assert_equal('xxxxx', getline(13))
+ enew!
+endfunction
diff --git a/src/nvim/testdir/test_syn_attr.vim b/src/nvim/testdir/test_syn_attr.vim
index 94d6b8735f..64aab3411d 100644
--- a/src/nvim/testdir/test_syn_attr.vim
+++ b/src/nvim/testdir/test_syn_attr.vim
@@ -20,7 +20,7 @@ func Test_missing_attr()
if fontname == ''
let fontname = 'something'
endif
- exe 'hi Mine guifg=blue guibg=red font=' . escape(fontname, ' \')
+ exe "hi Mine guifg=blue guibg=red font='" . fontname . "'"
call assert_equal('blue', synIDattr(hlID("Mine"), "fg", 'gui'))
call assert_equal('red', synIDattr(hlID("Mine"), "bg", 'gui'))
call assert_equal(fontname, synIDattr(hlID("Mine"), "font", 'gui'))
diff --git a/src/nvim/testdir/test_tabpage.vim b/src/nvim/testdir/test_tabpage.vim
index 7c3039ba24..33139fcda0 100644
--- a/src/nvim/testdir/test_tabpage.vim
+++ b/src/nvim/testdir/test_tabpage.vim
@@ -11,6 +11,7 @@ function Test_tabpage()
0tabnew
1tabnew
$tabnew
+ %del
tabdo call append(line('$'), tabpagenr())
tabclose! 2
tabrewind
@@ -93,10 +94,6 @@ function Test_tabpage()
call assert_equal(7, tabpagenr())
tabmove
call assert_equal(10, tabpagenr())
- tabmove -20
- call assert_equal(1, tabpagenr())
- tabmove +20
- call assert_equal(10, tabpagenr())
0tabmove
call assert_equal(1, tabpagenr())
$tabmove
@@ -109,7 +106,16 @@ function Test_tabpage()
call assert_equal(4, tabpagenr())
7tabmove 5
call assert_equal(5, tabpagenr())
+ call assert_fails("99tabmove", 'E16:')
+ call assert_fails("+99tabmove", 'E16:')
+ call assert_fails("-99tabmove", 'E16:')
call assert_fails("tabmove foo", 'E474:')
+ call assert_fails("tabmove 99", 'E474:')
+ call assert_fails("tabmove +99", 'E474:')
+ call assert_fails("tabmove -99", 'E474:')
+ call assert_fails("tabmove -3+", 'E474:')
+ call assert_fails("tabmove $3", 'E474:')
+ 1tabonly!
endfunc
" Test autocommands
@@ -117,7 +123,6 @@ function Test_tabpage_with_autocmd()
if !has('autocmd')
return
endif
- tabonly!
command -nargs=1 -bar C :call add(s:li, '=== ' . <q-args> . ' ===')|<args>
augroup TestTabpageGroup
au!
@@ -182,8 +187,10 @@ function Test_tabpage_with_autocmd()
autocmd TabDestructive TabEnter * nested :C tabnext 2 | C tabclose 3
let s:li = []
- C tabnext 3
- call assert_equal(['=== tabnext 3 ===', 'BufLeave', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', '=== tabnext 2 ===', 'BufLeave', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', '=== tabnext 2 ===', '=== tabclose 3 ===', 'BufEnter', '=== tabclose 3 ==='], s:li)
+ call assert_equal(3, tabpagenr('$'))
+ C tabnext 2
+ call assert_equal(2, tabpagenr('$'))
+ call assert_equal(['=== tabnext 2 ===', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', '=== tabnext 2 ===', '=== tabclose 3 ==='], s:li)
call assert_equal(['2/2'], [tabpagenr().'/'.tabpagenr('$')])
delcommand C
@@ -191,8 +198,7 @@ function Test_tabpage_with_autocmd()
augroup! TabDestructive
autocmd! TestTabpageGroup
augroup! TestTabpageGroup
- tabonly!
- bw!
+ 1tabonly!
endfunction
function Test_tabpage_with_tab_modifier()
@@ -204,7 +210,7 @@ function Test_tabpage_with_tab_modifier()
exec 'tabnext ' . a:pre_nr
exec a:cmd
call assert_equal(a:post_nr, tabpagenr())
- call assert_equal('help', &filetype)
+ call assert_equal('help', &buftype)
helpclose
endfunc
@@ -223,8 +229,223 @@ function Test_tabpage_with_tab_modifier()
call assert_fails('-99tab help', 'E16:')
delfunction s:check_tab
- tabonly!
- bw!
+ 1tabonly!
+endfunction
+
+function Check_tab_count(pre_nr, cmd, post_nr)
+ exec 'tabnext' a:pre_nr
+ normal! G
+ exec a:cmd
+ call assert_equal(a:post_nr, tabpagenr(), a:cmd)
+endfunc
+
+" Test for [count] of tabnext
+function Test_tabpage_with_tabnext()
+ for n in range(4)
+ tabedit
+ call setline(1, ['', '', '3'])
+ endfor
+
+ call Check_tab_count(1, 'tabnext', 2)
+ call Check_tab_count(1, '3tabnext', 3)
+ call Check_tab_count(1, '.tabnext', 1)
+ call Check_tab_count(1, '.+1tabnext', 2)
+ call Check_tab_count(2, '+tabnext', 3)
+ call Check_tab_count(2, '+2tabnext', 4)
+ call Check_tab_count(4, '-tabnext', 3)
+ call Check_tab_count(4, '-2tabnext', 2)
+ call Check_tab_count(3, '$tabnext', 5)
+ call assert_fails('0tabnext', 'E16:')
+ call assert_fails('99tabnext', 'E16:')
+ call assert_fails('+99tabnext', 'E16:')
+ call assert_fails('-99tabnext', 'E16:')
+ call Check_tab_count(1, 'tabnext 3', 3)
+ call Check_tab_count(2, 'tabnext +', 3)
+ call Check_tab_count(2, 'tabnext +2', 4)
+ call Check_tab_count(4, 'tabnext -', 3)
+ call Check_tab_count(4, 'tabnext -2', 2)
+ call Check_tab_count(3, 'tabnext $', 5)
+ call assert_fails('tabnext 0', 'E474:')
+ call assert_fails('tabnext .', 'E474:')
+ call assert_fails('tabnext -+', 'E474:')
+ call assert_fails('tabnext +2-', 'E474:')
+ call assert_fails('tabnext $3', 'E474:')
+ call assert_fails('tabnext 99', 'E474:')
+ call assert_fails('tabnext +99', 'E474:')
+ call assert_fails('tabnext -99', 'E474:')
+
+ 1tabonly!
+endfunction
+
+" Test for [count] of tabprevious
+function Test_tabpage_with_tabprevious()
+ for n in range(5)
+ tabedit
+ call setline(1, ['', '', '3'])
+ endfor
+
+ for cmd in ['tabNext', 'tabprevious']
+ call Check_tab_count(6, cmd, 5)
+ call Check_tab_count(6, '3' . cmd, 3)
+ call Check_tab_count(6, '8' . cmd, 4)
+ call Check_tab_count(6, cmd . ' 3', 3)
+ call Check_tab_count(6, cmd . ' 8', 4)
+ for n in range(2)
+ for c in ['0', '.+3', '+', '+2' , '-', '-2' , '$', '+99', '-99']
+ if n == 0 " pre count
+ let entire_cmd = c . cmd
+ let err_code = 'E16:'
+ else
+ let entire_cmd = cmd . ' ' . c
+ let err_code = 'E474:'
+ endif
+ call assert_fails(entire_cmd, err_code)
+ endfor
+ endfor
+ endfor
+
+ 1tabonly!
+endfunction
+
+function s:reconstruct_tabpage_for_test(nr)
+ let n = (a:nr > 2) ? a:nr - 2 : 1
+ 1tabonly!
+ 0tabedit n0
+ for n in range(1, n)
+ exec '$tabedit n' . n
+ if n == 1
+ call setline(1, ['', '', '3'])
+ endif
+ endfor
+endfunc
+
+" Test for [count] of tabclose
+function Test_tabpage_with_tabclose()
+
+ " pre count
+ call s:reconstruct_tabpage_for_test(6)
+ call Check_tab_count(3, 'tabclose!', 3)
+ call Check_tab_count(1, '3tabclose', 1)
+ call Check_tab_count(4, '4tabclose', 3)
+ call Check_tab_count(3, '1tabclose', 2)
+ call Check_tab_count(2, 'tabclose', 1)
+ call assert_equal(1, tabpagenr('$'))
+ call assert_equal('', bufname(''))
+
+ call s:reconstruct_tabpage_for_test(6)
+ call Check_tab_count(2, '$tabclose', 2)
+ call Check_tab_count(4, '.tabclose', 4)
+ call Check_tab_count(3, '.+tabclose', 3)
+ call Check_tab_count(3, '.-2tabclose', 2)
+ call Check_tab_count(1, '.+1tabclose!', 1)
+ call assert_equal(1, tabpagenr('$'))
+ call assert_equal('', bufname(''))
+
+ " post count
+ call s:reconstruct_tabpage_for_test(6)
+ call Check_tab_count(3, 'tabclose!', 3)
+ call Check_tab_count(1, 'tabclose 3', 1)
+ call Check_tab_count(4, 'tabclose 4', 3)
+ call Check_tab_count(3, 'tabclose 1', 2)
+ call Check_tab_count(2, 'tabclose', 1)
+ call assert_equal(1, tabpagenr('$'))
+ call assert_equal('', bufname(''))
+
+ call s:reconstruct_tabpage_for_test(6)
+ call Check_tab_count(2, 'tabclose $', 2)
+ call Check_tab_count(4, 'tabclose', 4)
+ call Check_tab_count(3, 'tabclose +', 3)
+ call Check_tab_count(3, 'tabclose -2', 2)
+ call Check_tab_count(1, 'tabclose! +1', 1)
+ call assert_equal(1, tabpagenr('$'))
+ call assert_equal('', bufname(''))
+
+ call s:reconstruct_tabpage_for_test(6)
+ for n in range(2)
+ for c in ['0', '$3', '99', '+99', '-99']
+ if n == 0 " pre count
+ let entire_cmd = c . 'tabclose'
+ let err_code = 'E16:'
+ else
+ let entire_cmd = 'tabclose ' . c
+ let err_code = 'E474:'
+ endif
+ call assert_fails(entire_cmd, err_code)
+ call assert_equal(6, tabpagenr('$'))
+ endfor
+ endfor
+
+ call assert_fails('3tabclose', 'E37:')
+ call assert_fails('tabclose 3', 'E37:')
+ call assert_fails('tabclose -+', 'E474:')
+ call assert_fails('tabclose +2-', 'E474:')
+ call assert_equal(6, tabpagenr('$'))
+
+ 1tabonly!
+endfunction
+
+" Test for [count] of tabonly
+function Test_tabpage_with_tabonly()
+
+ " Test for the normal behavior (pre count only)
+ let tc = [ [4, '.', '!'], [2, '.+', ''], [3, '.-2', '!'], [1, '.+1', '!'] ]
+ for c in tc
+ call s:reconstruct_tabpage_for_test(6)
+ let entire_cmd = c[1] . 'tabonly' . c[2]
+ call Check_tab_count(c[0], entire_cmd, 1)
+ call assert_equal(1, tabpagenr('$'))
+ endfor
+
+ " Test for the normal behavior
+ let tc2 = [ [3, '', ''], [1, '3', ''], [4, '4', '!'], [3, '1', '!'],
+ \ [2, '', '!'],
+ \ [2, '$', '!'], [3, '+', '!'], [3, '-2', '!'], [3, '+1', '!']
+ \ ]
+ for n in range(2)
+ for c in tc2
+ call s:reconstruct_tabpage_for_test(6)
+ if n == 0 " pre count
+ let entire_cmd = c[1] . 'tabonly' . c[2]
+ else
+ let entire_cmd = 'tabonly' . c[2] . ' ' . c[1]
+ endif
+ call Check_tab_count(c[0], entire_cmd, 1)
+ call assert_equal(1, tabpagenr('$'))
+ endfor
+ endfor
+
+ " Test for the error behavior
+ for n in range(2)
+ for c in ['0', '$3', '99', '+99', '-99']
+ call s:reconstruct_tabpage_for_test(6)
+ if n == 0 " pre count
+ let entire_cmd = c . 'tabonly'
+ let err_code = 'E16:'
+ else
+ let entire_cmd = 'tabonly ' . c
+ let err_code = 'E474:'
+ endif
+ call assert_fails(entire_cmd, err_code)
+ call assert_equal(6, tabpagenr('$'))
+ endfor
+ endfor
+
+ " Test for the error behavior (post count only)
+ for c in tc
+ call s:reconstruct_tabpage_for_test(6)
+ let entire_cmd = 'tabonly' . c[2] . ' ' . c[1]
+ let err_code = 'E474:'
+ call assert_fails(entire_cmd, err_code)
+ call assert_equal(6, tabpagenr('$'))
+ endfor
+
+ call assert_fails('tabonly -+', 'E474:')
+ call assert_fails('tabonly +2-', 'E474:')
+ call assert_equal(6, tabpagenr('$'))
+
+ 1tabonly!
+ new
+ only!
endfunction
func Test_tabnext_on_buf_unload1()
diff --git a/src/nvim/testdir/test_tagcase.vim b/src/nvim/testdir/test_tagcase.vim
new file mode 100644
index 0000000000..833cb9f990
--- /dev/null
+++ b/src/nvim/testdir/test_tagcase.vim
@@ -0,0 +1,73 @@
+" test 'tagcase' option
+
+func Test_tagcase()
+ call writefile(["Bar\tXtext\t3", "Foo\tXtext\t2", "foo\tXtext\t4"], 'Xtags')
+ set tags=Xtags
+ e Xtext
+
+ for &ic in [0, 1]
+ for &scs in [0, 1]
+ for &g:tc in ["followic", "ignore", "match", "followscs", "smart"]
+ for &l:tc in ["", "followic", "ignore", "match", "followscs", "smart"]
+ let smart = 0
+ if &l:tc != ''
+ let tc = &l:tc
+ else
+ let tc = &g:tc
+ endif
+ if tc == 'followic'
+ let ic = &ic
+ elseif tc == 'ignore'
+ let ic = 1
+ elseif tc == 'followscs'
+ let ic = &ic
+ let smart = &scs
+ elseif tc == 'smart'
+ let ic = 1
+ let smart = 1
+ else
+ let ic = 0
+ endif
+ if ic && smart
+ call assert_equal(['foo', 'Foo'], map(taglist("^foo$"), {i, v -> v.name}))
+ call assert_equal(['Foo'], map(taglist("^Foo$"), {i, v -> v.name}))
+ elseif ic
+ call assert_equal(['foo', 'Foo'], map(taglist("^foo$"), {i, v -> v.name}))
+ call assert_equal(['Foo', 'foo'], map(taglist("^Foo$"), {i, v -> v.name}))
+ else
+ call assert_equal(['foo'], map(taglist("^foo$"), {i, v -> v.name}))
+ call assert_equal(['Foo'], map(taglist("^Foo$"), {i, v -> v.name}))
+ endif
+ endfor
+ endfor
+ endfor
+ endfor
+
+ call delete('Xtags')
+ set ic&
+ setg tc&
+ setl tc&
+ set scs&
+endfunc
+
+func Test_set_tagcase()
+ " Verify default values.
+ set ic&
+ setg tc&
+ setl tc&
+ call assert_equal(0, &ic)
+ call assert_equal('followic', &g:tc)
+ call assert_equal('followic', &l:tc)
+ call assert_equal('followic', &tc)
+
+ " Verify that the local setting accepts <empty> but that the global setting
+ " does not. The first of these (setting the local value to <empty>) should
+ " succeed; the other two should fail.
+ setl tc=
+ call assert_fails('setg tc=', 'E474:')
+ call assert_fails('set tc=', 'E474:')
+
+ set ic&
+ setg tc&
+ setl tc&
+endfunc
diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim
index d8a333f44c..0d697b3f3e 100644
--- a/src/nvim/testdir/test_tagjump.vim
+++ b/src/nvim/testdir/test_tagjump.vim
@@ -6,4 +6,93 @@ func Test_ptag_with_notagstack()
call assert_fails('ptag does_not_exist_tag_name', 'E426')
set tagstack&vim
endfunc
-" vim: sw=2 et
+
+func Test_cancel_ptjump()
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "word\tfile1\tcmd1",
+ \ "word\tfile2\tcmd2"],
+ \ 'Xtags')
+
+ only!
+ call feedkeys(":ptjump word\<CR>\<CR>", "xt")
+ help
+ call assert_equal(2, winnr('$'))
+
+ call delete('Xtags')
+ quit
+endfunc
+
+func Test_static_tagjump()
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile1\t/^one/;\"\tf\tfile:\tsignature:(void)",
+ \ "word\tXfile2\tcmd2"],
+ \ 'Xtags')
+ new Xfile1
+ call setline(1, ['empty', 'one()', 'empty'])
+ write
+ tag one
+ call assert_equal(2, line('.'))
+
+ bwipe!
+ set tags&
+ call delete('Xtags')
+ call delete('Xfile1')
+endfunc
+
+func Test_duplicate_tagjump()
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "thesame\tXfile1\t1;\"\td\tfile:",
+ \ "thesame\tXfile1\t2;\"\td\tfile:",
+ \ "thesame\tXfile1\t3;\"\td\tfile:",
+ \ ],
+ \ 'Xtags')
+ new Xfile1
+ call setline(1, ['thesame one', 'thesame two', 'thesame three'])
+ write
+ tag thesame
+ call assert_equal(1, line('.'))
+ tnext
+ call assert_equal(2, line('.'))
+ tnext
+ call assert_equal(3, line('.'))
+
+ bwipe!
+ set tags&
+ call delete('Xtags')
+ call delete('Xfile1')
+endfunc
+
+" Tests for [ CTRL-I and CTRL-W CTRL-I commands
+function Test_keyword_jump()
+ call writefile(["#include Xinclude", "",
+ \ "",
+ \ "/* test text test tex start here",
+ \ " some text",
+ \ " test text",
+ \ " start OK if found this line",
+ \ " start found wrong line",
+ \ "test text"], 'Xtestfile')
+ call writefile(["/* test text test tex start here",
+ \ " some text",
+ \ " test text",
+ \ " start OK if found this line",
+ \ " start found wrong line",
+ \ "test text"], 'Xinclude')
+ new Xtestfile
+ call cursor(1,1)
+ call search("start")
+ exe "normal! 5[\<C-I>"
+ call assert_equal(" start OK if found this line", getline('.'))
+ call cursor(1,1)
+ call search("start")
+ exe "normal! 5\<C-W>\<C-I>"
+ call assert_equal(" start OK if found this line", getline('.'))
+ enew! | only
+ call delete('Xtestfile')
+ call delete('Xinclude')
+endfunction
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_taglist.vim b/src/nvim/testdir/test_taglist.vim
new file mode 100644
index 0000000000..2d1557ebd9
--- /dev/null
+++ b/src/nvim/testdir/test_taglist.vim
@@ -0,0 +1,58 @@
+" test 'taglist' function
+
+func Test_taglist()
+ call writefile([
+ \ "FFoo\tXfoo\t1",
+ \ "FBar\tXfoo\t2",
+ \ "BFoo\tXbar\t1",
+ \ "BBar\tXbar\t2"
+ \ ], 'Xtags')
+ set tags=Xtags
+ split Xtext
+
+ call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo"), {i, v -> v.name}))
+ call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo", "Xtext"), {i, v -> v.name}))
+ call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo", "Xfoo"), {i, v -> v.name}))
+ call assert_equal(['BFoo', 'FFoo'], map(taglist("Foo", "Xbar"), {i, v -> v.name}))
+
+ call delete('Xtags')
+ bwipe
+endfunc
+
+func Test_taglist_native_etags()
+ if !has('emacs_tags')
+ return
+ endif
+ call writefile([
+ \ "\x0c",
+ \ "src/os_unix.c,13491",
+ \ "set_signals(\x7f1335,32699",
+ \ "reset_signals(\x7f1407,34136",
+ \ ], 'Xtags')
+
+ set tags=Xtags
+
+ call assert_equal([['set_signals', '1335,32699'], ['reset_signals', '1407,34136']],
+ \ map(taglist('set_signals'), {i, v -> [v.name, v.cmd]}))
+
+ call delete('Xtags')
+endfunc
+
+func Test_taglist_ctags_etags()
+ if !has('emacs_tags')
+ return
+ endif
+ call writefile([
+ \ "\x0c",
+ \ "src/os_unix.c,13491",
+ \ "set_signals(void)\x7fset_signals\x011335,32699",
+ \ "reset_signals(void)\x7freset_signals\x011407,34136",
+ \ ], 'Xtags')
+
+ set tags=Xtags
+
+ call assert_equal([['set_signals', '1335,32699'], ['reset_signals', '1407,34136']],
+ \ map(taglist('set_signals'), {i, v -> [v.name, v.cmd]}))
+
+ call delete('Xtags')
+endfunc
diff --git a/src/nvim/testdir/test_textobjects.vim b/src/nvim/testdir/test_textobjects.vim
new file mode 100644
index 0000000000..630ae5d3a4
--- /dev/null
+++ b/src/nvim/testdir/test_textobjects.vim
@@ -0,0 +1,43 @@
+" Test for textobjects
+
+if !has('textobjects')
+ finish
+endif
+
+function! CpoM(line, useM, expected)
+ new
+
+ if a:useM
+ set cpoptions+=M
+ else
+ set cpoptions-=M
+ endif
+
+ call setline(1, a:line)
+
+ call setreg('"', '')
+ normal! ggfrmavi)y
+ call assert_equal(getreg('"'), a:expected[0])
+
+ call setreg('"', '')
+ normal! `afbmavi)y
+ call assert_equal(getreg('"'), a:expected[1])
+
+ call setreg('"', '')
+ normal! `afgmavi)y
+ call assert_equal(getreg('"'), a:expected[2])
+
+ q!
+endfunction
+
+function! Test_inner_block_without_cpo_M()
+ call CpoM('(red \(blue) green)', 0, ['red \(blue', 'red \(blue', ''])
+endfunction
+
+function! Test_inner_block_with_cpo_M_left_backslash()
+ call CpoM('(red \(blue) green)', 1, ['red \(blue) green', 'blue', 'red \(blue) green'])
+endfunction
+
+function! Test_inner_block_with_cpo_M_right_backslash()
+ call CpoM('(red (blue\) green)', 1, ['red (blue\) green', 'blue\', 'red (blue\) green'])
+endfunction
diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim
index d92cbe6897..d377062780 100644
--- a/src/nvim/testdir/test_timers.vim
+++ b/src/nvim/testdir/test_timers.vim
@@ -4,8 +4,10 @@ if !has('timers')
finish
endif
+source shared.vim
+
func MyHandler(timer)
- let s:val += 1
+ let g:val += 1
endfunc
func MyHandlerWithLists(lists, timer)
@@ -13,43 +15,159 @@ func MyHandlerWithLists(lists, timer)
endfunc
func Test_oneshot()
- let s:val = 0
+ let g:val = 0
let timer = timer_start(50, 'MyHandler')
- sleep 200m
- call assert_equal(1, s:val)
+ let slept = WaitFor('g:val == 1')
+ call assert_equal(1, g:val)
+ if has('reltime')
+ call assert_inrange(40, 100, slept)
+ else
+ call assert_inrange(20, 100, slept)
+ endif
endfunc
func Test_repeat_three()
- let s:val = 0
+ let g:val = 0
let timer = timer_start(50, 'MyHandler', {'repeat': 3})
- sleep 500m
- call assert_equal(3, s:val)
+ let slept = WaitFor('g:val == 3')
+ call assert_equal(3, g:val)
+ if has('reltime')
+ call assert_inrange(120, 250, slept)
+ else
+ call assert_inrange(80, 200, slept)
+ endif
endfunc
func Test_repeat_many()
- let s:val = 0
+ let g:val = 0
let timer = timer_start(50, 'MyHandler', {'repeat': -1})
sleep 200m
call timer_stop(timer)
- call assert_true(s:val > 1)
- call assert_true(s:val < 5)
+ call assert_inrange(2, 4, g:val)
endfunc
func Test_with_partial_callback()
- let s:val = 0
- let s:meow = {}
- function s:meow.bite(...)
- let s:val += 1
+ let g:val = 0
+ let meow = {'one': 1}
+ function meow.bite(...)
+ let g:val += self.one
endfunction
- call timer_start(50, s:meow.bite)
- sleep 200m
- call assert_equal(1, s:val)
+ call timer_start(50, meow.bite)
+ let slept = WaitFor('g:val == 1')
+ call assert_equal(1, g:val)
+ if has('reltime')
+ call assert_inrange(40, 130, slept)
+ else
+ call assert_inrange(20, 100, slept)
+ endif
endfunc
func Test_retain_partial()
- call timer_start(100, function('MyHandlerWithLists', [['a']]))
+ call timer_start(50, function('MyHandlerWithLists', [['a']]))
call garbagecollect()
+ sleep 100m
+endfunc
+
+func Test_info()
+ let id = timer_start(1000, 'MyHandler')
+ let info = timer_info(id)
+ call assert_equal(id, info[0]['id'])
+ call assert_equal(1000, info[0]['time'])
+ call assert_equal("function('MyHandler')", string(info[0]['callback']))
+
+ let found = 0
+ for info in timer_info()
+ if info['id'] == id
+ let found += 1
+ endif
+ endfor
+ call assert_equal(1, found)
+
+ call timer_stop(id)
+ call assert_equal([], timer_info(id))
+endfunc
+
+func Test_stopall()
+ let id1 = timer_start(1000, 'MyHandler')
+ let id2 = timer_start(2000, 'MyHandler')
+ let info = timer_info()
+ call assert_equal(2, len(info))
+
+ call timer_stopall()
+ let info = timer_info()
+ call assert_equal(0, len(info))
+endfunc
+
+func Test_paused()
+ let g:val = 0
+
+ let id = timer_start(50, 'MyHandler')
+ let info = timer_info(id)
+ call assert_equal(0, info[0]['paused'])
+
+ call timer_pause(id, 1)
+ let info = timer_info(id)
+ call assert_equal(1, info[0]['paused'])
sleep 200m
+ call assert_equal(0, g:val)
+
+ call timer_pause(id, 0)
+ let info = timer_info(id)
+ call assert_equal(0, info[0]['paused'])
+
+ let slept = WaitFor('g:val == 1')
+ call assert_equal(1, g:val)
+ if has('reltime')
+ call assert_inrange(0, 60, slept)
+ else
+ call assert_inrange(0, 10, slept)
+ endif
endfunc
-" vim: ts=2 sw=0 et
+
+func StopMyself(timer)
+ let g:called += 1
+ if g:called == 2
+ call timer_stop(a:timer)
+ endif
+endfunc
+
+func Test_delete_myself()
+ let g:called = 0
+ let t = timer_start(10, 'StopMyself', {'repeat': -1})
+ call WaitFor('g:called == 2')
+ call assert_equal(2, g:called)
+ call assert_equal([], timer_info(t))
+endfunc
+
+func StopTimer1(timer)
+ let g:timer2 = timer_start(10, 'StopTimer2')
+ " avoid maxfuncdepth error
+ call timer_pause(g:timer1, 1)
+ sleep 40m
+endfunc
+
+func StopTimer2(timer)
+ call timer_stop(g:timer1)
+endfunc
+
+func Test_stop_in_callback()
+ let g:timer1 = timer_start(10, 'StopTimer1')
+ sleep 40m
+endfunc
+
+func StopTimerAll(timer)
+ call timer_stopall()
+endfunc
+
+func Test_stop_all_in_callback()
+ let g:timer1 = timer_start(10, 'StopTimerAll')
+ let info = timer_info()
+ call assert_equal(1, len(info))
+ sleep 40m
+ let info = timer_info()
+ call assert_equal(0, len(info))
+endfunc
+
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_true_false.vim b/src/nvim/testdir/test_true_false.vim
new file mode 100644
index 0000000000..84aca737ac
--- /dev/null
+++ b/src/nvim/testdir/test_true_false.vim
@@ -0,0 +1,150 @@
+" Test behavior of boolean-like values.
+
+" Test what is explained at ":help TRUE" and ":help FALSE".
+func Test_if()
+ if v:false
+ call assert_true(false, 'v:false is false')
+ endif
+ if 0
+ call assert_true(false, 'zero is false')
+ endif
+ if "0"
+ call assert_true(false, 'zero string is false')
+ endif
+ if "foo"
+ call assert_true(false, 'foo is false')
+ endif
+ if " "
+ call assert_true(false, 'space is false')
+ endif
+ if empty("foo")
+ call assert_true(false, 'foo is not empty')
+ endif
+
+ if v:true
+ else
+ call assert_true(false, 'v:true is true')
+ endif
+ if 1
+ else
+ call assert_true(false, 'one is true')
+ endif
+ if "1"
+ else
+ call assert_true(false, 'one string is true')
+ endif
+ if "1foo"
+ else
+ call assert_true(false, 'one in string is true')
+ endif
+
+ call assert_fails('if [1]', 'E745')
+ call assert_fails('if {1: 1}', 'E728')
+ call assert_fails('if function("string")', 'E703')
+ call assert_fails('if 1.3")', 'E805')
+endfunc
+
+function Try_arg_true_false(expr, false_val, true_val)
+ for v in ['v:false', '0', '"0"', '"foo"', '" "']
+ let r = eval(substitute(a:expr, '%v%', v, ''))
+ call assert_equal(a:false_val, r, 'result for ' . v . ' is not ' . string(a:false_val) . ' but ' . string(r))
+ endfor
+ for v in ['v:true', '1', '"1"', '"1foo"']
+ let r = eval(substitute(a:expr, '%v%', v, ''))
+ call assert_equal(a:true_val, r, 'result for ' . v . ' is not ' . string(a:true_val) . ' but ' . string(r))
+ endfor
+endfunc
+
+" Test using TRUE or FALSE values for an argument.
+func Test_true_false_arg()
+ call Try_arg_true_false('count(["a", "A"], "a", %v%)', 1, 2)
+
+ set wildignore=*.swp
+ call Try_arg_true_false('expand("foo.swp", %v%)', "", "foo.swp")
+ call Try_arg_true_false('expand("foo.vim", 0, %v%)', "foo.vim", ["foo.vim"])
+
+ call setreg('a', ['x', 'y'])
+ call Try_arg_true_false('getreg("a", 1, %v%)', "x\ny\n", ['x', 'y'])
+
+ set wildignore=*.vim
+ call Try_arg_true_false('glob("runtest.vim", %v%)', "", "runtest.vim")
+ set wildignore=*.swp
+ call Try_arg_true_false('glob("runtest.vim", 0, %v%)', "runtest.vim", ["runtest.vim"])
+ if has('unix')
+ silent !ln -s doesntexit Xlink
+ call Try_arg_true_false('glob("Xlink", 0, 0, %v%)', "", "Xlink")
+ silent !rm Xlink
+ endif
+
+ set wildignore=*.vim
+ call Try_arg_true_false('globpath(".", "runtest.vim", %v%)', "", "./runtest.vim")
+ set wildignore=*.swp
+ call Try_arg_true_false('globpath(".", "runtest.vim", 0, %v%)', "./runtest.vim", ["./runtest.vim"])
+ if has('unix')
+ silent !ln -s doesntexit Xlink
+ call Try_arg_true_false('globpath(".", "Xlink", 0, 0, %v%)', "", "./Xlink")
+ silent !rm Xlink
+ endif
+
+ abbr asdf asdff
+ call Try_arg_true_false('hasmapto("asdff", "i", %v%)', 0, 1)
+
+ call Try_arg_true_false('index(["a", "A"], "A", 0, %v%)', 1, 0)
+
+ function FilterMapArg(d)
+ if type(a:d) == type({})
+ return filter(a:d, 'v:key == "rhs"')
+ endif
+ return a:d
+ endfunction
+ call Try_arg_true_false('maparg("asdf", "i", %v%)', "", "asdff")
+ call Try_arg_true_false('FilterMapArg(maparg("asdf", "i", 1, %v%))', "asdff", {'rhs': 'asdff'})
+
+ call Try_arg_true_false('hasmapto("asdf", "i", %v%)', 0, 1)
+
+ new colored
+ call setline(1, '<here>')
+ syn match brackets "<.*>"
+ syn match here "here" transparent
+ let brackets_id = synID(1, 1, 0)
+ let here_id = synID(1, 3, 0)
+ call Try_arg_true_false('synID(1, 3, %v%)', here_id, brackets_id)
+ bwipe!
+endfunc
+
+function Try_arg_non_zero(expr, false_val, true_val)
+ for v in ['v:false', '0', '[1]', '{2:3}', '3.4']
+ let r = eval(substitute(a:expr, '%v%', v, ''))
+ call assert_equal(a:false_val, r, 'result for ' . v . ' is not ' . a:false_val . ' but ' . r)
+ endfor
+ for v in ['v:true', '1', '" "', '"0"']
+ let r = eval(substitute(a:expr, '%v%', v, ''))
+ call assert_equal(a:true_val, r, 'result for ' . v . ' is not ' . a:true_val . ' but ' . r)
+ endfor
+endfunc
+
+
+" Test using non-zero-arg for an argument.
+func Test_non_zero_arg()
+ " call test_settime(93784)
+ " call Try_arg_non_zero("mode(%v%)", 'x', 'x!')
+ " call test_settime(0)
+
+ call Try_arg_non_zero("shellescape('foo%', %v%)", "'foo%'", "'foo\\%'")
+
+ " visualmode() needs to be called twice to check
+ for v in [v:false, 0, [1], {2:3}, 3.4]
+ normal vv
+ let r = visualmode(v)
+ call assert_equal('v', r, 'result for ' . string(v) . ' is not "v" but ' . r)
+ let r = visualmode(v)
+ call assert_equal('v', r, 'result for ' . string(v) . ' is not "v" but ' . r)
+ endfor
+ for v in [v:true, 1, " ", "0"]
+ normal vv
+ let r = visualmode(v)
+ call assert_equal('v', r, 'result for ' . v . ' is not "v" but ' . r)
+ let r = visualmode(v)
+ call assert_equal('', r, 'result for ' . v . ' is not "" but ' . r)
+ endfor
+endfunc
diff --git a/src/nvim/testdir/test_undo.vim b/src/nvim/testdir/test_undo.vim
new file mode 100644
index 0000000000..171618f6f7
--- /dev/null
+++ b/src/nvim/testdir/test_undo.vim
@@ -0,0 +1,267 @@
+" Tests for the undo tree.
+" Since this script is sourced we need to explicitly break changes up in
+" undo-able pieces. Do that by setting 'undolevels'.
+" Also tests :earlier and :later.
+
+func Test_undotree()
+ exe "normal Aabc\<Esc>"
+ set ul=100
+ exe "normal Adef\<Esc>"
+ set ul=100
+ undo
+ let d = undotree()
+ call assert_true(d.seq_last > 0)
+ call assert_true(d.seq_cur > 0)
+ call assert_true(d.seq_cur < d.seq_last)
+ call assert_true(len(d.entries) > 0)
+ " TODO: check more members of d
+
+ w! Xtest
+ call assert_equal(d.save_last + 1, undotree().save_last)
+ call delete('Xtest')
+ bwipe Xtest
+endfunc
+
+func FillBuffer()
+ for i in range(1,13)
+ put=i
+ " Set 'undolevels' to split undo.
+ exe "setg ul=" . &g:ul
+ endfor
+endfunc
+
+func Test_global_local_undolevels()
+ new one
+ set undolevels=5
+ call FillBuffer()
+ " will only undo the last 5 changes, end up with 13 - (5 + 1) = 7 lines
+ earlier 10
+ call assert_equal(5, &g:undolevels)
+ call assert_equal(-123456, &l:undolevels)
+ call assert_equal('7', getline('$'))
+
+ new two
+ setlocal undolevels=2
+ call FillBuffer()
+ " will only undo the last 2 changes, end up with 13 - (2 + 1) = 10 lines
+ earlier 10
+ call assert_equal(5, &g:undolevels)
+ call assert_equal(2, &l:undolevels)
+ call assert_equal('10', getline('$'))
+
+ setlocal ul=10
+ call assert_equal(5, &g:undolevels)
+ call assert_equal(10, &l:undolevels)
+
+ " Setting local value in "two" must not change local value in "one"
+ wincmd p
+ call assert_equal(5, &g:undolevels)
+ call assert_equal(-123456, &l:undolevels)
+
+ new three
+ setglobal ul=50
+ call assert_equal(50, &g:undolevels)
+ call assert_equal(-123456, &l:undolevels)
+
+ " Drop created windows
+ set ul&
+ new
+ only!
+endfunc
+
+func BackOne(expected)
+ call feedkeys('g-', 'xt')
+ call assert_equal(a:expected, getline(1))
+endfunc
+
+func Test_undo_del_chars()
+ throw 'skipped: Nvim does not support test_settime()'
+
+ " Setup a buffer without creating undo entries
+ new
+ set ul=-1
+ call setline(1, ['123-456'])
+ set ul=100
+ 1
+ call test_settime(100)
+
+ " Delete three characters and undo with g-
+ call feedkeys('x', 'xt')
+ call feedkeys('x', 'xt')
+ call feedkeys('x', 'xt')
+ call assert_equal('-456', getline(1))
+ call BackOne('3-456')
+ call BackOne('23-456')
+ call BackOne('123-456')
+ call assert_fails("BackOne('123-456')")
+
+ :" Delete three other characters and go back in time with g-
+ call feedkeys('$x', 'xt')
+ call feedkeys('x', 'xt')
+ call feedkeys('x', 'xt')
+ call assert_equal('123-', getline(1))
+ call test_settime(101)
+
+ call BackOne('123-4')
+ call BackOne('123-45')
+ " skips '123-456' because it's older
+ call BackOne('-456')
+ call BackOne('3-456')
+ call BackOne('23-456')
+ call BackOne('123-456')
+ call assert_fails("BackOne('123-456')")
+ normal 10g+
+ call assert_equal('123-', getline(1))
+
+ :" Jump two seconds and go some seconds forward and backward
+ call test_settime(103)
+ call feedkeys("Aa\<Esc>", 'xt')
+ call feedkeys("Ab\<Esc>", 'xt')
+ call feedkeys("Ac\<Esc>", 'xt')
+ call assert_equal('123-abc', getline(1))
+ earlier 1s
+ call assert_equal('123-', getline(1))
+ earlier 3s
+ call assert_equal('123-456', getline(1))
+ later 1s
+ call assert_equal('123-', getline(1))
+ later 1h
+ call assert_equal('123-abc', getline(1))
+
+ close!
+endfunc
+
+func Test_undolist()
+ new
+ set ul=100
+
+ let a=execute('undolist')
+ call assert_equal("\nNothing to undo", a)
+
+ " 1 leaf (2 changes).
+ call feedkeys('achange1', 'xt')
+ call feedkeys('achange2', 'xt')
+ let a=execute('undolist')
+ call assert_match("^\nnumber changes when *saved\n *2 *2 .*$", a)
+
+ " 2 leaves.
+ call feedkeys('u', 'xt')
+ call feedkeys('achange3\<Esc>', 'xt')
+ let a=execute('undolist')
+ call assert_match("^\nnumber changes when *saved\n *2 *2 *.*\n *3 *2 .*$", a)
+ close!
+endfunc
+
+func Test_U_command()
+ new
+ set ul=100
+ call feedkeys("achange1\<Esc>", 'xt')
+ call feedkeys("achange2\<Esc>", 'xt')
+ norm! U
+ call assert_equal('', getline(1))
+ norm! U
+ call assert_equal('change1change2', getline(1))
+ close!
+endfunc
+
+func Test_undojoin()
+ new
+ call feedkeys("Goaaaa\<Esc>", 'xt')
+ call feedkeys("obbbb\<Esc>", 'xt')
+ call assert_equal(['aaaa', 'bbbb'], getline(2, '$'))
+ call feedkeys("u", 'xt')
+ call assert_equal(['aaaa'], getline(2, '$'))
+ call feedkeys("obbbb\<Esc>", 'xt')
+ undojoin
+ " Note: next change must not be as if typed
+ call feedkeys("occcc\<Esc>", 'x')
+ call assert_equal(['aaaa', 'bbbb', 'cccc'], getline(2, '$'))
+ call feedkeys("u", 'xt')
+ call assert_equal(['aaaa'], getline(2, '$'))
+ close!
+endfunc
+
+func Test_undo_write()
+ split Xtest
+ call feedkeys("ione one one\<Esc>", 'xt')
+ w!
+ call feedkeys("otwo\<Esc>", 'xt')
+ call feedkeys("otwo\<Esc>", 'xt')
+ w
+ call feedkeys("othree\<Esc>", 'xt')
+ call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
+ earlier 1f
+ call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
+ earlier 1f
+ call assert_equal(['one one one'], getline(1, '$'))
+ earlier 1f
+ call assert_equal([''], getline(1, '$'))
+ later 1f
+ call assert_equal(['one one one'], getline(1, '$'))
+ later 1f
+ call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
+ later 1f
+ call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
+
+ close!
+ call delete('Xtest')
+ bwipe! Xtest
+endfunc
+
+func Test_insert_expr()
+ new
+ " calling setline() triggers undo sync
+ call feedkeys("oa\<Esc>", 'xt')
+ call feedkeys("ob\<Esc>", 'xt')
+ set ul=100
+ call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
+ call assert_equal(['a', 'b', '120', '34'], getline(2, '$'))
+ call feedkeys("u", 'x')
+ call assert_equal(['a', 'b', '12'], getline(2, '$'))
+ call feedkeys("u", 'x')
+ call assert_equal(['a', 'b'], getline(2, '$'))
+
+ call feedkeys("oc\<Esc>", 'xt')
+ set ul=100
+ call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
+ call assert_equal(['a', 'b', 'c', '120', '34'], getline(2, '$'))
+ call feedkeys("u", 'x')
+ call assert_equal(['a', 'b', 'c', '12'], getline(2, '$'))
+
+ call feedkeys("od\<Esc>", 'xt')
+ set ul=100
+ call feedkeys("o1\<Esc>a2\<C-R>=string(123)\<CR>\<Esc>", 'x')
+ call assert_equal(['a', 'b', 'c', '12', 'd', '12123'], getline(2, '$'))
+ call feedkeys("u", 'x')
+ call assert_equal(['a', 'b', 'c', '12', 'd'], getline(2, '$'))
+
+ close!
+endfunc
+
+func Test_undofile_earlier()
+ throw 'skipped: Nvim does not support test_settime()'
+
+ let t0 = localtime() - 43200
+ call test_settime(t0)
+ new Xfile
+ call feedkeys("ione\<Esc>", 'xt')
+ set ul=100
+ call test_settime(t0 + 1)
+ call feedkeys("otwo\<Esc>", 'xt')
+ set ul=100
+ call test_settime(t0 + 2)
+ call feedkeys("othree\<Esc>", 'xt')
+ set ul=100
+ w
+ wundo Xundofile
+ bwipe!
+ " restore normal timestamps.
+ call test_settime(0)
+ new Xfile
+ rundo Xundofile
+ earlier 1d
+ call assert_equal('', getline(1))
+ bwipe!
+ call delete('Xfile')
+ call delete('Xundofile')
+endfunc
diff --git a/src/nvim/testdir/test_utf8.vim b/src/nvim/testdir/test_utf8.vim
new file mode 100644
index 0000000000..24e3db86fb
--- /dev/null
+++ b/src/nvim/testdir/test_utf8.vim
@@ -0,0 +1,65 @@
+" Tests for Unicode manipulations
+if !has('multi_byte')
+ finish
+endif
+
+
+" Visual block Insert adjusts for multi-byte char
+func Test_visual_block_insert()
+ new
+ call setline(1, ["aaa", "ã‚ã‚ã‚", "bbb"])
+ exe ":norm! gg0l\<C-V>jjIx\<Esc>"
+ call assert_equal(['axaa', 'xã‚ã‚ã‚', 'bxbb'], getline(1, '$'))
+ bwipeout!
+endfunc
+
+" Test for built-in function strchars()
+func Test_strchars()
+ let inp = ["a", "ã‚ã„a", "A\u20dd", "A\u20dd\u20dd", "\u20dd"]
+ let exp = [[1, 1, 1], [3, 3, 3], [2, 2, 1], [3, 3, 1], [1, 1, 1]]
+ for i in range(len(inp))
+ call assert_equal(exp[i][0], strchars(inp[i]))
+ call assert_equal(exp[i][1], strchars(inp[i], 0))
+ call assert_equal(exp[i][2], strchars(inp[i], 1))
+ endfor
+endfunc
+
+" Test for customlist completion
+function! CustomComplete1(lead, line, pos)
+ return ['ã‚', 'ã„']
+endfunction
+
+function! CustomComplete2(lead, line, pos)
+ return ['ã‚ãŸã—', 'ã‚ãŸã¾', 'ã‚ãŸã‚Šã‚']
+endfunction
+
+function! CustomComplete3(lead, line, pos)
+ return ['Nã“', 'Nã‚“', 'Nã¶']
+endfunction
+
+func Test_customlist_completion()
+ command -nargs=1 -complete=customlist,CustomComplete1 Test1 echo
+ call feedkeys(":Test1 \<C-L>\<C-B>\"\<CR>", 'itx')
+ call assert_equal('"Test1 ', getreg(':'))
+
+ command -nargs=1 -complete=customlist,CustomComplete2 Test2 echo
+ call feedkeys(":Test2 \<C-L>\<C-B>\"\<CR>", 'itx')
+ call assert_equal('"Test2 ã‚ãŸ', getreg(':'))
+
+ command -nargs=1 -complete=customlist,CustomComplete3 Test3 echo
+ call feedkeys(":Test3 \<C-L>\<C-B>\"\<CR>", 'itx')
+ call assert_equal('"Test3 N', getreg(':'))
+
+ call garbagecollect(1)
+endfunc
+
+" Yank one 3 byte character and check the mark columns.
+func Test_getvcol()
+ new
+ call setline(1, "x\u2500x")
+ normal 0lvy
+ call assert_equal(2, col("'["))
+ call assert_equal(4, col("']"))
+ call assert_equal(2, virtcol("'["))
+ call assert_equal(2, virtcol("']"))
+endfunc
diff --git a/src/nvim/testdir/test_viml.vim b/src/nvim/testdir/test_vimscript.vim
index a2997b6d4d..4e0f1bbd2f 100644
--- a/src/nvim/testdir/test_viml.vim
+++ b/src/nvim/testdir/test_vimscript.vim
@@ -1062,6 +1062,157 @@ func Test_echo_and_string()
call assert_equal(["{'a': [], 'b': []}",
\ "{'a': [], 'b': []}"], l)
+"-------------------------------------------------------------------------------
+" Test 94: 64-bit Numbers {{{1
+"-------------------------------------------------------------------------------
+
+func Test_num64()
+ if !has('num64')
+ return
+ endif
+
+ call assert_notequal( 4294967296, 0)
+ call assert_notequal(-4294967296, 0)
+ call assert_equal( 4294967296, 0xFFFFffff + 1)
+ call assert_equal(-4294967296, -0xFFFFffff - 1)
+
+ call assert_equal( 9223372036854775807, 1 / 0)
+ call assert_equal(-9223372036854775807, -1 / 0)
+ call assert_equal(-9223372036854775807 - 1, 0 / 0)
+
+ call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
+ call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
+
+ let rng = range(0xFFFFffff, 0x100000001)
+ call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng)
+ call assert_equal(0x100000001, max(rng))
+ call assert_equal(0xFFFFffff, min(rng))
+ call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N'))
+endfunc
+
+"-------------------------------------------------------------------------------
+" Test 95: lines of :append, :change, :insert {{{1
+"-------------------------------------------------------------------------------
+
+function! DefineFunction(name, body)
+ let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n")
+ exec func
+endfunction
+
+func Test_script_lines()
+ " :append
+ try
+ call DefineFunction('T_Append', [
+ \ 'append',
+ \ 'py <<EOS',
+ \ '.',
+ \ ])
+ catch
+ call assert_report("Can't define function")
+ endtry
+ try
+ call DefineFunction('T_Append', [
+ \ 'append',
+ \ 'abc',
+ \ ])
+ call assert_report("Shouldn't be able to define function")
+ catch
+ call assert_exception('Vim(function):E126: Missing :endfunction')
+ endtry
+
+ " :change
+ try
+ call DefineFunction('T_Change', [
+ \ 'change',
+ \ 'py <<EOS',
+ \ '.',
+ \ ])
+ catch
+ call assert_report("Can't define function")
+ endtry
+ try
+ call DefineFunction('T_Change', [
+ \ 'change',
+ \ 'abc',
+ \ ])
+ call assert_report("Shouldn't be able to define function")
+ catch
+ call assert_exception('Vim(function):E126: Missing :endfunction')
+ endtry
+
+ " :insert
+ try
+ call DefineFunction('T_Insert', [
+ \ 'insert',
+ \ 'py <<EOS',
+ \ '.',
+ \ ])
+ catch
+ call assert_report("Can't define function")
+ endtry
+ try
+ call DefineFunction('T_Insert', [
+ \ 'insert',
+ \ 'abc',
+ \ ])
+ call assert_report("Shouldn't be able to define function")
+ catch
+ call assert_exception('Vim(function):E126: Missing :endfunction')
+ endtry
+endfunc
+
+"-------------------------------------------------------------------------------
+" Test 96: line continuation {{{1
+"
+" Undefined behavior was detected by ubsan with line continuation
+" after an empty line.
+"-------------------------------------------------------------------------------
+func Test_script_emty_line_continuation()
+
+ \
+endfunc
+
+"-------------------------------------------------------------------------------
+" Test 97: bitwise functions {{{1
+"-------------------------------------------------------------------------------
+func Test_bitwise_functions()
+ " and
+ call assert_equal(127, and(127, 127))
+ call assert_equal(16, and(127, 16))
+ call assert_equal(0, and(127, 128))
+ call assert_fails("call and(1.0, 1)", 'E805:')
+ call assert_fails("call and([], 1)", 'E745:')
+ call assert_fails("call and({}, 1)", 'E728:')
+ call assert_fails("call and(1, 1.0)", 'E805:')
+ call assert_fails("call and(1, [])", 'E745:')
+ call assert_fails("call and(1, {})", 'E728:')
+ " or
+ call assert_equal(23, or(16, 7))
+ call assert_equal(15, or(8, 7))
+ call assert_equal(123, or(0, 123))
+ call assert_fails("call or(1.0, 1)", 'E805:')
+ call assert_fails("call or([], 1)", 'E745:')
+ call assert_fails("call or({}, 1)", 'E728:')
+ call assert_fails("call or(1, 1.0)", 'E805:')
+ call assert_fails("call or(1, [])", 'E745:')
+ call assert_fails("call or(1, {})", 'E728:')
+ " xor
+ call assert_equal(0, xor(127, 127))
+ call assert_equal(111, xor(127, 16))
+ call assert_equal(255, xor(127, 128))
+ call assert_fails("call xor(1.0, 1)", 'E805:')
+ call assert_fails("call xor([], 1)", 'E745:')
+ call assert_fails("call xor({}, 1)", 'E728:')
+ call assert_fails("call xor(1, 1.0)", 'E805:')
+ call assert_fails("call xor(1, [])", 'E745:')
+ call assert_fails("call xor(1, {})", 'E728:')
+ " invert
+ call assert_equal(65408, and(invert(127), 65535))
+ call assert_equal(65519, and(invert(16), 65535))
+ call assert_equal(65407, and(invert(128), 65535))
+ call assert_fails("call invert(1.0)", 'E805:')
+ call assert_fails("call invert([])", 'E745:')
+ call assert_fails("call invert({})", 'E728:')
endfunc
"-------------------------------------------------------------------------------
diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim
index b7f41a711b..9d61921988 100644
--- a/src/nvim/testdir/test_window_cmd.vim
+++ b/src/nvim/testdir/test_window_cmd.vim
@@ -67,4 +67,360 @@ function Test_window_cmd_wincmd_gf()
augroup! test_window_cmd_wincmd_gf
endfunc
-" vim: sw=2 et
+func Test_next_split_all()
+ " This was causing an illegal memory access.
+ n x
+ norm axxx
+ split
+ split
+ s/x
+ s/x
+ all
+ bwipe!
+endfunc
+
+func Test_window_quit()
+ e Xa
+ split Xb
+ call assert_equal(2, winnr('$'))
+ call assert_equal('Xb', bufname(winbufnr(1)))
+ call assert_equal('Xa', bufname(winbufnr(2)))
+
+ wincmd q
+ call assert_equal(1, winnr('$'))
+ call assert_equal('Xa', bufname(winbufnr(1)))
+
+ bw Xa Xb
+endfunc
+
+func Test_window_horizontal_split()
+ call assert_equal(1, winnr('$'))
+ 3wincmd s
+ call assert_equal(2, winnr('$'))
+ call assert_equal(3, winheight(0))
+ call assert_equal(winwidth(1), winwidth(2))
+
+ call assert_fails('botright topleft wincmd s', 'E442:')
+ bw
+endfunc
+
+func Test_window_vertical_split()
+ call assert_equal(1, winnr('$'))
+ 3wincmd v
+ call assert_equal(2, winnr('$'))
+ call assert_equal(3, winwidth(0))
+ call assert_equal(winheight(1), winheight(2))
+
+ call assert_fails('botright topleft wincmd v', 'E442:')
+ bw
+endfunc
+
+func Test_window_split_edit_alternate()
+ e Xa
+ e Xb
+
+ wincmd ^
+ call assert_equal('Xa', bufname(winbufnr(1)))
+ call assert_equal('Xb', bufname(winbufnr(2)))
+
+ bw Xa Xb
+endfunc
+
+func Test_window_preview()
+ " Open a preview window
+ pedit Xa
+ call assert_equal(2, winnr('$'))
+ call assert_equal(0, &previewwindow)
+
+ " Go to the preview window
+ wincmd P
+ call assert_equal(1, &previewwindow)
+
+ " Close preview window
+ wincmd z
+ call assert_equal(1, winnr('$'))
+ call assert_equal(0, &previewwindow)
+
+ call assert_fails('wincmd P', 'E441:')
+endfunc
+
+func Test_window_exchange()
+ e Xa
+
+ " Nothing happens with window exchange when there is 1 window
+ wincmd x
+ call assert_equal(1, winnr('$'))
+
+ split Xb
+ split Xc
+
+ call assert_equal('Xc', bufname(winbufnr(1)))
+ call assert_equal('Xb', bufname(winbufnr(2)))
+ call assert_equal('Xa', bufname(winbufnr(3)))
+
+ " Exchange current window 1 with window 3
+ 3wincmd x
+ call assert_equal('Xa', bufname(winbufnr(1)))
+ call assert_equal('Xb', bufname(winbufnr(2)))
+ call assert_equal('Xc', bufname(winbufnr(3)))
+
+ " Exchange window with next when at the top window
+ wincmd x
+ call assert_equal('Xb', bufname(winbufnr(1)))
+ call assert_equal('Xa', bufname(winbufnr(2)))
+ call assert_equal('Xc', bufname(winbufnr(3)))
+
+ " Exchange window with next when at the middle window
+ wincmd j
+ wincmd x
+ call assert_equal('Xb', bufname(winbufnr(1)))
+ call assert_equal('Xc', bufname(winbufnr(2)))
+ call assert_equal('Xa', bufname(winbufnr(3)))
+
+ " Exchange window with next when at the bottom window.
+ " When there is no next window, it exchanges with the previous window.
+ wincmd j
+ wincmd x
+ call assert_equal('Xb', bufname(winbufnr(1)))
+ call assert_equal('Xa', bufname(winbufnr(2)))
+ call assert_equal('Xc', bufname(winbufnr(3)))
+
+ bw Xa Xb Xc
+endfunc
+
+func Test_window_rotate()
+ e Xa
+ split Xb
+ split Xc
+ call assert_equal('Xc', bufname(winbufnr(1)))
+ call assert_equal('Xb', bufname(winbufnr(2)))
+ call assert_equal('Xa', bufname(winbufnr(3)))
+
+ " Rotate downwards
+ wincmd r
+ call assert_equal('Xa', bufname(winbufnr(1)))
+ call assert_equal('Xc', bufname(winbufnr(2)))
+ call assert_equal('Xb', bufname(winbufnr(3)))
+
+ 2wincmd r
+ call assert_equal('Xc', bufname(winbufnr(1)))
+ call assert_equal('Xb', bufname(winbufnr(2)))
+ call assert_equal('Xa', bufname(winbufnr(3)))
+
+ " Rotate upwards
+ wincmd R
+ call assert_equal('Xb', bufname(winbufnr(1)))
+ call assert_equal('Xa', bufname(winbufnr(2)))
+ call assert_equal('Xc', bufname(winbufnr(3)))
+
+ 2wincmd R
+ call assert_equal('Xc', bufname(winbufnr(1)))
+ call assert_equal('Xb', bufname(winbufnr(2)))
+ call assert_equal('Xa', bufname(winbufnr(3)))
+
+ bot vsplit
+ call assert_fails('wincmd R', 'E443:')
+
+ bw Xa Xb Xc
+endfunc
+
+func Test_window_height()
+ e Xa
+ split Xb
+
+ let [wh1, wh2] = [winheight(1), winheight(2)]
+ " Active window (1) should have the same height or 1 more
+ " than the other window.
+ call assert_inrange(wh2, wh2 + 1, wh1)
+
+ wincmd -
+ call assert_equal(wh1 - 1, winheight(1))
+ call assert_equal(wh2 + 1, winheight(2))
+
+ wincmd +
+ call assert_equal(wh1, winheight(1))
+ call assert_equal(wh2, winheight(2))
+
+ 2wincmd _
+ call assert_equal(2, winheight(1))
+ call assert_equal(wh1 + wh2 - 2, winheight(2))
+
+ wincmd =
+ call assert_equal(wh1, winheight(1))
+ call assert_equal(wh2, winheight(2))
+
+ 2wincmd _
+ set winfixheight
+ split Xc
+ let [wh1, wh2, wh3] = [winheight(1), winheight(2), winheight(3)]
+ call assert_equal(2, winheight(2))
+ call assert_inrange(wh3, wh3 + 1, wh1)
+ 3wincmd +
+ call assert_equal(2, winheight(2))
+ call assert_equal(wh1 + 3, winheight(1))
+ call assert_equal(wh3 - 3, winheight(3))
+ wincmd =
+ call assert_equal(2, winheight(2))
+ call assert_equal(wh1, winheight(1))
+ call assert_equal(wh3, winheight(3))
+
+ wincmd j
+ set winfixheight&
+
+ wincmd =
+ let [wh1, wh2, wh3] = [winheight(1), winheight(2), winheight(3)]
+ " Current window (2) should have the same height or 1 more
+ " than the other windows.
+ call assert_inrange(wh1, wh1 + 1, wh2)
+ call assert_inrange(wh3, wh3 + 1, wh2)
+
+ bw Xa Xb Xc
+endfunc
+
+func Test_window_width()
+ e Xa
+ vsplit Xb
+
+ let [ww1, ww2] = [winwidth(1), winwidth(2)]
+ " Active window (1) should have the same width or 1 more
+ " than the other window.
+ call assert_inrange(ww2, ww2 + 1, ww1)
+
+ wincmd <
+ call assert_equal(ww1 - 1, winwidth(1))
+ call assert_equal(ww2 + 1, winwidth(2))
+
+ wincmd >
+ call assert_equal(ww1, winwidth(1))
+ call assert_equal(ww2, winwidth(2))
+
+ 2wincmd |
+ call assert_equal(2, winwidth(1))
+ call assert_equal(ww1 + ww2 - 2, winwidth(2))
+
+ wincmd =
+ call assert_equal(ww1, winwidth(1))
+ call assert_equal(ww2, winwidth(2))
+
+ 2wincmd |
+ set winfixwidth
+ vsplit Xc
+ let [ww1, ww2, ww3] = [winwidth(1), winwidth(2), winwidth(3)]
+ " FIXME: commented out: I would expect the width of 2nd window to
+ " remain 2 but it's actually 1?!
+ "call assert_equal(2, winwidth(2))
+ call assert_inrange(ww3, ww3 + 1, ww1)
+ 3wincmd >
+ " FIXME: commented out: I would expect the width of 2nd window to
+ " remain 2 but it's actually 1?!
+ "call assert_equal(2, winwidth(2))
+ call assert_equal(ww1 + 3, winwidth(1))
+ call assert_equal(ww3 - 3, winwidth(3))
+ wincmd =
+ " FIXME: commented out: I would expect the width of 2nd window to
+ " remain 2 but it's actually 1?!
+ "call assert_equal(2, winwidth(2))
+ call assert_equal(ww1, winwidth(1))
+ call assert_equal(ww3, winwidth(3))
+
+ wincmd l
+ set winfixwidth&
+
+ wincmd =
+ let [ww1, ww2, ww3] = [winwidth(1), winwidth(2), winwidth(3)]
+ " Current window (2) should have the same width or 1 more
+ " than the other windows.
+ call assert_inrange(ww1, ww1 + 1, ww2)
+ call assert_inrange(ww3, ww3 + 1, ww2)
+
+ bw Xa Xb Xc
+endfunc
+
+func Test_equalalways_on_close()
+ set equalalways
+ vsplit
+ windo split
+ split
+ wincmd J
+ " now we have a frame top-left with two windows, a frame top-right with two
+ " windows and a frame at the bottom, full-width.
+ let height_1 = winheight(1)
+ let height_2 = winheight(2)
+ let height_3 = winheight(3)
+ let height_4 = winheight(4)
+ " closing the bottom window causes all windows to be resized.
+ close
+ call assert_notequal(height_1, winheight(1))
+ call assert_notequal(height_2, winheight(2))
+ call assert_notequal(height_3, winheight(3))
+ call assert_notequal(height_4, winheight(4))
+ call assert_equal(winheight(1), winheight(3))
+ call assert_equal(winheight(2), winheight(4))
+
+ 1wincmd w
+ split
+ 4wincmd w
+ resize + 5
+ " left column has three windows, equalized heights.
+ " right column has two windows, top one a bit higher
+ let height_1 = winheight(1)
+ let height_2 = winheight(2)
+ let height_4 = winheight(4)
+ let height_5 = winheight(5)
+ 3wincmd w
+ " closing window in left column equalizes heights in left column but not in
+ " the right column
+ close
+ call assert_notequal(height_1, winheight(1))
+ call assert_notequal(height_2, winheight(2))
+ call assert_equal(height_4, winheight(3))
+ call assert_equal(height_5, winheight(4))
+
+ only
+ set equalalways&
+endfunc
+
+func Test_window_jump_tag()
+ help
+ /iccf
+ call assert_match('^|iccf|', getline('.'))
+ call assert_equal(2, winnr('$'))
+ 2wincmd }
+ call assert_equal(3, winnr('$'))
+ call assert_match('^|iccf|', getline('.'))
+ wincmd k
+ call assert_match('\*iccf\*', getline('.'))
+ call assert_equal(2, winheight(0))
+
+ wincmd z
+ set previewheight=4
+ help
+ /bugs
+ wincmd }
+ wincmd k
+ call assert_match('\*bugs\*', getline('.'))
+ call assert_equal(4, winheight(0))
+ set previewheight&
+
+ %bw!
+endfunc
+
+func Test_window_newtab()
+ e Xa
+
+ call assert_equal(1, tabpagenr('$'))
+ call assert_equal("\nAlready only one window", execute('wincmd T'))
+
+ split Xb
+ split Xc
+
+ wincmd T
+ call assert_equal(2, tabpagenr('$'))
+ call assert_equal(['Xb', 'Xa'], map(tabpagebuflist(1), 'bufname(v:val)'))
+ call assert_equal(['Xc' ], map(tabpagebuflist(2), 'bufname(v:val)'))
+
+ %bw!
+endfunc
+
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_window_id.vim b/src/nvim/testdir/test_window_id.vim
index 66656e1d0a..b3b506d04d 100644
--- a/src/nvim/testdir/test_window_id.vim
+++ b/src/nvim/testdir/test_window_id.vim
@@ -92,3 +92,12 @@ func Test_win_getid()
only!
endfunc
+
+func Test_win_getid_curtab()
+ tabedit X
+ tabfirst
+ copen
+ only
+ call assert_equal(win_getid(1), win_getid(1, 1))
+ tabclose!
+endfunc
diff --git a/src/nvim/testdir/test_writefile.vim b/src/nvim/testdir/test_writefile.vim
new file mode 100644
index 0000000000..d820c580ac
--- /dev/null
+++ b/src/nvim/testdir/test_writefile.vim
@@ -0,0 +1,16 @@
+
+function! Test_WriteFile()
+ let f = tempname()
+ call writefile(["over","written"], f, "b")
+ call writefile(["hello","world"], f, "b")
+ call writefile(["!", "good"], f, "a")
+ call writefile(["morning"], f, "ab")
+ call writefile(["", "vimmers"], f, "ab")
+ let l = readfile(f)
+ call assert_equal("hello", l[0])
+ call assert_equal("world!", l[1])
+ call assert_equal("good", l[2])
+ call assert_equal("morning", l[3])
+ call assert_equal("vimmers", l[4])
+ call delete(f)
+endfunction
diff --git a/src/nvim/testdir/view_util.vim b/src/nvim/testdir/view_util.vim
new file mode 100644
index 0000000000..eb92630761
--- /dev/null
+++ b/src/nvim/testdir/view_util.vim
@@ -0,0 +1,30 @@
+" Functions about view shared by several tests
+
+" ScreenLines(lnum, width) or
+" ScreenLines([start, end], width)
+function! ScreenLines(lnum, width) abort
+ redraw!
+ if type(a:lnum) == v:t_list
+ let start = a:lnum[0]
+ let end = a:lnum[1]
+ else
+ let start = a:lnum
+ let end = a:lnum
+ endif
+ let lines = []
+ for l in range(start, end)
+ let lines += [join(map(range(1, a:width), 'nr2char(screenchar(l, v:val))'), '')]
+ endfor
+ return lines
+endfunction
+
+function! NewWindow(height, width) abort
+ exe a:height . 'new'
+ exe a:width . 'vsp'
+ redraw!
+endfunction
+
+function! CloseWindow() abort
+ bw!
+ redraw!
+endfunction
diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c
index 8e5adb14f9..03587d68f0 100644
--- a/src/nvim/tui/input.c
+++ b/src/nvim/tui/input.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include "nvim/tui/input.h"
#include "nvim/vim.h"
@@ -44,7 +47,13 @@ void term_input_init(TermInput *input, Loop *loop)
int curflags = termkey_get_canonflags(input->tk);
termkey_set_canonflags(input->tk, curflags | TERMKEY_CANON_DELBS);
// setup input handle
+#ifdef WIN32
+ uv_tty_init(loop, &input->tty_in, 0, 1);
+ uv_tty_set_mode(&input->tty_in, UV_TTY_MODE_RAW);
+ rstream_init_stream(&input->read_stream, &input->tty_in, 0xfff);
+#else
rstream_init_fd(loop, &input->read_stream, input->in_fd, 0xfff);
+#endif
// initialize a timer handle for handling ESC with libtermkey
time_watcher_init(loop, &input->timer_handle, input);
}
@@ -99,7 +108,7 @@ static void flush_input(TermInput *input, bool wait_until_empty)
size_t drain_boundary = wait_until_empty ? 0 : 0xff;
do {
uv_mutex_lock(&input->key_buffer_mutex);
- loop_schedule(&main_loop, event_create(1, wait_input_enqueue, 1, input));
+ loop_schedule(&main_loop, event_create(wait_input_enqueue, 1, input));
input->waiting = true;
while (input->waiting) {
uv_cond_wait(&input->key_buffer_cond, &input->key_buffer_mutex);
@@ -220,12 +229,14 @@ static int get_key_code_timeout(void)
{
Integer ms = -1;
// Check 'ttimeout' to determine if we should send ESC after 'ttimeoutlen'.
- // See :help 'ttimeout' for more information
Error err = ERROR_INIT;
if (nvim_get_option(cstr_as_string("ttimeout"), &err).data.boolean) {
- ms = nvim_get_option(cstr_as_string("ttimeoutlen"), &err).data.integer;
+ Object rv = nvim_get_option(cstr_as_string("ttimeoutlen"), &err);
+ if (!ERROR_SET(&err)) {
+ ms = rv.data.integer;
+ }
}
-
+ api_clear_error(&err);
return (int)ms;
}
@@ -347,7 +358,7 @@ static void read_cb(Stream *stream, RBuffer *buf, size_t c, void *data,
stream_close(&input->read_stream, NULL, NULL);
multiqueue_put(input->loop->fast_events, restart_reading, 1, input);
} else {
- loop_schedule(&main_loop, event_create(1, input_done_event, 0));
+ loop_schedule(&main_loop, event_create(input_done_event, 0));
}
return;
}
diff --git a/src/nvim/tui/input.h b/src/nvim/tui/input.h
index 7d59cf5c6a..573cc9d683 100644
--- a/src/nvim/tui/input.h
+++ b/src/nvim/tui/input.h
@@ -17,6 +17,9 @@ typedef struct term_input {
#endif
TimeWatcher timer_handle;
Loop *loop;
+#ifdef WIN32
+ uv_tty_t tty_in;
+#endif
Stream read_stream;
RBuffer *key_buffer;
uv_mutex_t key_buffer_mutex;
diff --git a/src/nvim/tui/terminfo.c b/src/nvim/tui/terminfo.c
new file mode 100644
index 0000000000..586fafba97
--- /dev/null
+++ b/src/nvim/tui/terminfo.c
@@ -0,0 +1,123 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+// Built-in fallback terminfo entries.
+
+#include <unibilium.h>
+
+#include "nvim/tui/terminfo.h"
+#include "nvim/tui/tui.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "tui/terminfo.c.generated.h"
+#endif
+
+// One creates the dumps from terminfo.src by using
+// od -t d1 -w | cut -c9- | sed -e 's/\>/,/g'
+// on the compiled files.
+
+// Taken from Dickey ncurses terminfo.src dated 2017-04-22.
+// This is a 256-colour terminfo description that lacks true-colour and
+// DECSTBM/DECSLRM/DECLRMM capabilities that xterm actually has.
+static const signed char xterm_256colour_terminfo[] = {
+ 26, 1, 37, 0, 29, 0, 15, 0, 105, 1, -42, 5, 120, 116, 101, 114, 109, 45, 50, 53, 54, 99, 111, 108, 111, 114, 124, 120, 116, 101, 114, 109, 32, 119, 105, 116, 104, 32, 50, 53, 54, 32, 99, 111, 108, 111, 114, 115, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 80, 0, 8, 0, 24, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 127, 0, 0, 4, 0, 6, 0, 8, 0, 25, 0, 30, 0, 38, 0, 42, 0, 46, 0, -1, -1, 57, 0, 74, 0, 76, 0, 80, 0, 87, 0, -1, -1, 89, 0, 102, 0, -1, -1, 106, 0, 110, 0, 120, 0, 124, 0, -1, -1, -1, -1,-128, 0,-124, 0,-119, 0,-114, 0, -1, -1,-105, 0,-100, 0, -95, 0, -1, -1, -90, 0, -85, 0, -80, 0, -75, 0, -66, 0, -62, 0, -55, 0, -1, -1, -46, 0, -41, 0, -35, 0, -29, 0, -1, -1, -1, -1, -1, -1, -11, 0, -1, -1, -1, -1, -1, -1, 7, 1, -1, -1, 11, 1, -1, -1, -1, -1, -1, -1, 13, 1, -1, -1, 18, 1, -1, -1, -1, -1, -1, -1, -1, -1, 22, 1, 26, 1, 32, 1, 36, 1, 40, 1, 44, 1, 50, 1, 56, 1, 62, 1, 68, 1, 74, 1, 78, 1, -1, -1, 83, 1, -1, -1, 87, 1, 92, 1, 97, 1, 101, 1, 108, 1, -1, -1, 115, 1, 119, 1, 127, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-121, 1,-112, 1, -1, -1, -1, -1,-103, 1, -94, 1, -85, 1, -76, 1, -67, 1, -58, 1, -49, 1, -40, 1, -31, 1, -22, 1, -1, -1, -1, -1, -1, -1, -13, 1, -9, 1, -4, 1, -1, -1, 1, 2, 10, 2, -1, -1, -1, -1, 28, 2, 31, 2, 42, 2, 45, 2, 47, 2, 50, 2,-113, 2, -1, -1,-110, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-108, 2, -1, -1, -1, -1, -1, -1, -1, -1,-104, 2, -1, -1, -51, 2, -1, -1, -1, -1, -47, 2, -41, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -35, 2, -31, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -27, 2, -1, -1, -1, -1, -20, 2, -1, -1, -1, -1, -1, -1, -1, -1, -13, 2, -6, 2, 1, 3, -1, -1, -1, -1, 8, 3, -1, -1, 15, 3, -1, -1, -1, -1, -1, -1, 22, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29, 3, 35, 3, 41, 3, 48, 3, 55, 3, 62, 3, 69, 3, 77, 3, 85, 3, 93, 3, 101, 3, 109, 3, 117, 3, 125, 3,-123, 3,-116, 3,-109, 3,-102, 3, -95, 3, -87, 3, -79, 3, -71, 3, -63, 3, -55, 3, -47, 3, -39, 3, -31, 3, -24, 3, -17, 3, -10, 3, -3, 3, 5, 4, 13, 4, 21, 4, 29, 4, 37, 4, 45, 4, 53, 4, 61, 4, 68, 4, 75, 4, 82, 4, 89, 4, 97, 4, 105, 4, 113, 4, 121, 4,-127, 4,-119, 4,-111, 4,-103, 4, -96, 4, -89, 4, -82, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -77, 4, -66, 4, -61, 4, -42, 4, -38, 4, -29, 4, -22, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 72, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 77, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 83, 5, -1, -1, -1, -1, -1, -1, 87, 5,-106, 5, 27, 91, 90, 0, 7, 0, 13, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 114, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 50, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 71, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 0, 8, 0, 27, 91, 63, 49, 50, 108, 27, 91, 63, 50, 53, 104, 0, 27, 91, 67, 0, 27, 91, 65, 0, 27, 91, 63, 49, 50, 59, 50, 53, 104, 0, 27, 91, 80, 0, 27, 91, 77, 0, 27, 40, 48, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 27, 91, 63, 49, 48, 52, 57, 104, 0, 27, 91, 50, 109, 0, 27, 91, 52, 104, 0, 27, 91, 56, 109, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 27, 91, 37, 112, 49, 37, 100, 88, 0, 27, 40, 66, 0, 27, 40, 66, 27, 91, 109, 0, 27, 91, 63, 49, 48, 52, 57, 108, 0, 27, 91, 52, 108, 0, 27, 91, 50, 55, 109, 0, 27, 91, 50, 52, 109, 0, 27, 91, 63, 53, 104, 36, 60, 49, 48, 48, 47, 62, 27, 91, 63, 53, 108, 0, 27, 91, 33, 112, 27, 91, 63, 51, 59, 52, 108, 27, 91, 52, 108, 27, 62, 0, 27, 91, 76, 0, 8, 0, 27, 91, 51, 126, 0, 27, 79, 66, 0, 27, 79, 80, 0, 27, 91, 50, 49, 126, 0, 27, 79, 81, 0, 27, 79, 82, 0, 27, 79, 83, 0, 27, 91, 49, 53, 126, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 79, 72, 0, 27, 91, 50, 126, 0, 27, 79, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 79, 67, 0, 27, 91, 49, 59, 50, 66, 0, 27, 91, 49, 59, 50, 65, 0, 27, 79, 65, 0, 27, 91, 63, 49, 108, 27, 62, 0, 27, 91, 63, 49, 104, 27, 61, 0, 27, 91, 63, 49, 48, 51, 52, 108, 0, 27, 91, 63, 49, 48, 51, 52, 104, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 83, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 84, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 91, 105, 0, 27, 91, 52, 105, 0, 27, 91, 53, 105, 0, 27, 99, 27, 93, 49, 48, 52, 7, 0, 27, 91, 33, 112, 27, 91, 63, 51, 59, 52, 108, 27, 91, 52, 108, 27, 62, 0, 27, 56, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 100, 0, 27, 55, 0, 10, 0, 27, 77, 0, 37, 63, 37, 112, 57, 37, 116, 27, 40, 48, 37, 101, 27, 40, 66, 37, 59, 27, 91, 48, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 53, 37, 116, 59, 50, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 49, 37, 112, 51, 37, 124, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 37, 63, 37, 112, 55, 37, 116, 59, 56, 37, 59, 109, 0, 27, 72, 0, 9, 0, 27, 79, 69, 0, 96, 96, 97, 97, 102, 102, 103, 103, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 0, 27, 91, 90, 0, 27, 91, 63, 55, 104, 0, 27, 91, 63, 55, 108, 0, 27, 79, 70, 0, 27, 79, 77, 0, 27, 91, 51, 59, 50, 126, 0, 27, 91, 49, 59, 50, 70, 0, 27, 91, 49, 59, 50, 72, 0, 27, 91, 50, 59, 50, 126, 0, 27, 91, 49, 59, 50, 68, 0, 27, 91, 54, 59, 50, 126, 0, 27, 91, 53, 59, 50, 126, 0, 27, 91, 49, 59, 50, 67, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 49, 59, 50, 80, 0, 27, 91, 49, 59, 50, 81, 0, 27, 91, 49, 59, 50, 82, 0, 27, 91, 49, 59, 50, 83, 0, 27, 91, 49, 53, 59, 50, 126, 0, 27, 91, 49, 55, 59, 50, 126, 0, 27, 91, 49, 56, 59, 50, 126, 0, 27, 91, 49, 57, 59, 50, 126, 0, 27, 91, 50, 48, 59, 50, 126, 0, 27, 91, 50, 49, 59, 50, 126, 0, 27, 91, 50, 51, 59, 50, 126, 0, 27, 91, 50, 52, 59, 50, 126, 0, 27, 91, 49, 59, 53, 80, 0, 27, 91, 49, 59, 53, 81, 0, 27, 91, 49, 59, 53, 82, 0, 27, 91, 49, 59, 53, 83, 0, 27, 91, 49, 53, 59, 53, 126, 0, 27, 91, 49, 55, 59, 53, 126, 0, 27, 91, 49, 56, 59, 53, 126, 0, 27, 91, 49, 57, 59, 53, 126, 0, 27, 91, 50, 48, 59, 53, 126, 0, 27, 91, 50, 49, 59, 53, 126, 0, 27, 91, 50, 51, 59, 53, 126, 0, 27, 91, 50, 52, 59, 53, 126, 0, 27, 91, 49, 59, 54, 80, 0, 27, 91, 49, 59, 54, 81, 0, 27, 91, 49, 59, 54, 82, 0, 27, 91, 49, 59, 54, 83, 0, 27, 91, 49, 53, 59, 54, 126, 0, 27, 91, 49, 55, 59, 54, 126, 0, 27, 91, 49, 56, 59, 54, 126, 0, 27, 91, 49, 57, 59, 54, 126, 0, 27, 91, 50, 48, 59, 54, 126, 0, 27, 91, 50, 49, 59, 54, 126, 0, 27, 91, 50, 51, 59, 54, 126, 0, 27, 91, 50, 52, 59, 54, 126, 0, 27, 91, 49, 59, 51, 80, 0, 27, 91, 49, 59, 51, 81, 0, 27, 91, 49, 59, 51, 82, 0, 27, 91, 49, 59, 51, 83, 0, 27, 91, 49, 53, 59, 51, 126, 0, 27, 91, 49, 55, 59, 51, 126, 0, 27, 91, 49, 56, 59, 51, 126, 0, 27, 91, 49, 57, 59, 51, 126, 0, 27, 91, 50, 48, 59, 51, 126, 0, 27, 91, 50, 49, 59, 51, 126, 0, 27, 91, 50, 51, 59, 51, 126, 0, 27, 91, 50, 52, 59, 51, 126, 0, 27, 91, 49, 59, 52, 80, 0, 27, 91, 49, 59, 52, 81, 0, 27, 91, 49, 59, 52, 82, 0, 27, 91, 49, 75, 0, 27, 91, 37, 105, 37, 100, 59, 37, 100, 82, 0, 27, 91, 54, 110, 0, 27, 91, 63, 37, 91, 59, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 93, 99, 0, 27, 91, 99, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 93, 49, 48, 52, 7, 0, 27, 93, 52, 59, 37, 112, 49, 37, 100, 59, 114, 103, 98, 58, 37, 112, 50, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 47, 37, 112, 51, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 47, 37, 112, 52, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 27, 92, 0, 27, 91, 51, 109, 0, 27, 91, 50, 51, 109, 0, 27, 91, 77, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 51, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 57, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 51, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 52, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 49, 48, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 52, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0
+};
+// Taken from unibilium/t/static_tmux.c as of 2015-08-14.
+// This is an 256-colour terminfo description that lacks
+// status line capabilities that tmux actually has.
+static const signed char tmux_256colour_terminfo[] = {
+ 26, 1, 56, 0, 15, 0, 15, 0, 105, 1, -48, 2, 116, 109, 117, 120, 124, 86, 84, 32, 49, 48, 48, 47, 65, 78, 83, 73, 32, 88, 51, 46, 54, 52, 32, 118, 105, 114, 116, 117, 97, 108, 32, 116, 101, 114, 109, 105, 110, 97, 108, 32, 119, 105, 116, 104, 32, 50, 53, 54, 32, 99, 111, 108, 111, 114, 115, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 80, 0, 8, 0, 24, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 127, 0, 0, 4, 0, 6, 0, 8, 0, 25, 0, 30, 0, 37, 0, 41, 0, -1, -1, -1, -1, 45, 0, 62, 0, 64, 0, 68, 0, 75, 0, -1, -1, 77, 0, 89, 0, -1, -1, 93, 0, 96, 0, 102, 0, 106, 0, -1, -1, -1, -1, 110, 0, 112, 0, 117, 0, 122, 0, -1, -1, -1, -1, 123, 0, -1, -1, -1, -1, -128, 0, -123, 0, -118, 0, -1, -1, -113, 0, -111, 0, -106, 0, -1, -1, -105, 0, -100, 0, -94, 0, -88, 0, -1, -1, -1, -1, -1, -1, -85, 0, -1, -1, -1, -1, -1, -1, -81, 0, -1, -1, -77, 0, -1, -1, -1, -1, -1, -1, -75, 0, -1, -1, -70, 0, -1, -1, -1, -1, -1, -1, -1, -1, -66, 0, -62, 0, -56, 0, -52, 0, -48, 0, -44, 0, -38, 0, -32, 0, -26, 0, -20, 0, -14, 0, -9, 0, -1, -1, -4, 0, -1, -1, 0, 1, 5, 1, 10, 1, -1, -1, -1, -1, -1, -1, 14, 1, 18, 1, 26, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 34, 1, -1, -1, 37, 1, 46, 1, 55, 1, 64, 1, -1, -1, 73, 1, 82, 1, 91, 1, -1, -1, 100, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 109, 1, -1, -1, -1, -1, 126, 1, -1, -1, -127, 1, -124, 1, -122, 1, -119, 1, -46, 1, -1, -1, -43, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -41, 1, -1, -1, 24, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 28, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 35, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, 2, 46, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 52, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 57, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 71, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 77, 2, -1, -1, -1, -1, -1, -1, 81, 2, -112, 2, 27, 91, 90, 0, 7, 0, 13, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 114, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 0, 8, 0, 27, 91, 51, 52, 104, 27, 91, 63, 50, 53, 104, 0, 27, 91, 67, 0, 27, 77, 0, 27, 91, 51, 52, 108, 0, 27, 91, 80, 0, 27, 91, 77, 0, 14, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 0, 27, 91, 52, 104, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 15, 0, 27, 91, 109, 15, 0, 0, 27, 91, 52, 108, 0, 27, 91, 50, 55, 109, 0, 27, 91, 50, 52, 109, 0, 27, 103, 0, 27, 41, 48, 0, 27, 91, 76, 0, 8, 0, 27, 91, 51, 126, 0, 27, 79, 66, 0, 27, 79, 80, 0, 27, 91, 50, 49, 126, 0, 27, 79, 81, 0, 27, 79, 82, 0, 27, 79, 83, 0, 27, 91, 49, 53, 126, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 91, 49, 126, 0, 27, 91, 50, 126, 0, 27, 79, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 79, 67, 0, 27, 79, 65, 0, 27, 91, 63, 49, 108, 27, 62, 0, 27, 91, 63, 49, 104, 27, 61, 0, 27, 69, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 99, 27, 91, 63, 49, 48, 48, 48, 108, 27, 91, 63, 50, 53, 104, 0, 27, 56, 0, 27, 55, 0, 10, 0, 27, 77, 0, 27, 91, 48, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 49, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 51, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 109, 37, 63, 37, 112, 57, 37, 116, 14, 37, 101, 15, 37, 59, 0, 27, 72, 0, 9, 0, 43, 43, 44, 44, 45, 45, 46, 46, 48, 48, 96, 96, 97, 97, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 0, 27, 91, 90, 0, 27, 40, 66, 27, 41, 48, 0, 27, 91, 52, 126, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 49, 75, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 91, 51, 109, 0, 27, 91, 50, 51, 109, 0, 27, 91, 77, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 51, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 57, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 51, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 52, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 49, 48, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 52, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0
+};
+// Taken from unibilium/t/static_screen-256color.c as of 2015-08-14.
+// This is an 256-colour terminfo description that lacks
+// status line capabilities that screen actually has.
+static const signed char screen_256colour_terminfo[] = {
+ 26, 1, 43, 0, 43, 0, 15, 0, 105, 1, -43, 2, 115, 99, 114, 101, 101, 110, 45, 50, 53, 54, 99, 111, 108, 111, 114, 124, 71, 78, 85, 32, 83, 99, 114, 101, 101, 110, 32, 119, 105, 116, 104, 32, 50, 53, 54, 32, 99, 111, 108, 111, 114, 115, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 80, 0, 8, 0, 24, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 127, 0, 0, 4, 0, 6, 0, 8, 0, 25, 0, 30, 0, 37, 0, 41, 0, -1, -1, -1, -1, 45, 0, 62, 0, 64, 0, 68, 0, 75, 0, -1, -1, 77, 0, 89, 0, -1, -1, 93, 0, 96, 0, 102, 0, 106, 0, -1, -1, -1, -1, 110, 0, 112, 0, 117, 0, 122, 0, -1, -1, -1, -1, -125, 0, -1, -1, -1, -1, -120, 0, -115, 0, -110, 0, -1, -1, -105, 0, -103, 0, -98, 0, -1, -1, -89, 0, -84, 0, -78, 0, -72, 0, -1, -1, -1, -1, -1, -1, -69, 0, -1, -1, -1, -1, -1, -1, -65, 0, -1, -1, -61, 0, -1, -1, -1, -1, -1, -1, -59, 0, -1, -1, -54, 0, -1, -1, -1, -1, -1, -1, -1, -1, -50, 0, -46, 0, -40, 0, -36, 0, -32, 0, -28, 0, -22, 0, -16, 0, -10, 0, -4, 0, 2, 1, 7, 1, -1, -1, 12, 1, -1, -1, 16, 1, 21, 1, 26, 1, -1, -1, -1, -1, -1, -1, 30, 1, 34, 1, 42, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 1, -1, -1, 53, 1, 62, 1, 71, 1, 80, 1, -1, -1, 89, 1, 98, 1, 107, 1, -1, -1, 116, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 125, 1, -1, -1, -1, -1, -114, 1, -1, -1, -111, 1, -108, 1, -106, 1, -103, 1, -30, 1, -1, -1, -27, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -25, 1, -1, -1, 40, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 51, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, 2, 62, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 68, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 73, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, 2, -1, -1, -1, -1, -1, -1, 86, 2, -107, 2, 27, 91, 90, 0, 7, 0, 13, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 114, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 0, 8, 0, 27, 91, 51, 52, 104, 27, 91, 63, 50, 53, 104, 0, 27, 91, 67, 0, 27, 77, 0, 27, 91, 51, 52, 108, 0, 27, 91, 80, 0, 27, 91, 77, 0, 14, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 27, 91, 63, 49, 48, 52, 57, 104, 0, 27, 91, 52, 104, 0, 27, 91, 55, 109, 0, 27, 91, 51, 109, 0, 27, 91, 52, 109, 0, 15, 0, 27, 91, 109, 15, 0, 27, 91, 63, 49, 48, 52, 57, 108, 0, 27, 91, 52, 108, 0, 27, 91, 50, 51, 109, 0, 27, 91, 50, 52, 109, 0, 27, 103, 0, 27, 41, 48, 0, 27, 91, 76, 0, 8, 0, 27, 91, 51, 126, 0, 27, 79, 66, 0, 27, 79, 80, 0, 27, 91, 50, 49, 126, 0, 27, 79, 81, 0, 27, 79, 82, 0, 27, 79, 83, 0, 27, 91, 49, 53, 126, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 91, 49, 126, 0, 27, 91, 50, 126, 0, 27, 79, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 79, 67, 0, 27, 79, 65, 0, 27, 91, 63, 49, 108, 27, 62, 0, 27, 91, 63, 49, 104, 27, 61, 0, 27, 69, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 99, 27, 91, 63, 49, 48, 48, 48, 108, 27, 91, 63, 50, 53, 104, 0, 27, 56, 0, 27, 55, 0, 10, 0, 27, 77, 0, 27, 91, 48, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 49, 37, 116, 59, 51, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 51, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 109, 37, 63, 37, 112, 57, 37, 116, 14, 37, 101, 15, 37, 59, 0, 27, 72, 0, 9, 0, 43, 43, 44, 44, 45, 45, 46, 46, 48, 48, 96, 96, 97, 97, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 0, 27, 91, 90, 0, 27, 40, 66, 27, 41, 48, 0, 27, 91, 52, 126, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 49, 75, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 91, 77, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 51, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 57, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 51, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 52, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 49, 48, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 52, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 0, 3, 0, 1, 0, 24, 0, 52, 0, -112, 0, 1, 1, 0, 0, 1, 0, 0, 0, 4, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 3, 0, 6, 0, 9, 0, 12, 0, 15, 0, 18, 0, 23, 0, 28, 0, 32, 0, 37, 0, 43, 0, 49, 0, 55, 0, 61, 0, 66, 0, 71, 0, 77, 0, 83, 0, 89, 0, 95, 0, 101, 0, 107, 0, 111, 0, 116, 0, 120, 0, 124, 0, -128, 0, 27, 40, 66, 0, 27, 40, 37, 112, 49, 37, 99, 0, 65, 88, 0, 71, 48, 0, 88, 84, 0, 85, 56, 0, 69, 48, 0, 83, 48, 0, 107, 68, 67, 53, 0, 107, 68, 67, 54, 0, 107, 68, 78, 0, 107, 68, 78, 53, 0, 107, 69, 78, 68, 53, 0, 107, 69, 78, 68, 54, 0, 107, 72, 79, 77, 53, 0, 107, 72, 79, 77, 54, 0, 107, 73, 67, 53, 0, 107, 73, 67, 54, 0, 107, 76, 70, 84, 53, 0, 107, 78, 88, 84, 53, 0, 107, 78, 88, 84, 54, 0, 107, 80, 82, 86, 53, 0, 107, 80, 82, 86, 54, 0, 107, 82, 73, 84, 53, 0, 107, 85, 80, 0, 107, 85, 80, 53, 0, 107, 97, 50, 0, 107, 98, 49, 0, 107, 98, 51, 0, 107, 99, 50, 0
+};
+// Taken from Dickey ncurses terminfo.src dated 2017-04-22.
+static const signed char iterm_256colour_terminfo[] = {
+ 26, 1, 57, 0, 29, 0, 15, 0, 105, 1, 73, 3, 105, 84, 101, 114, 109, 46, 97, 112, 112, 124, 105, 116, 101, 114, 109, 124, 105, 84, 101, 114, 109, 46, 97, 112, 112, 32, 116, 101, 114, 109, 105, 110, 97, 108, 32, 101, 109, 117, 108, 97, 116, 111, 114, 32, 102, 111, 114, 32, 77, 97, 99, 32, 79, 83, 32, 88, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 80, 0, 8, 0, 24, 0, -1, -1, -1, -1, -1, -1, -1, -1, 50, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 127, -1, -1, 0, 0, 2, 0, -2, -1, 4, 0, 9, 0, 16, 0, 20, 0, 24, 0, -1, -1, 35, 0, 52, 0, 54, 0, 58, 0, 65, 0, -1, -1, 67, 0, 74, 0, -1, -1, 78, 0, -1, -1, 82, 0, 86, 0, 90, 0, -1, -1, 96, 0, 98, 0, 103, 0, 108, 0, -1, -1, -2, -1, 117, 0, 122, 0, -1, -1, 127, 0,-124, 0,-119, 0, -1, -1,-114, 0,-112, 0,-107, 0, -1, -1, -94, 0, -89, 0, -85, 0, -81, 0, -1, -1, -63, 0, -1, -1, -1, -1, -1, -1, -1, -1, -61, 0, -57, 0, -1, -1, -53, 0, -1, -1, -1, -1, -1, -1, -51, 0, -1, -1, -46, 0, -1, -1, -1, -1, -1, -1, -1, -1, -42, 0, -38, 0, -32, 0, -28, 0, -24, 0, -20, 0, -14, 0, -8, 0, -2, 0, 4, 1, 10, 1, -1, -1, -1, -1, 14, 1, -1, -1, 18, 1, 23, 1, 28, 1, -1, -1, -1, -1, -1, -1, 32, 1, 36, 1, 44, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 52, 1, 61, 1, 70, 1, 79, 1, -1, -1, 88, 1, 97, 1, 106, 1, -1, -1, 115, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 124, 1, -1, -1, -1, -1,-104, 1,-101, 1, -90, 1, -87, 1, -85, 1, -82, 1, -4, 1, -1, -1, -1, 1, 1, 2, -1, -1, -1, -1, -1, -1, 6, 2, 10, 2, 14, 2, 18, 2, 22, 2, -1, -1, -1, -1, 26, 2, -1, -1, -1, -1, -1, -1, -1, -1, 77, 2, 83, 2, -1, -1, -1, -1, 89, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 2, 100, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, 2, 110, 2, 116, 2, 122, 2,-128, 2,-122, 2,-116, 2,-110, 2, 104, 2, -98, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -92, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -87, 2, -76, 2, -71, 2, -63, 2, -59, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -54, 2, 9, 3, 7, 0, 13, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 71, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 0, 8, 0, 27, 91, 63, 50, 53, 104, 0, 27, 91, 67, 0, 27, 91, 65, 0, 27, 91, 80, 0, 27, 91, 77, 0, 27, 93, 50, 59, 7, 0, 14, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 27, 55, 27, 91, 63, 52, 55, 104, 0, 27, 91, 52, 104, 0, 27, 91, 56, 109, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 15, 0, 27, 91, 109, 15, 0, 27, 91, 50, 74, 27, 91, 63, 52, 55, 108, 27, 56, 0, 27, 91, 52, 108, 0, 27, 91, 109, 0, 27, 91, 109, 0, 27, 91, 63, 53, 104, 36, 60, 50, 48, 48, 47, 62, 27, 91, 63, 53, 108, 0, 7, 0, 27, 91, 64, 0, 27, 91, 76, 0, 127, 0, 27, 91, 51, 126, 0, 27, 79, 66, 0, 27, 79, 80, 0, 27, 91, 50, 49, 126, 0, 27, 79, 81, 0, 27, 79, 82, 0, 27, 79, 83, 0, 27, 91, 49, 53, 126, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 79, 72, 0, 27, 79, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 79, 67, 0, 27, 79, 65, 0, 27, 91, 63, 49, 108, 27, 62, 0, 27, 91, 63, 49, 104, 27, 61, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 62, 27, 91, 63, 51, 108, 27, 91, 63, 52, 108, 27, 91, 63, 53, 108, 27, 91, 63, 55, 104, 27, 91, 63, 56, 104, 0, 27, 56, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 100, 0, 27, 55, 0, 10, 0, 27, 77, 0, 27, 91, 48, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 49, 37, 112, 51, 37, 124, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 37, 63, 37, 112, 55, 37, 116, 59, 56, 37, 59, 109, 37, 63, 37, 112, 57, 37, 116, 14, 37, 101, 15, 37, 59, 0, 27, 72, 0, 9, 0, 27, 93, 50, 59, 0, 27, 79, 113, 0, 27, 79, 115, 0, 27, 79, 114, 0, 27, 79, 112, 0, 27, 79, 110, 0, 96, 96, 97, 97, 102, 102, 103, 103, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 0, 27, 91, 63, 55, 104, 0, 27, 91, 63, 55, 108, 0, 27, 40, 66, 27, 41, 48, 0, 27, 79, 70, 0, 27, 79, 77, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 50, 53, 126, 0, 27, 91, 50, 54, 126, 0, 27, 91, 50, 56, 126, 0, 27, 91, 50, 57, 126, 0, 27, 91, 51, 49, 126, 0, 27, 91, 50, 50, 126, 0, 27, 91, 51, 51, 126, 0, 27, 91, 51, 52, 126, 0, 27, 91, 49, 75, 0, 27, 91, 37, 105, 37, 100, 59, 37, 100, 82, 0, 27, 91, 54, 110, 0, 27, 91, 63, 49, 59, 50, 99, 0, 27, 91, 99, 0, 27, 91, 48, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 51, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 57, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 51, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 52, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 49, 48, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 52, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0
+};
+// Taken from Dickey ncurses terminfo.src dated 2017-04-22.
+// This is a 256-colour terminfo description that lacks true-colour
+// capabilities that rxvt actually has.
+static const signed char rxvt_256colour_terminfo[] = {
+ 26, 1, 47, 0, 29, 0, 15, 0, 110, 1, -31, 4, 114, 120, 118, 116, 45, 50, 53, 54, 99, 111, 108, 111, 114, 124, 114, 120, 118, 116, 32, 50, 46, 55, 46, 57, 32, 119, 105, 116, 104, 32, 120, 116, 101, 114, 109, 32, 50, 53, 54, 45, 99, 111, 108, 111, 114, 115, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 80, 0, 8, 0, 24, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 127, -1, -1, 0, 0, 2, 0, 4, 0, 21, 0, 26, 0, 34, 0, 38, 0, 42, 0, -1, -1, 53, 0, 70, 0, 72, 0, 76, 0, 83, 0, -1, -1, 85, 0, 92, 0, -1, -1, 96, 0, -1, -1, -1, -1, 100, 0, -1, -1, -1, -1, 104, 0, 106, 0, 111, 0, 116, 0, -1, -1, -1, -1, 125, 0, -1, -1, -1, -1,-126, 0,-121, 0,-116, 0, -1, -1,-111, 0,-109, 0,-104, 0, -1, -1, -91, 0, -86, 0, -80, 0, -74, 0, -1, -1, -1, -1, -56, 0, -42, 0, -1, -1, -1, -1, -8, 0, -4, 0, -1, -1, 0, 1, -1, -1, -1, -1, -1, -1, 2, 1, -1, -1, 7, 1, -1, -1, 11, 1, -1, -1, 16, 1, 22, 1, 28, 1, 34, 1, 40, 1, 46, 1, 52, 1, 58, 1, 64, 1, 70, 1, 76, 1, 82, 1, 87, 1, -1, -1, 92, 1, -1, -1, 96, 1, 101, 1, 106, 1, 110, 1, 114, 1, -1, -1, 118, 1, 122, 1, 125, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-128, 1,-119, 1,-110, 1, -1, -1,-101, 1, -92, 1, -83, 1, -1, -1, -74, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -65, 1, -32, 1, -1, -1, -1, -1, 18, 2, 21, 2, 32, 2, 35, 2, 37, 2, 40, 2, 107, 2, -1, -1, 110, 2, -1, -1, -1, -1, -1, -1, -1, -1, 112, 2, 116, 2, 120, 2, 124, 2,-128, 2, -1, -1, -1, -1,-124, 2, -1, -1, -73, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -69, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -62, 2, -57, 2, -1, -1, -53, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -48, 2, -1, -1, -43, 2, -38, 2, -1, -1, -1, -1, -1, -1, -1, -1, -33, 2, -28, 2, -23, 2, -1, -1, -1, -1, -19, 2, -1, -1, -14, 2, -1, -1, -1, -1, -1, -1, -9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -5, 2, 1, 3, 7, 3, 13, 3, 19, 3, 25, 3, 31, 3, 37, 3, 43, 3, 49, 3, 55, 3, 61, 3, 67, 3, 73, 3, 79, 3, 85, 3, 91, 3, 97, 3, 103, 3, 109, 3, 115, 3, 121, 3, 127, 3,-123, 3,-117, 3,-111, 3,-105, 3, -99, 3, -93, 3, -87, 3, -81, 3, -75, 3, -69, 3, -63, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -57, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -52, 3, -41, 3, -36, 3, -28, 3, -24, 3, -15, 3, -8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 86, 4, -1, -1, -1, -1, -1, -1, 90, 4,-103, 4, -1, -1, -1, -1, -1, -1, -39, 4, -35, 4, 7, 0, 13, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 114, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 50, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 71, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 0, 8, 0, 27, 91, 63, 50, 53, 104, 0, 27, 91, 67, 0, 27, 91, 65, 0, 27, 91, 77, 0, 14, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 27, 55, 27, 91, 63, 52, 55, 104, 0, 27, 91, 52, 104, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 15, 0, 27, 91, 109, 15, 0, 27, 91, 50, 74, 27, 91, 63, 52, 55, 108, 27, 56, 0, 27, 91, 52, 108, 0, 27, 91, 50, 55, 109, 0, 27, 91, 50, 52, 109, 0, 27, 91, 63, 53, 104, 36, 60, 49, 48, 48, 47, 62, 27, 91, 63, 53, 108, 0, 27, 91, 63, 52, 55, 108, 27, 61, 27, 91, 63, 49, 108, 0, 27, 91, 114, 27, 91, 109, 27, 91, 50, 74, 27, 91, 72, 27, 91, 63, 55, 104, 27, 91, 63, 49, 59, 51, 59, 52, 59, 54, 108, 27, 91, 52, 108, 0, 27, 91, 64, 0, 27, 91, 76, 0, 8, 0, 27, 91, 51, 126, 0, 27, 91, 66, 0, 27, 91, 56, 94, 0, 27, 91, 50, 49, 126, 0, 27, 91, 49, 49, 126, 0, 27, 91, 50, 49, 126, 0, 27, 91, 49, 50, 126, 0, 27, 91, 49, 51, 126, 0, 27, 91, 49, 52, 126, 0, 27, 91, 49, 53, 126, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 91, 55, 126, 0, 27, 91, 50, 126, 0, 27, 91, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 91, 67, 0, 27, 91, 97, 0, 27, 91, 98, 0, 27, 91, 65, 0, 27, 62, 0, 27, 61, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 62, 27, 91, 49, 59, 51, 59, 52, 59, 53, 59, 54, 108, 27, 91, 63, 55, 104, 27, 91, 109, 27, 91, 114, 27, 91, 50, 74, 27, 91, 72, 0, 27, 91, 114, 27, 91, 109, 27, 91, 50, 74, 27, 91, 72, 27, 91, 63, 55, 104, 27, 91, 63, 49, 59, 51, 59, 52, 59, 54, 108, 27, 91, 52, 108, 27, 62, 27, 91, 63, 49, 48, 48, 48, 108, 27, 91, 63, 50, 53, 104, 0, 27, 56, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 100, 0, 27, 55, 0, 10, 0, 27, 77, 0, 27, 91, 48, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 49, 37, 112, 51, 37, 124, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 109, 37, 63, 37, 112, 57, 37, 116, 14, 37, 101, 15, 37, 59, 0, 27, 72, 0, 9, 0, 27, 79, 119, 0, 27, 79, 121, 0, 27, 79, 117, 0, 27, 79, 113, 0, 27, 79, 115, 0, 96, 96, 97, 97, 102, 102, 103, 103, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 0, 27, 91, 90, 0, 27, 40, 66, 27, 41, 48, 0, 27, 91, 56, 126, 0, 27, 79, 77, 0, 27, 91, 49, 126, 0, 27, 91, 51, 36, 0, 27, 91, 52, 126, 0, 27, 91, 56, 36, 0, 27, 91, 55, 36, 0, 27, 91, 50, 36, 0, 27, 91, 100, 0, 27, 91, 54, 36, 0, 27, 91, 53, 36, 0, 27, 91, 99, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 50, 53, 126, 0, 27, 91, 50, 54, 126, 0, 27, 91, 50, 56, 126, 0, 27, 91, 50, 57, 126, 0, 27, 91, 51, 49, 126, 0, 27, 91, 51, 50, 126, 0, 27, 91, 51, 51, 126, 0, 27, 91, 51, 52, 126, 0, 27, 91, 50, 51, 36, 0, 27, 91, 50, 52, 36, 0, 27, 91, 49, 49, 94, 0, 27, 91, 49, 50, 94, 0, 27, 91, 49, 51, 94, 0, 27, 91, 49, 52, 94, 0, 27, 91, 49, 53, 94, 0, 27, 91, 49, 55, 94, 0, 27, 91, 49, 56, 94, 0, 27, 91, 49, 57, 94, 0, 27, 91, 50, 48, 94, 0, 27, 91, 50, 49, 94, 0, 27, 91, 50, 51, 94, 0, 27, 91, 50, 52, 94, 0, 27, 91, 50, 53, 94, 0, 27, 91, 50, 54, 94, 0, 27, 91, 50, 56, 94, 0, 27, 91, 50, 57, 94, 0, 27, 91, 51, 49, 94, 0, 27, 91, 51, 50, 94, 0, 27, 91, 51, 51, 94, 0, 27, 91, 51, 52, 94, 0, 27, 91, 50, 51, 64, 0, 27, 91, 50, 52, 64, 0, 27, 91, 49, 75, 0, 27, 91, 37, 105, 37, 100, 59, 37, 100, 82, 0, 27, 91, 54, 110, 0, 27, 91, 63, 49, 59, 50, 99, 0, 27, 91, 99, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 93, 49, 48, 52, 7, 0, 27, 93, 52, 59, 37, 112, 49, 37, 100, 59, 114, 103, 98, 58, 37, 112, 50, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 47, 37, 112, 51, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 47, 37, 112, 52, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 27, 92, 0, 27, 91, 77, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 51, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 57, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 51, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 52, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 49, 48, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 52, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 40, 66, 0, 27, 40, 48, 0
+};
+// Taken from Dickey ncurses terminfo.src dated 2017-04-22.
+// This is a 16-colour terminfo description that lacks true-colour
+// and 256-colour capabilities that linux (4.8+) actually has.
+static const signed char linux_16colour_terminfo[] = {
+ 26, 1, 43, 0, 29, 0, 16, 0, 125, 1, 125, 3, 108, 105, 110, 117, 120, 45, 49, 54, 99, 111, 108, 111, 114, 124, 108, 105, 110, 117, 120, 32, 99, 111, 110, 115, 111, 108, 101, 32, 119, 105, 116, 104, 32, 49, 54, 32, 99, 111, 108, 111, 114, 115, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, -1, -1, 8, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, 0, 0, 1, 42, 0, -1, -1, 0, 0, 2, 0, 4, 0, 21, 0, 26, 0, 33, 0, 37, 0, 41, 0, -1, -1, 52, 0, 69, 0, 71, 0, 75, 0, 87, 0, -1, -1, 89, 0, 101, 0, -1, -1, 105, 0, 109, 0, 121, 0, 125, 0, -1, -1, -1, -1,-127, 0,-125, 0,-120, 0, -1, -1, -1, -1,-115, 0,-110, 0, -1, -1, -1, -1,-105, 0,-100, 0, -95, 0, -90, 0, -81, 0, -79, 0, -1, -1, -1, -1, -74, 0, -69, 0, -63, 0, -57, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -39, 0, -35, 0, -1, -1, -31, 0, -1, -1, -1, -1, -1, -1, -29, 0, -1, -1, -24, 0, -1, -1, -1, -1, -1, -1, -1, -1, -20, 0, -15, 0, -9, 0, -4, 0, 1, 1, 6, 1, 11, 1, 17, 1, 23, 1, 29, 1, 35, 1, 40, 1, -1, -1, 45, 1, -1, -1, 49, 1, 54, 1, 59, 1, -1, -1, -1, -1, -1, -1, 63, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 67, 1, -1, -1, 70, 1, 79, 1, 88, 1, 97, 1, -1, -1, 106, 1, 115, 1, 124, 1, -1, -1,-123, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-114, 1, -1, -1, -1, -1, -1, -1,-108, 1,-105, 1, -94, 1, -91, 1, -89, 1, -86, 1, 1, 2, -1, -1, 4, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, 10, 2, -1, -1, 77, 2, -1, -1, -1, -1, 81, 2, 87, 2, -1, -1, -1, -1, 93, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 97, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 102, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, 2, 110, 2, 116, 2, 122, 2,-128, 2,-122, 2,-116, 2,-110, 2,-104, 2, -98, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -92, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -87, 2, -76, 2, -71, 2, -65, 2, -61, 2, -52, 2, -48, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 3, -1, -1, -1, -1, -1, -1, 37, 3, 75, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 113, 3, 119, 3, 7, 0, 13, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 114, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 71, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 27, 91, 63, 49, 99, 0, 8, 0, 27, 91, 63, 50, 53, 104, 27, 91, 63, 48, 99, 0, 27, 91, 67, 0, 27, 91, 65, 0, 27, 91, 63, 50, 53, 104, 27, 91, 63, 56, 99, 0, 27, 91, 80, 0, 27, 91, 77, 0, 14, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 27, 91, 50, 109, 0, 27, 91, 52, 104, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 27, 91, 37, 112, 49, 37, 100, 88, 0, 15, 0, 27, 91, 109, 15, 0, 27, 91, 52, 108, 0, 27, 91, 50, 55, 109, 0, 27, 91, 50, 52, 109, 0, 27, 91, 63, 53, 104, 36, 60, 50, 48, 48, 47, 62, 27, 91, 63, 53, 108, 0, 27, 91, 64, 0, 27, 91, 76, 0, 127, 0, 27, 91, 51, 126, 0, 27, 91, 66, 0, 27, 91, 91, 65, 0, 27, 91, 50, 49, 126, 0, 27, 91, 91, 66, 0, 27, 91, 91, 67, 0, 27, 91, 91, 68, 0, 27, 91, 91, 69, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 91, 49, 126, 0, 27, 91, 50, 126, 0, 27, 91, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 91, 67, 0, 27, 91, 65, 0, 13, 10, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 99, 27, 93, 82, 0, 27, 56, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 100, 0, 27, 55, 0, 10, 0, 27, 77, 0, 27, 91, 48, 59, 49, 48, 37, 63, 37, 112, 49, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 51, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 37, 63, 37, 112, 53, 37, 116, 59, 50, 37, 59, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 109, 37, 63, 37, 112, 57, 37, 116, 14, 37, 101, 15, 37, 59, 0, 27, 72, 0, 9, 0, 27, 91, 71, 0, 43, 43, 44, 44, 45, 45, 46, 46, 48, 48, 95, 95, 96, 96, 97, 97, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 99, 126, 126, 0, 27, 91, 90, 0, 27, 91, 63, 55, 104, 0, 27, 91, 63, 55, 108, 0, 27, 41, 48, 0, 27, 91, 52, 126, 0, 26, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 50, 53, 126, 0, 27, 91, 50, 54, 126, 0, 27, 91, 50, 56, 126, 0, 27, 91, 50, 57, 126, 0, 27, 91, 51, 49, 126, 0, 27, 91, 51, 50, 126, 0, 27, 91, 51, 51, 126, 0, 27, 91, 51, 52, 126, 0, 27, 91, 49, 75, 0, 27, 91, 37, 105, 37, 100, 59, 37, 100, 82, 0, 27, 91, 54, 110, 0, 27, 91, 63, 54, 99, 0, 27, 91, 99, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 93, 82, 0, 27, 93, 80, 37, 112, 49, 37, 120, 37, 112, 50, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 48, 50, 120, 37, 112, 51, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 48, 50, 120, 37, 112, 52, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 48, 50, 120, 0, 27, 91, 77, 0, 27, 91, 51, 37, 112, 49, 37, 123, 56, 125, 37, 109, 37, 100, 37, 63, 37, 112, 49, 37, 123, 55, 125, 37, 62, 37, 116, 59, 49, 37, 101, 59, 50, 49, 37, 59, 109, 0, 27, 91, 52, 37, 112, 49, 37, 123, 56, 125, 37, 109, 37, 100, 37, 63, 37, 112, 49, 37, 123, 55, 125, 37, 62, 37, 116, 59, 53, 37, 101, 59, 50, 53, 37, 59, 109, 0, 27, 91, 49, 49, 109, 0, 27, 91, 49, 48, 109, 0
+};
+// Taken from Dickey ncurses terminfo.src dated 2017-04-22.
+static const signed char putty_256colour_terminfo[] = {
+ 26, 1, 48, 0, 29, 0, 16, 0, 125, 1,-106, 4, 112, 117, 116, 116, 121, 45, 50, 53, 54, 99, 111, 108, 111, 114, 124, 80, 117, 84, 84, 89, 32, 48, 46, 53, 56, 32, 119, 105, 116, 104, 32, 120, 116, 101, 114, 109, 32, 50, 53, 54, 45, 99, 111, 108, 111, 114, 115, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, -1, 8, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 127, 22, 0, 0, 0, 4, 0, 6, 0, 8, 0, 25, 0, 30, 0, 37, 0, 41, 0, 45, 0, -1, -1, 56, 0, 73, 0, 76, 0, 80, 0, 87, 0, -1, -1, 89, 0, 96, 0, -1, -1, 100, 0, -1, -1, 103, 0, 107, 0, 111, 0, -1, -1, 117, 0, 119, 0, 124, 0,-127, 0, -1, -1, -1, -1,-120, 0, -1, -1, -1, -1,-115, 0,-110, 0,-105, 0,-100, 0, -91, 0, -89, 0, -84, 0, -1, -1, -73, 0, -68, 0, -62, 0, -56, 0, -1, -1, -38, 0, -1, -1, -36, 0, -1, -1, -1, -1, -1, -1, -2, 0, -1, -1, 2, 1, -1, -1, -1, -1, -1, -1, 4, 1, -1, -1, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, 13, 1, 19, 1, 25, 1, 31, 1, 37, 1, 43, 1, 49, 1, 55, 1, 61, 1, 67, 1, 73, 1, 78, 1, -1, -1, 83, 1, -1, -1, 87, 1, 92, 1, 97, 1, 101, 1, 105, 1, -1, -1, 109, 1, 113, 1, 121, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-127, 1, -1, -1,-124, 1,-115, 1,-106, 1, -1, -1, -97, 1, -88, 1, -79, 1, -70, 1, -61, 1, -52, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -43, 1, -1, -1, -1, -1, -10, 1, -7, 1, 4, 2, 7, 2, 9, 2, 12, 2, 84, 2, -1, -1, 87, 2, 89, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 94, 2, -1, -1, -1, -1, -1, -1, -1, -1, 98, 2, -1, -1,-107, 2, -1, -1, -1, -1,-103, 2, -97, 2, -1, -1, -1, -1, -91, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -84, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -79, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -77, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -73, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -69, 2, -63, 2, -57, 2, -51, 2, -45, 2, -39, 2, -33, 2, -27, 2, -21, 2, -15, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -4, 2, 7, 3, 12, 3, 18, 3, 22, 3, 31, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 35, 3, -1, -1, -1, -1, -1, -1, 39, 3, 102, 3, -1, -1, -1, -1, -1, -1, -90, 3, -84, 3, -78, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -72, 3,-118, 4,-112, 4, 27, 91, 90, 0, 7, 0, 13, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 114, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 71, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 27, 68, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 0, 8, 0, 27, 91, 63, 50, 53, 104, 0, 27, 91, 67, 0, 27, 77, 0, 27, 91, 80, 0, 27, 91, 77, 0, 27, 93, 48, 59, 7, 0, 14, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 27, 91, 63, 52, 55, 104, 0, 27, 91, 52, 104, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 27, 91, 37, 112, 49, 37, 100, 88, 0, 15, 0, 27, 91, 109, 15, 0, 27, 91, 50, 74, 27, 91, 63, 52, 55, 108, 0, 27, 91, 52, 108, 0, 27, 91, 50, 55, 109, 0, 27, 91, 50, 52, 109, 0, 27, 91, 63, 53, 104, 36, 60, 49, 48, 48, 47, 62, 27, 91, 63, 53, 108, 0, 7, 0, 27, 55, 27, 91, 114, 27, 91, 109, 27, 91, 63, 55, 104, 27, 91, 63, 49, 59, 52, 59, 54, 108, 27, 91, 52, 108, 27, 56, 27, 62, 27, 93, 82, 0, 27, 91, 76, 0, 127, 0, 27, 91, 51, 126, 0, 27, 79, 66, 0, 27, 91, 49, 49, 126, 0, 27, 91, 50, 49, 126, 0, 27, 91, 49, 50, 126, 0, 27, 91, 49, 51, 126, 0, 27, 91, 49, 52, 126, 0, 27, 91, 49, 53, 126, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 91, 49, 126, 0, 27, 91, 50, 126, 0, 27, 79, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 79, 67, 0, 27, 91, 66, 0, 27, 91, 65, 0, 27, 79, 65, 0, 27, 91, 63, 49, 108, 27, 62, 0, 27, 91, 63, 49, 104, 27, 61, 0, 13, 10, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 83, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 84, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 60, 27, 91, 34, 112, 27, 91, 53, 48, 59, 54, 34, 112, 27, 99, 27, 91, 63, 51, 108, 27, 93, 82, 27, 91, 63, 49, 48, 48, 48, 108, 0, 27, 56, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 100, 0, 27, 55, 0, 10, 0, 27, 77, 0, 27, 91, 48, 37, 63, 37, 112, 49, 37, 112, 54, 37, 124, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 49, 37, 112, 51, 37, 124, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 109, 37, 63, 37, 112, 57, 37, 116, 14, 37, 101, 15, 37, 59, 0, 27, 72, 0, 9, 0, 27, 93, 48, 59, 0, 27, 91, 71, 0, 96, 96, 97, 97, 102, 102, 103, 103, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 0, 27, 91, 90, 0, 27, 91, 63, 55, 104, 0, 27, 91, 63, 55, 108, 0, 27, 40, 66, 27, 41, 48, 0, 27, 91, 52, 126, 0, 26, 0, 27, 91, 68, 0, 27, 91, 67, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 50, 53, 126, 0, 27, 91, 50, 54, 126, 0, 27, 91, 50, 56, 126, 0, 27, 91, 50, 57, 126, 0, 27, 91, 51, 49, 126, 0, 27, 91, 51, 50, 126, 0, 27, 91, 51, 51, 126, 0, 27, 91, 51, 52, 126, 0, 27, 91, 49, 75, 0, 27, 91, 37, 105, 37, 100, 59, 37, 100, 82, 0, 27, 91, 54, 110, 0, 27, 91, 63, 54, 99, 0, 27, 91, 99, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 93, 82, 0, 27, 91, 77, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 51, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 57, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 51, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 52, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 49, 48, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 52, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 49, 48, 109, 0, 27, 91, 49, 49, 109, 0, 27, 91, 49, 50, 109, 0, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 61, 37, 116, 27, 37, 37, 71, -30,-105,-104, 27, 37, 37, 64, 37, 101, 37, 112, 49, 37, 123, 49, 48, 125, 37, 61, 37, 116, 27, 37, 37, 71, -30,-105,-103, 27, 37, 37, 64, 37, 101, 37, 112, 49, 37, 123, 49, 50, 125, 37, 61, 37, 116, 27, 37, 37, 71, -30,-103,-128, 27, 37, 37, 64, 37, 101, 37, 112, 49, 37, 123, 49, 51, 125, 37, 61, 37, 116, 27, 37, 37, 71, -30,-103, -86, 27, 37, 37, 64, 37, 101, 37, 112, 49, 37, 123, 49, 52, 125, 37, 61, 37, 116, 27, 37, 37, 71, -30,-103, -85, 27, 37, 37, 64, 37, 101, 37, 112, 49, 37, 123, 49, 53, 125, 37, 61, 37, 116, 27, 37, 37, 71, -30,-104, -68, 27, 37, 37, 64, 37, 101, 37, 112, 49, 37, 123, 50, 55, 125, 37, 61, 37, 116, 27, 37, 37, 71, -30,-122,-112, 27, 37, 37, 64, 37, 101, 37, 112, 49, 37, 123, 49, 53, 53, 125, 37, 61, 37, 116, 27, 37, 37, 71, -32,-126, -94, 27, 37, 37, 64, 37, 101, 37, 112, 49, 37, 99, 37, 59, 0, 27, 91, 49, 49, 109, 0, 27, 91, 49, 48, 109, 0
+};
+// Taken from Dickey ncurses terminfo.src dated 2017-04-22.
+static const signed char interix_8colour_terminfo[] = {
+ 26, 1, 82, 0, 15, 0, 16, 0, 105, 1, 123, 2, 105, 110, 116, 101, 114, 105, 120, 124, 111, 112, 101, 110, 110, 116, 124, 111, 112, 101, 110, 110, 116, 45, 50, 53, 124, 110, 116, 99, 111, 110, 115, 111, 108, 101, 124, 110, 116, 99, 111, 110, 115, 111, 108, 101, 45, 50, 53, 124, 79, 112, 101, 110, 78, 84, 45, 116, 101, 114, 109, 32, 99, 111, 109, 112, 97, 116, 105, 98, 108, 101, 32, 119, 105, 116, 104, 32, 99, 111, 108, 111, 114, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 80, 0, -1, -1, 25, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8, 0, 64, 0, 3, 0, 0, 0, 4, 0, -1, -1, -1, -1, -1, -1, 6, 0, 11, 0, 15, 0, -1, -1, -1, -1, 19, 0, 36, 0, 38, 0, -1, -1, 42, 0, -1, -1, -1, -1, 46, 0, 50, 0, 54, 0, -1, -1, -1, -1, 58, 0, -1, -1, -1, -1, -1, -1, -1, -1, 62, 0, 67, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 75, 0, 80, 0, 85, 0, -1, -1, -1, -1, 90, 0, 95, 0, -1, -1, -1, -1, 107, 0, 111, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 115, 0, -1, -1, 119, 0, -1, -1, -1, -1, -1, -1, 121, 0, -1, -1, 125, 0, -1, -1, -1, -1, -1, -1,-127, 0,-123, 0,-119, 0,-115, 0,-111, 0,-107, 0,-103, 0, -99, 0, -95, 0, -91, 0, -87, 0, -1, -1, -83, 0, -1, -1, -79, 0, -75, 0, -71, 0, -67, 0, -63, 0, -1, -1, -1, -1, -1, -1, -59, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -55, 0, -1, -1, -1, -1, -52, 0, -43, 0, -1, -1, -34, 0, -25, 0, -16, 0, -7, 0, 2, 1, 11, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, 1, -1, -1, -1, -1, -1, -1, 23, 1, -1, -1, 27, 1, 31, 1, 35, 1, -1, -1, -1, -1, -1, -1, 39, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 41, 1, -1, -1, 104, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 108, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 112, 1, 116, 1, 120, 1, 124, 1,-128, 1,-124, 1,-120, 1,-116, 1,-112, 1,-108, 1,-104, 1,-100, 1, -96, 1, -92, 1, -88, 1, -84, 1, -80, 1, -76, 1, -72, 1, -68, 1, -64, 1, -60, 1, -56, 1, -52, 1, -48, 1, -44, 1, -40, 1, -36, 1, -32, 1, -28, 1, -24, 1, -20, 1, -16, 1, -12, 1, -8, 1, -4, 1, 0, 2, 4, 2, 8, 2, 12, 2, 16, 2, 20, 2, 24, 2, 28, 2, 32, 2, 36, 2, 40, 2, 44, 2, 48, 2, 52, 2, 56, 2, 60, 2, 64, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 68, 2, -1, -1, -1, -1, -1, -1, -1, -1, 72, 2, 88, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 103, 2, 113, 2, 27, 91, 90, 0, 7, 0, 27, 91, 50, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 68, 0, 27, 91, 67, 0, 27, 91, 85, 0, 27, 91, 65, 0, 27, 91, 77, 0, 27, 91, 49, 109, 0, 27, 91, 115, 27, 91, 49, 98, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 27, 91, 48, 109, 0, 27, 91, 50, 98, 27, 91, 117, 13, 27, 91, 75, 0, 27, 91, 109, 0, 27, 91, 109, 0, 27, 91, 76, 0, 8, 0, 27, 91, 77, 0, 27, 91, 66, 0, 27, 70, 65, 0, 27, 70, 49, 0, 27, 70, 65, 0, 27, 70, 50, 0, 27, 70, 51, 0, 27, 70, 52, 0, 27, 70, 53, 0, 27, 70, 54, 0, 27, 70, 55, 0, 27, 70, 56, 0, 27, 70, 57, 0, 27, 91, 76, 0, 27, 91, 68, 0, 27, 91, 85, 0, 27, 91, 84, 0, 27, 91, 83, 0, 27, 91, 67, 0, 27, 91, 65, 0, 13, 10, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 83, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 84, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 99, 0, 27, 91, 117, 0, 27, 91, 115, 0, 27, 91, 83, 0, 27, 91, 84, 0, 9, 0, 43, 16, 44, 17, 45, 24, 46, 25, 48, -37, 96, 4, 97, -79, 102, -8, 103, -15, 104, -80, 106, -39, 107, -65, 108, -38, 109, -64, 110, -59, 111, 126, 112, -60, 113, -60, 114, -60, 115, 95, 116, -61, 117, -76, 118, -63, 119, -62, 120, -77, 121, -13, 122, -14, 123, -29, 124, -40, 125,-100, 126, -2, 0, 27, 91, 90, 0, 27, 91, 85, 0, 27, 70, 66, 0, 27, 70, 67, 0, 27, 70, 68, 0, 27, 70, 69, 0, 27, 70, 70, 0, 27, 70, 71, 0, 27, 70, 72, 0, 27, 70, 73, 0, 27, 70, 74, 0, 27, 70, 75, 0, 27, 70, 76, 0, 27, 70, 77, 0, 27, 70, 78, 0, 27, 70, 79, 0, 27, 70, 80, 0, 27, 70, 81, 0, 27, 70, 82, 0, 27, 70, 83, 0, 27, 70, 84, 0, 27, 70, 85, 0, 27, 70, 86, 0, 27, 70, 87, 0, 27, 70, 88, 0, 27, 70, 89, 0, 27, 70, 90, 0, 27, 70, 97, 0, 27, 70, 98, 0, 27, 70, 99, 0, 27, 70, 100, 0, 27, 70, 101, 0, 27, 70, 102, 0, 27, 70, 103, 0, 27, 70, 104, 0, 27, 70, 105, 0, 27, 70, 106, 0, 27, 70, 107, 0, 27, 70, 109, 0, 27, 70, 110, 0, 27, 70, 111, 0, 27, 70, 112, 0, 27, 70, 113, 0, 27, 70, 114, 0, 27, 70, 115, 0, 27, 70, 116, 0, 27, 70, 117, 0, 27, 70, 118, 0, 27, 70, 119, 0, 27, 70, 120, 0, 27, 70, 121, 0, 27, 70, 122, 0, 27, 70, 43, 0, 27, 70, 45, 0, 27, 70, 12, 0, 27, 91, 109, 0, 27, 91, 37, 112, 49, 37, 123, 51, 48, 125, 37, 43, 37, 100, 109, 0, 27, 91, 37, 112, 49, 37, 39, 40, 39, 37, 43, 37, 100, 109, 0, 27, 91, 51, 37, 112, 49, 37, 100, 109, 0, 27, 91, 52, 37, 112, 49, 37, 100, 109, 0
+};
+// Taken from Dickey ncurses terminfo.src dated 2017-04-22.
+// This is a 256-colour terminfo description that lacks true-colour
+// capabilities that stterm actually has.
+static const signed char st_256colour_terminfo[] = {
+ 26, 1, 55, 0, 29, 0, 15, 0, 105, 1, 117, 5, 115, 116, 45, 50, 53, 54, 99, 111, 108, 111, 114, 124, 115, 116, 116, 101, 114, 109, 45, 50, 53, 54, 99, 111, 108, 111, 114, 124, 115, 105, 109, 112, 108, 101, 116, 101, 114, 109, 32, 119, 105, 116, 104, 32, 50, 53, 54, 32, 99, 111, 108, 111, 114, 115, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 80, 0, 8, 0, 24, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 127, 0, 0, 4, 0, 6, 0, 8, 0, 25, 0, 30, 0, 38, 0, 42, 0, 46, 0, -1, -1, 57, 0, 74, 0, 76, 0, 80, 0, 87, 0, -1, -1, 89, 0, 102, 0, -1, -1, 106, 0, 110, 0, 117, 0, 121, 0, -1, -1, -1, -1, 125, 0,-127, 0,-122, 0,-117, 0, -1, -1, -1, -1,-108, 0,-103, 0, -1, -1, -98, 0, -93, 0, -88, 0, -83, 0, -74, 0, -70, 0, -65, 0, -1, -1, -56, 0, -51, 0, -45, 0, -39, 0, -1, -1, -21, 0, -1, -1, -19, 0, -1, -1, -1, -1, -1, -1, -4, 0, -1, -1, 0, 1, -1, -1, 2, 1, -1, -1, 9, 1, 14, 1, 21, 1, 25, 1, 32, 1, 39, 1, -1, -1, 46, 1, 50, 1, 56, 1, 60, 1, 64, 1, 68, 1, 74, 1, 80, 1, 86, 1, 92, 1, 98, 1, 103, 1, 108, 1, 115, 1, -1, -1, 119, 1, 124, 1,-127, 1,-123, 1,-116, 1, -1, -1,-109, 1,-105, 1, -97, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -89, 1, -80, 1, -71, 1, -62, 1, -53, 1, -44, 1, -35, 1, -26, 1, -1, -1, -17, 1, -1, -1, -1, -1, -1, -1, -8, 1, -4, 1, 1, 2, -1, -1, 6, 2, 9, 2, -1, -1, -1, -1, 24, 2, 27, 2, 38, 2, 41, 2, 43, 2, 46, 2,-128, 2, -1, -1,-125, 2,-123, 2, -1, -1, -1, -1, -1, -1,-118, 2,-113, 2,-108, 2,-104, 2, -99, 2, -1, -1, -1, -1, -94, 2, -1, -1, -29, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -25, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -21, 2, -16, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -12, 2, -1, -1, -1, -1, -5, 2, -1, -1, -1, -1, -1, -1, -1, -1, 2, 3, 9, 3, 16, 3, -1, -1, -1, -1, 23, 3, -1, -1, 30, 3, -1, -1, -1, -1, -1, -1, 37, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, 3, 50, 3, 56, 3, 63, 3, 70, 3, 77, 3, 84, 3, 92, 3, 100, 3, 108, 3, 116, 3, 124, 3,-124, 3,-116, 3,-108, 3,-101, 3, -94, 3, -87, 3, -80, 3, -72, 3, -64, 3, -56, 3, -48, 3, -40, 3, -32, 3, -24, 3, -16, 3, -9, 3, -2, 3, 5, 4, 12, 4, 20, 4, 28, 4, 36, 4, 44, 4, 52, 4, 60, 4, 68, 4, 76, 4, 83, 4, 90, 4, 97, 4, 104, 4, 112, 4, 120, 4,-128, 4,-120, 4,-112, 4,-104, 4, -96, 4, -88, 4, -81, 4, -74, 4, -67, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -62, 4, -51, 4, -46, 4, -38, 4, -34, 4, -2, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -25, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -20, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -14, 4, -1, -1, -1, -1, -1, -1, -10, 4, 53, 5, 27, 91, 90, 0, 7, 0, 13, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 114, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 50, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 71, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 0, 8, 0, 27, 91, 63, 49, 50, 108, 27, 91, 63, 50, 53, 104, 0, 27, 91, 67, 0, 27, 91, 65, 0, 27, 91, 63, 50, 53, 104, 0, 27, 91, 80, 0, 27, 91, 77, 0, 27, 40, 48, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 27, 91, 63, 49, 48, 52, 57, 104, 0, 27, 91, 52, 104, 0, 27, 91, 56, 109, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 27, 91, 37, 112, 49, 37, 100, 88, 0, 27, 40, 66, 0, 27, 91, 48, 109, 0, 27, 91, 63, 49, 48, 52, 57, 108, 0, 27, 91, 52, 108, 0, 27, 91, 50, 55, 109, 0, 27, 91, 50, 52, 109, 0, 27, 91, 63, 53, 104, 36, 60, 49, 48, 48, 47, 62, 27, 91, 63, 53, 108, 0, 7, 0, 27, 91, 52, 108, 27, 62, 27, 91, 63, 49, 48, 51, 52, 108, 0, 27, 91, 76, 0, 127, 0, 27, 91, 51, 59, 53, 126, 0, 27, 91, 51, 126, 0, 27, 91, 51, 59, 50, 126, 0, 27, 79, 66, 0, 27, 91, 50, 59, 50, 126, 0, 27, 91, 49, 59, 50, 70, 0, 27, 91, 49, 59, 53, 70, 0, 27, 79, 80, 0, 27, 91, 50, 49, 126, 0, 27, 79, 81, 0, 27, 79, 82, 0, 27, 79, 83, 0, 27, 91, 49, 53, 126, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 91, 49, 126, 0, 27, 91, 50, 126, 0, 27, 91, 50, 59, 53, 126, 0, 27, 79, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 79, 67, 0, 27, 91, 49, 59, 50, 66, 0, 27, 91, 49, 59, 50, 65, 0, 27, 79, 65, 0, 27, 91, 63, 49, 108, 27, 62, 0, 27, 91, 63, 49, 104, 27, 61, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 83, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 91, 105, 0, 27, 91, 52, 105, 0, 27, 91, 53, 105, 0, 27, 99, 0, 27, 91, 52, 108, 27, 62, 27, 91, 63, 49, 48, 51, 52, 108, 0, 27, 56, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 100, 0, 27, 55, 0, 10, 0, 27, 77, 0, 37, 63, 37, 112, 57, 37, 116, 27, 40, 48, 37, 101, 27, 40, 66, 37, 59, 27, 91, 48, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 49, 37, 112, 51, 37, 124, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 37, 63, 37, 112, 55, 37, 116, 59, 56, 37, 59, 109, 0, 27, 72, 0, 9, 0, 27, 93, 48, 59, 0, 27, 91, 49, 126, 0, 27, 91, 53, 126, 0, 27, 79, 117, 0, 27, 91, 52, 126, 0, 27, 91, 54, 126, 0, 43, 67, 44, 68, 45, 65, 46, 66, 48, 69, 96, 96, 97, 97, 102, 102, 103, 103, 104, 70, 105, 71, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 0, 27, 91, 90, 0, 27, 41, 48, 0, 27, 91, 52, 126, 0, 27, 79, 77, 0, 27, 91, 51, 59, 50, 126, 0, 27, 91, 49, 59, 50, 70, 0, 27, 91, 49, 59, 50, 72, 0, 27, 91, 50, 59, 50, 126, 0, 27, 91, 49, 59, 50, 68, 0, 27, 91, 54, 59, 50, 126, 0, 27, 91, 53, 59, 50, 126, 0, 27, 91, 49, 59, 50, 67, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 49, 59, 50, 80, 0, 27, 91, 49, 59, 50, 81, 0, 27, 91, 49, 59, 50, 82, 0, 27, 91, 49, 59, 50, 83, 0, 27, 91, 49, 53, 59, 50, 126, 0, 27, 91, 49, 55, 59, 50, 126, 0, 27, 91, 49, 56, 59, 50, 126, 0, 27, 91, 49, 57, 59, 50, 126, 0, 27, 91, 50, 48, 59, 50, 126, 0, 27, 91, 50, 49, 59, 50, 126, 0, 27, 91, 50, 51, 59, 50, 126, 0, 27, 91, 50, 52, 59, 50, 126, 0, 27, 91, 49, 59, 53, 80, 0, 27, 91, 49, 59, 53, 81, 0, 27, 91, 49, 59, 53, 82, 0, 27, 91, 49, 59, 53, 83, 0, 27, 91, 49, 53, 59, 53, 126, 0, 27, 91, 49, 55, 59, 53, 126, 0, 27, 91, 49, 56, 59, 53, 126, 0, 27, 91, 49, 57, 59, 53, 126, 0, 27, 91, 50, 48, 59, 53, 126, 0, 27, 91, 50, 49, 59, 53, 126, 0, 27, 91, 50, 51, 59, 53, 126, 0, 27, 91, 50, 52, 59, 53, 126, 0, 27, 91, 49, 59, 54, 80, 0, 27, 91, 49, 59, 54, 81, 0, 27, 91, 49, 59, 54, 82, 0, 27, 91, 49, 59, 54, 83, 0, 27, 91, 49, 53, 59, 54, 126, 0, 27, 91, 49, 55, 59, 54, 126, 0, 27, 91, 49, 56, 59, 54, 126, 0, 27, 91, 49, 57, 59, 54, 126, 0, 27, 91, 50, 48, 59, 54, 126, 0, 27, 91, 50, 49, 59, 54, 126, 0, 27, 91, 50, 51, 59, 54, 126, 0, 27, 91, 50, 52, 59, 54, 126, 0, 27, 91, 49, 59, 51, 80, 0, 27, 91, 49, 59, 51, 81, 0, 27, 91, 49, 59, 51, 82, 0, 27, 91, 49, 59, 51, 83, 0, 27, 91, 49, 53, 59, 51, 126, 0, 27, 91, 49, 55, 59, 51, 126, 0, 27, 91, 49, 56, 59, 51, 126, 0, 27, 91, 49, 57, 59, 51, 126, 0, 27, 91, 50, 48, 59, 51, 126, 0, 27, 91, 50, 49, 59, 51, 126, 0, 27, 91, 50, 51, 59, 51, 126, 0, 27, 91, 50, 52, 59, 51, 126, 0, 27, 91, 49, 59, 52, 80, 0, 27, 91, 49, 59, 52, 81, 0, 27, 91, 49, 59, 52, 82, 0, 27, 91, 49, 75, 0, 27, 91, 37, 105, 37, 100, 59, 37, 100, 82, 0, 27, 91, 54, 110, 0, 27, 91, 63, 49, 59, 50, 99, 0, 27, 91, 99, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 91, 51, 109, 0, 27, 91, 50, 51, 109, 0, 27, 91, 77, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 51, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 57, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 51, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 52, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 49, 48, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 52, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0
+};
+// Taken from Dickey ncurses terminfo.src dated 2017-04-22.
+// This is a 256-colour terminfo description that lacks true-colour
+// capabilities that gnome actually has.
+static const signed char vte_256colour_terminfo[] = {
+ 26, 1, 52, 0, 29, 0, 15, 0, 105, 1, -55, 5, 103, 110, 111, 109, 101, 45, 50, 53, 54, 99, 111, 108, 111, 114, 124, 71, 78, 79, 77, 69, 32, 84, 101, 114, 109, 105, 110, 97, 108, 32, 119, 105, 116, 104, 32, 120, 116, 101, 114, 109, 32, 50, 53, 54, 45, 99, 111, 108, 111, 114, 115, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 80, 0, 8, 0, 24, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 127, 0, 0, 4, 0, 6, 0, 8, 0, 25, 0, 30, 0, 38, 0, 42, 0, 46, 0, -1, -1, 57, 0, 74, 0, 76, 0, 80, 0, 87, 0, -1, -1, 89, 0, 96, 0, -1, -1, 100, 0, -1, -1, 104, 0, 108, 0, -1, -1, -1, -1, 112, 0, -1, -1, 114, 0, 119, 0, -1, -1, -128, 0, -123, 0, -118, 0, -1, -1,-113, 0, -108, 0, -103, 0, -98, 0, -89, 0, -87, 0, -81, 0, -1, -1, -68, 0, -63, 0, -57, 0, -51, 0, -1, -1, -1, -1, -1, -1, -33, 0, -1, -1, -1, -1, -1, -1, 0, 1, -1, -1, 4, 1, -1, -1, -1, -1, -1, -1, 6, 1, -1, -1, 11, 1, -1, -1, -1, -1, -1, -1, -1, -1, 15, 1, 19, 1, 25, 1, 29, 1, 33, 1, 37, 1, 43, 1, 49, 1, 55, 1, 61, 1, 67, 1, 71, 1, -1, -1, 76, 1, -1, -1, 80, 1, 85, 1, 90, 1, 94, 1, 101, 1, -1, -1, 108, 1, 112, 1, 120, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -128, 1,-119, 1, -110, 1, -101, 1, -92, 1, -83, 1, -74, 1, -65, 1, -56, 1, -47, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -38, 1, -35, 1, -1, -1, -1, -1, 16, 2, 19, 2, 30, 2, 33, 2, 35, 2, 38, 2, 116, 2, -1, -1, 119, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 121, 2, -1, -1, -1, -1, -1, -1, -1, -1, 125, 2, -1, -1, -78, 2, -1, -1, -1, -1, -74, 2, -68, 2, -1, -1, -1, -1, -62, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -58, 2, -54, 2, -1, -1, -50, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -45, 2, -1, -1, -38, 2, -33, 2, -1, -1, -1, -1, -1, -1, -1, -1, -26, 2, -19, 2, -12, 2, -1, -1, -1, -1, -5, 2, -1, -1, 2, 3, -1, -1, -1, -1, -1, -1, 9, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, 3, 22, 3, 28, 3, 35, 3, 42, 3, 49, 3, 56, 3, 64, 3, 72, 3, 80, 3, 88, 3, 96, 3, 104, 3, 112, 3, 120, 3, 127, 3, -122, 3, -115, 3,-108, 3, -100, 3, -92, 3, -84, 3, -76, 3, -68, 3, -60, 3, -52, 3, -44, 3, -37, 3, -30, 3, -23, 3, -16, 3, -8, 3, 0, 4, 8, 4, 16, 4, 24, 4, 32, 4, 40, 4, 48, 4, 55, 4, 62, 4, 69, 4, 76, 4, 84, 4, 92, 4, 100, 4, 108, 4, 116, 4, 124, 4, -124, 4,-116, 4, -109, 4, -102, 4, -95, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -90, 4, -79, 4, -74, 4, -55, 4, -51, 4, -42, 4, -35, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 59, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 64, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 70, 5, -1, -1, -1, -1, -1, -1, 74, 5, -119, 5, 27, 91, 90, 0, 7, 0, 13, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 114, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 50, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 71, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 0, 8, 0, 27, 91, 63, 50, 53, 104, 0, 27, 91, 67, 0, 27, 91, 65, 0, 27, 91, 80, 0, 27, 91, 77, 0, 14, 0, 27, 91, 49, 109, 0, 27, 55, 27, 91, 63, 52, 55, 104, 0, 27, 91, 50, 109, 0, 27, 91, 52, 104, 0, 27, 91, 56, 109, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 27, 91, 37, 112, 49, 37, 100, 88, 0, 15, 0, 27, 91, 48, 109, 15, 0, 27, 91, 50, 74, 27, 91, 63, 52, 55, 108, 27, 56, 0, 27, 91, 52, 108, 0, 27, 91, 50, 55, 109, 0, 27, 91, 50, 52, 109, 0, 27, 91, 63, 53, 104, 36, 60, 49, 48, 48, 47, 62, 27, 91, 63, 53, 108, 0, 27, 91, 109, 27, 91, 63, 55, 104, 27, 91, 52, 108, 27, 62, 27, 55, 27, 91, 114, 27, 91, 63, 49, 59, 51, 59, 52, 59, 54, 108, 27, 56, 0, 27, 91, 76, 0, 127, 0, 27, 91, 51, 126, 0, 27, 79, 66, 0, 27, 79, 80, 0, 27, 91, 50, 49, 126, 0, 27, 79, 81, 0, 27, 79, 82, 0, 27, 79, 83, 0, 27, 91, 49, 53, 126, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 79, 72, 0, 27, 91, 50, 126, 0, 27, 79, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 79, 67, 0, 27, 91, 49, 59, 50, 66, 0, 27, 91, 49, 59, 50, 65, 0, 27, 79, 65, 0, 27, 91, 63, 49, 108, 27, 62, 0, 27, 91, 63, 49, 104, 27, 61, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 83, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 84, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 99, 0, 27, 55, 27, 91, 114, 27, 56, 27, 91, 109, 27, 91, 63, 55, 104, 27, 91, 33, 112, 27, 91, 63, 49, 59, 51, 59, 52, 59, 54, 108, 27, 91, 52, 108, 27, 62, 27, 91, 63, 49, 48, 48, 48, 108, 27, 91, 63, 50, 53, 104, 0, 27, 56, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 100, 0, 27, 55, 0, 10, 0, 27, 77, 0, 27, 91, 48, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 53, 37, 116, 59, 50, 37, 59, 37, 63, 37, 112, 55, 37, 116, 59, 56, 37, 59, 37, 63, 37, 112, 49, 37, 112, 51, 37, 124, 37, 116, 59, 55, 37, 59, 109, 37, 63, 37, 112, 57, 37, 116, 14, 37, 101, 15, 37, 59, 0, 27, 72, 0, 9, 0, 27, 91, 69, 0, 96, 96, 97, 97, 102, 102, 103, 103, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 0, 27, 91, 90, 0, 27, 91, 63, 55, 104, 0, 27, 91, 63, 55, 108, 0, 27, 41, 48, 0, 27, 79, 70, 0, 27, 79, 77, 0, 27, 91, 49, 126, 0, 27, 91, 51, 59, 50, 126, 0, 27, 91, 52, 126, 0, 27, 91, 49, 59, 50, 70, 0, 27, 91, 49, 59, 50, 72, 0, 27, 91, 50, 59, 50, 126, 0, 27, 91, 49, 59, 50, 68, 0, 27, 91, 54, 59, 50, 126, 0, 27, 91, 53, 59, 50, 126, 0, 27, 91, 49, 59, 50, 67, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 49, 59, 50, 80, 0, 27, 91, 49, 59, 50, 81, 0, 27, 91, 49, 59, 50, 82, 0, 27, 91, 49, 59, 50, 83, 0, 27, 91, 49, 53, 59, 50, 126, 0, 27, 91, 49, 55, 59, 50, 126, 0, 27, 91, 49, 56, 59, 50, 126, 0, 27, 91, 49, 57, 59, 50, 126, 0, 27, 91, 50, 48, 59, 50, 126, 0, 27, 91, 50, 49, 59, 50, 126, 0, 27, 91, 50, 51, 59, 50, 126, 0, 27, 91, 50, 52, 59, 50, 126, 0, 27, 91, 49, 59, 53, 80, 0, 27, 91, 49, 59, 53, 81, 0, 27, 91, 49, 59, 53, 82, 0, 27, 91, 49, 59, 53, 83, 0, 27, 91, 49, 53, 59, 53, 126, 0, 27, 91, 49, 55, 59, 53, 126, 0, 27, 91, 49, 56, 59, 53, 126, 0, 27, 91, 49, 57, 59, 53, 126, 0, 27, 91, 50, 48, 59, 53, 126, 0, 27, 91, 50, 49, 59, 53, 126, 0, 27, 91, 50, 51, 59, 53, 126, 0, 27, 91, 50, 52, 59, 53, 126, 0, 27, 91, 49, 59, 54, 80, 0, 27, 91, 49, 59, 54, 81, 0, 27, 91, 49, 59, 54, 82, 0, 27, 91, 49, 59, 54, 83, 0, 27, 91, 49, 53, 59, 54, 126, 0, 27, 91, 49, 55, 59, 54, 126, 0, 27, 91, 49, 56, 59, 54, 126, 0, 27, 91, 49, 57, 59, 54, 126, 0, 27, 91, 50, 48, 59, 54, 126, 0, 27, 91, 50, 49, 59, 54, 126, 0, 27, 91, 50, 51, 59, 54, 126, 0, 27, 91, 50, 52, 59, 54, 126, 0, 27, 91, 49, 59, 51, 80, 0, 27, 91, 49, 59, 51, 81, 0, 27, 91, 49, 59, 51, 82, 0, 27, 91, 49, 59, 51, 83, 0, 27, 91, 49, 53, 59, 51, 126, 0, 27, 91, 49, 55, 59, 51, 126, 0, 27, 91, 49, 56, 59, 51, 126, 0, 27, 91, 49, 57, 59, 51, 126, 0, 27, 91, 50, 48, 59, 51, 126, 0, 27, 91, 50, 49, 59, 51, 126, 0, 27, 91, 50, 51, 59, 51, 126, 0, 27, 91, 50, 52, 59, 51, 126, 0, 27, 91, 49, 59, 52, 80, 0, 27, 91, 49, 59, 52, 81, 0, 27, 91, 49, 59, 52, 82, 0, 27, 91, 49, 75, 0, 27, 91, 37, 105, 37, 100, 59, 37, 100, 82, 0, 27, 91, 54, 110, 0, 27, 91, 63, 37, 91, 59, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 93, 99, 0, 27, 91, 99, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 93, 49, 48, 52, 7, 0, 27, 93, 52, 59, 37, 112, 49, 37, 100, 59, 114, 103, 98, 58, 37, 112, 50, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 47, 37, 112, 51, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 47, 37, 112, 52, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 27, 92, 0, 27, 91, 51, 109, 0, 27, 91, 50, 51, 109, 0, 27, 91, 77, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 51, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 57, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 51, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 52, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 49, 48, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 52, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0
+};
+// Taken from Dickey ncurses terminfo.src dated 2017-04-22.
+static const signed char ansi_terminfo[] = {
+ 26, 1, 40, 0, 23, 0, 16, 0, 125, 1, 68, 2, 97, 110, 115, 105, 124, 97, 110, 115, 105, 47, 112, 99, 45, 116, 101, 114, 109, 32, 99, 111, 109, 112, 97, 116, 105, 98, 108, 101, 32, 119, 105, 116, 104, 32, 99, 111, 108, 111, 114, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 80, 0, 8, 0, 24, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8, 0, 64, 0, 3, 0, 0, 0, 4, 0, 6, 0, -1, -1, 8, 0, 13, 0, 20, 0, 24, 0, 28, 0, -1, -1, 39, 0, 56, 0, 60, 0, -1, -1, 64, 0, -1, -1, -1, -1, 68, 0, -1, -1, 72, 0, -1, -1, 76, 0, 80, 0, -1, -1, -1, -1, 84, 0, 90, 0, 95, 0, -1, -1, -1, -1, -1, -1, -1, -1, 100, 0, -1, -1, 105, 0, 110, 0, 115, 0, 120, 0,-127, 0,-121, 0, -1, -1, -1, -1, -1, -1,-113, 0,-109, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-105, 0, -1, -1,-101, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -99, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -95, 0, -91, 0, -1, -1, -87, 0, -1, -1, -1, -1, -1, -1, -83, 0, -1, -1, -1, -1, -1, -1, -79, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -75, 0, -1, -1, -70, 0, -61, 0, -52, 0, -43, 0, -34, 0, -25, 0, -16, 0, -7, 0, 2, 1, 11, 1, -1, -1, -1, -1, -1, -1, -1, -1, 20, 1, 25, 1, 30, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 1, -1, -1, 61, 1, -1, -1, 63, 1,-107, 1, -1, -1,-104, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-100, 1, -1, -1, -37, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -33, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -28, 1, -17, 1, -12, 1, 7, 2, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, 2, 30, 2, -1, -1, -1, -1, -1, -1, 40, 2, 44, 2, 48, 2, 52, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, 2, 62, 2, 27, 91, 90, 0, 7, 0, 13, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 71, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 27, 91, 66, 0, 27, 91, 72, 0, 27, 91, 68, 0, 27, 91, 67, 0, 27, 91, 65, 0, 27, 91, 80, 0, 27, 91, 77, 0, 27, 91, 49, 49, 109, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 27, 91, 56, 109, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 27, 91, 37, 112, 49, 37, 100, 88, 0, 27, 91, 49, 48, 109, 0, 27, 91, 48, 59, 49, 48, 109, 0, 27, 91, 109, 0, 27, 91, 109, 0, 27, 91, 76, 0, 8, 0, 27, 91, 66, 0, 27, 91, 72, 0, 27, 91, 76, 0, 27, 91, 68, 0, 27, 91, 67, 0, 27, 91, 65, 0, 13, 27, 91, 83, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 83, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 84, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 91, 52, 105, 0, 27, 91, 53, 105, 0, 37, 112, 49, 37, 99, 27, 91, 37, 112, 50, 37, 123, 49, 125, 37, 45, 37, 100, 98, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 100, 0, 10, 0, 27, 91, 48, 59, 49, 48, 37, 63, 37, 112, 49, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 51, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 55, 37, 116, 59, 56, 37, 59, 37, 63, 37, 112, 57, 37, 116, 59, 49, 49, 37, 59, 109, 0, 27, 72, 0, 27, 91, 73, 0, 43, 16, 44, 17, 45, 24, 46, 25, 48, -37, 96, 4, 97, -79, 102, -8, 103, -15, 104, -80, 106, -39, 107, -65, 108, -38, 109, -64, 110, -59, 111, 126, 112, -60, 113, -60, 114, -60, 115, 95, 116, -61, 117, -76, 118, -63, 119, -62, 120, -77, 121, -13, 122, -14, 123, -29, 124, -40, 125,-100, 126, -2, 0, 27, 91, 90, 0, 27, 91, 49, 75, 0, 27, 91, 37, 105, 37, 100, 59, 37, 100, 82, 0, 27, 91, 54, 110, 0, 27, 91, 63, 37, 91, 59, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 93, 99, 0, 27, 91, 99, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 91, 51, 37, 112, 49, 37, 100, 109, 0, 27, 91, 52, 37, 112, 49, 37, 100, 109, 0, 27, 40, 66, 0, 27, 41, 66, 0, 27, 42, 66, 0, 27, 43, 66, 0, 27, 91, 49, 49, 109, 0, 27, 91, 49, 48, 109, 0
+};
+
+/// Load one of the built-in terminfo entries when unibilium has failed to
+/// load a terminfo record from an external database, as it does on termcap-
+/// -only systems. We do not do any fancy recognition of xterm pretenders
+/// here. An external terminfo database would not do that, and we want to
+/// behave as much like an external terminfo database as possible.
+unibi_term *load_builtin_terminfo(const char * term)
+{
+ if (terminfo_is_term_family(term, "xterm")) {
+ return unibi_from_mem((const char *)xterm_256colour_terminfo,
+ sizeof xterm_256colour_terminfo);
+ } else if (terminfo_is_term_family(term, "screen")) {
+ return unibi_from_mem((const char *)screen_256colour_terminfo,
+ sizeof screen_256colour_terminfo);
+ } else if (terminfo_is_term_family(term, "tmux")) {
+ return unibi_from_mem((const char *)tmux_256colour_terminfo,
+ sizeof tmux_256colour_terminfo);
+ } else if (terminfo_is_term_family(term, "rxvt")) {
+ return unibi_from_mem((const char *)rxvt_256colour_terminfo,
+ sizeof rxvt_256colour_terminfo);
+ } else if (terminfo_is_term_family(term, "putty")) {
+ return unibi_from_mem((const char *)putty_256colour_terminfo,
+ sizeof putty_256colour_terminfo);
+ } else if (terminfo_is_term_family(term, "linux")) {
+ return unibi_from_mem((const char *)linux_16colour_terminfo,
+ sizeof linux_16colour_terminfo);
+ } else if (terminfo_is_term_family(term, "interix")) {
+ return unibi_from_mem((const char *)interix_8colour_terminfo,
+ sizeof interix_8colour_terminfo);
+ } else if (terminfo_is_term_family(term, "iterm")
+ || terminfo_is_term_family(term, "iterm2")
+ || terminfo_is_term_family(term, "iTerm.app")
+ || terminfo_is_term_family(term, "iTerm2.app")) {
+ return unibi_from_mem((const char *)iterm_256colour_terminfo,
+ sizeof iterm_256colour_terminfo);
+ } else if (terminfo_is_term_family(term, "st")) {
+ return unibi_from_mem((const char *)st_256colour_terminfo,
+ sizeof st_256colour_terminfo);
+ } else if (terminfo_is_term_family(term, "gnome")
+ || terminfo_is_term_family(term, "vte")) {
+ return unibi_from_mem((const char *)vte_256colour_terminfo,
+ sizeof vte_256colour_terminfo);
+ } else {
+ return unibi_from_mem((const char *)ansi_terminfo,
+ sizeof ansi_terminfo);
+ }
+}
diff --git a/src/nvim/tui/terminfo.h b/src/nvim/tui/terminfo.h
new file mode 100644
index 0000000000..099df8967f
--- /dev/null
+++ b/src/nvim/tui/terminfo.h
@@ -0,0 +1,10 @@
+#ifndef NVIM_TUI_TERMINFO_H
+#define NVIM_TUI_TERMINFO_H
+
+#include <unibilium.h>
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "tui/terminfo.h.generated.h"
+#endif
+
+#endif // NVIM_TUI_TERMINFO_H
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 74187e07c0..1cbd02dfd9 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
// Terminal UI functions. Invoked (by ui_bridge.c) on the TUI thread.
#include <assert.h>
@@ -31,13 +34,37 @@
#include "nvim/ugrid.h"
#include "nvim/tui/input.h"
#include "nvim/tui/tui.h"
+#include "nvim/tui/terminfo.h"
+#include "nvim/cursor_shape.h"
+#include "nvim/syntax.h"
+#include "nvim/macros.h"
-// Space reserved in the output buffer to restore the cursor to normal when
-// flushing. No existing terminal will require 32 bytes to do that.
+// Space reserved in two output buffers to make the cursor normal or invisible
+// when flushing. No existing terminal will require 32 bytes to do that.
#define CNORM_COMMAND_MAX_SIZE 32
#define OUTBUF_SIZE 0xffff
#define TOO_MANY_EVENTS 1000000
+#define STARTS_WITH(str, prefix) (strlen(str) >= (sizeof(prefix) - 1) \
+ && 0 == memcmp((str), (prefix), sizeof(prefix) - 1))
+#define TMUX_WRAP(is_tmux, seq) ((is_tmux) \
+ ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq)
+#define LINUXSET0C "\x1b[?0c"
+#define LINUXSET1C "\x1b[?1c"
+
+// Per the commentary in terminfo, only a minus sign is a true suffix
+// separator.
+bool terminfo_is_term_family(const char *term, const char *family)
+{
+ if (!term) {
+ return false;
+ }
+ size_t tlen = strlen(term);
+ size_t flen = strlen(family);
+ return tlen >= flen
+ && 0 == memcmp(term, family, flen) \
+ && ('\0' == term[flen] || '-' == term[flen]);
+}
typedef struct {
int top, bot, left, right;
@@ -49,7 +76,10 @@ typedef struct {
bool stop;
unibi_var_t params[9];
char buf[OUTBUF_SIZE];
- size_t bufpos, bufsize;
+ size_t bufpos;
+ char norm[CNORM_COMMAND_MAX_SIZE];
+ char invis[CNORM_COMMAND_MAX_SIZE];
+ size_t normlen, invislen;
TermInput input;
uv_loop_t write_loop;
unibi_term *ut;
@@ -60,27 +90,35 @@ typedef struct {
bool out_isatty;
SignalWatcher winch_handle, cont_handle;
bool cont_received;
- // Event scheduled by the ui bridge. Since the main thread suspends until
- // the event is handled, it is fine to use a single field instead of a queue
- Event scheduled_event;
UGrid grid;
kvec_t(Rect) invalid_regions;
int out_fd;
- bool can_use_terminal_scroll;
+ bool scroll_region_is_full_screen;
+ bool can_change_scroll_region;
+ bool can_set_lr_margin;
+ bool can_set_left_right_margin;
+ bool immediate_wrap_after_last_column;
bool mouse_enabled;
- bool busy;
+ bool busy, is_invisible;
+ cursorentry_T cursor_shapes[SHAPE_IDX_COUNT];
HlAttrs print_attrs;
- int showing_mode;
+ bool default_attr;
+ ModeShape showing_mode;
struct {
int enable_mouse, disable_mouse;
int enable_bracketed_paste, disable_bracketed_paste;
- int set_cursor_shape_bar, set_cursor_shape_ul, set_cursor_shape_block;
+ int enable_lr_margin, disable_lr_margin;
int set_rgb_foreground, set_rgb_background;
+ int set_cursor_color;
int enable_focus_reporting, disable_focus_reporting;
+ int resize_screen;
+ int reset_scroll_region;
+ int set_cursor_style, reset_cursor_style;
} unibi_ext;
} TUIData;
static bool volatile got_winch = false;
+static bool cursor_style_enabled = false;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "tui/tui.c.generated.h"
@@ -92,11 +130,11 @@ UI *tui_start(void)
UI *ui = xcalloc(1, sizeof(UI));
ui->stop = tui_stop;
ui->rgb = p_tgc;
- ui->pum_external = false;
ui->resize = tui_resize;
ui->clear = tui_clear;
ui->eol_clear = tui_eol_clear;
ui->cursor_goto = tui_cursor_goto;
+ ui->mode_info_set = tui_mode_info_set;
ui->update_menu = tui_update_menu;
ui->busy_start = tui_busy_start;
ui->busy_stop = tui_busy_stop;
@@ -117,50 +155,96 @@ UI *tui_start(void)
ui->set_title = tui_set_title;
ui->set_icon = tui_set_icon;
ui->event = tui_event;
+
+ memset(ui->ui_ext, 0, sizeof(ui->ui_ext));
+
return ui_bridge_attach(ui, tui_main, tui_scheduler);
}
+static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index,
+ char * buf, size_t len)
+{
+ const char *str = unibi_get_str(data->ut, unibi_index);
+ if (!str) {
+ return 0U;
+ }
+ return unibi_run(str, data->params, buf, len);
+}
+
static void terminfo_start(UI *ui)
{
TUIData *data = ui->data;
- data->can_use_terminal_scroll = true;
+ data->scroll_region_is_full_screen = true;
data->bufpos = 0;
- data->bufsize = sizeof(data->buf) - CNORM_COMMAND_MAX_SIZE;
- data->showing_mode = 0;
+ data->default_attr = false;
+ data->is_invisible = true;
+ data->busy = false;
+ data->showing_mode = SHAPE_IDX_N;
data->unibi_ext.enable_mouse = -1;
data->unibi_ext.disable_mouse = -1;
+ data->unibi_ext.set_cursor_color = -1;
data->unibi_ext.enable_bracketed_paste = -1;
data->unibi_ext.disable_bracketed_paste = -1;
- data->unibi_ext.set_cursor_shape_bar = -1;
- data->unibi_ext.set_cursor_shape_ul = -1;
- data->unibi_ext.set_cursor_shape_block = -1;
+ data->unibi_ext.enable_lr_margin = -1;
+ data->unibi_ext.disable_lr_margin = -1;
data->unibi_ext.enable_focus_reporting = -1;
data->unibi_ext.disable_focus_reporting = -1;
+ data->unibi_ext.resize_screen = -1;
+ data->unibi_ext.reset_scroll_region = -1;
+ data->unibi_ext.set_cursor_style = -1;
+ data->unibi_ext.reset_cursor_style = -1;
data->out_fd = 1;
data->out_isatty = os_isatty(data->out_fd);
// setup unibilium
+ const char *term = os_getenv("TERM");
data->ut = unibi_from_env();
if (!data->ut) {
- // For some reason could not read terminfo file, use a dummy entry that
- // will be populated with common values by fix_terminfo below
- data->ut = unibi_dummy();
+ data->ut = load_builtin_terminfo(term);
}
- fix_terminfo(data);
- // Initialize the cursor shape.
- unibi_out(ui, data->unibi_ext.set_cursor_shape_block);
+ // None of the following work over SSH; see :help TERM .
+ const char *colorterm = os_getenv("COLORTERM");
+ const char *termprg = os_getenv("TERM_PROGRAM");
+ const char *vte_version_env = os_getenv("VTE_VERSION");
+ long vte_version = vte_version_env ? strtol(vte_version_env, NULL, 10) : 0;
+ bool iterm_env = termprg && strstr(termprg, "iTerm.app");
+ bool konsole = os_getenv("KONSOLE_PROFILE_NAME")
+ || os_getenv("KONSOLE_DBUS_SESSION");
+
+ patch_terminfo_bugs(data, term, colorterm, vte_version, konsole, iterm_env);
+ augment_terminfo(data, term, colorterm, vte_version, konsole, iterm_env);
+ data->can_change_scroll_region =
+ !!unibi_get_str(data->ut, unibi_change_scroll_region);
+ data->can_set_lr_margin =
+ !!unibi_get_str(data->ut, unibi_set_lr_margin);
+ data->can_set_left_right_margin =
+ !!unibi_get_str(data->ut, unibi_set_left_margin_parm)
+ && !!unibi_get_str(data->ut, unibi_set_right_margin_parm);
+ data->immediate_wrap_after_last_column =
+ terminfo_is_term_family(term, "cygwin")
+ || terminfo_is_term_family(term, "interix");
+ data->normlen = unibi_pre_fmt_str(data, unibi_cursor_normal,
+ data->norm, sizeof data->norm);
+ data->invislen = unibi_pre_fmt_str(data, unibi_cursor_invisible,
+ data->invis, sizeof data->invis);
// Set 't_Co' from the result of unibilium & fix_terminfo.
t_colors = unibi_get_num(data->ut, unibi_max_colors);
// Enter alternate screen and clear
+ // NOTE: Do this *before* changing terminal settings. #6433
unibi_out(ui, unibi_enter_ca_mode);
+ unibi_out(ui, unibi_keypad_xmit);
unibi_out(ui, unibi_clear_screen);
// Enable bracketed paste
- unibi_out(ui, data->unibi_ext.enable_bracketed_paste);
+ unibi_out_ext(ui, data->unibi_ext.enable_bracketed_paste);
// Enable focus reporting
- unibi_out(ui, data->unibi_ext.enable_focus_reporting);
+ unibi_out_ext(ui, data->unibi_ext.enable_focus_reporting);
uv_loop_init(&data->write_loop);
if (data->out_isatty) {
uv_tty_init(&data->write_loop, &data->output_handle.tty, data->out_fd, 0);
+#ifdef WIN32
uv_tty_set_mode(&data->output_handle.tty, UV_TTY_MODE_RAW);
+#else
+ uv_tty_set_mode(&data->output_handle.tty, UV_TTY_MODE_IO);
+#endif
} else {
uv_pipe_init(&data->write_loop, &data->output_handle.pipe, 0);
uv_pipe_open(&data->output_handle.pipe, data->out_fd);
@@ -171,16 +255,17 @@ static void terminfo_stop(UI *ui)
{
TUIData *data = ui->data;
// Destroy output stuff
- tui_mode_change(ui, NORMAL);
+ tui_mode_change(ui, (String)STRING_INIT, SHAPE_IDX_N);
tui_mouse_off(ui);
unibi_out(ui, unibi_exit_attribute_mode);
// cursor should be set to normal before exiting alternate screen
unibi_out(ui, unibi_cursor_normal);
+ unibi_out(ui, unibi_keypad_local);
unibi_out(ui, unibi_exit_ca_mode);
// Disable bracketed paste
- unibi_out(ui, data->unibi_ext.disable_bracketed_paste);
+ unibi_out_ext(ui, data->unibi_ext.disable_bracketed_paste);
// Disable focus reporting
- unibi_out(ui, data->unibi_ext.disable_focus_reporting);
+ unibi_out_ext(ui, data->unibi_ext.disable_focus_reporting);
flush_buf(ui, true);
uv_tty_reset_mode();
uv_close((uv_handle_t *)&data->output_handle, NULL);
@@ -199,11 +284,6 @@ static void tui_terminal_start(UI *ui)
terminfo_start(ui);
update_size(ui);
signal_watcher_start(&data->winch_handle, sigwinch_cb, SIGWINCH);
-
-#if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18
- data->input.tk_ti_hook_fn = tui_tk_ti_getstr;
-#endif
- term_input_init(&data->input, data->loop);
term_input_start(&data->input);
}
@@ -235,9 +315,17 @@ static void tui_main(UIBridgeData *bridge, UI *ui)
kv_init(data->invalid_regions);
signal_watcher_init(data->loop, &data->winch_handle, ui);
signal_watcher_init(data->loop, &data->cont_handle, data);
+#ifdef UNIX
signal_watcher_start(&data->cont_handle, sigcont_cb, SIGCONT);
+#endif
+
+#if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18
+ data->input.tk_ti_hook_fn = tui_tk_ti_getstr;
+#endif
+ term_input_init(&data->input, &tui_loop);
tui_terminal_start(ui);
data->stop = false;
+
// allow the main thread to continue, we are ready to start handling UI
// callbacks
CONTINUE(bridge);
@@ -264,10 +352,12 @@ static void tui_scheduler(Event event, void *d)
loop_schedule(data->loop, event);
}
+#ifdef UNIX
static void sigcont_cb(SignalWatcher *watcher, int signum, void *data)
{
((TUIData *)data)->cont_received = true;
}
+#endif
static void sigwinch_cb(SignalWatcher *watcher, int signum, void *data)
{
@@ -294,25 +384,56 @@ static void update_attrs(UI *ui, HlAttrs attrs)
}
data->print_attrs = attrs;
- unibi_out(ui, unibi_exit_attribute_mode);
UGrid *grid = &data->grid;
int fg = attrs.foreground != -1 ? attrs.foreground : grid->fg;
int bg = attrs.background != -1 ? attrs.background : grid->bg;
+ if (unibi_get_str(data->ut, unibi_set_attributes)) {
+ if (attrs.bold || attrs.reverse || attrs.underline || attrs.undercurl) {
+ data->params[0].i = 0; // standout
+ data->params[1].i = attrs.underline || attrs.undercurl;
+ data->params[2].i = attrs.reverse;
+ data->params[3].i = 0; // blink
+ data->params[4].i = 0; // dim
+ data->params[5].i = attrs.bold;
+ data->params[6].i = 0; // blank
+ data->params[7].i = 0; // protect
+ data->params[8].i = 0; // alternate character set
+ unibi_out(ui, unibi_set_attributes);
+ } else if (!data->default_attr) {
+ unibi_out(ui, unibi_exit_attribute_mode);
+ }
+ } else {
+ if (!data->default_attr) {
+ unibi_out(ui, unibi_exit_attribute_mode);
+ }
+ if (attrs.bold) {
+ unibi_out(ui, unibi_enter_bold_mode);
+ }
+ if (attrs.underline || attrs.undercurl) {
+ unibi_out(ui, unibi_enter_underline_mode);
+ }
+ if (attrs.reverse) {
+ unibi_out(ui, unibi_enter_reverse_mode);
+ }
+ }
+ if (attrs.italic) {
+ unibi_out(ui, unibi_enter_italics_mode);
+ }
if (ui->rgb) {
if (fg != -1) {
data->params[0].i = (fg >> 16) & 0xff; // red
data->params[1].i = (fg >> 8) & 0xff; // green
data->params[2].i = fg & 0xff; // blue
- unibi_out(ui, data->unibi_ext.set_rgb_foreground);
+ unibi_out_ext(ui, data->unibi_ext.set_rgb_foreground);
}
if (bg != -1) {
data->params[0].i = (bg >> 16) & 0xff; // red
data->params[1].i = (bg >> 8) & 0xff; // green
data->params[2].i = bg & 0xff; // blue
- unibi_out(ui, data->unibi_ext.set_rgb_background);
+ unibi_out_ext(ui, data->unibi_ext.set_rgb_background);
}
} else {
if (fg != -1) {
@@ -326,30 +447,173 @@ static void update_attrs(UI *ui, HlAttrs attrs)
}
}
- if (attrs.bold) {
- unibi_out(ui, unibi_enter_bold_mode);
- }
- if (attrs.italic) {
- unibi_out(ui, unibi_enter_italics_mode);
- }
- if (attrs.underline || attrs.undercurl) {
- unibi_out(ui, unibi_enter_underline_mode);
- }
- if (attrs.reverse) {
- unibi_out(ui, unibi_enter_reverse_mode);
+ data->default_attr = fg == -1 && bg == -1
+ && !attrs.bold && !attrs.italic && !attrs.underline && !attrs.undercurl
+ && !attrs.reverse;
+}
+
+static void final_column_wrap(UI *ui)
+{
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+ if (grid->col == ui->width) {
+ grid->col = 0;
+ if (grid->row < ui->height) {
+ grid->row++;
+ }
}
}
+/// It is undocumented, but in the majority of terminals and terminal emulators
+/// printing at the right margin does not cause an automatic wrap until the
+/// next character is printed, holding the cursor in place until then.
static void print_cell(UI *ui, UCell *ptr)
{
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+ if (!data->immediate_wrap_after_last_column) {
+ // Printing the next character finally advances the cursor.
+ final_column_wrap(ui);
+ }
update_attrs(ui, ptr->attrs);
out(ui, ptr->data, strlen(ptr->data));
+ grid->col++;
+ if (data->immediate_wrap_after_last_column) {
+ // Printing at the right margin immediately advances the cursor.
+ final_column_wrap(ui);
+ }
+}
+
+static bool cheap_to_print(UI *ui, int row, int col, int next)
+{
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+ UCell *cell = grid->cells[row] + col;
+ while (next) {
+ next--;
+ if (attrs_differ(cell->attrs, data->print_attrs)) {
+ if (data->default_attr) {
+ return false;
+ }
+ }
+ if (strlen(cell->data) > 1) {
+ return false;
+ }
+ cell++;
+ }
+ return true;
+}
+
+/// This optimizes several cases where it is cheaper to do something other
+/// than send a full cursor positioning control sequence. However, there are
+/// some further optimizations that may seem obvious but that will not work.
+///
+/// We cannot use VT (ASCII 0/11) for moving the cursor up, because VT means
+/// move the cursor down on a DEC terminal. Similarly, on a DEC terminal FF
+/// (ASCII 0/12) means the same thing and does not mean home. VT, CVT, and
+/// TAB also stop at software-defined tabulation stops, not at a fixed set
+/// of row/column positions.
+static void cursor_goto(UI *ui, int row, int col)
+{
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+ if (row == grid->row && col == grid->col) {
+ return;
+ }
+ if (0 == row && 0 == col) {
+ unibi_out(ui, unibi_cursor_home);
+ ugrid_goto(grid, row, col);
+ return;
+ }
+ if (0 == col ? col != grid->col :
+ row != grid->row ? false :
+ 1 == col ? 2 < grid->col && cheap_to_print(ui, grid->row, 0, col) :
+ 2 == col ? 5 < grid->col && cheap_to_print(ui, grid->row, 0, col) :
+ false) {
+ // Motion to left margin from anywhere else, or CR + printing chars is
+ // even less expensive than using BSes or CUB.
+ unibi_out(ui, unibi_carriage_return);
+ ugrid_goto(grid, grid->row, 0);
+ } else if (col > grid->col) {
+ int n = col - grid->col;
+ if (n <= (row == grid->row ? 4 : 2)
+ && cheap_to_print(ui, grid->row, grid->col, n)) {
+ UGRID_FOREACH_CELL(grid, grid->row, grid->row,
+ grid->col, col - 1, {
+ print_cell(ui, cell);
+ });
+ }
+ }
+ if (row == grid->row) {
+ if (col < grid->col
+ // Deferred right margin wrap terminals have inconsistent ideas about
+ // where the cursor actually is during a deferred wrap. Relative
+ // motion calculations have OBOEs that cannot be compensated for,
+ // because two terminals that claim to be the same will implement
+ // different cursor positioning rules.
+ && (data->immediate_wrap_after_last_column || grid->col < ui->width)) {
+ int n = grid->col - col;
+ if (n <= 4) { // This might be just BS, so it is considered really cheap.
+ while (n--) {
+ unibi_out(ui, unibi_cursor_left);
+ }
+ } else {
+ data->params[0].i = n;
+ unibi_out(ui, unibi_parm_left_cursor);
+ }
+ ugrid_goto(grid, row, col);
+ return;
+ } else if (col > grid->col) {
+ int n = col - grid->col;
+ if (n <= 2) {
+ while (n--) {
+ unibi_out(ui, unibi_cursor_right);
+ }
+ } else {
+ data->params[0].i = n;
+ unibi_out(ui, unibi_parm_right_cursor);
+ }
+ ugrid_goto(grid, row, col);
+ return;
+ }
+ }
+ if (col == grid->col) {
+ if (row > grid->row) {
+ int n = row - grid->row;
+ if (n <= 4) { // This might be just LF, so it is considered really cheap.
+ while (n--) {
+ unibi_out(ui, unibi_cursor_down);
+ }
+ } else {
+ data->params[0].i = n;
+ unibi_out(ui, unibi_parm_down_cursor);
+ }
+ ugrid_goto(grid, row, col);
+ return;
+ } else if (row < grid->row) {
+ int n = grid->row - row;
+ if (n <= 2) {
+ while (n--) {
+ unibi_out(ui, unibi_cursor_up);
+ }
+ } else {
+ data->params[0].i = n;
+ unibi_out(ui, unibi_parm_up_cursor);
+ }
+ ugrid_goto(grid, row, col);
+ return;
+ }
+ }
+ unibi_goto(ui, row, col);
+ ugrid_goto(grid, row, col);
}
static void clear_region(UI *ui, int top, int bot, int left, int right)
{
TUIData *data = ui->data;
UGrid *grid = &data->grid;
+ int saved_row = grid->row;
+ int saved_col = grid->col;
bool cleared = false;
if (grid->bg == -1 && right == ui->width -1) {
@@ -363,8 +627,9 @@ static void clear_region(UI *ui, int top, int bot, int left, int right)
if (bot == ui->height - 1) {
if (top == 0) {
unibi_out(ui, unibi_clear_screen);
+ ugrid_goto(&data->grid, top, left);
} else {
- unibi_goto(ui, top, 0);
+ cursor_goto(ui, top, 0);
unibi_out(ui, unibi_clr_eos);
}
cleared = true;
@@ -373,8 +638,8 @@ static void clear_region(UI *ui, int top, int bot, int left, int right)
if (!cleared) {
// iterate through each line and clear with clr_eol
- for (int row = top; row <= bot; ++row) {
- unibi_goto(ui, row, left);
+ for (int row = top; row <= bot; row++) {
+ cursor_goto(ui, row, left);
unibi_out(ui, unibi_clr_eol);
}
cleared = true;
@@ -383,29 +648,93 @@ static void clear_region(UI *ui, int top, int bot, int left, int right)
if (!cleared) {
// could not clear using faster terminal codes, refresh the whole region
- int currow = -1;
UGRID_FOREACH_CELL(grid, top, bot, left, right, {
- if (currow != row) {
- unibi_goto(ui, row, col);
- currow = row;
- }
+ cursor_goto(ui, row, col);
print_cell(ui, cell);
});
}
// restore cursor
+ cursor_goto(ui, saved_row, saved_col);
+}
+
+static bool can_use_scroll(UI * ui)
+{
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+
+ return data->scroll_region_is_full_screen
+ || (data->can_change_scroll_region
+ && ((grid->left == 0 && grid->right == ui->width - 1)
+ || data->can_set_lr_margin
+ || data->can_set_left_right_margin));
+}
+
+static void set_scroll_region(UI *ui)
+{
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+
+ data->params[0].i = grid->top;
+ data->params[1].i = grid->bot;
+ unibi_out(ui, unibi_change_scroll_region);
+ if (grid->left != 0 || grid->right != ui->width - 1) {
+ unibi_out_ext(ui, data->unibi_ext.enable_lr_margin);
+ if (data->can_set_lr_margin) {
+ data->params[0].i = grid->left;
+ data->params[1].i = grid->right;
+ unibi_out(ui, unibi_set_lr_margin);
+ } else {
+ data->params[0].i = grid->left;
+ unibi_out(ui, unibi_set_left_margin_parm);
+ data->params[0].i = grid->right;
+ unibi_out(ui, unibi_set_right_margin_parm);
+ }
+ }
unibi_goto(ui, grid->row, grid->col);
}
-static void tui_resize(UI *ui, int width, int height)
+static void reset_scroll_region(UI *ui)
{
TUIData *data = ui->data;
- ugrid_resize(&data->grid, width, height);
+ UGrid *grid = &data->grid;
+
+ if (0 <= data->unibi_ext.reset_scroll_region) {
+ unibi_out_ext(ui, data->unibi_ext.reset_scroll_region);
+ } else {
+ data->params[0].i = 0;
+ data->params[1].i = ui->height - 1;
+ unibi_out(ui, unibi_change_scroll_region);
+ }
+ if (grid->left != 0 || grid->right != ui->width - 1) {
+ if (data->can_set_lr_margin) {
+ data->params[0].i = 0;
+ data->params[1].i = ui->width - 1;
+ unibi_out(ui, unibi_set_lr_margin);
+ } else {
+ data->params[0].i = 0;
+ unibi_out(ui, unibi_set_left_margin_parm);
+ data->params[0].i = ui->width - 1;
+ unibi_out(ui, unibi_set_right_margin_parm);
+ }
+ unibi_out_ext(ui, data->unibi_ext.disable_lr_margin);
+ }
+ unibi_goto(ui, grid->row, grid->col);
+}
+
+static void tui_resize(UI *ui, Integer width, Integer height)
+{
+ TUIData *data = ui->data;
+ ugrid_resize(&data->grid, (int)width, (int)height);
if (!got_winch) { // Try to resize the terminal window.
- char r[16]; // enough for 9999x9999
- snprintf(r, sizeof(r), "\x1b[8;%d;%dt", height, width);
- out(ui, r, strlen(r));
+ data->params[0].i = (int)height;
+ data->params[1].i = (int)width;
+ unibi_out_ext(ui, data->unibi_ext.resize_screen);
+ // DECSLPP does not reset the scroll region.
+ if (data->scroll_region_is_full_screen) {
+ reset_scroll_region(ui);
+ }
} else { // Already handled the SIGWINCH signal; avoid double-resize.
got_winch = false;
}
@@ -427,11 +756,65 @@ static void tui_eol_clear(UI *ui)
clear_region(ui, grid->row, grid->row, grid->col, grid->right);
}
-static void tui_cursor_goto(UI *ui, int row, int col)
+static void tui_cursor_goto(UI *ui, Integer row, Integer col)
+{
+ cursor_goto(ui, (int)row, (int)col);
+}
+
+CursorShape tui_cursor_decode_shape(const char *shape_str)
{
+ CursorShape shape = 0;
+ if (strequal(shape_str, "block")) {
+ shape = SHAPE_BLOCK;
+ } else if (strequal(shape_str, "vertical")) {
+ shape = SHAPE_VER;
+ } else if (strequal(shape_str, "horizontal")) {
+ shape = SHAPE_HOR;
+ } else {
+ EMSG2(_(e_invarg2), shape_str);
+ }
+ return shape;
+}
+
+static cursorentry_T decode_cursor_entry(Dictionary args)
+{
+ cursorentry_T r;
+
+ for (size_t i = 0; i < args.size; i++) {
+ char *key = args.items[i].key.data;
+ Object value = args.items[i].value;
+
+ if (strequal(key, "cursor_shape")) {
+ r.shape = tui_cursor_decode_shape(args.items[i].value.data.string.data);
+ } else if (strequal(key, "blinkon")) {
+ r.blinkon = (int)value.data.integer;
+ } else if (strequal(key, "blinkoff")) {
+ r.blinkoff = (int)value.data.integer;
+ } else if (strequal(key, "hl_id")) {
+ r.id = (int)value.data.integer;
+ }
+ }
+ return r;
+}
+
+static void tui_mode_info_set(UI *ui, bool guicursor_enabled, Array args)
+{
+ cursor_style_enabled = guicursor_enabled;
+ if (!guicursor_enabled) {
+ return; // Do not send cursor style control codes.
+ }
TUIData *data = ui->data;
- ugrid_goto(&data->grid, row, col);
- unibi_goto(ui, row, col);
+
+ assert(args.size);
+
+ // cursor style entries as defined by `shape_table`.
+ for (size_t i = 0; i < args.size; i++) {
+ assert(args.items[i].type == kObjectTypeDictionary);
+ cursorentry_T r = decode_cursor_entry(args.items[i].data.dictionary);
+ data->cursor_shapes[i] = r;
+ }
+
+ tui_set_mode(ui, data->showing_mode);
}
static void tui_update_menu(UI *ui)
@@ -452,106 +835,119 @@ static void tui_busy_stop(UI *ui)
static void tui_mouse_on(UI *ui)
{
TUIData *data = ui->data;
- unibi_out(ui, data->unibi_ext.enable_mouse);
- data->mouse_enabled = true;
+ if (!data->mouse_enabled) {
+ unibi_out_ext(ui, data->unibi_ext.enable_mouse);
+ data->mouse_enabled = true;
+ }
}
static void tui_mouse_off(UI *ui)
{
TUIData *data = ui->data;
- unibi_out(ui, data->unibi_ext.disable_mouse);
- data->mouse_enabled = false;
+ if (data->mouse_enabled) {
+ unibi_out_ext(ui, data->unibi_ext.disable_mouse);
+ data->mouse_enabled = false;
+ }
}
-static void tui_mode_change(UI *ui, int mode)
+static void tui_set_mode(UI *ui, ModeShape mode)
{
+ if (!cursor_style_enabled) {
+ return;
+ }
TUIData *data = ui->data;
-
- if (mode == INSERT) {
- if (data->showing_mode != INSERT) {
- unibi_out(ui, data->unibi_ext.set_cursor_shape_bar);
- }
- } else if (mode == CMDLINE) {
- if (data->showing_mode != CMDLINE) {
- unibi_out(ui, data->unibi_ext.set_cursor_shape_bar);
- }
- } else if (mode == REPLACE) {
- if (data->showing_mode != REPLACE) {
- unibi_out(ui, data->unibi_ext.set_cursor_shape_ul);
- }
- } else {
- assert(mode == NORMAL);
- if (data->showing_mode != NORMAL) {
- unibi_out(ui, data->unibi_ext.set_cursor_shape_block);
+ cursorentry_T c = data->cursor_shapes[mode];
+ int shape = c.shape;
+
+ if (c.id != 0 && ui->rgb) {
+ int attr = syn_id2attr(c.id);
+ if (attr > 0) {
+ attrentry_T *aep = syn_cterm_attr2entry(attr);
+ data->params[0].i = aep->rgb_bg_color;
+ unibi_out_ext(ui, data->unibi_ext.set_cursor_color);
}
}
- data->showing_mode = mode;
+
+ switch (shape) {
+ case SHAPE_BLOCK: shape = 1; break;
+ case SHAPE_HOR: shape = 3; break;
+ case SHAPE_VER: shape = 5; break;
+ default: WLOG("Unknown shape value %d", shape); break;
+ }
+ data->params[0].i = shape + (int)(c.blinkon == 0);
+ unibi_out_ext(ui, data->unibi_ext.set_cursor_style);
+}
+
+/// @param mode editor mode
+static void tui_mode_change(UI *ui, String mode, Integer mode_idx)
+{
+ TUIData *data = ui->data;
+ tui_set_mode(ui, (ModeShape)mode_idx);
+ data->showing_mode = (ModeShape)mode_idx;
}
-static void tui_set_scroll_region(UI *ui, int top, int bot, int left,
- int right)
+static void tui_set_scroll_region(UI *ui, Integer top, Integer bot,
+ Integer left, Integer right)
{
TUIData *data = ui->data;
- ugrid_set_scroll_region(&data->grid, top, bot, left, right);
- data->can_use_terminal_scroll =
+ ugrid_set_scroll_region(&data->grid, (int)top, (int)bot,
+ (int)left, (int)right);
+ data->scroll_region_is_full_screen =
left == 0 && right == ui->width - 1
- && ((top == 0 && bot == ui->height - 1)
- || unibi_get_str(data->ut, unibi_change_scroll_region));
+ && top == 0 && bot == ui->height - 1;
}
-static void tui_scroll(UI *ui, int count)
+static void tui_scroll(UI *ui, Integer count)
{
TUIData *data = ui->data;
UGrid *grid = &data->grid;
int clear_top, clear_bot;
- ugrid_scroll(grid, count, &clear_top, &clear_bot);
+ ugrid_scroll(grid, (int)count, &clear_top, &clear_bot);
+
+ if (can_use_scroll(ui)) {
+ int saved_row = grid->row;
+ int saved_col = grid->col;
+ bool scroll_clears_to_current_colour =
+ unibi_get_bool(data->ut, unibi_back_color_erase);
- if (data->can_use_terminal_scroll) {
// Change terminal scroll region and move cursor to the top
- data->params[0].i = grid->top;
- data->params[1].i = grid->bot;
- unibi_out(ui, unibi_change_scroll_region);
- unibi_goto(ui, grid->top, grid->left);
+ if (!data->scroll_region_is_full_screen) {
+ set_scroll_region(ui);
+ }
+ cursor_goto(ui, grid->top, grid->left);
// also set default color attributes or some terminals can become funny
- HlAttrs clear_attrs = EMPTY_ATTRS;
- clear_attrs.foreground = grid->fg;
- clear_attrs.background = grid->bg;
- update_attrs(ui, clear_attrs);
- }
+ if (scroll_clears_to_current_colour) {
+ HlAttrs clear_attrs = EMPTY_ATTRS;
+ clear_attrs.foreground = grid->fg;
+ clear_attrs.background = grid->bg;
+ update_attrs(ui, clear_attrs);
+ }
- if (count > 0) {
- if (data->can_use_terminal_scroll) {
+ if (count > 0) {
if (count == 1) {
unibi_out(ui, unibi_delete_line);
} else {
- data->params[0].i = count;
+ data->params[0].i = (int)count;
unibi_out(ui, unibi_parm_delete_line);
}
- }
-
- } else {
- if (data->can_use_terminal_scroll) {
+ } else {
if (count == -1) {
unibi_out(ui, unibi_insert_line);
} else {
- data->params[0].i = -count;
+ data->params[0].i = -(int)count;
unibi_out(ui, unibi_parm_insert_line);
}
}
- }
- if (data->can_use_terminal_scroll) {
// Restore terminal scroll region and cursor
- data->params[0].i = 0;
- data->params[1].i = ui->height - 1;
- unibi_out(ui, unibi_change_scroll_region);
- unibi_goto(ui, grid->row, grid->col);
+ if (!data->scroll_region_is_full_screen) {
+ reset_scroll_region(ui);
+ }
+ cursor_goto(ui, saved_row, saved_col);
- if (grid->bg != -1) {
- // Update the cleared area of the terminal if its builtin scrolling
- // facility was used and the background color is not the default. This is
- // required because scrolling may leave wrong background in the cleared
- // area.
+ if (!scroll_clears_to_current_colour) {
+ // This is required because scrolling will leave wrong background in the
+ // cleared area on non-bge terminals.
clear_region(ui, clear_top, clear_bot, grid->left, grid->right);
}
} else {
@@ -565,10 +961,18 @@ static void tui_highlight_set(UI *ui, HlAttrs attrs)
((TUIData *)ui->data)->grid.attrs = attrs;
}
-static void tui_put(UI *ui, uint8_t *text, size_t size)
+static void tui_put(UI *ui, String text)
{
TUIData *data = ui->data;
- print_cell(ui, ugrid_put(&data->grid, text, size));
+ UGrid *grid = &data->grid;
+ UCell *cell;
+
+ cell = ugrid_put(&data->grid, (uint8_t *)text.data, text.size);
+ // ugrid_put does not advance the cursor correctly, as the actual terminal
+ // will when we print. Its cursor motion model is simplistic and wrong. So
+ // we have to undo what it has just done before doing it right.
+ grid->col--;
+ print_cell(ui, cell);
}
static void tui_bell(UI *ui)
@@ -581,17 +985,17 @@ static void tui_visual_bell(UI *ui)
unibi_out(ui, unibi_flash_screen);
}
-static void tui_update_fg(UI *ui, int fg)
+static void tui_update_fg(UI *ui, Integer fg)
{
- ((TUIData *)ui->data)->grid.fg = fg;
+ ((TUIData *)ui->data)->grid.fg = (int)fg;
}
-static void tui_update_bg(UI *ui, int bg)
+static void tui_update_bg(UI *ui, Integer bg)
{
- ((TUIData *)ui->data)->grid.bg = bg;
+ ((TUIData *)ui->data)->grid.bg = (int)bg;
}
-static void tui_update_sp(UI *ui, int sp)
+static void tui_update_sp(UI *ui, Integer sp)
{
// Do nothing; 'special' color is for GUI only
}
@@ -603,7 +1007,7 @@ static void tui_flush(UI *ui)
size_t nrevents = loop_size(data->loop);
if (nrevents > TOO_MANY_EVENTS) {
- ILOG("TUI event-queue flooded (thread_events=%zu); purging", nrevents);
+ WLOG("TUI event-queue flooded (thread_events=%zu); purging", nrevents);
// Back-pressure: UI events may accumulate much faster than the terminal
// device can serve them. Even if SIGINT/CTRL-C is received, user must still
// wait for the TUI event-queue to drain, and if there are ~millions of
@@ -613,23 +1017,23 @@ static void tui_flush(UI *ui)
tui_busy_stop(ui); // avoid hidden cursor
}
+ int saved_row = grid->row;
+ int saved_col = grid->col;
+
while (kv_size(data->invalid_regions)) {
Rect r = kv_pop(data->invalid_regions);
- int currow = -1;
UGRID_FOREACH_CELL(grid, r.top, r.bot, r.left, r.right, {
- if (currow != row) {
- unibi_goto(ui, row, col);
- currow = row;
- }
+ cursor_goto(ui, row, col);
print_cell(ui, cell);
});
}
- unibi_goto(ui, grid->row, grid->col);
+ cursor_goto(ui, saved_row, saved_col);
flush_buf(ui, true);
}
+#ifdef UNIX
static void suspend_event(void **argv)
{
UI *ui = argv[0];
@@ -651,30 +1055,33 @@ static void suspend_event(void **argv)
// resume the main thread
CONTINUE(data->bridge);
}
+#endif
static void tui_suspend(UI *ui)
{
+#ifdef UNIX
TUIData *data = ui->data;
// kill(0, SIGTSTP) won't stop the UI thread, so we must poll for SIGCONT
// before continuing. This is done in another callback to avoid
// loop_poll_events recursion
multiqueue_put_event(data->loop->fast_events,
- event_create(1, suspend_event, 1, ui));
+ event_create(suspend_event, 1, ui));
+#endif
}
-static void tui_set_title(UI *ui, char *title)
+static void tui_set_title(UI *ui, String title)
{
TUIData *data = ui->data;
- if (!(title && unibi_get_str(data->ut, unibi_to_status_line)
+ if (!(title.data && unibi_get_str(data->ut, unibi_to_status_line)
&& unibi_get_str(data->ut, unibi_from_status_line))) {
return;
}
unibi_out(ui, unibi_to_status_line);
- out(ui, title, strlen(title));
+ out(ui, title.data, title.size);
unibi_out(ui, unibi_from_status_line);
}
-static void tui_set_icon(UI *ui, char *icon)
+static void tui_set_icon(UI *ui, String icon)
{
}
@@ -775,31 +1182,33 @@ static void unibi_goto(UI *ui, int row, int col)
unibi_out(ui, unibi_cursor_address);
}
+#define UNIBI_OUT(fn) \
+ do { \
+ TUIData *data = ui->data; \
+ const char *str = NULL; \
+ if (unibi_index >= 0) { \
+ str = fn(data->ut, (unsigned)unibi_index); \
+ } \
+ if (str) { \
+ unibi_var_t vars[26 + 26] = { { 0 } }; \
+ unibi_format(vars, vars + 26, str, data->params, out, ui, NULL, NULL); \
+ } \
+ } while (0)
static void unibi_out(UI *ui, int unibi_index)
{
- TUIData *data = ui->data;
-
- const char *str = NULL;
-
- if (unibi_index >= 0) {
- if (unibi_index < unibi_string_begin_) {
- str = unibi_get_ext_str(data->ut, (unsigned)unibi_index);
- } else {
- str = unibi_get_str(data->ut, (unsigned)unibi_index);
- }
- }
-
- if (str) {
- unibi_var_t vars[26 + 26] = {{0}};
- unibi_format(vars, vars + 26, str, data->params, out, ui, NULL, NULL);
- }
+ UNIBI_OUT(unibi_get_str);
+}
+static void unibi_out_ext(UI *ui, int unibi_index)
+{
+ UNIBI_OUT(unibi_get_ext_str);
}
+#undef UNIBI_OUT
static void out(void *ctx, const char *str, size_t len)
{
UI *ui = ctx;
TUIData *data = ui->data;
- size_t available = data->bufsize - data->bufpos;
+ size_t available = sizeof(data->buf) - data->bufpos;
if (len > available) {
flush_buf(ui, false);
@@ -817,152 +1226,453 @@ static void unibi_set_if_empty(unibi_term *ut, enum unibi_string str,
}
}
-static void fix_terminfo(TUIData *data)
+static int unibi_find_ext_str(unibi_term *ut, const char *name)
{
- unibi_term *ut = data->ut;
+ size_t max = unibi_count_ext_str(ut);
+ for (size_t i = 0; i < max; i++) {
+ const char * n = unibi_get_ext_str_name(ut, i);
+ if (n && 0 == strcmp(n, name)) {
+ return (int)i;
+ }
+ }
+ return -1;
+}
- const char *term = os_getenv("TERM");
- const char *colorterm = os_getenv("COLORTERM");
- if (!term) {
- goto end;
+/// Several entries in terminfo are known to be deficient or outright wrong,
+/// unfortunately; and several terminal emulators falsely announce incorrect
+/// terminal types. So patch the terminfo records after loading from an
+/// external or a built-in database. In an ideal world, the real terminfo data
+/// would be correct and complete, and this function would be almost empty.
+static void patch_terminfo_bugs(TUIData *data, const char *term,
+ const char *colorterm, long vte_version,
+ bool konsole, bool iterm_env)
+{
+ unibi_term *ut = data->ut;
+ const char * xterm_version = os_getenv("XTERM_VERSION");
+#if 0 // We don't need to identify this specifically, for now.
+ bool roxterm = !!os_getenv("ROXTERM_ID");
+#endif
+ bool xterm = terminfo_is_term_family(term, "xterm");
+ bool linuxvt = terminfo_is_term_family(term, "linux");
+ bool rxvt = terminfo_is_term_family(term, "rxvt");
+ bool teraterm = terminfo_is_term_family(term, "teraterm");
+ bool putty = terminfo_is_term_family(term, "putty");
+ bool screen = terminfo_is_term_family(term, "screen");
+ bool tmux = terminfo_is_term_family(term, "tmux") || !!os_getenv("TMUX");
+ bool st = terminfo_is_term_family(term, "st");
+ bool gnome = terminfo_is_term_family(term, "gnome")
+ || terminfo_is_term_family(term, "vte");
+ bool iterm = terminfo_is_term_family(term, "iterm")
+ || terminfo_is_term_family(term, "iterm2")
+ || terminfo_is_term_family(term, "iTerm.app")
+ || terminfo_is_term_family(term, "iTerm2.app");
+ // None of the following work over SSH; see :help TERM .
+ bool iterm_pretending_xterm = xterm && iterm_env;
+ bool konsole_pretending_xterm = xterm && konsole;
+ bool gnome_pretending_xterm = xterm && colorterm
+ && strstr(colorterm, "gnome-terminal");
+ bool mate_pretending_xterm = xterm && colorterm
+ && strstr(colorterm, "mate-terminal");
+ bool true_xterm = xterm && !!xterm_version;
+
+ char *fix_normal = (char *)unibi_get_str(ut, unibi_cursor_normal);
+ if (fix_normal) {
+ if (STARTS_WITH(fix_normal, "\x1b[?12l")) {
+ // terminfo typically includes DECRST 12 as part of setting up the
+ // normal cursor, which interferes with the user's control via
+ // set_cursor_style. When DECRST 12 is present, skip over it, but honor
+ // the rest of the cnorm setting.
+ fix_normal += sizeof "\x1b[?12l" - 1;
+ unibi_set_str(ut, unibi_cursor_normal, fix_normal);
+ }
+ if (linuxvt
+ && strlen(fix_normal) >= (sizeof LINUXSET0C - 1)
+ && !memcmp(strchr(fix_normal, 0) - (sizeof LINUXSET0C - 1),
+ LINUXSET0C, sizeof LINUXSET0C - 1)) {
+ // The Linux terminfo entry similarly includes a Linux-idiosyncractic
+ // cursor shape reset in cnorm, which similarly interferes with
+ // set_cursor_style.
+ fix_normal[strlen(fix_normal) - (sizeof LINUXSET0C - 1)] = 0;
+ }
+ }
+ char *fix_invisible = (char *)unibi_get_str(ut, unibi_cursor_invisible);
+ if (fix_invisible) {
+ if (linuxvt
+ && strlen(fix_invisible) >= (sizeof LINUXSET1C - 1)
+ && !memcmp(strchr(fix_invisible, 0) - (sizeof LINUXSET1C - 1),
+ LINUXSET1C, sizeof LINUXSET1C - 1)) {
+ // The Linux terminfo entry similarly includes a Linux-idiosyncractic
+ // cursor shape reset in cinvis, which similarly interferes with
+ // set_cursor_style.
+ fix_invisible[strlen(fix_invisible) - (sizeof LINUXSET1C - 1)] = 0;
+ }
}
- bool inside_tmux = os_getenv("TMUX") != NULL;
+ if (xterm) {
+ // Termit, LXTerminal, GTKTerm2, GNOME Terminal, MATE Terminal, roxterm,
+ // and EvilVTE falsely claim to be xterm and do not support important xterm
+ // control sequences that we use. In an ideal world, these would have
+ // their own terminal types and terminfo entries, like PuTTY does, and not
+ // claim to be xterm. Or they would mimic xterm properly enough to be
+ // treatable as xterm.
-#define STARTS_WITH(str, prefix) (!memcmp(str, prefix, sizeof(prefix) - 1))
+ // 2017-04 terminfo.src lacks these. genuine Xterm has them, as have
+ // the false claimants.
+ unibi_set_if_empty(ut, unibi_to_status_line, "\x1b]0;");
+ unibi_set_if_empty(ut, unibi_from_status_line, "\x07");
+ unibi_set_if_empty(ut, unibi_set_tb_margin, "\x1b[%i%p1%d;%p2%dr");
- if (STARTS_WITH(term, "rxvt")) {
- unibi_set_if_empty(ut, unibi_exit_attribute_mode, "\x1b[m\x1b(B");
- unibi_set_if_empty(ut, unibi_flash_screen, "\x1b[?5h$<20/>\x1b[?5l");
+ if (true_xterm) {
+ // 2017-04 terminfo.src lacks these. genuine Xterm has them.
+ unibi_set_if_empty(ut, unibi_set_lr_margin, "\x1b[%i%p1%d;%p2%ds");
+ unibi_set_if_empty(ut, unibi_set_left_margin_parm, "\x1b[%i%p1%ds");
+ unibi_set_if_empty(ut, unibi_set_right_margin_parm, "\x1b[%i;%p2%ds");
+ }
+ if (true_xterm
+ || iterm_pretending_xterm
+ || gnome_pretending_xterm
+ || konsole_pretending_xterm) {
+ // Apple's outdated copy of terminfo.src for MacOS lacks these.
+ // genuine Xterm and three false claimants have them.
+ unibi_set_if_empty(ut, unibi_enter_italics_mode, "\x1b[3m");
+ unibi_set_if_empty(ut, unibi_exit_italics_mode, "\x1b[23m");
+ }
+ } else if (rxvt) {
+ // 2017-04 terminfo.src lacks these. Unicode rxvt has them.
unibi_set_if_empty(ut, unibi_enter_italics_mode, "\x1b[3m");
+ unibi_set_if_empty(ut, unibi_exit_italics_mode, "\x1b[23m");
unibi_set_if_empty(ut, unibi_to_status_line, "\x1b]2");
- } else if (STARTS_WITH(term, "xterm")) {
- unibi_set_if_empty(ut, unibi_to_status_line, "\x1b]0;");
- } else if (STARTS_WITH(term, "screen") || STARTS_WITH(term, "tmux")) {
+ unibi_set_if_empty(ut, unibi_from_status_line, "\x07");
+ // 2017-04 terminfo.src has older control sequences.
+ unibi_set_str(ut, unibi_enter_ca_mode, "\x1b[?1049h");
+ unibi_set_str(ut, unibi_exit_ca_mode, "\x1b[?1049l");
+ } else if (screen) {
+ // per the screen manual; 2017-04 terminfo.src lacks these.
unibi_set_if_empty(ut, unibi_to_status_line, "\x1b_");
unibi_set_if_empty(ut, unibi_from_status_line, "\x1b\\");
+ } else if (tmux) {
+ unibi_set_if_empty(ut, unibi_to_status_line, "\x1b_");
+ unibi_set_if_empty(ut, unibi_from_status_line, "\x1b\\");
+ } else if (terminfo_is_term_family(term, "interix")) {
+ // 2017-04 terminfo.src lacks this.
+ unibi_set_if_empty(ut, unibi_carriage_return, "\x0d");
+ } else if (linuxvt) {
+ // Apple's outdated copy of terminfo.src for MacOS lacks these.
+ unibi_set_if_empty(ut, unibi_parm_up_cursor, "\x1b[%p1%dA");
+ unibi_set_if_empty(ut, unibi_parm_down_cursor, "\x1b[%p1%dB");
+ unibi_set_if_empty(ut, unibi_parm_right_cursor, "\x1b[%p1%dC");
+ unibi_set_if_empty(ut, unibi_parm_left_cursor, "\x1b[%p1%dD");
+ } else if (putty) {
+ // No bugs in the vanilla terminfo for our purposes.
+ } else if (iterm) {
+ // 2017-04 terminfo.src has older control sequences.
+ unibi_set_str(ut, unibi_enter_ca_mode, "\x1b[?1049h");
+ unibi_set_str(ut, unibi_exit_ca_mode, "\x1b[?1049l");
+ // 2017-04 terminfo.src lacks these.
+ unibi_set_if_empty(ut, unibi_set_tb_margin, "\x1b[%i%p1%d;%p2%dr");
+ unibi_set_if_empty(ut, unibi_orig_pair, "\x1b[39;49m");
+ unibi_set_if_empty(ut, unibi_enter_dim_mode, "\x1b[2m");
+ unibi_set_if_empty(ut, unibi_enter_italics_mode, "\x1b[3m");
+ unibi_set_if_empty(ut, unibi_exit_italics_mode, "\x1b[23m");
+ unibi_set_if_empty(ut, unibi_exit_underline_mode, "\x1b[24m");
+ unibi_set_if_empty(ut, unibi_exit_standout_mode, "\x1b[27m");
+ } else if (st) {
+ // No bugs in the vanilla terminfo for our purposes.
}
- if (STARTS_WITH(term, "xterm") || STARTS_WITH(term, "rxvt")) {
- unibi_set_if_empty(ut, unibi_cursor_normal, "\x1b[?12l\x1b[?25h");
- unibi_set_if_empty(ut, unibi_cursor_invisible, "\x1b[?25l");
- unibi_set_if_empty(ut, unibi_flash_screen, "\x1b[?5h$<100/>\x1b[?5l");
- unibi_set_if_empty(ut, unibi_exit_attribute_mode, "\x1b(B\x1b[m");
- unibi_set_if_empty(ut, unibi_change_scroll_region, "\x1b[%i%p1%d;%p2%dr");
- unibi_set_if_empty(ut, unibi_clear_screen, "\x1b[H\x1b[2J");
- unibi_set_if_empty(ut, unibi_from_status_line, "\x07");
- }
-
- data->unibi_ext.enable_bracketed_paste = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[?2004h");
- data->unibi_ext.disable_bracketed_paste = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[?2004l");
+// At this time (2017-07-12) it seems like all terminals that support 256
+// color codes can use semicolons in the terminal code and be fine.
+// However, this is not correct according to the spec. So to reward those
+// terminals that also support colons, we output the code that way on these
+// specific ones.
- data->unibi_ext.enable_focus_reporting = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[?1004h");
- data->unibi_ext.disable_focus_reporting = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[?1004l");
+// using colons like ISO 8613-6:1994/ITU T.416:1993 says.
+#define XTERM_SETAF_256_COLON \
+ "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38:5:%p1%d%;m"
+#define XTERM_SETAB_256_COLON \
+ "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48:5:%p1%d%;m"
-#define XTERM_SETAF \
+#define XTERM_SETAF_256 \
"\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m"
-#define XTERM_SETAB \
+#define XTERM_SETAB_256 \
"\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m"
+#define XTERM_SETAF_16 \
+ "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e39%;m"
+#define XTERM_SETAB_16 \
+ "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e39%;m"
+
+ // Terminals where there is actually 256-colour SGR support despite what
+ // the terminfo record may say.
+ if (unibi_get_num(ut, unibi_max_colors) < 256) {
+ // See http://fedoraproject.org/wiki/Features/256_Color_Terminals for
+ // more on this.
+ if (true_xterm || iterm || iterm_pretending_xterm) {
+ unibi_set_num(ut, unibi_max_colors, 256);
+ unibi_set_str(ut, unibi_set_a_foreground, XTERM_SETAF_256_COLON);
+ unibi_set_str(ut, unibi_set_a_background, XTERM_SETAB_256_COLON);
+ } else if (konsole || xterm || gnome || rxvt || st || putty
+ || linuxvt // Linux 4.8+ supports 256-colour SGR.
+ || mate_pretending_xterm || gnome_pretending_xterm
+ || tmux
+ || (colorterm && strstr(colorterm, "256"))
+ || (term && strstr(term, "256"))) {
+ unibi_set_num(ut, unibi_max_colors, 256);
+ unibi_set_str(ut, unibi_set_a_foreground, XTERM_SETAF_256);
+ unibi_set_str(ut, unibi_set_a_background, XTERM_SETAB_256);
+ }
+ }
+ // Terminals where there is actually 16-colour SGR support despite what
+ // the terminfo record may say.
+ if (unibi_get_num(ut, unibi_max_colors) < 16) {
+ if (colorterm) {
+ unibi_set_num(ut, unibi_max_colors, 16);
+ unibi_set_if_empty(ut, unibi_set_a_foreground, XTERM_SETAF_16);
+ unibi_set_if_empty(ut, unibi_set_a_background, XTERM_SETAB_16);
+ }
+ }
- if ((colorterm && strstr(colorterm, "256"))
- || strstr(term, "256")
- || strstr(term, "xterm")) {
- // Assume TERM~=xterm or COLORTERM~=256 supports 256 colors.
- unibi_set_num(ut, unibi_max_colors, 256);
- unibi_set_str(ut, unibi_set_a_foreground, XTERM_SETAF);
- unibi_set_str(ut, unibi_set_a_background, XTERM_SETAB);
+ // Some terminals can not currently be trusted to report if they support
+ // DECSCUSR or not. So we need to have a blacklist for when we should not
+ // trust the reported features.
+ if (!((vte_version != 0 && vte_version < 3900) || konsole)) {
+ // Dickey ncurses terminfo has included the Ss and Se capabilities,
+ // pioneered by tmux, since 2011-07-14. So adding them to terminal types,
+ // that do actually have such control sequences but lack the correct
+ // definitions in terminfo, is a fixup, not an augmentation.
+ data->unibi_ext.reset_cursor_style = unibi_find_ext_str(ut, "Se");
+ data->unibi_ext.set_cursor_style = unibi_find_ext_str(ut, "Ss");
}
+ if (-1 == data->unibi_ext.set_cursor_style) {
+ // The DECSCUSR sequence to change the cursor shape is widely
+ // supported by several terminal types and should be in many
+ // teminfo entries. See
+ // https://github.com/gnachman/iTerm2/pull/92 for more.
+ // xterm even has an extended version that has a vertical bar.
+ if (!konsole && (true_xterm // per xterm ctlseqs doco (since version 282)
+ // per MinTTY 0.4.3-1 release notes from 2009
+ || putty
+ // per https://bugzilla.gnome.org/show_bug.cgi?id=720821
+ || (vte_version >= 3900)
+ || tmux // per tmux manual page
+ // https://lists.gnu.org/archive/html/screen-devel/2013-03/msg00000.html
+ || screen
+ || rxvt // per command.C
+ // per analysis of VT100Terminal.m
+ || iterm || iterm_pretending_xterm
+ || teraterm // per TeraTerm "Supported Control Functions" doco
+ // Allows forcing the use of DECSCUSR on linux type terminals, such as
+ // console-terminal-emulator from the nosh toolset, which does indeed
+ // implement the xterm extension:
+ || (linuxvt && (xterm_version || (vte_version > 0) || colorterm)))) {
+ data->unibi_ext.set_cursor_style =
+ (int)unibi_add_ext_str(ut, "Ss", "\x1b[%p1%d q");
+ if (-1 == data->unibi_ext.reset_cursor_style) {
+ data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
+ "");
+ }
+ unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style,
+ "\x1b[ q");
+ } else if (linuxvt) {
+ // Linux uses an idiosyncratic escape code to set the cursor shape and
+ // does not support DECSCUSR.
+ // See http://linuxgazette.net/137/anonymous.html for more info
+ data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss",
+ "\x1b[?"
+ "%?"
+ // The parameter passed to Ss is the DECSCUSR parameter, so the
+ // terminal capability has to translate into the Linux idiosyncratic
+ // parameter.
+ //
+ // linuxvt only supports block and underline. It is also only
+ // possible to have a steady block (no steady underline)
+ "%p1%{2}%<" "%t%{8}" // blink block
+ "%e%p1%{2}%=" "%t%{112}" // steady block
+ "%e%p1%{3}%=" "%t%{4}" // blink underline (set to half block)
+ "%e%p1%{4}%=" "%t%{4}" // steady underline
+ "%e%p1%{5}%=" "%t%{2}" // blink bar (set to underline)
+ "%e%p1%{6}%=" "%t%{2}" // steady bar
+ "%e%{0}" // anything else
+ "%;" "%dc");
+ if (-1 == data->unibi_ext.reset_cursor_style) {
+ data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
+ "");
+ }
+ unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style,
+ "\x1b[?c");
+ } else if (konsole) {
+ // Konsole uses an idiosyncratic escape code to set the cursor shape and
+ // does not support DECSCUSR. This makes Konsole set up and apply a
+ // nonce profile, which has side-effects on temporary font resizing.
+ // In an ideal world, Konsole would just support DECSCUSR.
+ data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss",
+ TMUX_WRAP(tmux, "\x1b]50;CursorShape=%?"
+ "%p1%{3}%<" "%t%{0}" // block
+ "%e%p1%{5}%<" "%t%{2}" // underline
+ "%e%{1}" // everything else is bar
+ "%;%d;BlinkingCursorEnabled=%?"
+ "%p1%{1}%<" "%t%{1}" // Fortunately if we exclude zero as special,
+ "%e%p1%{1}%&" // in all other cases we can treat bit #0 as a flag.
+ "%;%d\x07"));
+ if (-1 == data->unibi_ext.reset_cursor_style) {
+ data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
+ "");
+ }
+ unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style,
+ "\x1b]50;\x07");
+ }
+ }
+}
- if (os_getenv("NVIM_TUI_ENABLE_CURSOR_SHAPE") == NULL) {
- goto end;
+/// This adds stuff that is not in standard terminfo as extended unibilium
+/// capabilities.
+static void augment_terminfo(TUIData *data, const char *term,
+ const char *colorterm, long vte_version, bool konsole, bool iterm_env)
+{
+ unibi_term *ut = data->ut;
+ bool xterm = terminfo_is_term_family(term, "xterm");
+ bool dtterm = terminfo_is_term_family(term, "dtterm");
+ bool rxvt = terminfo_is_term_family(term, "rxvt");
+ bool teraterm = terminfo_is_term_family(term, "teraterm");
+ bool putty = terminfo_is_term_family(term, "putty");
+ bool screen = terminfo_is_term_family(term, "screen");
+ bool tmux = terminfo_is_term_family(term, "tmux") || !!os_getenv("TMUX");
+ bool iterm = terminfo_is_term_family(term, "iterm")
+ || terminfo_is_term_family(term, "iterm2")
+ || terminfo_is_term_family(term, "iTerm.app")
+ || terminfo_is_term_family(term, "iTerm2.app");
+ // None of the following work over SSH; see :help TERM .
+ bool iterm_pretending_xterm = xterm && iterm_env;
+
+ const char * xterm_version = os_getenv("XTERM_VERSION");
+ bool true_xterm = xterm && !!xterm_version;
+
+ // Only define this capability for terminal types that we know understand it.
+ if (dtterm // originated this extension
+ || xterm // per xterm ctlseqs doco
+ || konsole // per commentary in VT102Emulation.cpp
+ || teraterm // per TeraTerm "Supported Control Functions" doco
+ || rxvt) { // per command.C
+ data->unibi_ext.resize_screen = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[8;%p1%d;%p2%dt");
+ }
+ if (putty || xterm || rxvt) {
+ data->unibi_ext.reset_scroll_region = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[r");
+ }
+
+ // Dickey ncurses terminfo does not include the setrgbf and setrgbb
+ // capabilities, proposed by Rüdiger Sonderfeld on 2013-10-15. So adding
+ // them to terminal types, that do actually have such control sequences but
+ // lack the correct definitions in terminfo, is an augmentation, not a
+ // fixup. See https://gist.github.com/XVilka/8346728 for more about this.
+
+ // At this time (2017-07-12) it seems like all terminals that support rgb
+ // color codes can use semicolons in the terminal code and be fine.
+ // However, this is not correct according to the spec. So to reward those
+ // terminals that also support colons, we output the code that way on these
+ // specific ones.
+
+ // can use colons like ISO 8613-6:1994/ITU T.416:1993 says.
+ bool has_colon_rgb = !tmux && !screen
+ && ((vte_version >= 3600) // per GNOME bug #685759, #704449
+ || iterm || iterm_pretending_xterm // per analysis of VT100Terminal.m
+ // per http://invisible-island.net/xterm/xterm.log.html#xterm_282
+ || true_xterm);
+
+ data->unibi_ext.set_rgb_foreground = unibi_find_ext_str(ut, "setrgbf");
+ if (-1 == data->unibi_ext.set_rgb_foreground) {
+ if (has_colon_rgb) {
+ data->unibi_ext.set_rgb_foreground = (int)unibi_add_ext_str(ut, "setrgbf",
+ "\x1b[38:2:%p1%d:%p2%d:%p3%dm");
+ } else {
+ data->unibi_ext.set_rgb_foreground = (int)unibi_add_ext_str(ut, "setrgbf",
+ "\x1b[38;2;%p1%d;%p2%d;%p3%dm");
+ }
+ }
+ data->unibi_ext.set_rgb_background = unibi_find_ext_str(ut, "setrgbb");
+ if (-1 == data->unibi_ext.set_rgb_background) {
+ if (has_colon_rgb) {
+ data->unibi_ext.set_rgb_background = (int)unibi_add_ext_str(ut, "setrgbb",
+ "\x1b[48:2:%p1%d:%p2%d:%p3%dm");
+ } else {
+ data->unibi_ext.set_rgb_background = (int)unibi_add_ext_str(ut, "setrgbb",
+ "\x1b[48;2;%p1%d;%p2%d;%p3%dm");
+ }
}
-#define TMUX_WRAP(seq) (inside_tmux ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq)
- // Support changing cursor shape on some popular terminals.
- const char *term_prog = os_getenv("TERM_PROGRAM");
- const char *vte_version = os_getenv("VTE_VERSION");
-
- if ((term_prog && !strcmp(term_prog, "Konsole"))
- || os_getenv("KONSOLE_DBUS_SESSION") != NULL) {
- // Konsole uses a proprietary escape code to set the cursor shape
- // and does not support DECSCUSR.
- data->unibi_ext.set_cursor_shape_bar = (int)unibi_add_ext_str(ut, NULL,
- TMUX_WRAP("\x1b]50;CursorShape=1;BlinkingCursorEnabled=1\x07"));
- data->unibi_ext.set_cursor_shape_ul = (int)unibi_add_ext_str(ut, NULL,
- TMUX_WRAP("\x1b]50;CursorShape=2;BlinkingCursorEnabled=1\x07"));
- data->unibi_ext.set_cursor_shape_block = (int)unibi_add_ext_str(ut, NULL,
- TMUX_WRAP("\x1b]50;CursorShape=0;BlinkingCursorEnabled=0\x07"));
- } else if (!vte_version || atoi(vte_version) >= 3900) {
- // Assume that the terminal supports DECSCUSR unless it is an
- // old VTE based terminal. This should not get wrapped for tmux,
- // which will handle it via its Ss/Se terminfo extension - usually
- // according to its terminal-overrides.
- data->unibi_ext.set_cursor_shape_bar =
- (int)unibi_add_ext_str(ut, NULL, "\x1b[5 q");
- data->unibi_ext.set_cursor_shape_ul =
- (int)unibi_add_ext_str(ut, NULL, "\x1b[3 q");
- data->unibi_ext.set_cursor_shape_block =
- (int)unibi_add_ext_str(ut, NULL, "\x1b[2 q");
+ if (iterm || iterm_pretending_xterm) {
+ // FIXME: Bypassing tmux like this affects the cursor colour globally, in
+ // all panes, which is not particularly desirable. A better approach
+ // would use a tmux control sequence and an extra if(screen) test.
+ data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(
+ ut, NULL, TMUX_WRAP(tmux, "\033]Pl%p1%06x\033\\"));
+ } else if (xterm || (vte_version != 0) || rxvt) {
+ // This seems to be supported for a long time in VTE
+ // urxvt also supports this
+ data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(
+ ut, NULL, "\033]12;#%p1%06x\007");
}
-end:
- // Fill some empty slots with common terminal strings
+ /// Terminals generally ignore private modes that they do not recognize,
+ /// and there is no known ambiguity with these modes from terminal type to
+ /// terminal type, so we can afford to just set these unconditionally.
+ data->unibi_ext.enable_lr_margin = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[?69h");
+ data->unibi_ext.disable_lr_margin = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[?69l");
+ data->unibi_ext.enable_bracketed_paste = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[?2004h");
+ data->unibi_ext.disable_bracketed_paste = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[?2004l");
+ data->unibi_ext.enable_focus_reporting = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[?1004h");
+ data->unibi_ext.disable_focus_reporting = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[?1004l");
data->unibi_ext.enable_mouse = (int)unibi_add_ext_str(ut, NULL,
"\x1b[?1002h\x1b[?1006h");
data->unibi_ext.disable_mouse = (int)unibi_add_ext_str(ut, NULL,
"\x1b[?1002l\x1b[?1006l");
- data->unibi_ext.set_rgb_foreground = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[38;2;%p1%d;%p2%d;%p3%dm");
- data->unibi_ext.set_rgb_background = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[48;2;%p1%d;%p2%d;%p3%dm");
- unibi_set_if_empty(ut, unibi_cursor_address, "\x1b[%i%p1%d;%p2%dH");
- unibi_set_if_empty(ut, unibi_exit_attribute_mode, "\x1b[0;10m");
- unibi_set_if_empty(ut, unibi_set_a_foreground, XTERM_SETAF);
- unibi_set_if_empty(ut, unibi_set_a_background, XTERM_SETAB);
- unibi_set_if_empty(ut, unibi_enter_bold_mode, "\x1b[1m");
- unibi_set_if_empty(ut, unibi_enter_underline_mode, "\x1b[4m");
- unibi_set_if_empty(ut, unibi_enter_reverse_mode, "\x1b[7m");
- unibi_set_if_empty(ut, unibi_bell, "\x07");
- unibi_set_if_empty(data->ut, unibi_enter_ca_mode, "\x1b[?1049h");
- unibi_set_if_empty(data->ut, unibi_exit_ca_mode, "\x1b[?1049l");
- unibi_set_if_empty(ut, unibi_delete_line, "\x1b[M");
- unibi_set_if_empty(ut, unibi_parm_delete_line, "\x1b[%p1%dM");
- unibi_set_if_empty(ut, unibi_insert_line, "\x1b[L");
- unibi_set_if_empty(ut, unibi_parm_insert_line, "\x1b[%p1%dL");
- unibi_set_if_empty(ut, unibi_clear_screen, "\x1b[H\x1b[J");
- unibi_set_if_empty(ut, unibi_clr_eol, "\x1b[K");
- unibi_set_if_empty(ut, unibi_clr_eos, "\x1b[J");
}
static void flush_buf(UI *ui, bool toggle_cursor)
{
uv_write_t req;
- uv_buf_t buf;
+ uv_buf_t bufs[3];
+ uv_buf_t *bufp = bufs;
TUIData *data = ui->data;
- if (toggle_cursor && !data->busy) {
- // not busy and the cursor is invisible(see below). Append a "cursor
- // normal" command to the end of the buffer.
- data->bufsize += CNORM_COMMAND_MAX_SIZE;
- unibi_out(ui, unibi_cursor_normal);
- data->bufsize -= CNORM_COMMAND_MAX_SIZE;
+ if (data->bufpos <= 0 && data->busy == data->is_invisible) {
+ return;
+ }
+
+ if (toggle_cursor && !data->is_invisible) {
+ // cursor is visible. Write a "cursor invisible" command before writing the
+ // buffer.
+ bufp->base = data->invis;
+ bufp->len = data->invislen;
+ bufp++;
+ data->is_invisible = true;
}
- buf.base = data->buf;
- buf.len = data->bufpos;
- uv_write(&req, (uv_stream_t *)&data->output_handle, &buf, 1, NULL);
- uv_run(&data->write_loop, UV_RUN_DEFAULT);
- data->bufpos = 0;
+ if (data->bufpos > 0) {
+ bufp->base = data->buf;
+ bufp->len = data->bufpos;
+ bufp++;
+ }
- if (toggle_cursor && !data->busy) {
- // not busy and cursor is visible(see above), append a "cursor invisible"
- // command to the beginning of the buffer for the next flush
- unibi_out(ui, unibi_cursor_invisible);
+ if (toggle_cursor && !data->busy && data->is_invisible) {
+ // not busy and the cursor is invisible. Write a "cursor normal" command
+ // after writing the buffer.
+ bufp->base = data->norm;
+ bufp->len = data->normlen;
+ bufp++;
+ data->is_invisible = data->busy;
}
+
+ uv_write(&req, STRUCT_CAST(uv_stream_t, &data->output_handle),
+ bufs, (unsigned)(bufp - bufs), NULL);
+ uv_run(&data->write_loop, UV_RUN_DEFAULT);
+ data->bufpos = 0;
}
#if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18
@@ -979,7 +1689,7 @@ static const char *tui_get_stty_erase(void)
if (tcgetattr(input_global_fd(), &t) != -1) {
stty_erase[0] = (char)t.c_cc[VERASE];
stty_erase[1] = '\0';
- ILOG("stty/termios:erase=%s", stty_erase);
+ DLOG("stty/termios:erase=%s", stty_erase);
}
#endif
return stty_erase;
@@ -995,16 +1705,16 @@ static const char *tui_tk_ti_getstr(const char *name, const char *value,
stty_erase = tui_get_stty_erase();
}
- if (strcmp(name, "key_backspace") == 0) {
- ILOG("libtermkey:kbs=%s", value);
- if (stty_erase != NULL && stty_erase[0] != 0) {
+ if (strequal(name, "key_backspace")) {
+ DLOG("libtermkey:kbs=%s", value);
+ if (stty_erase[0] != 0) {
return stty_erase;
}
- } else if (strcmp(name, "key_dc") == 0) {
- ILOG("libtermkey:kdch1=%s", value);
+ } else if (strequal(name, "key_dc")) {
+ DLOG("libtermkey:kdch1=%s", value);
// Vim: "If <BS> and <DEL> are now the same, redefine <DEL>."
- if (stty_erase != NULL && strcmp(stty_erase, value) == 0) {
- return stty_erase[0] == DEL ? (char *)CTRL_H_STR : (char *)DEL_STR;
+ if (value != NULL && strequal(stty_erase, value)) {
+ return stty_erase[0] == DEL ? CTRL_H_STR : DEL_STR;
}
}
diff --git a/src/nvim/tui/tui.h b/src/nvim/tui/tui.h
index 07523bc124..996496ee60 100644
--- a/src/nvim/tui/tui.h
+++ b/src/nvim/tui/tui.h
@@ -1,6 +1,9 @@
#ifndef NVIM_TUI_TUI_H
#define NVIM_TUI_TUI_H
+#include "nvim/cursor_shape.h"
+#include "nvim/ui.h"
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "tui/tui.h.generated.h"
#endif
diff --git a/src/nvim/types.h b/src/nvim/types.h
index 35a5d1e2bd..317bead3bb 100644
--- a/src/nvim/types.h
+++ b/src/nvim/types.h
@@ -14,4 +14,5 @@ typedef unsigned char char_u;
typedef uint32_t u8char_T;
typedef struct expand expand_T;
+
#endif // NVIM_TYPES_H
diff --git a/src/nvim/ugrid.c b/src/nvim/ugrid.c
index 127b18feb6..7a0a16687e 100644
--- a/src/nvim/ugrid.c
+++ b/src/nvim/ugrid.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index d3784b6cd3..b85a01814d 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
@@ -5,6 +8,7 @@
#include <limits.h>
#include "nvim/vim.h"
+#include "nvim/log.h"
#include "nvim/ui.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
@@ -29,6 +33,7 @@
#include "nvim/screen.h"
#include "nvim/syntax.h"
#include "nvim/window.h"
+#include "nvim/cursor_shape.h"
#ifdef FEAT_TUI
# include "nvim/tui/tui.h"
#else
@@ -43,6 +48,7 @@
#define MAX_UI_COUNT 16
static UI *uis[MAX_UI_COUNT];
+static bool ui_ext[UI_WIDGETS] = { 0 };
static size_t ui_count = 0;
static int row = 0, col = 0;
static struct {
@@ -52,6 +58,28 @@ static int current_attr_code = 0;
static bool pending_cursor_update = false;
static int busy = 0;
static int height, width;
+static int old_mode_idx = -1;
+
+#if MIN_LOG_LEVEL > DEBUG_LOG_LEVEL
+# define UI_LOG(funname, ...)
+#else
+static size_t uilog_seen = 0;
+static char uilog_last_event[1024] = { 0 };
+# define UI_LOG(funname, ...) \
+ do { \
+ if (strequal(uilog_last_event, STR(funname))) { \
+ uilog_seen++; \
+ } else { \
+ if (uilog_seen > 0) { \
+ do_log(DEBUG_LOG_LEVEL, "ui", 0, true, \
+ "%s (+%zu times...)", uilog_last_event, uilog_seen); \
+ } \
+ DLOG("ui: " STR(funname)); \
+ uilog_seen = 0; \
+ xstrlcpy(uilog_last_event, STR(funname), sizeof(uilog_last_event)); \
+ } \
+ } while (0)
+#endif
// UI_CALL invokes a function on all registered UI instances. The functions can
// have 0-5 arguments (configurable by SELECT_NTH).
@@ -61,6 +89,7 @@ static int height, width;
# define UI_CALL(funname, ...) \
do { \
flush_cursor_update(); \
+ UI_LOG(funname, 0); \
for (size_t i = 0; i < ui_count; i++) { \
UI *ui = uis[i]; \
UI_CALL_MORE(funname, __VA_ARGS__); \
@@ -70,6 +99,7 @@ static int height, width;
# define UI_CALL(...) \
do { \
flush_cursor_update(); \
+ UI_LOG(__VA_ARGS__, 0); \
for (size_t i = 0; i < ui_count; i++) { \
UI *ui = uis[i]; \
UI_CALL_HELPER(CNT(__VA_ARGS__), __VA_ARGS__); \
@@ -79,10 +109,15 @@ static int height, width;
#define CNT(...) SELECT_NTH(__VA_ARGS__, MORE, MORE, MORE, MORE, ZERO, ignore)
#define SELECT_NTH(a1, a2, a3, a4, a5, a6, ...) a6
#define UI_CALL_HELPER(c, ...) UI_CALL_HELPER2(c, __VA_ARGS__)
+// Resolves to UI_CALL_MORE or UI_CALL_ZERO.
#define UI_CALL_HELPER2(c, ...) UI_CALL_##c(__VA_ARGS__)
#define UI_CALL_MORE(method, ...) if (ui->method) ui->method(ui, __VA_ARGS__)
#define UI_CALL_ZERO(method) if (ui->method) ui->method(ui)
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "ui_events_call.generated.h"
+#endif
+
void ui_builtin_start(void)
{
#ifdef FEAT_TUI
@@ -122,24 +157,6 @@ bool ui_active(void)
return ui_count != 0;
}
-void ui_suspend(void)
-{
- UI_CALL(suspend);
- UI_CALL(flush);
-}
-
-void ui_set_title(char *title)
-{
- UI_CALL(set_title, title);
- UI_CALL(flush);
-}
-
-void ui_set_icon(char *icon)
-{
- UI_CALL(set_icon, icon);
- UI_CALL(flush);
-}
-
void ui_event(char *name, Array args)
{
bool args_consumed = false;
@@ -149,31 +166,45 @@ void ui_event(char *name, Array args)
}
}
-// May update the shape of the cursor.
-void ui_cursor_shape(void)
-{
- ui_mode_change();
-}
-
void ui_refresh(void)
{
if (!ui_active()) {
return;
}
+ if (updating_screen) {
+ ui_schedule_refresh();
+ return;
+ }
+
int width = INT_MAX, height = INT_MAX;
- bool pum_external = true;
+ bool ext_widgets[UI_WIDGETS];
+ for (UIWidget i = 0; (int)i < UI_WIDGETS; i++) {
+ ext_widgets[i] = true;
+ }
for (size_t i = 0; i < ui_count; i++) {
UI *ui = uis[i];
width = MIN(ui->width, width);
height = MIN(ui->height, height);
- pum_external &= ui->pum_external;
+ for (UIWidget i = 0; (int)i < UI_WIDGETS; i++) {
+ ext_widgets[i] &= ui->ui_ext[i];
+ }
}
row = col = 0;
+
+ int save_p_lz = p_lz;
+ p_lz = false; // convince redrawing() to return true ...
screen_resize(width, height);
- pum_set_external(pum_external);
+ p_lz = save_p_lz;
+
+ for (UIWidget i = 0; (int)i < UI_WIDGETS; i++) {
+ ui_set_external(i, ext_widgets[i]);
+ }
+ ui_mode_info_set();
+ old_mode_idx = -1;
+ ui_cursor_shape();
}
static void ui_refresh_event(void **argv)
@@ -183,7 +214,7 @@ static void ui_refresh_event(void **argv)
void ui_schedule_refresh(void)
{
- loop_schedule(&main_loop, event_create(1, ui_refresh_event, 0));
+ loop_schedule(&main_loop, event_create(ui_refresh_event, 0));
}
void ui_resize(int new_width, int new_height)
@@ -199,33 +230,23 @@ void ui_resize(int new_width, int new_height)
sr.bot = height - 1;
sr.left = 0;
sr.right = width - 1;
- UI_CALL(resize, width, height);
+ ui_call_resize(width, height);
}
void ui_busy_start(void)
{
if (!(busy++)) {
- UI_CALL(busy_start);
+ ui_call_busy_start();
}
}
void ui_busy_stop(void)
{
if (!(--busy)) {
- UI_CALL(busy_stop);
+ ui_call_busy_stop();
}
}
-void ui_mouse_on(void)
-{
- UI_CALL(mouse_on);
-}
-
-void ui_mouse_off(void)
-{
- UI_CALL(mouse_off);
-}
-
void ui_attach_impl(UI *ui)
{
if (ui_count == MAX_UI_COUNT) {
@@ -258,16 +279,14 @@ void ui_detach_impl(UI *ui)
shift_index++;
}
- if (--ui_count) {
+ if (--ui_count
+ // During teardown/exit the loop was already destroyed, cannot schedule.
+ // https://github.com/neovim/neovim/pull/5119#issuecomment-258667046
+ && !exiting) {
ui_schedule_refresh();
}
}
-void ui_clear(void)
-{
- UI_CALL(clear);
-}
-
// Set scrolling region for window 'wp'.
// The region starts 'off' lines from the start of the window.
// Also set the vertical scroll region for a vertically split window. Always
@@ -282,7 +301,7 @@ void ui_set_scroll_region(win_T *wp, int off)
sr.right = wp->w_wincol + wp->w_width - 1;
}
- UI_CALL(set_scroll_region, sr.top, sr.bot, sr.left, sr.right);
+ ui_call_set_scroll_region(sr.top, sr.bot, sr.left, sr.right);
}
// Reset scrolling region to the whole screen.
@@ -292,22 +311,7 @@ void ui_reset_scroll_region(void)
sr.bot = (int)Rows - 1;
sr.left = 0;
sr.right = (int)Columns - 1;
- UI_CALL(set_scroll_region, sr.top, sr.bot, sr.left, sr.right);
-}
-
-void ui_append_lines(int count)
-{
- UI_CALL(scroll, -count);
-}
-
-void ui_delete_lines(int count)
-{
- UI_CALL(scroll, count);
-}
-
-void ui_eol_clear(void)
-{
- UI_CALL(eol_clear);
+ ui_call_set_scroll_region(sr.top, sr.bot, sr.left, sr.right);
}
void ui_start_highlight(int attr_code)
@@ -332,23 +336,31 @@ void ui_stop_highlight(void)
set_highlight_args(current_attr_code);
}
-void ui_visual_bell(void)
-{
- UI_CALL(visual_bell);
-}
-
void ui_puts(uint8_t *str)
{
- uint8_t *ptr = str;
+ uint8_t *p = str;
uint8_t c;
- while ((c = *ptr)) {
+ while ((c = *p)) {
if (c < 0x20) {
- parse_control_character(c);
- ptr++;
- } else {
- send_output(&ptr);
+ abort();
+ }
+
+ size_t clen = (size_t)mb_ptr2len(p);
+ ui_call_put((String){ .data = (char *)p, .size = clen });
+ col++;
+ if (mb_ptr2cells(p) > 1) {
+ // double cell character, blank the next cell
+ ui_call_put((String)STRING_INIT);
+ col++;
+ }
+ if (utf_ambiguous_width(utf_ptr2char(p))) {
+ pending_cursor_update = true;
+ }
+ if (col >= width) {
+ ui_linefeed();
}
+ p += clen;
}
}
@@ -368,9 +380,12 @@ void ui_cursor_goto(int new_row, int new_col)
pending_cursor_update = true;
}
-void ui_update_menu(void)
+void ui_mode_info_set(void)
{
- UI_CALL(update_menu);
+ Array style = mode_style_array();
+ bool enabled = (*p_guicursor != NUL);
+ ui_call_mode_info_set(enabled, style);
+ api_free_array(style);
}
int ui_current_row(void)
@@ -385,47 +400,7 @@ int ui_current_col(void)
void ui_flush(void)
{
- UI_CALL(flush);
-}
-
-static void send_output(uint8_t **ptr)
-{
- uint8_t *p = *ptr;
-
- while (*p >= 0x20) {
- size_t clen = (size_t)mb_ptr2len(p);
- UI_CALL(put, p, (size_t)clen);
- col++;
- if (mb_ptr2cells(p) > 1) {
- // double cell character, blank the next cell
- UI_CALL(put, NULL, 0);
- col++;
- }
- if (utf_ambiguous_width(utf_ptr2char(p))) {
- pending_cursor_update = true;
- }
- if (col >= width) {
- ui_linefeed();
- }
- p += clen;
- }
-
- *ptr = p;
-}
-
-static void parse_control_character(uint8_t c)
-{
- if (c == '\n') {
- ui_linefeed();
- } else if (c == '\r') {
- ui_carriage_return();
- } else if (c == '\b') {
- ui_cursor_left();
- } else if (c == Ctrl_L) {
- ui_cursor_right();
- } else if (c == Ctrl_G) {
- UI_CALL(bell);
- }
+ ui_call_flush();
}
static void set_highlight_args(int attr_code)
@@ -483,65 +458,53 @@ end:
UI_CALL(highlight_set, (ui->rgb ? rgb_attrs : cterm_attrs));
}
-static void ui_linefeed(void)
+void ui_linefeed(void)
{
int new_col = 0;
int new_row = row;
if (new_row < sr.bot) {
new_row++;
} else {
- UI_CALL(scroll, 1);
+ ui_call_scroll(1);
}
ui_cursor_goto(new_row, new_col);
}
-static void ui_carriage_return(void)
-{
- int new_col = 0;
- ui_cursor_goto(row, new_col);
-}
-
-static void ui_cursor_left(void)
-{
- int new_col = col - 1;
- assert(new_col >= 0);
- ui_cursor_goto(row, new_col);
-}
-
-static void ui_cursor_right(void)
-{
- int new_col = col + 1;
- assert(new_col < width);
- ui_cursor_goto(row, new_col);
-}
-
static void flush_cursor_update(void)
{
if (pending_cursor_update) {
pending_cursor_update = false;
- UI_CALL(cursor_goto, row, col);
+ ui_call_cursor_goto(row, col);
}
}
-// Notify that the current mode has changed. Can be used to change cursor
-// shape, for example.
-static void ui_mode_change(void)
+/// Check if current mode has changed.
+/// May update the shape of the cursor.
+void ui_cursor_shape(void)
{
- int mode;
if (!full_screen) {
return;
}
- // Get a simple UI mode out of State.
- if ((State & REPLACE) == REPLACE) {
- mode = REPLACE;
- } else if (State & INSERT) {
- mode = INSERT;
- } else if (State & CMDLINE) {
- mode = CMDLINE;
- } else {
- mode = NORMAL;
+ int mode_idx = cursor_get_mode_idx();
+
+ if (old_mode_idx != mode_idx) {
+ old_mode_idx = mode_idx;
+ char *full_name = shape_table[mode_idx].full_name;
+ ui_call_mode_change(cstr_as_string(full_name), mode_idx);
}
- UI_CALL(mode_change, mode);
conceal_check_cursur_line();
}
+/// Returns true if `widget` is externalized.
+bool ui_is_external(UIWidget widget)
+{
+ return ui_ext[widget];
+}
+
+/// Sets `widget` as "external".
+/// Such widgets are not drawn by Nvim; external UIs are expected to handle
+/// higher-level UI events and present the data.
+void ui_set_external(UIWidget widget, bool external)
+{
+ ui_ext[widget] = external;
+}
diff --git a/src/nvim/ui.h b/src/nvim/ui.h
index d14bc5812c..064f77fee1 100644
--- a/src/nvim/ui.h
+++ b/src/nvim/ui.h
@@ -6,6 +6,15 @@
#include <stdint.h>
#include "api/private/defs.h"
+#include "nvim/buffer_defs.h"
+
+typedef enum {
+ kUICmdline = 0,
+ kUIPopupmenu,
+ kUITabline,
+ kUIWildmenu,
+} UIWidget;
+#define UI_WIDGETS (kUIWildmenu + 1)
typedef struct {
bool bold, underline, undercurl, italic, reverse;
@@ -15,37 +24,21 @@ typedef struct {
typedef struct ui_t UI;
struct ui_t {
- bool rgb, pum_external;
+ bool rgb;
+ bool ui_ext[UI_WIDGETS]; ///< Externalized widgets
int width, height;
void *data;
- void (*resize)(UI *ui, int rows, int columns);
- void (*clear)(UI *ui);
- void (*eol_clear)(UI *ui);
- void (*cursor_goto)(UI *ui, int row, int col);
- void (*update_menu)(UI *ui);
- void (*busy_start)(UI *ui);
- void (*busy_stop)(UI *ui);
- void (*mouse_on)(UI *ui);
- void (*mouse_off)(UI *ui);
- void (*mode_change)(UI *ui, int mode);
- void (*set_scroll_region)(UI *ui, int top, int bot, int left, int right);
- void (*scroll)(UI *ui, int count);
- void (*highlight_set)(UI *ui, HlAttrs attrs);
- void (*put)(UI *ui, uint8_t *str, size_t len);
- void (*bell)(UI *ui);
- void (*visual_bell)(UI *ui);
- void (*flush)(UI *ui);
- void (*update_fg)(UI *ui, int fg);
- void (*update_bg)(UI *ui, int bg);
- void (*update_sp)(UI *ui, int sp);
- void (*suspend)(UI *ui);
- void (*set_title)(UI *ui, char *title);
- void (*set_icon)(UI *ui, char *icon);
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "ui_events.generated.h"
+#endif
+
void (*event)(UI *ui, char *name, Array args, bool *args_consumed);
void (*stop)(UI *ui);
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ui.h.generated.h"
+# include "ui_events_call.h.generated.h"
#endif
#endif // NVIM_UI_H
diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c
index 25861abc1b..5585886612 100644
--- a/src/nvim/ui_bridge.c
+++ b/src/nvim/ui_bridge.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
// UI wrapper that sends requests to the UI thread.
// Used by the built-in TUI and libnvim-based UIs.
@@ -13,6 +16,7 @@
#include "nvim/memory.h"
#include "nvim/ui_bridge.h"
#include "nvim/ugrid.h"
+#include "nvim/api/private/helpers.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ui_bridge.c.generated.h"
@@ -20,45 +24,29 @@
#define UI(b) (((UIBridgeData *)b)->ui)
-#if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL
-static size_t uilog_seen = 0;
-static argv_callback uilog_event = NULL;
-#define UI_CALL(ui, name, argc, ...) \
- do { \
- if (uilog_event == ui_bridge_##name##_event) { \
- uilog_seen++; \
- } else { \
- if (uilog_seen > 0) { \
- DLOG("UI bridge: ...%zu times", uilog_seen); \
- } \
- DLOG("UI bridge: " STR(name)); \
- uilog_seen = 0; \
- uilog_event = ui_bridge_##name##_event; \
- } \
- ((UIBridgeData *)ui)->scheduler( \
- event_create(1, ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui)); \
- } while (0)
-#else
// Schedule a function call on the UI bridge thread.
-#define UI_CALL(ui, name, argc, ...) \
+#define UI_BRIDGE_CALL(ui, name, argc, ...) \
((UIBridgeData *)ui)->scheduler( \
- event_create(1, ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui))
-#endif
+ event_create(ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui))
+
+#define INT2PTR(i) ((void *)(intptr_t)i)
+#define PTR2INT(p) ((Integer)(intptr_t)p)
-#define INT2PTR(i) ((void *)(uintptr_t)i)
-#define PTR2INT(p) ((int)(uintptr_t)p)
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "ui_events_bridge.generated.h"
+#endif
UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)
{
UIBridgeData *rv = xcalloc(1, sizeof(UIBridgeData));
rv->ui = ui;
rv->bridge.rgb = ui->rgb;
- rv->bridge.pum_external = ui->pum_external;
rv->bridge.stop = ui_bridge_stop;
rv->bridge.resize = ui_bridge_resize;
rv->bridge.clear = ui_bridge_clear;
rv->bridge.eol_clear = ui_bridge_eol_clear;
rv->bridge.cursor_goto = ui_bridge_cursor_goto;
+ rv->bridge.mode_info_set = ui_bridge_mode_info_set;
rv->bridge.update_menu = ui_bridge_update_menu;
rv->bridge.busy_start = ui_bridge_busy_start;
rv->bridge.busy_stop = ui_bridge_busy_stop;
@@ -80,6 +68,10 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)
rv->bridge.set_icon = ui_bridge_set_icon;
rv->scheduler = scheduler;
+ for (UIWidget i = 0; (int)i < UI_WIDGETS; i++) {
+ rv->bridge.ui_ext[i] = ui->ui_ext[i];
+ }
+
rv->ui_main = ui_main;
uv_mutex_init(&rv->mutex);
uv_cond_init(&rv->cond);
@@ -116,7 +108,7 @@ static void ui_bridge_stop(UI *b)
{
UIBridgeData *bridge = (UIBridgeData *)b;
bool stopped = bridge->stopped = false;
- UI_CALL(b, stop, 1, b);
+ UI_BRIDGE_CALL(b, stop, 1, b);
for (;;) {
uv_mutex_lock(&bridge->mutex);
stopped = bridge->stopped;
@@ -138,134 +130,11 @@ static void ui_bridge_stop_event(void **argv)
ui->stop(ui);
}
-static void ui_bridge_resize(UI *b, int width, int height)
-{
- UI_CALL(b, resize, 3, b, INT2PTR(width), INT2PTR(height));
-}
-static void ui_bridge_resize_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->resize(ui, PTR2INT(argv[1]), PTR2INT(argv[2]));
-}
-
-static void ui_bridge_clear(UI *b)
-{
- UI_CALL(b, clear, 1, b);
-}
-static void ui_bridge_clear_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->clear(ui);
-}
-
-static void ui_bridge_eol_clear(UI *b)
-{
- UI_CALL(b, eol_clear, 1, b);
-}
-static void ui_bridge_eol_clear_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->eol_clear(ui);
-}
-
-static void ui_bridge_cursor_goto(UI *b, int row, int col)
-{
- UI_CALL(b, cursor_goto, 3, b, INT2PTR(row), INT2PTR(col));
-}
-static void ui_bridge_cursor_goto_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->cursor_goto(ui, PTR2INT(argv[1]), PTR2INT(argv[2]));
-}
-
-static void ui_bridge_update_menu(UI *b)
-{
- UI_CALL(b, update_menu, 1, b);
-}
-static void ui_bridge_update_menu_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->update_menu(ui);
-}
-
-static void ui_bridge_busy_start(UI *b)
-{
- UI_CALL(b, busy_start, 1, b);
-}
-static void ui_bridge_busy_start_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->busy_start(ui);
-}
-
-static void ui_bridge_busy_stop(UI *b)
-{
- UI_CALL(b, busy_stop, 1, b);
-}
-static void ui_bridge_busy_stop_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->busy_stop(ui);
-}
-
-static void ui_bridge_mouse_on(UI *b)
-{
- UI_CALL(b, mouse_on, 1, b);
-}
-static void ui_bridge_mouse_on_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->mouse_on(ui);
-}
-
-static void ui_bridge_mouse_off(UI *b)
-{
- UI_CALL(b, mouse_off, 1, b);
-}
-static void ui_bridge_mouse_off_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->mouse_off(ui);
-}
-
-static void ui_bridge_mode_change(UI *b, int mode)
-{
- UI_CALL(b, mode_change, 2, b, INT2PTR(mode));
-}
-static void ui_bridge_mode_change_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->mode_change(ui, PTR2INT(argv[1]));
-}
-
-static void ui_bridge_set_scroll_region(UI *b, int top, int bot, int left,
- int right)
-{
- UI_CALL(b, set_scroll_region, 5, b, INT2PTR(top), INT2PTR(bot),
- INT2PTR(left), INT2PTR(right));
-}
-static void ui_bridge_set_scroll_region_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->set_scroll_region(ui, PTR2INT(argv[1]), PTR2INT(argv[2]),
- PTR2INT(argv[3]), PTR2INT(argv[4]));
-}
-
-static void ui_bridge_scroll(UI *b, int count)
-{
- UI_CALL(b, scroll, 2, b, INT2PTR(count));
-}
-static void ui_bridge_scroll_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->scroll(ui, PTR2INT(argv[1]));
-}
-
static void ui_bridge_highlight_set(UI *b, HlAttrs attrs)
{
HlAttrs *a = xmalloc(sizeof(HlAttrs));
*a = attrs;
- UI_CALL(b, highlight_set, 2, b, a);
+ UI_BRIDGE_CALL(b, highlight_set, 2, b, a);
}
static void ui_bridge_highlight_set_event(void **argv)
{
@@ -274,87 +143,11 @@ static void ui_bridge_highlight_set_event(void **argv)
xfree(argv[1]);
}
-static void ui_bridge_put(UI *b, uint8_t *text, size_t size)
-{
- uint8_t *t = NULL;
- if (text) {
- t = xmalloc(sizeof(((UCell *)0)->data));
- memcpy(t, text, size);
- }
- UI_CALL(b, put, 3, b, t, INT2PTR(size));
-}
-static void ui_bridge_put_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->put(ui, (uint8_t *)argv[1], (size_t)(uintptr_t)argv[2]);
- xfree(argv[1]);
-}
-
-static void ui_bridge_bell(UI *b)
-{
- UI_CALL(b, bell, 1, b);
-}
-static void ui_bridge_bell_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->bell(ui);
-}
-
-static void ui_bridge_visual_bell(UI *b)
-{
- UI_CALL(b, visual_bell, 1, b);
-}
-static void ui_bridge_visual_bell_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->visual_bell(ui);
-}
-
-static void ui_bridge_update_fg(UI *b, int fg)
-{
- UI_CALL(b, update_fg, 2, b, INT2PTR(fg));
-}
-static void ui_bridge_update_fg_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->update_fg(ui, PTR2INT(argv[1]));
-}
-
-static void ui_bridge_update_bg(UI *b, int bg)
-{
- UI_CALL(b, update_bg, 2, b, INT2PTR(bg));
-}
-static void ui_bridge_update_bg_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->update_bg(ui, PTR2INT(argv[1]));
-}
-
-static void ui_bridge_update_sp(UI *b, int sp)
-{
- UI_CALL(b, update_sp, 2, b, INT2PTR(sp));
-}
-static void ui_bridge_update_sp_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->update_sp(ui, PTR2INT(argv[1]));
-}
-
-static void ui_bridge_flush(UI *b)
-{
- UI_CALL(b, flush, 1, b);
-}
-static void ui_bridge_flush_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->flush(ui);
-}
-
static void ui_bridge_suspend(UI *b)
{
UIBridgeData *data = (UIBridgeData *)b;
uv_mutex_lock(&data->mutex);
- UI_CALL(b, suspend, 1, b);
+ UI_BRIDGE_CALL(b, suspend, 1, b);
data->ready = false;
// suspend the main thread until CONTINUE is called by the UI thread
while (!data->ready) {
@@ -367,25 +160,3 @@ static void ui_bridge_suspend_event(void **argv)
UI *ui = UI(argv[0]);
ui->suspend(ui);
}
-
-static void ui_bridge_set_title(UI *b, char *title)
-{
- UI_CALL(b, set_title, 2, b, title ? xstrdup(title) : NULL);
-}
-static void ui_bridge_set_title_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->set_title(ui, argv[1]);
- xfree(argv[1]);
-}
-
-static void ui_bridge_set_icon(UI *b, char *icon)
-{
- UI_CALL(b, set_icon, 2, b, icon ? xstrdup(icon) : NULL);
-}
-static void ui_bridge_set_icon_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->set_icon(ui, argv[1]);
- xfree(argv[1]);
-}
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index 4d56046bc1..3d7ebc8837 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* undo.c: multi level undo facility
*
@@ -76,12 +79,14 @@
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
+#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/undo.h"
+#include "nvim/macros.h"
#include "nvim/cursor.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
@@ -305,23 +310,19 @@ bool undo_allowed(void)
return true;
}
-/*
- * Get the undolevle value for the current buffer.
- */
+/// Get the 'undolevels' value for the current buffer.
static long get_undolevel(void)
{
- if (curbuf->terminal) {
- return -1;
- }
- if (curbuf->b_p_ul == NO_LOCAL_UNDOLEVEL)
+ if (curbuf->b_p_ul == NO_LOCAL_UNDOLEVEL) {
return p_ul;
+ }
return curbuf->b_p_ul;
}
static inline void zero_fmark_additional_data(fmark_T *fmarks)
{
for (size_t i = 0; i < NMARKS; i++) {
- dict_unref(fmarks[i].additional_data);
+ tv_dict_unref(fmarks[i].additional_data);
fmarks[i].additional_data = NULL;
}
}
@@ -969,12 +970,12 @@ static u_entry_T *unserialize_uep(bufinfo_T * bi, bool *error,
uep->ue_lcount = undo_read_4c(bi);
uep->ue_size = undo_read_4c(bi);
- char_u **array;
+ char_u **array = NULL;
if (uep->ue_size > 0) {
- array = xmalloc(sizeof(char_u *) * (size_t)uep->ue_size);
- memset(array, 0, sizeof(char_u *) * (size_t)uep->ue_size);
- } else {
- array = NULL;
+ if ((size_t)uep->ue_size < SIZE_MAX / sizeof(char_u *)) {
+ array = xmalloc(sizeof(char_u *) * (size_t)uep->ue_size);
+ memset(array, 0, sizeof(char_u *) * (size_t)uep->ue_size);
+ }
}
uep->ue_array = array;
@@ -1084,7 +1085,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
*/
perm = 0600;
if (buf->b_ffname != NULL) {
- perm = os_getperm(buf->b_ffname);
+ perm = os_getperm((const char *)buf->b_ffname);
if (perm < 0) {
perm = 0600;
}
@@ -1143,7 +1144,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
EMSG2(_(e_not_open), file_name);
goto theend;
}
- (void)os_setperm((char_u *)file_name, perm);
+ (void)os_setperm(file_name, perm);
if (p_verbose > 0) {
verbose_enter();
smsg(_("Writing undo file: %s"), file_name);
@@ -1168,7 +1169,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
&& os_fileinfo(file_name, &file_info_new)
&& file_info_old.stat.st_gid != file_info_new.stat.st_gid
&& os_fchown(fd, (uv_uid_t)-1, (uv_gid_t)file_info_old.stat.st_gid)) {
- os_setperm((char_u *)file_name, (perm & 0707) | ((perm & 07) << 3));
+ os_setperm(file_name, (perm & 0707) | ((perm & 07) << 3));
}
# ifdef HAVE_SELINUX
if (buf->b_ffname != NULL)
@@ -1403,7 +1404,9 @@ void u_read_undo(char *name, char_u *hash, char_u *orig_name)
// sequence numbers of the headers.
// When there are no headers uhp_table is NULL.
if (num_head > 0) {
- uhp_table = xmalloc((size_t)num_head * sizeof(u_header_T *));
+ if ((size_t)num_head < SIZE_MAX / sizeof(*uhp_table)) {
+ uhp_table = xmalloc((size_t)num_head * sizeof(*uhp_table));
+ }
}
long num_read_uhps = 0;
@@ -1710,7 +1713,8 @@ bool u_undo_and_forget(int count)
if (curbuf->b_u_curhead) {
to_forget->uh_alt_next.ptr = NULL;
curbuf->b_u_curhead->uh_alt_prev.ptr = to_forget->uh_alt_prev.ptr;
- curbuf->b_u_seq_cur = curbuf->b_u_curhead->uh_seq-1;
+ curbuf->b_u_seq_cur = curbuf->b_u_curhead->uh_next.ptr ?
+ curbuf->b_u_curhead->uh_next.ptr->uh_seq : 0;
} else if (curbuf->b_u_newhead) {
curbuf->b_u_seq_cur = curbuf->b_u_newhead->uh_seq;
}
@@ -1834,11 +1838,9 @@ void undo_time(long step, int sec, int file, int absolute)
}
closest = -1;
} else {
- /* When doing computations with time_t subtract starttime, because
- * time_t converted to a long may result in a wrong number. */
- if (dosec)
- target = (long)(curbuf->b_u_time_cur - starttime) + step;
- else if (dofile) {
+ if (dosec) {
+ target = (long)(curbuf->b_u_time_cur) + step;
+ } else if (dofile) {
if (step < 0) {
/* Going back to a previous write. If there were changes after
* the last write, count that as moving one file-write, so
@@ -1876,14 +1878,16 @@ void undo_time(long step, int sec, int file, int absolute)
target = 0;
closest = -1;
} else {
- if (dosec)
- closest = (long)(time(NULL) - starttime + 1);
- else if (dofile)
+ if (dosec) {
+ closest = (long)(os_time() + 1);
+ } else if (dofile) {
closest = curbuf->b_u_save_nr_last + 2;
- else
+ } else {
closest = curbuf->b_u_seq_last + 2;
- if (target >= closest)
+ }
+ if (target >= closest) {
target = closest - 1;
+ }
}
}
closest_start = closest;
@@ -1912,12 +1916,13 @@ void undo_time(long step, int sec, int file, int absolute)
while (uhp != NULL) {
uhp->uh_walk = mark;
- if (dosec)
- val = (long)(uhp->uh_time - starttime);
- else if (dofile)
+ if (dosec) {
+ val = (long)(uhp->uh_time);
+ } else if (dofile) {
val = uhp->uh_save_nr;
- else
+ } else {
val = uhp->uh_seq;
+ }
if (round == 1 && !(dofile && val == 0)) {
/* Remember the header that is closest to the target.
@@ -2228,11 +2233,13 @@ static void u_undoredo(int undo)
/* adjust marks */
if (oldsize != newsize) {
mark_adjust(top + 1, top + oldsize, (long)MAXLNUM,
- (long)newsize - (long)oldsize);
- if (curbuf->b_op_start.lnum > top + oldsize)
+ (long)newsize - (long)oldsize, false);
+ if (curbuf->b_op_start.lnum > top + oldsize) {
curbuf->b_op_start.lnum += newsize - oldsize;
- if (curbuf->b_op_end.lnum > top + oldsize)
+ }
+ if (curbuf->b_op_end.lnum > top + oldsize) {
curbuf->b_op_end.lnum += newsize - oldsize;
+ }
}
changed_lines(top + 1, 0, bot, newsize - oldsize);
@@ -2321,7 +2328,8 @@ static void u_undoredo(int undo)
if (undo)
/* We are below the previous undo. However, to make ":earlier 1s"
* work we compute this as being just above the just undone change. */
- --curbuf->b_u_seq_cur;
+ curbuf->b_u_seq_cur = curhead->uh_next.ptr ?
+ curhead->uh_next.ptr->uh_seq : 0;
/* Remember where we are for ":earlier 1f" and ":later 1f". */
if (curhead->uh_save_nr != 0) {
@@ -2510,13 +2518,14 @@ void ex_undolist(exarg_T *eap)
sort_strings((char_u **)ga.ga_data, ga.ga_len);
msg_start();
- msg_puts_attr((char_u *)_("number changes when saved"),
- hl_attr(HLF_T));
- for (int i = 0; i < ga.ga_len && !got_int; ++i) {
+ msg_puts_attr(_("number changes when saved"),
+ hl_attr(HLF_T));
+ for (int i = 0; i < ga.ga_len && !got_int; i++) {
msg_putchar('\n');
- if (got_int)
+ if (got_int) {
break;
- msg_puts(((char_u **)ga.ga_data)[i]);
+ }
+ msg_puts(((const char **)ga.ga_data)[i]);
}
msg_end();
@@ -2549,20 +2558,20 @@ static void u_add_time(char_u *buf, size_t buflen, time_t tt)
*/
void ex_undojoin(exarg_T *eap)
{
- if (curbuf->b_u_newhead == NULL)
- return; /* nothing changed before */
+ if (curbuf->b_u_newhead == NULL) {
+ return; // nothing changed before
+ }
if (curbuf->b_u_curhead != NULL) {
EMSG(_("E790: undojoin is not allowed after undo"));
return;
}
- if (!curbuf->b_u_synced)
- return; /* already unsynced */
- if (get_undolevel() < 0)
- return; /* no entries, nothing to do */
- else {
- /* Go back to the last entry */
- curbuf->b_u_curhead = curbuf->b_u_newhead;
- curbuf->b_u_synced = false; /* no entries, nothing to do */
+ if (!curbuf->b_u_synced) {
+ return; // already unsynced
+ }
+ if (get_undolevel() < 0) {
+ return; // no entries, nothing to do
+ } else {
+ curbuf->b_u_synced = false; // Append next change to last entry
}
}
@@ -2942,25 +2951,28 @@ void u_eval_tree(u_header_T *first_uhp, list_T *list)
dict_T *dict;
while (uhp != NULL) {
- dict = dict_alloc();
- dict_add_nr_str(dict, "seq", uhp->uh_seq, NULL);
- dict_add_nr_str(dict, "time", (long)uhp->uh_time, NULL);
- if (uhp == curbuf->b_u_newhead)
- dict_add_nr_str(dict, "newhead", 1, NULL);
- if (uhp == curbuf->b_u_curhead)
- dict_add_nr_str(dict, "curhead", 1, NULL);
- if (uhp->uh_save_nr > 0)
- dict_add_nr_str(dict, "save", uhp->uh_save_nr, NULL);
+ dict = tv_dict_alloc();
+ tv_dict_add_nr(dict, S_LEN("seq"), (varnumber_T)uhp->uh_seq);
+ tv_dict_add_nr(dict, S_LEN("time"), (varnumber_T)uhp->uh_time);
+ if (uhp == curbuf->b_u_newhead) {
+ tv_dict_add_nr(dict, S_LEN("newhead"), 1);
+ }
+ if (uhp == curbuf->b_u_curhead) {
+ tv_dict_add_nr(dict, S_LEN("curhead"), 1);
+ }
+ if (uhp->uh_save_nr > 0) {
+ tv_dict_add_nr(dict, S_LEN("save"), (varnumber_T)uhp->uh_save_nr);
+ }
if (uhp->uh_alt_next.ptr != NULL) {
- list_T *alt_list = list_alloc();
+ list_T *alt_list = tv_list_alloc();
- /* Recursive call to add alternate undo tree. */
+ // Recursive call to add alternate undo tree.
u_eval_tree(uhp->uh_alt_next.ptr, alt_list);
- dict_add_list(dict, "alt", alt_list);
+ tv_dict_add_list(dict, S_LEN("alt"), alt_list);
}
- list_append_dict(list, dict);
+ tv_list_append_dict(list, dict);
uhp = uhp->uh_prev.ptr;
}
}
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 3e9cccda20..6e24e30a09 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/// @file version.c
///
/// Nvim was forked from Vim 7.4.160.
@@ -25,8 +28,9 @@
// for ":version", ":intro", and "nvim --version"
#ifndef NVIM_VERSION_MEDIUM
-#define NVIM_VERSION_MEDIUM STR(NVIM_VERSION_MAJOR) "." STR(NVIM_VERSION_MINOR)\
- "." STR(NVIM_VERSION_PATCH) NVIM_VERSION_PRERELEASE
+#define NVIM_VERSION_MEDIUM "v" STR(NVIM_VERSION_MAJOR)\
+ "." STR(NVIM_VERSION_MINOR) "." STR(NVIM_VERSION_PATCH)\
+ NVIM_VERSION_PRERELEASE
#endif
#define NVIM_VERSION_LONG "NVIM " NVIM_VERSION_MEDIUM
@@ -72,2371 +76,878 @@ static char *features[] = {
};
// clang-format off
-static int included_patches[] = {
- // 2367,
- // 2366 NA
- // 2365 NA
- // 2364,
- // 2363 NA
- // 2362,
- // 2361 NA
- // 2360,
- // 2359 NA
- // 2358 NA
- // 2357,
- // 2356,
- // 2355,
- // 2354,
- // 2353,
- // 2352 NA
- // 2351 NA
- // 2350,
- // 2349,
- // 2348,
- // 2347,
- // 2346,
- // 2345 NA
- // 2344 NA
- // 2343,
- // 2342 NA
- // 2341,
- // 2340 NA
- // 2339,
- // 2338 NA
- 2337,
- // 2336,
- 2335,
- // 2334,
- // 2333,
- // 2332 NA
- 2331,
- // 2330,
- // 2329,
- // 2328,
- // 2327 NA
- // 2326,
- // 2325 NA
- // 2324,
- // 2323,
- // 2322,
- 2321,
- // 2320,
- // 2319 NA
- // 2318,
- // 2317,
- // 2316 NA
- // 2315,
- // 2314,
- // 2313,
- 2312,
- // 2311 NA
- // 2310 NA
- 2309,
- // 2308 NA
- // 2307,
- // 2306,
- // 2305,
- // 2304 NA
- // 2303,
- // 2302 NA
- // 2301 NA
- // 2300,
- // 2299,
- // 2298 NA
- // 2297 NA
- // 2296,
- // 2295,
- 2294,
- // 2293,
- // 2292,
- // 2291,
- // 2290 NA
- // 2289 NA
- // 2288 NA
- // 2287 NA
- // 2286 NA
- // 2285 NA
- 2284,
- // 2283,
- // 2282 NA
- // 2281 NA
- // 2280,
- // 2279,
- // 2278 NA
- 2277,
- // 2276,
- // 2275,
- 2274,
- 2273,
- 2272,
- // 2271 NA
- // 2270 NA
- // 2269,
- // 2268,
- // 2267 NA
- // 2266,
- // 2265,
- // 2264,
- // 2263,
- // 2262 NA
- // 2261 NA
- // 2260 NA
- // 2259,
- // 2258 NA
- // 2257 NA
- // 2256,
- // 2255,
- // 2254 NA
- // 2253 NA
- // 2252 NA
- 2251,
- // 2250,
- // 2249,
- // 2248,
- // 2247 NA
- // 2246,
- // 2245,
- // 2244,
- // 2243 NA
- // 2242,
- // 2241,
- // 2240,
- // 2239,
- // 2238 NA
- 2237,
- // 2236,
- // 2235,
- // 2234 NA
- // 2233,
- // 2232 NA
- // 2231,
- // 2230,
- // 2229,
- // 2228,
- 2227,
- 2226,
- 2225,
- // 2224,
- // 2223,
- // 2222,
- // 2221,
- // 2220,
- 2219,
- // 2218 NA
- 2217,
- // 2216 NA
- 2215,
- // 2214 NA
- 2213,
- 2212,
- // 2211 NA
- // 2210 NA
- // 2209,
- // 2208,
- // 2207 NA
- // 2206 NA
- 2205,
- 2204,
- // 2203 NA
- // 2202 NA
- 2201,
- // 2200,
- // 2199 NA
- // 2198 NA
- // 2197,
- // 2196,
- // 2195 NA
- 2194,
- // 2193 NA
- // 2192 NA
- // 2191 NA
- // 2190,
- // 2189,
- 2188,
- // 2187,
- // 2186 NA
- // 2185,
- // 2184,
- 2183,
- // 2182 NA
- // 2181,
- // 2180,
- // 2179,
- // 2178,
- // 2177,
- // 2176 NA
- // 2175,
- 2174,
- // 2173,
- // 2172,
- // 2171,
- // 2170,
- // 2169,
- // 2168 NA
- // 2167 NA
- // 2166 NA
- // 2165,
- // 2164,
- 2163,
- 2162,
- // 2161,
- // 2160,
- // 2159,
- 2158,
- // 2157 NA
- // 2156 NA
- // 2155 NA
- // 2154 NA
- // 2153 NA
- // 2152,
- // 2151,
- // 2150 NA
- 2149,
- // 2148,
- 2147,
- 2146,
- // 2145 NA
- // 2144,
- // 2143,
- // 2142,
- // 2141,
- // 2140 NA
- // 2139,
- // 2138 NA
- // 2137,
- // 2136,
- // 2135,
- // 2134,
- // 2133 NA
- // 2132 NA
- // 2131 NA
- // 2130 NA
- // 2129 NA
- 2128,
- 2127,
- 2126,
- // 2125 NA
- 2124,
- 2123,
- // 2122 NA
- // 2121,
- // 2120,
- // 2119,
- // 2118 NA
- // 2117,
- // 2116 NA
- // 2115 NA
- // 2114 NA
- // 2113,
- 2112,
- // 2111,
- 2110,
- 2109,
- // 2108 NA
- // 2107,
- // 2106,
- // 2105 NA
- // 2104,
- 2103,
- // 2102 NA
- // 2101,
- 2100,
- // 2099,
- // 2098,
- // 2097,
- // 2096,
- // 2095,
- // 2094 NA
- // 2093 NA
- // 2092 NA
- // 2091 NA
- // 2090,
- // 2089 NA
- // 2088,
- // 2087,
- 2086,
- // 2085,
- // 2084,
- // 2083,
- // 2082,
- // 2081,
- // 2080,
- // 2079 NA
- // 2078 NA
- // 2077,
- // 2076,
- // 2075,
- // 2074,
- // 2073 NA
- // 2072,
- 2071,
- // 2070 NA
- // 2069,
- // 2068,
- // 2067,
- 2066,
- // 2065,
- // 2064,
- // 2063 NA
- // 2062,
- // 2061,
- // 2060 NA
- // 2059 NA
- // 2058,
- // 2057 NA
- // 2056 NA
- // 2055 NA
- // 2054 NA
- // 2053 NA
- // 2052 NA
- // 2051,
- // 2050,
- // 2049,
- // 2048 NA
- // 2047,
- // 2046,
- // 2045 NA
- // 2044,
- 2043,
- // 2042 NA
- // 2041 NA
- // 2040 NA
- // 2039 NA
- // 2038 NA
- // 2037 NA
- // 2036,
- // 2035 NA
- // 2034 NA
- 2033,
- // 2032 NA
- // 2031,
- // 2030 NA
- // 2029,
- 2028,
- // 2027 NA
- // 2026 NA
- // 2025 NA
- // 2024,
- // 2023,
- // 2022,
- // 2021,
- // 2020 NA
- 2019,
- // 2018,
- // 2017,
- // 2016 NA
- 2015,
- 2014,
- 2013,
- 2012,
- 2011,
- 2010,
- 2009,
- 2008,
- 2007,
- // 2006,
- 2005,
- // 2004 NA
- // 2003 NA
- // 2002,
- // 2001 NA
- 2000,
- 1999,
- // 1998 NA
- 1997,
- 1996,
- // 1995 NA
- // 1994,
- // 1993,
- // 1992,
- // 1991,
- 1990,
- // 1989,
- // 1988 NA
- // 1987 NA
- // 1986,
- // 1985 NA
- 1984,
- // 1983 NA
- // 1982 NA
- // 1981,
- 1980,
- // 1979,
- // 1978,
- // 1977,
- // 1976,
- // 1975,
- // 1974 NA
- 1973,
- // 1972 NA
- 1971,
- 1970,
- // 1969 NA
- // 1968,
- 1967,
- 1966,
- // 1965 NA
- 1964,
- // 1963 NA
- // 1962,
- 1961,
- 1960,
- // 1959 NA
- // 1958 NA
- // 1957 NA
- 1956,
- // 1955 NA
- // 1954,
- 1953,
- 1952,
- // 1951 NA
- 1950,
- 1949,
- // 1948,
- // 1947 NA
- // 1946 NA
- // 1945 NA
- // 1944 NA
- // 1943 NA
- // 1942 NA
- 1941,
- 1940,
- // 1939 NA
- // 1938 NA
- 1937,
- // 1936 NA
- // 1935 NA
- // 1934 NA
- // 1933 NA
- // 1932 NA
- // 1931 NA
- // 1930 NA
- // 1929 NA
- 1928,
- // 1927 NA
- // 1926 NA
- 1925,
- // 1924 NA
- 1923,
- // 1922 NA
- // 1921 NA
- // 1920 NA
- // 1919 NA
- // 1918 NA
- // 1917 NA
- // 1916 NA
- // 1915 NA
- // 1914,
- 1913,
- 1912,
- // 1911 NA
- // 1910,
- 1909,
- // 1908 NA
- // 1907 NA
- // 1906 NA
- // 1905 NA
- // 1904 NA
- // 1903 NA
- // 1902 NA
- // 1901 NA
- 1900,
- // 1899 NA
- 1898,
- 1897,
- 1896,
- 1895,
- 1894,
- 1893,
- 1892,
- // 1891 NA
- // 1890 NA
- 1889,
- // 1888 NA
- // 1887 NA
- // 1886 NA
- // 1885 NA
- 1884,
- // 1883 NA
- 1882,
- 1881,
- // 1880 NA
- // 1879 NA
- // 1878 NA
- // 1877 NA
- 1876,
- 1875,
- // 1874 NA
- // 1873 NA
- // 1872 NA
- 1871,
- // 1870 NA
- // 1869 NA
- 1868,
- 1867,
- 1866,
- // 1865 NA
- // 1864 NA
- // 1863 NA
- // 1862 NA
- 1861,
- 1860,
- // 1859 NA
- // 1858 NA
- // 1857 NA
- // 1856 NA
- // 1855 NA
- // 1854 NA
- // 1853 NA
- // 1852 NA
- // 1851,
- // 1850 NA
- // 1849 NA
- // 1848 NA
- 1847,
- // 1846 NA
- // 1845 NA
- // 1844 NA
- // 1843 NA
- 1842,
- 1841,
- 1840,
- 1839,
- 1838,
- 1837,
- 1836,
- 1835,
- 1834,
- 1833,
- 1832,
- 1831,
- // 1830 NA
- // 1829 NA
- // 1828 NA
- // 1827 NA
- // 1826 NA
- // 1825 NA
- // 1824 NA
- 1823,
- // 1822 NA
- 1821,
- 1820,
- // 1819 NA
- 1818,
- // 1817 NA
- 1816,
- 1815,
- // 1814 NA
- 1813,
- // 1812 NA
- // 1811 NA
- // 1810 NA
- 1809,
- 1808,
- // 1807 NA
- 1806,
- // 1805 NA
- // 1804 NA
- // 1803 NA
- 1802,
- // 1801 NA
- // 1800 NA
- 1799,
- // 1798 NA
- // 1797 NA
- // 1796 NA
- // 1795 NA
- // 1794 NA
- 1793,
- // 1792 NA
- // 1791 NA
- // 1790 NA
- // 1789 NA
- // 1789 NA
- // 1788 NA
- // 1787 NA
- // 1786 NA
- 1785,
- // 1784 NA
- 1783,
- 1782,
- 1781,
- 1780,
- 1779,
- // 1778 NA
- // 1777 NA
- // 1776 NA
- // 1775 NA
- // 1774 NA
- // 1773 NA
- // 1772 NA
- // 1771 NA
- // 1770 NA
- // 1769 NA
- 1768,
- // 1767 NA
- // 1766 NA
- 1765,
- // 1764 NA
- 1763,
- // 1762 NA
- // 1761 NA
- // 1760 NA
- 1759,
- 1758,
- 1757,
- // 1756 NA
- 1755,
- 1754,
- 1753,
- 1752,
- 1751,
- // 1750 NA
- // 1749 NA
- 1748,
- // 1747 NA
- // 1746 NA
- // 1745 NA
- // 1744 NA
- // 1743 NA
- 1742,
- 1741,
- 1740,
- 1739,
- 1738,
- // 1737 NA
- // 1736 NA
- 1735,
- 1734,
- // 1733 NA
- 1732,
- // 1731 NA
- 1730,
- // 1729 NA
- 1728,
- // 1727 NA
- // 1726 NA
- // 1725 NA
- // 1724 NA
- 1723,
- // 1722 NA
- // 1721 NA
- // 1720 NA
- 1719,
- 1718,
- // 1717 NA
- 1716,
- 1715,
- 1714,
- // 1713 NA
- 1712,
- 1711,
- // 1710 NA
- // 1709 NA
- 1708,
- 1707,
- // 1706 NA
- // 1705 NA
- 1704,
- 1703,
- 1702,
- 1701,
- 1700,
- 1699,
- // 1698 NA
- 1697,
- 1696,
- 1695,
- // 1694 NA
- // 1693 NA
- 1692,
- 1691,
- // 1690 NA
- // 1689 NA
- // 1688 NA
- // 1687 NA
- 1686,
- 1685,
- // 1684 NA
- // 1683 NA
- 1682,
- 1681,
- // 1680 NA
- 1679,
- // 1678 NA
- // 1677 NA
- 1676,
- 1675,
- // 1674 NA
- 1673,
- // 1672 NA
- 1671,
- 1670,
- // 1669 NA
- // 1668 NA
- // 1667 NA
- // 1666 NA
- // 1665 NA
- 1664,
- 1663,
- // 1662 NA
- // 1661 NA
- 1660,
- // 1659 NA
- 1658,
- // 1657 NA
- 1656,
- // 1655 NA
- 1654,
- // 1653 NA
- 1652,
- // 1651 NA
- 1650,
- 1649,
- 1648,
- 1647,
- // 1646 NA
- 1645,
- // 1644 NA
- 1643,
- 1642,
- 1641,
- 1640,
- 1639,
- 1638,
- // 1637 NA
- // 1636 NA
- // 1635 NA
- 1634,
- // 1633 NA
- // 1632 NA
- // 1631 NA
- 1630,
- 1629,
- // 1628 NA
- // 1627 NA
- // 1626 NA
- // 1625 NA
- // 1624 NA
- // 1623 NA
- // 1622 NA
- // 1621 NA
- 1620,
- 1619,
- // 1618 NA
- // 1617 NA
- // 1616 NA
- // 1615 NA
- 1614,
- // 1613 NA
- // 1612 NA
- // 1611 NA
- // 1610 NA
- // 1609 NA
- 1608,
- 1607,
- 1606,
- 1605,
- 1604,
- 1603,
- // 1602 NA
- // 1601 NA
- // 1600 NA
- // 1599 NA
- // 1598 NA
- // 1597 NA
- 1596,
- // 1595 NA
- // 1594 NA
- // 1593 NA
- 1592,
- 1591,
- 1590,
- 1589,
- 1588,
- // 1587 NA
- 1586,
- 1585,
- // 1584 NA
- // 1583 NA
- 1582,
- 1581,
- 1580,
- // 1579 NA
- 1578,
- 1577,
- 1576,
- // 1575 NA
- 1574,
- // 1573 NA
- // 1572 NA
- 1571,
- 1570,
- 1569,
- 1568,
- 1567,
- // 1566 NA
- 1565,
- 1564,
- 1563,
- // 1562 NA
- // 1561 NA
- // 1560 NA
- 1559,
- 1558,
- 1557,
- // 1556 NA
- // 1555 NA
- 1554,
- 1553,
- 1552,
- 1551,
- 1550,
- 1549,
- 1548,
- 1547,
- 1546,
- // 1545 NA
- // 1544 NA
- // 1543 NA
- // 1542 NA
- // 1541 NA
- // 1540 NA
- // 1539 NA
- // 1538 NA
- // 1537 NA
- // 1536 NA
- 1535,
- // 1534 NA
- 1533,
- // 1532 NA
- // 1531 NA
- // 1530 NA
- // 1529 NA
- 1528,
- // 1527 NA
- // 1526 NA
- // 1525 NA
- // 1524 NA
- // 1523 NA
- // 1522 NA
- 1521,
- // 1520 NA
- // 1519 NA
- // 1518 NA
- // 1517 NA
- 1516,
- // 1515 NA
- // 1514 NA
- 1513,
- // 1512 NA
- 1511,
- // 1510 NA
- // 1509 NA
- // 1508 NA
- // 1507 NA
- // 1506 NA
- // 1505 NA
- // 1504 NA
- // 1503 NA
- // 1502 NA
- // 1501 NA
- 1500,
- 1499,
- // 1498 NA
- // 1497 NA
- // 1496 NA
- // 1495 NA
- 1494,
- // 1493 NA
- 1492,
- 1491,
- // 1490 NA
- // 1489 NA
- // 1488 NA
- // 1487 NA
- 1486,
- // 1485 NA
- // 1484 NA
- // 1483 NA
- // 1482 NA
- // 1481 NA
- 1480,
- 1479,
- 1478,
- 1477,
- // 1476 NA
- // 1475 NA
- // 1474 NA
- // 1473 NA
- // 1472 NA
- // 1471 NA
- // 1470 NA
- // 1469 NA
- 1468,
- // 1467 NA
- // 1466 NA
- // 1465 NA
- 1464,
- // 1463 NA
- // 1462 NA
- // 1461 NA
- // 1460 NA
- // 1459 NA
- // 1458 NA
- // 1457 NA
- // 1456 NA
- // 1455 NA
- // 1454 NA
- // 1453 NA
- // 1452 NA
- // 1451 NA
- // 1450 NA
- // 1449 NA
- // 1448 NA
- // 1447 NA
- // 1446 NA
- // 1445 NA
- // 1444 NA
- // 1443 NA
- // 1442 NA
- // 1441 NA
- // 1440 NA
- // 1439 NA
- // 1438 NA
- // 1437 NA
- // 1436 NA
- // 1435 NA
- // 1434 NA
- // 1433 NA
- // 1432 NA
- // 1431 NA
- // 1430 NA
- // 1429 NA
- // 1428 NA
- // 1427 NA
- // 1426 NA
- 1425,
- // 1424 NA
- // 1423 NA
- // 1422 NA
- // 1421 NA
- // 1420 NA
- // 1419 NA
- // 1418 NA
- // 1417 NA
- // 1416 NA
- // 1415 NA
- // 1414 NA
- // 1413 NA
- // 1412 NA
- // 1411 NA
- 1410,
- // 1409 NA
- // 1408 NA
- // 1407 NA
- 1406,
- 1405,
- // 1404 NA
- // 1403 NA
- // 1402 NA
- 1401,
- // 1400 NA
- // 1399 NA
- // 1398 NA
- 1397,
- 1396,
- // 1395 NA
- 1394,
- // 1393 NA
- // 1392 NA
- // 1391 NA
- // 1390 NA
- // 1389 NA
- 1388,
- // 1387 NA
- // 1386 NA
- // 1385 NA
- 1384,
- // 1383 NA
- // 1382 NA
- // 1381 NA
- // 1380 NA
- // 1379 NA
- // 1378 NA
- // 1377 NA
- // 1376 NA
- // 1375 NA
- // 1374 NA
- // 1373 NA
- // 1372 NA
- // 1371 NA
- // 1370 NA
- // 1369 NA
- // 1368 NA
- // 1367 NA
- 1366,
- 1365,
- // 1364 NA
- // 1363 NA
- // 1362 NA
- // 1361 NA
- // 1360 NA
- // 1359 NA
- // 1358 NA
- // 1357 NA
- // 1356 NA
- // 1355 NA
- // 1354 NA
- // 1353 NA
- 1352,
- // 1351 NA
- // 1350 NA
- // 1349 NA
- // 1348 NA
- 1347,
- 1346,
- // 1345 NA
- // 1344 NA
- // 1343 NA
- // 1342 NA
- // 1341 NA
- // 1340 NA
- // 1339 NA
- // 1338 NA
- // 1337 NA
- // 1336 NA
- // 1335 NA
- // 1334 NA
- // 1333 NA
- // 1332 NA
- // 1331 NA
- // 1330 NA
- // 1329 NA
- // 1328 NA
- // 1327 NA
- // 1326 NA
- // 1325 NA
- // 1324 NA
- // 1323 NA
- // 1322 NA
- // 1321 NA
- // 1320 NA
- // 1319 NA
- // 1318 NA
- // 1317 NA
- // 1316 NA
- // 1315 NA
- // 1314 NA
- // 1313 NA
- // 1312 NA
- // 1311 NA
- // 1310 NA
- 1309,
- // 1308 NA
- // 1307 NA
- // 1306 NA
- 1305,
- 1304,
- // 1303 NA
- // 1302 NA
- // 1301 NA
- // 1300 NA
- // 1299 NA
- // 1298 NA
- // 1297 NA
- 1296,
- // 1295 NA
- // 1294 NA
- // 1293 NA
- 1292,
- // 1291 NA
- // 1290 NA
- // 1289 NA
- // 1288 NA
- // 1287 NA
- // 1286 NA
- 1285,
- 1284,
- // 1283 NA
- 1282,
- 1281,
- // 1280 NA
- // 1279 NA
- // 1278 NA
- // 1277 NA
- 1276,
- // 1275 NA
- // 1274 NA
- // 1273 NA
- // 1272 NA
- 1271,
- // 1270 NA
- 1269,
- // 1268 NA
- 1267,
- 1266,
- // 1265 NA
- // 1264 NA
- // 1263 NA
- // 1262 NA
- // 1261 NA
- // 1260 NA
- 1259,
- // 1258 NA
- // 1257 NA
- // 1256 NA
- // 1255 NA
- // 1254 NA
- // 1253 NA
- // 1252 NA
- // 1251 NA
- // 1250 NA
- // 1249 NA
- // 1248 NA
- // 1247 NA
- // 1246 NA
- // 1245 NA
- // 1244 NA
- // 1243 NA
- // 1242 NA
- // 1241 NA
- // 1240 NA
- // 1239 NA
- // 1238 NA
- 1237,
- 1236,
- // 1235 NA
- // 1234 NA
- // 1233 NA
- // 1232 NA
- // 1231 NA
- // 1230 NA
- // 1229 NA
- 1228,
- // 1227 NA
- // 1226 NA
- // 1225 NA
- // 1224 NA
- 1223,
- // 1222 NA
- // 1221 NA
- // 1220 NA
- // 1219 NA
- // 1218 NA
- // 1217 NA
- // 1216 NA
- // 1215 NA
- // 1214 NA
- // 1213 NA
- // 1212 NA
- // 1211 NA
- // 1210 NA
- // 1209 NA
- // 1208 NA
- // 1207 NA
- // 1206 NA
- // 1205 NA
- // 1204 NA
- // 1203 NA
- // 1202 NA
- // 1201 NA
- // 1200 NA
- // 1199 NA
- // 1198 NA
- // 1197 NA
- // 1196 NA
- // 1195 NA
- // 1194 NA
- // 1193 NA
- // 1192 NA
- // 1191 NA
- // 1190 NA
- // 1189 NA
- // 1188 NA
- // 1187 NA
- // 1186 NA
- // 1185 NA
- // 1184 NA
- // 1183 NA
- // 1182 NA
- 1181,
- 1180,
- 1179,
- 1178,
- // 1177 NA
- // 1176 NA
- // 1175 NA
- // 1174 NA
- 1173,
- // 1172 NA
- // 1171 NA
- // 1170 NA
- // 1169 NA
- 1168,
- 1167,
- 1166,
- // 1165 NA
- 1164,
- 1163,
- // 1162 NA
- 1161,
- 1160,
- // 1159 NA
- // 1158 NA
- 1157,
- // 1156 NA
- // 1155 NA
- // 1154 NA
- 1153,
- // 1152 NA
- 1151,
- 1150,
- 1149,
- // 1148 NA
- 1147,
- // 1146 NA
- // 1145 NA
- 1144,
- 1143,
- 1142,
- 1141,
- 1140,
- // 1139 NA
- // 1138 NA
- 1137,
- 1136,
- // 1135 NA
- // 1134 NA
- // 1133 NA
- 1132,
- // 1131 NA
- // 1130 NA
- // 1129 NA
- // 1128 NA
- // 1127 NA
- 1126,
- // 1125 NA
- // 1124 NA
- 1123,
- // 1122 NA
- 1121,
- 1120,
- 1119,
- 1118,
- 1117,
- 1116,
- // 1115 NA
- 1114,
- 1113,
- 1112,
- 1111,
- 1110,
- // 1109 NA
- 1108,
- 1107,
- // 1106 NA
- 1105,
- // 1104 NA
- // 1103 NA
- 1102,
- 1101,
- // 1100 NA
- // 1099 NA
- // 1098 NA
- // 1097 NA
- 1096,
- // 1095 NA
- 1094,
- 1093,
- 1092,
- 1091,
- 1090,
- 1089,
- 1088,
- 1087,
- 1086,
- 1085,
- 1084,
- // 1083 NA
- // 1082 NA
- 1081,
- // 1080 NA
- // 1079 NA
- // 1078 NA
- // 1077 NA
- 1076,
- 1075,
- // 1074 NA
- // 1073 NA
- 1072,
- 1071,
- // 1070 NA
- // 1069 NA
- 1068,
- // 1067 NA
- // 1066 NA
- 1065,
- 1064,
- // 1063 NA
- // 1062 NA
- 1061,
- // 1060 NA
- 1059,
- // 1058 NA
- 1057,
- 1056,
- 1055,
- 1054,
- 1053,
- 1052,
- 1051,
- 1050,
- 1049,
- 1048,
- 1047,
- 1046,
- // 1045 NA
- // 1044 NA
- // 1043 NA
- 1042,
- 1041,
- // 1040 NA
- // 1039 NA
- // 1038 NA
- 1037,
- 1036,
- 1035,
- 1034,
- // 1033 NA
- 1032,
- // 1031 NA
- 1030,
- 1029,
- // 1028 NA
- 1027,
- // 1026 NA
- // 1025 NA
- // 1024 NA
- // 1023 NA
- // 1022 NA
- // 1021 NA
- // 1020 NA
- // 1019 NA
- 1018,
- 1017,
- // 1016 NA
- 1015,
- // 1014 NA
- 1013,
- // 1012 NA
- // 1011 NA
- // 1010 NA
- // 1009 NA
- // 1008 NA
- 1007,
- 1006,
- // 1005 NA
- // 1004 NA
- // 1003 NA
- // 1002 NA
- 1001,
- 1000,
- // 999 NA
- 998,
- // 997 NA
- // 996 NA
- // 995 NA
- // 994 NA
- // 993 NA
- // 992 NA
- 991,
- // 990 NA
- 989,
- // 988 NA
- // 987 NA
- // 986 NA
- // 985 NA
- 984,
- // 983 NA
- // 982 NA
- 981,
- 980,
- // 979 NA
- 978,
- 977,
- // 976 NA
- 975,
- 974,
- 973,
- 972,
- // 971 NA
- // 970 NA
- // 969 NA
- // 968 NA
- // 967 NA
- // 966 NA
- // 965 NA
- // 964 NA
- 963,
- // 962 NA
- 961,
- // 960 NA
- // 959 NA
- 958,
- 957,
- // 956 NA
- 955,
- // 954 NA
- 953,
- 952,
- 951,
- 950,
- 949,
- // 948 NA
- // 947 NA
- 946,
- 945,
- 944,
- // 943 NA
- 942,
- 941,
- // 940 NA
- 939,
- // 938 NA
- 937,
- 936,
- // 935 NA
- // 934 NA
- 933,
- 932,
- // 931 NA
- // 930 NA
- 929,
- // 928 NA
- // 927 NA
- 926,
- 925,
- // 924 NA
- // 923 NA
- 922,
- // 921 NA
- // 920 NA
- // 919 NA
- // 918 NA
- // 917 NA
- 916,
- 915,
- // 914 NA
- // 913 NA
- 912,
- // 911 NA
- // 910 NA
- // 909 NA
- // 908 NA
- // 907 NA
- // 906 NA
- // 905 NA
- // 904 NA
- 903,
- // 902 NA
- 901,
- // 900 NA
- // 899 NA
- 898,
- // 897 NA
- 896,
- 895,
- // 894 NA
- 893,
- // 892 NA
- 891,
- // 890 NA
- 889,
- 888,
- 887,
- // 886 NA
- 885,
- // 884 NA
- 883,
- 882,
- 881,
- // 880 NA
- 879,
- 878,
- 877,
- // 876 NA
- // 875 NA
- // 874 NA
- // 873 NA
- // 872 NA
- 871,
- 870,
- // 869 NA
- 868,
- // 867 NA
- // 866 NA
- // 865 NA
- // 864 NA
- // 863 NA
- // 862 NA
- // 861 NA
- // 860 NA
- 859,
- 858,
- 857,
- 856,
- // 855 NA
- // 854 NA
- 853,
- // 852 NA
- // 851 NA
- // 850 NA
- 849,
- 848,
- 847,
- // 846 NA
- 845,
- 844,
- 843,
- // 842 NA
- // 841 NA
- // 840 NA
- // 839 NA
- // 838 NA
- // 837 NA
- 836,
- 835,
- 834,
- 833,
- 832,
- 831,
- 830,
- // 829 NA
- 828,
- // 827 NA
- 826,
- 825,
- // 824 NA
- 823,
- 822,
- // 821 NA
- 820,
- 819,
- 818,
- 817,
- 816,
- 815,
- 814,
- 813,
- // 812 NA
- 811,
- 810,
- 809,
- // 808 NA
- 807,
- 806,
- 805,
- // 804 NA
- 803,
- 802,
- 801,
- 800,
- 799,
- 798,
- // 797 NA
- // 796 NA
- 795,
- // 794 NA
- 793,
- 792,
- 791,
- 790,
- 789,
- // 788 NA
- 787,
- 786,
- 785,
- 784,
- // 783 NA
- 782,
- 781,
- 780,
- 779,
- 778,
- // 777 NA
- 776,
- 775,
- 774,
- 773,
- // 772 NA
- 771,
- // 770 NA
- 769,
- 768,
- // 767 NA
- // 766 NA
- 765,
- 764,
- // 763 NA
- // 762 NA
- // 761 NA
- 760,
- // 759 NA
- 758,
- // 757 NA
- // 756 NA
- 755,
- 754,
- 753,
- // 752 NA
- // 751 NA
- // 750 NA
- 749,
- 748,
- 747,
- 746,
- 745,
- // 744 NA
- 743,
- 742,
- 741,
- 740,
- 739,
- // 738 NA
- 737,
- 736,
- // 735 NA
- 734,
- // 733 NA
- 732,
- // 731 NA
- // 730 NA
- 729,
- // 728 NA
- // 727 NA
- // 726 NA
- // 725 NA
- // 724 NA
- 723,
- 722,
- 721,
- // 720 NA
- 719,
- 718,
- 717,
- 716,
- 715,
- 714,
- 713,
- 712,
- 711,
+static const int included_patches[] = {
+ // 875,
+ // 874,
+ // 873,
+ // 872,
+ // 871,
+ // 870,
+ // 869,
+ // 868,
+ // 867,
+ // 866,
+ // 865,
+ // 864,
+ // 863,
+ // 862,
+ // 861,
+ // 860,
+ // 859,
+ // 858,
+ // 857,
+ // 856,
+ // 855,
+ // 854,
+ // 853,
+ // 852,
+ // 851,
+ // 850,
+ // 849,
+ // 848,
+ // 847,
+ // 846,
+ // 845,
+ // 844,
+ // 843,
+ // 842,
+ // 841,
+ // 840,
+ // 839,
+ // 838,
+ // 837,
+ // 836,
+ // 835,
+ // 834,
+ // 833,
+ // 832,
+ // 831,
+ // 830,
+ // 829,
+ // 828,
+ // 827,
+ // 826,
+ // 825,
+ // 824,
+ // 823,
+ // 822,
+ // 821,
+ // 820,
+ // 819,
+ // 818,
+ // 817,
+ // 816,
+ // 815,
+ // 814,
+ // 813,
+ // 812,
+ // 811,
+ // 810,
+ // 809,
+ // 808,
+ // 807,
+ // 806,
+ // 805,
+ // 804,
+ // 803,
+ // 802,
+ // 801,
+ // 800,
+ // 799,
+ // 798,
+ // 797,
+ // 796,
+ // 795,
+ // 794,
+ // 793,
+ // 792,
+ // 791,
+ // 790,
+ // 789,
+ // 788,
+ // 787,
+ // 786,
+ // 785,
+ // 784,
+ // 783,
+ // 782,
+ // 781,
+ // 780,
+ // 779,
+ // 778,
+ // 777,
+ // 776,
+ // 775,
+ // 774,
+ // 773,
+ // 772,
+ // 771,
+ // 770,
+ // 769,
+ // 768,
+ // 767,
+ // 766,
+ // 765,
+ // 764,
+ // 763,
+ // 762,
+ // 761,
+ // 760,
+ // 759,
+ // 758,
+ // 757,
+ // 756,
+ // 755,
+ // 754,
+ // 753,
+ // 752,
+ // 751,
+ // 750,
+ // 749,
+ // 748,
+ // 747,
+ // 746,
+ // 745,
+ // 744,
+ // 743,
+ // 742,
+ // 741,
+ // 740,
+ // 739,
+ // 738,
+ // 737,
+ // 736,
+ // 735,
+ // 734,
+ // 733,
+ // 732,
+ // 731,
+ // 730,
+ // 729,
+ // 728,
+ // 727,
+ // 726,
+ // 725,
+ // 724,
+ // 723,
+ // 722,
+ // 721,
+ // 720,
+ // 719,
+ // 718,
+ // 717,
+ // 716,
+ // 715,
+ // 714,
+ // 713,
+ // 712,
+ // 711,
710,
- 709,
- 708,
- 707,
- 706,
- // 705 NA
- 704,
- // 703 NA
- 702,
- // 701 NA
- 700,
- 699,
- 698,
- 697,
- 696,
- 695,
- 694,
- 693,
- // 692 NA
- // 691 NA
- 690,
- 689,
- 688,
- // 687 NA
- 686,
- 685,
- // 684 NA
- // 683 NA
- 682,
- // 681 NA
+ // 709,
+ // 708,
+ // 707,
+ // 706,
+ // 705,
+ // 704,
+ // 703,
+ // 702,
+ // 701,
+ // 700,
+ // 699,
+ // 698,
+ // 697,
+ // 696,
+ // 695,
+ // 694,
+ // 693,
+ // 692,
+ // 691,
+ // 690,
+ // 689,
+ // 688,
+ // 687,
+ // 686,
+ // 685,
+ // 684,
+ // 683,
+ // 682,
+ // 681,
680,
- // 679 NA
- // 678 NA
- // 677 NA
- // 676 NA
- 675,
- // 674 NA
- 673,
- 672,
- 671,
- 670,
- // 669 NA
- 668,
- 667,
- // 666 NA
- 665,
- // 664 NA
- // 663 NA
- 662,
- // 661 NA
- 660,
- 659,
- 658,
- // 657 NA
- 656,
- 655,
- 654,
- 653,
- // 652 NA
- 651,
- // 650 NA
- 649,
- // 648 NA
- // 647 NA
- 646,
- 645,
- // 644 NA
- 643,
- 642,
- // 641 NA
- 640,
- 639,
- // 638 NA
- 637,
- 636,
- 635,
- 634,
- 633,
- // 632 NA
- 631,
- 630,
- 629,
- // 628 NA
- // 627 NA
- // 626 NA
- // 625 NA
- // 624 NA
- 623,
- // 622 NA
- // 621 NA
- // 620 NA
- // 619 NA
- // 618 NA
- 617,
- 616,
- 615,
+ 679,
+ 678,
+ // 677,
+ // 676,
+ // 675,
+ // 674,
+ // 673,
+ // 672,
+ // 671,
+ // 670,
+ // 669,
+ // 668,
+ // 667,
+ // 666,
+ // 665,
+ // 664,
+ // 663,
+ // 662,
+ // 661,
+ // 660,
+ // 659,
+ // 658,
+ // 657,
+ // 656,
+ // 655,
+ // 654,
+ // 653,
+ 652,
+ // 651,
+ // 650,
+ // 649,
+ // 648,
+ // 647,
+ // 646,
+ // 645,
+ // 644,
+ // 643,
+ // 642,
+ // 641,
+ // 640,
+ // 639,
+ // 638,
+ // 637,
+ // 636,
+ // 635,
+ // 634,
+ // 633,
+ // 632,
+ // 631,
+ // 630,
+ // 629,
+ // 628,
+ // 627,
+ // 626,
+ // 625,
+ // 624,
+ // 623,
+ // 622,
+ // 621,
+ // 620,
+ // 619,
+ 618,
+ // 617,
+ // 616,
+ // 615,
614,
- 613,
+ // 613,
612,
- // 611 NA
- // 610 NA
- 609,
- 608,
- // 607 NA
- 606,
+ // 611,
+ // 610,
+ // 609,
+ // 608,
+ 607,
+ // 606,
605,
- 604,
- 603,
- 602,
- 601,
- 600,
- 599,
- 598,
- 597,
- // 596 NA
- 595,
- 594,
- 593,
- // 592 NA
- // 591 NA
- 590,
- // 589 NA
- 588,
- 587,
- // 586 NA
- 585,
- // 584 NA
- // 583 NA
- 582,
- // 581 NA
- 580,
- 579,
- 578,
- 577,
- 576,
- 575,
- 574,
- 573,
- 572,
- // 571 NA
- // 570 NA
- 569,
- 568,
- 567,
- 566,
- 565,
- // 564 NA
- 563,
- 562,
+ // 604,
+ // 603,
+ // 602,
+ // 601,
+ // 600,
+ // 599,
+ // 598,
+ // 597,
+ // 596,
+ // 595,
+ // 594,
+ // 593,
+ // 592,
+ // 591,
+ // 590,
+ // 589,
+ // 588,
+ // 587,
+ // 586,
+ // 585,
+ // 584,
+ // 583,
+ // 582,
+ // 581,
+ // 580,
+ // 579,
+ // 578,
+ // 577,
+ // 576,
+ // 575,
+ // 574,
+ // 573,
+ // 572,
+ 571,
+ // 570,
+ // 569,
+ // 568,
+ // 567,
+ // 566,
+ // 565,
+ // 564,
+ // 563,
+ // 562,
561,
- // 560 NA
- 559,
- // 558 NA
- // 557 NA
- // 556 NA
- // 555 NA
+ // 560,
+ // 559,
+ // 558,
+ // 557,
+ // 556,
+ 555,
554,
553,
552,
- 551,
+ // 551,
550,
- 549,
- // 548 NA
- 547,
- 546,
- 545,
- // 544 NA
- 543,
- 542,
- 541,
- // 540 NA
- 539,
- 538,
- 537,
- 536,
- 535,
- // 534 NA
- 533,
- 532,
- 531,
- 530,
- 529,
- 528,
- 527,
- 526,
- 525,
+ // 549,
+ // 548,
+ // 547,
+ // 546,
+ // 545,
+ // 544,
+ // 543,
+ // 542,
+ // 541,
+ // 540,
+ // 539,
+ // 538,
+ // 537,
+ // 536,
+ // 535,
+ // 534,
+ // 533,
+ // 532,
+ // 531,
+ // 530,
+ // 529,
+ // 528,
+ // 527,
+ // 526,
+ // 525,
524,
- // 523 NA
- // 522 NA
- 521,
- 520,
- 519,
+ // 523,
+ // 522,
+ // 521,
+ // 520,
+ // 519,
518,
- 517,
- 516,
- 515,
- 514,
- 513,
- // 512 NA
- // 511 NA
- // 510 NA
- // 509 NA
- 508,
- // 507 NA
- // 506 NA
- // 505 NA
- // 504 NA
- 503,
+ // 517,
+ // 516,
+ // 515,
+ // 514,
+ // 513,
+ // 512,
+ // 511,
+ // 510,
+ // 509,
+ // 508,
+ // 507,
+ // 506,
+ // 505,
+ // 504,
+ // 503,
502,
- // 501 NA
- 500,
+ // 501,
+ // 500,
499,
- // 498 NA
- 497,
- // 496 NA
- // 495 NA
- 494,
- 493,
- 492,
- 491,
- 490,
- 489,
- 488,
+ 498,
+ // 497,
+ // 496,
+ // 495,
+ // 494,
+ // 493,
+ // 492,
+ // 491,
+ // 490,
+ // 489,
+ // 488,
487,
486,
485,
- // 484 NA
+ // 484,
483,
- // 482 NA
- // 481 NA
- // 480 NA
- // 479 NA
+ 482,
+ // 481,
+ // 480,
+ // 479,
478,
477,
- // 476 NA
- // 475 NA
- 474,
- 473,
- 472,
- // 471 NA
- 470,
- // 469 NA
- 468,
- 467,
- 466,
- // 465 NA
- // 464 NA
- 463,
- 462,
- // 461 NA
- // 460 NA
- // 459 NA
- 458,
+ // 476,
+ // 475,
+ // 474,
+ // 473,
+ // 472,
+ // 471,
+ // 470,
+ // 469,
+ // 468,
+ // 467,
+ // 466,
+ 465,
+ // 464,
+ // 463,
+ // 462,
+ 461,
+ // 460,
+ 459,
+ // 458,
457,
- 456,
- 455,
- 454,
- // 453 NA
- 452,
- // 451 NA
- 450,
- 449,
- // 448 NA
- 447,
- 446,
- 445,
- 444,
- // 443 NA
- 442,
- 441,
- 440,
- 439,
- 438,
+ // 456,
+ // 455,
+ // 454,
+ 453,
+ // 452,
+ // 451,
+ // 450,
+ // 449,
+ // 448,
+ // 447,
+ // 446,
+ // 445,
+ // 444,
+ // 443,
+ // 442,
+ // 441,
+ // 440,
+ // 439,
+ // 438,
437,
- 436,
- 435,
- 434,
- 433,
- // 432 NA
- // 431 NA
- // 430 NA
- // 429 NA
- // 428 NA
- 427,
- // 426 NA
- 425,
- // 424 NA
- 423,
- 422,
- 421,
- // 420 NA
- 419,
- 418,
- 417,
- 416,
- 415,
- 414,
- // 413 NA
- // 412 NA
- 411,
- 410,
- // 409 NA
+ // 436,
+ // 435,
+ // 434,
+ // 433,
+ // 432,
+ // 431,
+ // 430,
+ // 429,
+ // 428,
+ // 427,
+ // 426,
+ // 425,
+ // 424,
+ // 423,
+ // 422,
+ // 421,
+ // 420,
+ // 419,
+ // 418,
+ // 417,
+ // 416,
+ // 415,
+ // 414,
+ // 413,
+ // 412,
+ // 411,
+ // 410,
+ // 409,
408,
407,
- 406,
- 405,
- // 404 NA
- // 403 NA
- // 402 NA
- // 401 NA
+ // 406,
+ // 405 NA
+ // 404,
+ // 403,
+ // 402,
+ // 401,
// 400 NA
- // 399 NA
- // 398 NA
- 397,
- 396,
- 395,
- // 394 NA
- // 393 NA
- 392,
- 391,
+ // 399,
+ // 398,
+ // 397,
+ // 396,
+ // 395,
+ 394,
+ 393,
+ // 392,
+ // 391,
390,
- 389,
+ // 389,
388,
- 387,
- 386,
- // 385 NA
- // 384 NA
- 383,
- 382,
- 381,
- // 380 NA
- 379,
+ // 387,
+ // 386,
+ // 385,
+ // 384,
+ // 383,
+ // 382,
+ // 381,
+ // 380,
+ // 379,
378,
377,
376,
- 375,
- 374,
- 373,
- 372,
- 371,
- 370,
- 369,
- 368,
- 367,
- // 366 NA
- 365,
- 364,
- // 363 NA
- 362,
- 361,
+ // 375,
+ // 374,
+ // 373,
+ // 372,
+ // 371,
+ // 370,
+ // 369,
+ // 368,
+ // 367,
+ // 366,
+ // 365,
+ // 364,
+ // 363,
+ // 362,
+ // 361,
360,
- 359,
- 358,
- 357,
- // 356 NA
- 355,
- // 354 NA
+ // 359,
+ // 358,
+ // 357,
+ // 356,
+ // 355,
+ // 354,
353,
- 352,
- 351,
- 350,
- 349,
- 348,
+ // 352,
+ // 351,
+ // 350,
+ // 349,
+ // 348,
347,
- 346,
+ // 346,
345,
- 344,
+ // 344,
343,
- // 342 NA
+ // 342,
341,
- // 340 NA
- 339,
- 338,
- 337,
- 336,
- 335,
- 334,
- // 333 NA
- // 332 NA
+ // 340,
+ // 339,
+ // 338,
+ // 337,
+ // 336,
+ // 335,
+ // 334,
+ // 333,
+ // 332,
331,
- 330,
- 329,
- 328,
- 327,
- // 326 NA
+ // 330,
+ // 329,
+ // 328,
+ // 327,
+ 326,
325,
- 324,
- 323,
- // 322 NA
- // 321 NA
- 320,
- // 319 NA
- 318,
- 317,
- // 316 NA
- 315,
- 314,
- 313,
- 312,
+ // 324,
+ // 323,
+ 322,
+ // 321,
+ // 320,
+ 319,
+ // 318,
+ // 317,
+ // 316,
+ // 315,
+ // 314,
+ // 313,
+ // 312,
311,
- 310,
- 309,
+ // 310,
+ // 309,
308,
- // 307 NA
- 306,
- 305,
- // 304 NA
- 303,
- 302,
- 301,
- // 300 NA
- // 299 NA
- 298,
+ 307,
+ // 306,
+ // 305,
+ // 304,
+ // 303,
+ // 302,
+ // 301,
+ // 300,
+ // 299,
+ // 298,
297,
- 296,
- 295,
- 294,
- 293,
- 292,
- 291,
+ // 296,
+ // 295,
+ // 294,
+ // 293,
+ // 292,
+ // 291,
290,
- 289,
- 288,
- // 287 NA
- 286,
- 285,
- 284,
- // 283 NA
- 282,
- 281,
+ // 289,
+ // 288 NA
+ // 287,
+ // 286,
+ // 285 NA
+ // 284 NA
+ // 283,
+ // 282,
+ // 281 NA
280,
- 279,
- 278,
- 277,
- 276,
+ // 279 NA
+ // 278 NA
+ // 277 NA
+ // 276 NA
275,
274,
// 273 NA
- 272,
+ // 272 NA
// 271 NA
// 270 NA
- 269,
- 268,
- 267,
+ // 269 NA
+ // 268 NA
+ // 267 NA
266,
- 265,
- 264,
- // 263 NA
- 262,
- 261,
- 260,
- // 259 NA
- // 258 NA
+ // 265,
+ // 264,
+ // 263,
+ // 262,
+ // 261,
+ // 260 NA
+ 259,
+ // 258,
// 257 NA
- 256,
- // 255 NA
- // 254 NA
- 253,
- // 252 NA
- 251,
- // 250 NA
- 249,
- 248,
+ // 256,
+ // 255,
+ // 254,
+ // 253,
+ // 252,
+ // 251,
+ 250,
+ // 249 NA
+ // 248,
247,
// 246 NA
- 245,
- // 244 NA
+ // 245,
+ // 244,
243,
- 242,
- 241,
- 240,
- 239,
- // 238 NA
- 237,
- 236,
+ // 242,
+ // 241 NA
+ // 240 NA
+ // 239 NA
+ // 238,
+ // 237,
+ // 236,
235,
- 234,
- 233,
- 232,
- 231,
- 230,
+ // 234,
+ // 233,
+ // 232 NA
+ // 231,
+ // 230,
229,
- // 228 NA
- // 227 NA
- 226,
- // 225 NA
- // 224 NA
- // 223 NA
- // 222 NA
- 221,
- 220,
+ // 228,
+ // 227,
+ // 226,
+ // 225,
+ // 224,
+ 223,
+ // 222,
+ // 221 NA
+ // 220,
219,
- 218,
+ // 218,
// 217 NA
- // 216 NA
- 215,
- // 214 NA
- 213,
- // 212 NA
- 211,
- 210,
+ // 216,
+ // 215,
+ // 214,
+ // 213 NA
+ // 212,
+ // 211 NA
+ // 210,
209,
- // 208 NA
- 207,
- // 206 NA
+ 208,
+ // 207,
+ // 206,
205,
- 204,
- 203,
- // 202 NA
- 201,
- // 200 NA
- 199,
- // 198 NA
- // 197 NA
- // 196 NA
- // 195 NA
- // 194 NA
- 193,
- 192,
- 191,
- // 190 NA
- // 189 NA
- // 188 NA
- 187,
- 186,
- // 185 NA
- 184,
- // 183 NA
- // 182 NA
- 181,
- // 180 NA
- // 179 NA
+ // 204,
+ // 203 NA
+ // 202,
+ // 201,
+ // 200,
+ // 199 NA
+ // 198,
+ // 197,
+ // 196,
+ 195,
+ // 194,
+ // 193 NA
+ // 192 NA
+ // 191 NA
+ 190,
+ // 189,
+ // 188,
+ // 187 NA
+ // 186,
+ // 185,
+ // 184,
+ // 183,
+ // 182,
+ // 181,
+ // 180,
+ 179,
178,
- // 177 NA
- // 176 NA
- // 175 NA
- // 174 NA
- 173,
+ 177,
+ 176,
+ // 175,
+ 174,
+ // 173 NA
172,
- 171,
- 170,
- 169,
- // 168 NA
+ // 171,
+ // 170,
+ // 169,
+ 168,
167,
- 166,
+ // 166,
165,
- // 164 NA
+ // 164,
// 163 NA
// 162 NA
// 161 NA
- 160,
+ // 160,
159,
158,
- 157,
+ // 157,
156,
- 155,
- 154,
- 153,
- 152,
- 151,
+ // 155,
+ // 154,
+ // 153,
+ // 152 NA
+ // 151,
150,
149,
- 148,
+ // 148,
147,
146,
- 145,
- 144,
+ // 145 NA
+ // 144 NA
143,
- 142,
- 141,
- 140,
- 139,
- 138,
+ // 142,
+ // 141,
+ // 140,
+ // 139 NA
+ // 138 NA
137,
136,
135,
134,
133,
- 132,
- 131,
- 130,
- 129,
+ // 132,
+ // 131,
+ // 130 NA
+ // 129 NA
128,
127,
126,
125,
124,
- 123,
- 122,
+ // 123 NA
+ // 122 NA
121,
- 120,
+ // 120 NA
119,
- 118,
- 117,
+ // 118,
+ // 117 NA
116,
- 115,
- 114,
- 113,
- 112,
+ // 115 NA
+ // 114 NA
+ // 113 NA
+ // 112,
111,
110,
- 109,
- 108,
- 107,
- 106,
- 105,
- 104,
- 103,
- 102,
- 101,
+ // 109 NA
+ // 108 NA
+ // 107 NA
+ // 106,
+ // 105 NA
+ // 104,
+ // 103 NA
+ // 102,
+ // 101,
100,
99,
- 98,
- 97,
- 96,
- 95,
- 94,
- 93,
+ // 98 NA
+ // 97 NA
+ // 96,
+ // 95 NA
+ // 94 NA
+ // 93 NA
92,
- 91,
+ // 91,
90,
- 89,
+ // 89 NA
88,
- 87,
+ // 87 NA
86,
85,
84,
83,
- 82,
+ // 82 NA
81,
- 80,
+ // 80 NA
79,
78,
- 77,
- 76,
+ // 77 NA
+ // 76 NA
75,
- 74,
+ // 74,
73,
- 72,
- 71,
- 70,
+ // 72 NA
+ // 71 NA
+ // 70 NA
69,
68,
- 67,
+ // 67 NA
66,
- 65,
+ // 65 NA
64,
- 63,
+ // 63 NA
62,
- 61,
+ // 61 NA
60,
- 59,
+ // 59 NA
58,
57,
56,
- 55,
- 54,
+ // 55 NA
+ // 54 NA
53,
52,
- 51,
- 50,
+ // 51 NA
+ // 50 NA
49,
- 48,
+ // 48 NA
47,
46,
- 45,
+ // 45 NA
44,
43,
42,
41,
40,
- 39,
+ // 39 NA
38,
37,
- 36,
+ // 36 NA
35,
34,
33,
32,
31,
- 30,
- 29,
- 28,
- 27,
+ // 30 NA
+ // 29 NA
+ // 28 NA
+ // 27 NA
26,
25,
- 24,
+ // 24 NA
23,
- 22,
- 21,
+ // 22 NA
+ // 21,
20,
19,
- 18,
+ // 18,
17,
- 16,
- 15,
- 14,
- 13,
+ // 16 NA
+ // 15 NA
+ // 14 NA
+ // 13 NA
12,
- 11,
- 10,
- 9,
+ // 11 NA
+ // 10 NA
+ // 9 NA
8,
- 7,
+ // 7 NA
6,
- 5,
+ // 5 NA
4,
3,
2,
@@ -2460,10 +971,10 @@ static char *(extra_patches[]) = {
/// @param version Version string like "1.3.42"
///
/// @return true if Nvim is at or above the version.
-bool has_nvim_version(char *version_str)
- FUNC_ATTR_NONNULL_ALL
+bool has_nvim_version(const char *const version_str)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- char *p = version_str;
+ const char *p = version_str;
int major = 0;
int minor = 0;
int patch = 0;
@@ -2472,7 +983,7 @@ bool has_nvim_version(char *version_str)
return false;
}
major = atoi(p);
- p = strchr(p, '.'); // Find the next dot.
+ p = strchr(p, '.'); // Find the next dot.
if (p) {
p++; // Advance past the dot.
@@ -2480,7 +991,7 @@ bool has_nvim_version(char *version_str)
return false;
}
minor = atoi(p);
- p = strchr(p, '.');
+ p = strchr(p, '.');
if (p) {
p++;
if (!ascii_isdigit(*p)) {
@@ -2572,19 +1083,13 @@ static void list_features(void)
int idx = (i / ncol) + (i % ncol) * nrow;
if (idx < nfeat) {
int last_col = (i + 1) % ncol == 0;
- msg_puts((char_u *)features[idx]);
+ msg_puts(features[idx]);
if (last_col) {
if (msg_col > 0) {
msg_putchar('\n');
}
} else {
- while (msg_col % width) {
- int old_msg_col = msg_col;
- msg_putchar(' ');
- if (old_msg_col == msg_col) {
- break; // XXX: Avoid infinite loop.
- }
- }
+ msg_putchar(' ');
}
} else {
if (msg_col > 0) {
@@ -2592,7 +1097,7 @@ static void list_features(void)
}
}
}
- MSG_PUTS("For differences from Vim, see :help vim-differences\n\n");
+ MSG_PUTS("See \":help feature-compile\"\n\n");
}
void list_version(void)
@@ -2633,7 +1138,7 @@ void list_version(void)
}
#endif // ifdef HAVE_PATHDEF
- version_msg(_("\n\nOptional features included (+) or not (-): "));
+ version_msg(_("\n\nFeatures: "));
list_features();
@@ -2705,7 +1210,6 @@ void intro_message(int colon)
static char *(lines[]) = {
N_(NVIM_VERSION_LONG),
"",
- N_("by Bram Moolenaar et al."),
N_("Nvim is open source and freely distributable"),
N_("https://neovim.io/community"),
"",
diff --git a/src/nvim/version.h b/src/nvim/version.h
index 1de809e539..c10f6fa534 100644
--- a/src/nvim/version.h
+++ b/src/nvim/version.h
@@ -1,6 +1,8 @@
#ifndef NVIM_VERSION_H
#define NVIM_VERSION_H
+#include "nvim/ex_cmds_defs.h"
+
// defined in version.c
extern char* Version;
extern char* longVersion;
@@ -8,14 +10,14 @@ extern char* longVersion;
//
// Vim version number, name, etc. Patchlevel is defined in version.c.
//
-#define VIM_VERSION_MAJOR 7
-#define VIM_VERSION_MINOR 4
+#define VIM_VERSION_MAJOR 8
+#define VIM_VERSION_MINOR 0
#define VIM_VERSION_100 (VIM_VERSION_MAJOR * 100 + VIM_VERSION_MINOR)
// used for the runtime directory name
-#define VIM_VERSION_NODOT "vim74"
+#define VIM_VERSION_NODOT "vim80"
// swap file compatibility (max. length is 6 chars)
-#define VIM_VERSION_SHORT "7.4"
+#define VIM_VERSION_SHORT "8.0"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "version.h.generated.h"
diff --git a/src/nvim/vim.h b/src/nvim/vim.h
index 8271abda8d..62ffc7433e 100644
--- a/src/nvim/vim.h
+++ b/src/nvim/vim.h
@@ -11,26 +11,22 @@
#define RUNTIME_DIRNAME "runtime"
/* end */
-/* ============ the header file puzzle (ca. 50-100 pieces) ========= */
-
-#ifdef HAVE_CONFIG_H /* GNU autoconf (or something else) was here */
-# include "auto/config.h"
-# define HAVE_PATHDEF
+#include "auto/config.h"
+#define HAVE_PATHDEF
/*
* Check if configure correctly managed to find sizeof(int). If this failed,
* it becomes zero. This is likely a problem of not being able to run the
* test program. Other items from configure may also be wrong then!
*/
-# if (SIZEOF_INT == 0)
-Error: configure did not run properly.Check auto/config.log.
-# endif
+#if (SIZEOF_INT == 0)
+# error Configure did not run properly.
#endif
#include "nvim/os/os_defs.h" /* bring lots of system header files */
/// length of a buffer to store a number in ASCII (64 bits binary + NUL)
-#define NUMBUFLEN 65
+enum { NUMBUFLEN = 65 };
// flags for vim_str2nr()
#define STR2NR_BIN 1
@@ -46,27 +42,7 @@ Error: configure did not run properly.Check auto/config.log.
#include "nvim/keymap.h"
#include "nvim/macros.h"
-
-
-
-/* ================ end of the header file puzzle =============== */
-
-#ifdef HAVE_WORKING_LIBINTL
-# include <libintl.h>
-# define _(x) gettext((char *)(x))
-// XXX do we actually need this?
-# ifdef gettext_noop
-# define N_(x) gettext_noop(x)
-# else
-# define N_(x) x
-# endif
-#else
-# define _(x) ((char *)(x))
-# define N_(x) x
-# define bindtextdomain(x, y) /* empty */
-# define bind_textdomain_codeset(x, y) /* empty */
-# define textdomain(x) /* empty */
-#endif
+#include "nvim/gettext.h"
/* special attribute addition: Put message in history */
#define MSG_HIST 0x1000
@@ -109,11 +85,14 @@ Error: configure did not run properly.Check auto/config.log.
// all mode bits used for mapping
#define MAP_ALL_MODES (0x3f | SELECTMODE | TERM_FOCUS)
-/* directions */
-#define FORWARD 1
-#define BACKWARD (-1)
-#define FORWARD_FILE 3
-#define BACKWARD_FILE (-3)
+/// Directions.
+typedef enum {
+ kDirectionNotSet = 0,
+ FORWARD = 1,
+ BACKWARD = (-1),
+ FORWARD_FILE = 3,
+ BACKWARD_FILE = (-3),
+} Direction;
/* return values for functions */
#if !(defined(OK) && (OK == 1))
@@ -184,6 +163,7 @@ enum {
EXPAND_SYNTIME,
EXPAND_USER_ADDR_TYPE,
EXPAND_PACKADD,
+ EXPAND_MESSAGES,
};
@@ -225,6 +205,8 @@ enum {
#define DIALOG_MSG_SIZE 1000 /* buffer size for dialog_msg() */
+enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext()
+
/*
* Maximum length of key sequence to be mapped.
* Must be able to hold an Amiga resize report.
@@ -269,6 +251,7 @@ enum {
#define STRCAT(d, s) strcat((char *)(d), (char *)(s))
#define STRNCAT(d, s, n) strncat((char *)(d), (char *)(s), (size_t)(n))
+#define STRLCAT(d, s, n) xstrlcat((char *)(d), (char *)(s), (size_t)(n))
# define vim_strpbrk(s, cs) (char_u *)strpbrk((char *)(s), (char *)(cs))
@@ -281,15 +264,22 @@ enum {
#define SHOWCMD_COLS 10 /* columns needed by shown command */
#define STL_MAX_ITEM 80 /* max nr of %<flag> in statusline */
-/*
- * fnamecmp() is used to compare file names.
- * On some systems case in a file name does not matter, on others it does.
- * (this does not account for maximum name lengths and things like "../dir",
- * thus it is not 100% accurate!)
- */
-#define fnamecmp(x, y) vim_fnamecmp((char_u *)(x), (char_u *)(y))
-#define fnamencmp(x, y, n) vim_fnamencmp((char_u *)(x), (char_u *)(y), \
- (size_t)(n))
+/// Compare file names
+///
+/// On some systems case in a file name does not matter, on others it does.
+///
+/// @note Does not account for maximum name lengths and things like "../dir",
+/// thus it is not 100% accurate. OS may also use different algorythm for
+/// case-insensitive comparison.
+///
+/// @param[in] x First file name to compare.
+/// @param[in] y Second file name to compare.
+///
+/// @return 0 for equal file names, non-zero otherwise.
+#define fnamecmp(x, y) path_fnamecmp((const char *)(x), (const char *)(y))
+#define fnamencmp(x, y, n) path_fnamencmp((const char *)(x), \
+ (const char *)(y), \
+ (size_t)(n))
/*
* Enums need a typecast to be used as array index (for Ultrix).
@@ -324,8 +314,14 @@ enum {
#define DIP_START 0x08 // also use "start" directory in 'packpath'
#define DIP_OPT 0x10 // also use "opt" directory in 'packpath'
#define DIP_NORTP 0x20 // do not use 'runtimepath'
+#define DIP_NOAFTER 0x40 // skip "after" directories
+#define DIP_AFTER 0x80 // only use "after" directories
// Lowest number used for window ID. Cannot have this many windows per tab.
#define LOWEST_WIN_ID 1000
+#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && defined(S_ISCHR)
+# define OPEN_CHR_FILES
+#endif
+
#endif /* NVIM_VIM_H */
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 00229ccca9..c2d0a9b3b1 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
@@ -45,6 +48,7 @@
#include "nvim/syntax.h"
#include "nvim/terminal.h"
#include "nvim/undo.h"
+#include "nvim/ui.h"
#include "nvim/os/os.h"
@@ -129,9 +133,10 @@ newwindow:
vim_snprintf(cbuf, sizeof(cbuf) - 5, "%" PRId64, (int64_t)Prenum);
else
cbuf[0] = NUL;
- if (nchar == 'v' || nchar == Ctrl_V)
- strcat(cbuf, "v");
- strcat(cbuf, "new");
+ if (nchar == 'v' || nchar == Ctrl_V) {
+ xstrlcat(cbuf, "v", sizeof(cbuf));
+ }
+ xstrlcat(cbuf, "new", sizeof(cbuf));
do_cmdline_cmd(cbuf);
break;
@@ -160,13 +165,18 @@ newwindow:
/* cursor to preview window */
case 'P':
- for (wp = firstwin; wp != NULL; wp = wp->w_next)
- if (wp->w_p_pvw)
+ wp = NULL;
+ FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) {
+ if (wp2->w_p_pvw) {
+ wp = wp2;
break;
- if (wp == NULL)
+ }
+ }
+ if (wp == NULL) {
EMSG(_("E441: There is no preview window"));
- else
+ } else {
win_goto(wp);
+ }
break;
/* close all but current window */
@@ -183,7 +193,7 @@ newwindow:
/* cursor to previous window with wrap around */
case 'W':
CHECK_CMDWIN
- if (firstwin == lastwin && Prenum != 1) /* just one window */
+ if (ONE_WINDOW && Prenum != 1) /* just one window */
beep_flush();
else {
if (Prenum) { /* go to specified window */
@@ -441,13 +451,12 @@ wingotofile:
case 'g':
case Ctrl_G:
CHECK_CMDWIN
- ++ no_mapping;
- ++allow_keys; /* no mapping for xchar, but allow key codes */
- if (xchar == NUL)
+ no_mapping++;
+ if (xchar == NUL) {
xchar = plain_vgetc();
- LANGMAP_ADJUST(xchar, TRUE);
- --no_mapping;
- --allow_keys;
+ }
+ LANGMAP_ADJUST(xchar, true);
+ no_mapping--;
(void)add_to_showcmd(xchar);
switch (xchar) {
case '}':
@@ -565,7 +574,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
oldwin = curwin;
/* add a status line when p_ls == 1 and splitting the first window */
- if (lastwin == firstwin && p_ls == 1 && oldwin->w_status_height == 0) {
+ if (ONE_WINDOW && p_ls == 1 && oldwin->w_status_height == 0) {
if (oldwin->w_height <= p_wmh && new_wp == NULL) {
EMSG(_(e_noroom));
return FAIL;
@@ -973,11 +982,12 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
/*
* make the new window the current window
*/
- win_enter(wp, false);
- if (flags & WSP_VERT)
+ win_enter_ext(wp, false, false, true, true, true);
+ if (flags & WSP_VERT) {
p_wiw = i;
- else
+ } else {
p_wh = i;
+ }
return OK;
}
@@ -1033,7 +1043,7 @@ static void win_init(win_T *newp, win_T *oldp, int flags)
win_init_some(newp, oldp);
- check_colorcolumn(newp);
+ didset_window_options(newp);
}
/*
@@ -1172,7 +1182,7 @@ static void win_exchange(long Prenum)
win_T *wp2;
int temp;
- if (lastwin == firstwin) { /* just one window */
+ if (ONE_WINDOW) { /* just one window */
beep_flush();
return;
}
@@ -1261,7 +1271,7 @@ static void win_rotate(int upwards, int count)
frame_T *frp;
int n;
- if (firstwin == lastwin) { /* nothing to do */
+ if (ONE_WINDOW) { /* nothing to do */
beep_flush();
return;
}
@@ -1333,7 +1343,7 @@ static void win_totop(int size, int flags)
int dir;
int height = curwin->w_height;
- if (lastwin == firstwin) {
+ if (ONE_WINDOW) {
beep_flush();
return;
}
@@ -1707,25 +1717,24 @@ static void win_equal_rec(
}
}
-/*
- * close all windows for buffer 'buf'
- */
-void
-close_windows (
- buf_T *buf,
- int keep_curwin /* don't close "curwin" */
-)
+/// Closes all windows for buffer `buf`.
+///
+/// @param keep_curwin don't close `curwin`
+void close_windows(buf_T *buf, int keep_curwin)
{
tabpage_T *tp, *nexttp;
int h = tabline_height();
+ int count = tabpage_index(NULL);
++RedrawingDisabled;
- for (win_T *wp = firstwin; wp != NULL && lastwin != firstwin; ) {
+ for (win_T *wp = firstwin; wp != NULL && !ONE_WINDOW; ) {
if (wp->w_buffer == buf && (!keep_curwin || wp != curwin)
- && !(wp->w_closing || wp->w_buffer->b_closing)
- ) {
- win_close(wp, FALSE);
+ && !(wp->w_closing || wp->w_buffer->b_locked > 0)) {
+ if (win_close(wp, false) == FAIL) {
+ // If closing the window fails give up, to avoid looping forever.
+ break;
+ }
/* Start all over, autocommands may change the window layout. */
wp = firstwin;
@@ -1739,9 +1748,8 @@ close_windows (
if (tp != curtab) {
FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
if (wp->w_buffer == buf
- && !(wp->w_closing || wp->w_buffer->b_closing)
- ) {
- win_close_othertab(wp, FALSE, tp);
+ && !(wp->w_closing || wp->w_buffer->b_locked > 0)) {
+ win_close_othertab(wp, false, tp);
/* Start all over, the tab page may be closed and
* autocommands may change the window layout. */
@@ -1754,9 +1762,14 @@ close_windows (
--RedrawingDisabled;
- redraw_tabline = TRUE;
- if (h != tabline_height())
+ if (count != tabpage_index(NULL)) {
+ apply_autocmds(EVENT_TABCLOSED, NULL, NULL, false, curbuf);
+ }
+
+ redraw_tabline = true;
+ if (h != tabline_height()) {
shell_new_rows();
+ }
}
/// Check that current window is the last one.
@@ -1797,7 +1810,7 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf,
tabpage_T *prev_curtab)
FUNC_ATTR_NONNULL_ARG(1)
{
- if (firstwin != lastwin) {
+ if (!ONE_WINDOW) {
return false;
}
buf_T *old_curbuf = curbuf;
@@ -1865,14 +1878,17 @@ int win_close(win_T *win, int free_buf)
int dir;
int help_window = FALSE;
tabpage_T *prev_curtab = curtab;
+ frame_T *win_frame = win->w_frame->fr_parent;
if (last_window()) {
EMSG(_("E444: Cannot close last window"));
return FAIL;
}
- if (win->w_closing || (win->w_buffer != NULL && win->w_buffer->b_closing))
- return FAIL; /* window is already being closed */
+ if (win->w_closing
+ || (win->w_buffer != NULL && win->w_buffer->b_locked > 0)) {
+ return FAIL; // window is already being closed
+ }
if (win == aucmd_win) {
EMSG(_("E813: Cannot close autocmd window"));
return FAIL;
@@ -1937,6 +1953,8 @@ int win_close(win_T *win, int free_buf)
* Close the link to the buffer.
*/
if (win->w_buffer != NULL) {
+ bufref_T bufref;
+ set_bufref(&bufref, curbuf);
win->w_closing = true;
close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, true);
if (win_valid_any_tab(win)) {
@@ -1945,7 +1963,7 @@ int win_close(win_T *win, int free_buf)
// Make sure curbuf is valid. It can become invalid if 'bufhidden' is
// "wipe".
- if (!buf_valid(curbuf)) {
+ if (!bufref_valid(&bufref)) {
curbuf = firstbuf;
}
}
@@ -2004,20 +2022,25 @@ int win_close(win_T *win, int free_buf)
}
curbuf = curwin->w_buffer;
close_curwin = TRUE;
+
+ // The cursor position may be invalid if the buffer changed after last
+ // using the window.
+ check_cursor();
}
- if (p_ea
- && (*p_ead == 'b' || *p_ead == dir)
- ) {
- win_equal(curwin, true, dir);
+ if (p_ea && (*p_ead == 'b' || *p_ead == dir)) {
+ // If the frame of the closed window contains the new current window,
+ // only resize that frame. Otherwise resize all windows.
+ win_equal(curwin, curwin->w_frame->fr_parent == win_frame, dir);
} else {
win_comp_pos();
}
if (close_curwin) {
- win_enter_ext(wp, false, TRUE, TRUE, TRUE);
- if (other_buffer)
- /* careful: after this wp and win may be invalid! */
- apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
+ win_enter_ext(wp, false, true, false, true, true);
+ if (other_buffer) {
+ // careful: after this wp and win may be invalid!
+ apply_autocmds(EVENT_BUFENTER, NULL, NULL, false, curbuf);
+ }
}
/*
@@ -2050,7 +2073,8 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
// Get here with win->w_buffer == NULL when win_close() detects the tab page
// changed.
- if (win->w_closing || (win->w_buffer != NULL && win->w_buffer->b_closing)) {
+ if (win->w_closing
+ || (win->w_buffer != NULL && win->w_buffer->b_locked > 0)) {
return; // window is already being closed
}
@@ -2173,7 +2197,7 @@ winframe_remove (
/*
* If there is only one window there is nothing to remove.
*/
- if (tp == NULL ? firstwin == lastwin : tp->tp_firstwin == tp->tp_lastwin)
+ if (tp == NULL ? ONE_WINDOW : tp->tp_firstwin == tp->tp_lastwin)
return NULL;
/*
@@ -2310,7 +2334,7 @@ win_altframe (
frame_T *frp;
int b;
- if (tp == NULL ? firstwin == lastwin : tp->tp_firstwin == tp->tp_lastwin)
+ if (tp == NULL ? ONE_WINDOW : 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;
@@ -2830,7 +2854,7 @@ close_others (
win_close(wp, !P_HID(wp->w_buffer) && !bufIsChanged(wp->w_buffer));
}
- if (message && lastwin != firstwin)
+ if (message && !ONE_WINDOW)
EMSG(_("E445: Other window contains changes"));
}
@@ -2966,8 +2990,8 @@ static tabpage_T *alloc_tabpage(void)
tp->handle = ++last_tp_handle;
handle_register_tabpage(tp);
- /* init t: variables */
- tp->tp_vars = dict_alloc();
+ // Init t: variables.
+ tp->tp_vars = tv_dict_alloc();
init_var_dict(tp->tp_vars, &tp->tp_winvar, VAR_SCOPE);
tp->tp_diff_invalid = TRUE;
tp->tp_ch_used = p_ch;
@@ -2987,8 +3011,7 @@ void free_tabpage(tabpage_T *tp)
hash_init(&tp->tp_vars->dv_hashtab);
unref_var_dict(tp->tp_vars);
-
- xfree(tp->localdir); // Free tab-local working directory
+ xfree(tp->tp_localdir);
xfree(tp);
}
@@ -3014,7 +3037,7 @@ int win_new_tabpage(int after, char_u *filename)
return FAIL;
}
- newtp->localdir = tp->localdir ? vim_strsave(tp->localdir) : NULL;
+ newtp->tp_localdir = tp->tp_localdir ? vim_strsave(tp->tp_localdir) : NULL;
curtab = newtp;
@@ -3045,8 +3068,9 @@ int win_new_tabpage(int after, char_u *filename)
redraw_all_later(CLEAR);
- apply_autocmds(EVENT_TABNEW, filename, filename, false, curbuf);
+ apply_autocmds(EVENT_WINNEW, NULL, NULL, false, curbuf);
apply_autocmds(EVENT_WINENTER, NULL, NULL, false, curbuf);
+ apply_autocmds(EVENT_TABNEW, filename, filename, false, curbuf);
apply_autocmds(EVENT_TABENTER, NULL, NULL, false, curbuf);
return OK;
@@ -3118,6 +3142,45 @@ bool valid_tabpage(tabpage_T *tpc) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
return false;
}
+/// Returns true when `tpc` is valid and at least one window is valid.
+int valid_tabpage_win(tabpage_T *tpc)
+{
+ FOR_ALL_TABS(tp) {
+ if (tp == tpc) {
+ FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
+ if (win_valid_any_tab(wp)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+ // shouldn't happen
+ return false;
+}
+
+/// Close tabpage `tab`, assuming it has no windows in it.
+/// There must be another tabpage or this will crash.
+void close_tabpage(tabpage_T *tab)
+{
+ tabpage_T *ptp;
+
+ if (tab == first_tabpage) {
+ first_tabpage = tab->tp_next;
+ ptp = first_tabpage;
+ } else {
+ for (ptp = first_tabpage; ptp != NULL && ptp->tp_next != tab;
+ ptp = ptp->tp_next) {
+ // do nothing
+ }
+ assert(ptp != NULL);
+ ptp->tp_next = tab->tp_next;
+ }
+
+ goto_tabpage_tp(ptp, false, false);
+ free_tabpage(tab);
+}
+
/*
* Find tab page "n" (first one is 1). Returns NULL when not found.
*/
@@ -3204,8 +3267,8 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, int trigger_enter_au
/* We would like doing the TabEnter event first, but we don't have a
* valid current window yet, which may break some commands.
* This triggers autocommands, thus may make "tp" invalid. */
- win_enter_ext(tp->tp_curwin, false, TRUE,
- trigger_enter_autocmds, trigger_leave_autocmds);
+ win_enter_ext(tp->tp_curwin, false, true, false,
+ trigger_enter_autocmds, trigger_leave_autocmds);
prevwin = next_prevwin;
last_status(FALSE); /* status line may appear or disappear */
@@ -3350,15 +3413,20 @@ void tabpage_move(int nr)
tp_dst = tp;
- /* Remove the current tab page from the list of tab pages. */
- if (curtab == first_tabpage)
+ // Remove the current tab page from the list of tab pages.
+ if (curtab == first_tabpage) {
first_tabpage = curtab->tp_next;
- else {
- for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
- if (tp->tp_next == curtab)
+ } else {
+ tp = NULL;
+ FOR_ALL_TABS(tp2) {
+ if (tp2->tp_next == curtab) {
+ tp = tp2;
break;
- if (tp == NULL) /* "cannot happen" */
+ }
+ }
+ if (tp == NULL) { // "cannot happen"
return;
+ }
tp->tp_next = curtab->tp_next;
}
@@ -3546,7 +3614,7 @@ end:
*/
void win_enter(win_T *wp, bool undo_sync)
{
- win_enter_ext(wp, undo_sync, FALSE, TRUE, TRUE);
+ win_enter_ext(wp, undo_sync, false, false, true, true);
}
/*
@@ -3554,7 +3622,9 @@ void win_enter(win_T *wp, bool undo_sync)
* Can be called with "curwin_invalid" TRUE, which means that curwin has just
* been closed and isn't valid.
*/
-static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid, int trigger_enter_autocmds, int trigger_leave_autocmds)
+static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid,
+ int trigger_new_autocmds, int trigger_enter_autocmds,
+ int trigger_leave_autocmds)
{
int other_buffer = FALSE;
@@ -3603,33 +3673,46 @@ static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid, int tri
curwin->w_cursor.coladd = 0;
changed_line_abv_curs(); /* assume cursor position needs updating */
- // The new directory is either the local directory of the window, of the tab
- // or NULL.
- char_u *new_dir = curwin->w_localdir ? curwin->w_localdir : curtab->localdir;
+ // New directory is either the local directory of the window, tab or NULL.
+ char *new_dir = (char *)(curwin->w_localdir
+ ? curwin->w_localdir : curtab->tp_localdir);
+
+ char cwd[MAXPATHL];
+ if (os_dirname((char_u *)cwd, MAXPATHL) != OK) {
+ cwd[0] = NUL;
+ }
if (new_dir) {
// Window/tab has a local directory: Save current directory as global
- // directory (unless that was done already) and change to the local
- // directory.
+ // (unless that was done already) and change to the local directory.
if (globaldir == NULL) {
- char_u cwd[MAXPATHL];
-
- if (os_dirname(cwd, MAXPATHL) == OK) {
- globaldir = vim_strsave(cwd);
+ if (cwd[0] != NUL) {
+ globaldir = (char_u *)xstrdup(cwd);
}
}
- if (os_chdir((char *)new_dir) == 0) {
+ if (os_chdir(new_dir) == 0) {
+ if (!p_acd && !strequal(new_dir, cwd)) {
+ do_autocmd_dirchanged(new_dir, curwin->w_localdir
+ ? kCdScopeWindow : kCdScopeTab);
+ }
shorten_fnames(true);
}
} else if (globaldir != NULL) {
- /* Window doesn't have a local directory and we are not in the global
- * directory: Change to the global directory. */
- ignored = os_chdir((char *)globaldir);
+ // Window doesn't have a local directory and we are not in the global
+ // directory: Change to the global directory.
+ if (os_chdir((char *)globaldir) == 0) {
+ if (!p_acd && !strequal((char *)globaldir, cwd)) {
+ do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal);
+ }
+ }
xfree(globaldir);
globaldir = NULL;
shorten_fnames(TRUE);
}
+ if (trigger_new_autocmds) {
+ apply_autocmds(EVENT_WINNEW, NULL, NULL, false, curbuf);
+ }
if (trigger_enter_autocmds) {
apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
if (other_buffer)
@@ -3642,6 +3725,12 @@ static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid, int tri
if (restart_edit)
redraw_later(VALID); /* causes status line redraw */
+ if (hl_attr(HLF_INACTIVE)
+ || (prevwin && prevwin->w_hl_ids[HLF_INACTIVE])
+ || curwin->w_hl_ids[HLF_INACTIVE]) {
+ redraw_all_later(NOT_VALID);
+ }
+
/* set window height to desired minimal value */
if (curwin->w_height < p_wh && !curwin->w_p_wfh)
win_setheight((int)p_wh);
@@ -3735,8 +3824,8 @@ static win_T *win_alloc(win_T *after, int hidden)
new_wp->handle = ++last_win_id;
handle_register_window(new_wp);
- /* init w: variables */
- new_wp->w_vars = dict_alloc();
+ // Init w: variables.
+ new_wp->w_vars = tv_dict_alloc();
init_var_dict(new_wp->w_vars, &new_wp->w_winvar, VAR_SCOPE);
/* Don't execute autocommands while the window is not properly
@@ -4700,8 +4789,6 @@ void set_fraction(win_T *wp)
*/
void win_new_height(win_T *wp, int height)
{
- linenr_T lnum;
- int sline, line_size;
int prev_height = wp->w_height;
/* Don't want a negative height. Happens when splitting a tiny window.
@@ -4728,6 +4815,19 @@ void win_new_height(win_T *wp, int height)
wp->w_height = height;
wp->w_skipcol = 0;
+ // There is no point in adjusting the scroll position when exiting. Some
+ // values might be invalid.
+ if (!exiting) {
+ scroll_to_fraction(wp, prev_height);
+ }
+}
+
+void scroll_to_fraction(win_T *wp, int prev_height)
+{
+ linenr_T lnum;
+ int sline, line_size;
+ int height = wp->w_height;
+
/* Don't change w_topline when height is zero. Don't set w_topline when
* 'scrollbind' is set and this isn't the current window. */
if (height > 0
@@ -4824,7 +4924,7 @@ void win_new_height(win_T *wp, int height)
if (wp->w_buffer->terminal) {
terminal_resize(wp->w_buffer->terminal, 0, wp->w_height);
- redraw_win_later(wp, CLEAR);
+ redraw_win_later(wp, NOT_VALID);
}
}
@@ -4848,7 +4948,6 @@ void win_new_width(win_T *wp, int width)
if (wp->w_height != 0) {
terminal_resize(wp->w_buffer->terminal, wp->w_width, 0);
}
- redraw_win_later(wp, CLEAR);
}
}
@@ -5077,7 +5176,7 @@ last_status (
{
/* Don't make a difference between horizontal or vertical split. */
last_status_rec(topframe, (p_ls == 2
- || (p_ls == 1 && (morewin || lastwin != firstwin))));
+ || (p_ls == 1 && (morewin || !ONE_WINDOW))));
}
static void last_status_rec(frame_T *fr, int statusline)
@@ -5134,6 +5233,9 @@ static void last_status_rec(frame_T *fr, int statusline)
*/
int tabline_height(void)
{
+ if (ui_is_external(kUITabline)) {
+ return 0;
+ }
assert(first_tabpage);
switch (p_stal) {
case 0: return 0;
@@ -5283,10 +5385,8 @@ restore_snapshot (
clear_snapshot(curtab, idx);
}
-/*
- * Check if frames "sn" and "fr" have the same layout, same following frames
- * and same children.
- */
+/// Check if frames "sn" and "fr" have the same layout, same following frames
+/// and same children. And the window pointer is valid.
static int check_snapshot_rec(frame_T *sn, frame_T *fr)
{
if (sn->fr_layout != fr->fr_layout
@@ -5295,7 +5395,8 @@ static int check_snapshot_rec(frame_T *sn, frame_T *fr)
|| (sn->fr_next != NULL
&& check_snapshot_rec(sn->fr_next, fr->fr_next) == FAIL)
|| (sn->fr_child != NULL
- && check_snapshot_rec(sn->fr_child, fr->fr_child) == FAIL))
+ && check_snapshot_rec(sn->fr_child, fr->fr_child) == FAIL)
+ || (sn->fr_win != NULL && !win_valid(sn->fr_win)))
return FAIL;
return OK;
}
@@ -5386,44 +5487,45 @@ void restore_win(win_T *save_curwin, tabpage_T *save_curtab, int no_display)
unblock_autocmds();
}
-/*
- * Make "buf" the current buffer. restore_buffer() MUST be called to undo.
- * No autocommands will be executed. Use aucmd_prepbuf() if there are any.
- */
-void switch_buffer(buf_T **save_curbuf, buf_T *buf)
+/// Make "buf" the current buffer.
+///
+/// restore_buffer() MUST be called to undo.
+/// No autocommands will be executed. Use aucmd_prepbuf() if there are any.
+void switch_buffer(bufref_T *save_curbuf, buf_T *buf)
{
block_autocmds();
- *save_curbuf = curbuf;
- --curbuf->b_nwindows;
+ set_bufref(save_curbuf, curbuf);
+ curbuf->b_nwindows--;
curbuf = buf;
curwin->w_buffer = buf;
- ++curbuf->b_nwindows;
+ curbuf->b_nwindows++;
}
-/*
- * Restore the current buffer after using switch_buffer().
- */
-void restore_buffer(buf_T *save_curbuf)
+/// Restore the current buffer after using switch_buffer().
+void restore_buffer(bufref_T *save_curbuf)
{
unblock_autocmds();
- /* Check for valid buffer, just in case. */
- if (buf_valid(save_curbuf)) {
- --curbuf->b_nwindows;
- curwin->w_buffer = save_curbuf;
- curbuf = save_curbuf;
- ++curbuf->b_nwindows;
+ // Check for valid buffer, just in case.
+ if (bufref_valid(save_curbuf)) {
+ curbuf->b_nwindows--;
+ curwin->w_buffer = save_curbuf->br_buf;
+ curbuf = save_curbuf->br_buf;
+ curbuf->b_nwindows++;
}
}
-// Add match to the match list of window 'wp'. The pattern 'pat' will be
-// highlighted with the group 'grp' with priority 'prio'.
-// Optionally, a desired ID 'id' can be specified (greater than or equal to 1).
-// If no particular ID is desired, -1 must be specified for 'id'.
-// Return ID of added match, -1 on failure.
-int match_add(win_T *wp, char_u *grp, char_u *pat,
+/// Add match to the match list of window 'wp'. The pattern 'pat' will be
+/// highlighted with the group 'grp' with priority 'prio'.
+/// Optionally, a desired ID 'id' can be specified (greater than or equal to 1).
+///
+/// @param[in] id a desired ID 'id' can be specified
+/// (greater than or equal to 1). -1 must be specified if no
+/// particular ID is desired
+/// @return ID of added match, -1 on failure.
+int match_add(win_T *wp, const char *const grp, const char *const pat,
int prio, int id, list_T *pos_list,
- char_u *conceal_char)
+ const char *const conceal_char)
{
matchitem_T *cur;
matchitem_T *prev;
@@ -5436,8 +5538,8 @@ int match_add(win_T *wp, char_u *grp, char_u *pat,
return -1;
}
if (id < -1 || id == 0) {
- EMSGN("E799: Invalid ID: %" PRId64
- " (must be greater than or equal to 1)",
+ EMSGN(_("E799: Invalid ID: %" PRId64
+ " (must be greater than or equal to 1)"),
id);
return -1;
}
@@ -5445,17 +5547,17 @@ int match_add(win_T *wp, char_u *grp, char_u *pat,
cur = wp->w_match_head;
while (cur != NULL) {
if (cur->id == id) {
- EMSGN("E801: ID already taken: %" PRId64, id);
+ EMSGN(_("E801: ID already taken: %" PRId64), id);
return -1;
}
cur = cur->next;
}
}
- if ((hlg_id = syn_namen2id(grp, (int)STRLEN(grp))) == 0) {
+ if ((hlg_id = syn_name2id((const char_u *)grp)) == 0) {
EMSG2(_(e_nogroup), grp);
return -1;
}
- if (pat != NULL && (regprog = vim_regcomp(pat, RE_MAGIC)) == NULL) {
+ if (pat != NULL && (regprog = vim_regcomp((char_u *)pat, RE_MAGIC)) == NULL) {
EMSG2(_(e_invarg2), pat);
return -1;
}
@@ -5474,14 +5576,14 @@ int match_add(win_T *wp, char_u *grp, char_u *pat,
m = xcalloc(1, sizeof(matchitem_T));
m->id = id;
m->priority = prio;
- m->pattern = pat == NULL ? NULL: vim_strsave(pat);
+ m->pattern = pat == NULL ? NULL: (char_u *)xstrdup(pat);
m->hlg_id = hlg_id;
m->match.regprog = regprog;
m->match.rmm_ic = FALSE;
m->match.rmm_maxcol = 0;
m->conceal_char = 0;
if (conceal_char != NULL) {
- m->conceal_char = (*mb_ptr2char)(conceal_char);
+ m->conceal_char = (*mb_ptr2char)((const char_u *)conceal_char);
}
// Set up position matches
@@ -5499,7 +5601,7 @@ int match_add(win_T *wp, char_u *grp, char_u *pat,
int len = 1;
list_T *subl;
listitem_T *subli;
- int error = false;
+ bool error = false;
if (li->li_tv.v_type == VAR_LIST) {
subl = li->li_tv.vval.v_list;
@@ -5510,8 +5612,8 @@ int match_add(win_T *wp, char_u *grp, char_u *pat,
if (subli == NULL) {
goto fail;
}
- lnum = get_tv_number_chk(&subli->li_tv, &error);
- if (error == true) {
+ lnum = tv_get_number_chk(&subli->li_tv, &error);
+ if (error) {
goto fail;
}
if (lnum == 0) {
@@ -5521,13 +5623,14 @@ int match_add(win_T *wp, char_u *grp, char_u *pat,
m->pos.pos[i].lnum = lnum;
subli = subli->li_next;
if (subli != NULL) {
- col = get_tv_number_chk(&subli->li_tv, &error);
- if (error == true)
+ col = tv_get_number_chk(&subli->li_tv, &error);
+ if (error) {
goto fail;
+ }
subli = subli->li_next;
if (subli != NULL) {
- len = get_tv_number_chk(&subli->li_tv, &error);
- if (error == true) {
+ len = tv_get_number_chk(&subli->li_tv, &error);
+ if (error) {
goto fail;
}
}
@@ -5597,10 +5700,9 @@ fail:
return -1;
}
-/*
- * Delete match with ID 'id' in the match list of window 'wp'.
- * Print error messages if 'perr' is TRUE.
- */
+
+/// Delete match with ID 'id' in the match list of window 'wp'.
+/// Print error messages if 'perr' is TRUE.
int match_delete(win_T *wp, int id, int perr)
{
matchitem_T *cur = wp->w_match_head;
@@ -5608,10 +5710,11 @@ int match_delete(win_T *wp, int id, int perr)
int rtype = SOME_VALID;
if (id < 1) {
- if (perr == TRUE)
- EMSGN("E802: Invalid ID: %" PRId64
- " (must be greater than or equal to 1)",
+ if (perr) {
+ EMSGN(_("E802: Invalid ID: %" PRId64
+ " (must be greater than or equal to 1)"),
id);
+ }
return -1;
}
while (cur != NULL && cur->id != id) {
@@ -5619,8 +5722,9 @@ int match_delete(win_T *wp, int id, int perr)
cur = cur->next;
}
if (cur == NULL) {
- if (perr == TRUE)
- EMSGN("E803: ID not found: %" PRId64, id);
+ if (perr) {
+ EMSGN(_("E803: ID not found: %" PRId64), id);
+ }
return -1;
}
if (cur == prev)
@@ -5726,23 +5830,28 @@ int win_getid(typval_T *argvars)
if (argvars[0].v_type == VAR_UNKNOWN) {
return curwin->handle;
}
- int winnr = get_tv_number(&argvars[0]);
+ int winnr = tv_get_number(&argvars[0]);
win_T *wp;
if (winnr > 0) {
if (argvars[1].v_type == VAR_UNKNOWN) {
wp = firstwin;
} else {
- tabpage_T *tp;
- int tabnr = get_tv_number(&argvars[1]);
- for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) {
+ tabpage_T *tp = NULL;
+ int tabnr = tv_get_number(&argvars[1]);
+ FOR_ALL_TABS(tp2) {
if (--tabnr == 0) {
+ tp = tp2;
break;
}
}
if (tp == NULL) {
return -1;
}
- wp = tp->tp_firstwin;
+ if (tp == curtab) {
+ wp = firstwin;
+ } else {
+ wp = tp->tp_firstwin;
+ }
}
for ( ; wp != NULL; wp = wp->w_next) {
if (--winnr == 0) {
@@ -5755,7 +5864,7 @@ int win_getid(typval_T *argvars)
int win_gotoid(typval_T *argvars)
{
- int id = get_tv_number(&argvars[0]);
+ int id = tv_get_number(&argvars[0]);
FOR_ALL_TAB_WINDOWS(tp, wp) {
if (wp->handle == id) {
@@ -5790,16 +5899,16 @@ void win_id2tabwin(typval_T *argvars, list_T *list)
{
int winnr = 1;
int tabnr = 1;
- int id = get_tv_number(&argvars[0]);
+ handle_T id = (handle_T)tv_get_number(&argvars[0]);
win_get_tabwin(id, &tabnr, &winnr);
- list_append_number(list, tabnr);
- list_append_number(list, winnr);
+ tv_list_append_number(list, tabnr);
+ tv_list_append_number(list, winnr);
}
win_T * win_id2wp(typval_T *argvars)
{
- int id = get_tv_number(&argvars[0]);
+ int id = tv_get_number(&argvars[0]);
FOR_ALL_TAB_WINDOWS(tp, wp) {
if (wp->handle == id) {
@@ -5812,11 +5921,10 @@ win_T * win_id2wp(typval_T *argvars)
int win_id2win(typval_T *argvars)
{
- win_T *wp;
int nr = 1;
- int id = get_tv_number(&argvars[0]);
+ int id = tv_get_number(&argvars[0]);
- for (wp = firstwin; wp != NULL; wp = wp->w_next) {
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->handle == id) {
return nr;
}
@@ -5827,14 +5935,11 @@ int win_id2win(typval_T *argvars)
void win_findbuf(typval_T *argvars, list_T *list)
{
- int bufnr = get_tv_number(&argvars[0]);
+ int bufnr = tv_get_number(&argvars[0]);
- for (tabpage_T *tp = first_tabpage; tp != NULL; tp = tp->tp_next) {
- for (win_T *wp = tp == curtab ? firstwin : tp->tp_firstwin;
- wp != NULL; wp = wp->w_next) {
- if (wp->w_buffer->b_fnum == bufnr) {
- list_append_number(list, wp->handle);
- }
+ FOR_ALL_TAB_WINDOWS(tp, wp) {
+ if (wp->w_buffer->b_fnum == bufnr) {
+ tv_list_append_number(list, wp->handle);
}
}
}
diff --git a/src/nvim/window.h b/src/nvim/window.h
index 2ac4c00c28..82b3fe5e88 100644
--- a/src/nvim/window.h
+++ b/src/nvim/window.h
@@ -3,6 +3,8 @@
#include <stdbool.h>
+#include "nvim/buffer_defs.h"
+
/* Values for file_name_in_line() */
#define FNAME_MESS 1 /* give error message */
#define FNAME_EXP 2 /* expand to path */